1f903da7335433ae243cf7ff59662be1a03ee9a14Tom Stellard//===-- AMDGPUTargetMachine.cpp - TargetMachine for hw codegen targets-----===//
2a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//
3a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//                     The LLVM Compiler Infrastructure
4a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//
5a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// This file is distributed under the University of Illinois Open Source
6a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// License. See LICENSE.TXT for details.
7a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//
8a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===----------------------------------------------------------------------===//
9a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//
10f903da7335433ae243cf7ff59662be1a03ee9a14Tom Stellard// The AMDGPU target machine contains all of the hardware specific information
11f903da7335433ae243cf7ff59662be1a03ee9a14Tom Stellard// needed to emit code for R600 and SI GPUs.
12a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//
13a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===----------------------------------------------------------------------===//
14a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
15a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "AMDGPUTargetMachine.h"
16a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "AMDGPU.h"
17a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "R600ISelLowering.h"
18a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "R600InstrInfo.h"
19a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "SIISelLowering.h"
20a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "SIInstrInfo.h"
21a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/Analysis/Passes.h"
22a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/Analysis/Verifier.h"
23a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/CodeGen/MachineFunctionAnalysis.h"
24a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/CodeGen/MachineModuleInfo.h"
25a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/CodeGen/Passes.h"
26a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/MC/MCAsmInfo.h"
27a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/PassManager.h"
28a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/Support/TargetRegistry.h"
29a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/Support/raw_os_ostream.h"
30a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/Transforms/IPO.h"
31a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/Transforms/Scalar.h"
32565a4e2a8625c79bde0eacf674a4f633151eeb0eVincent Lejeune#include <llvm/CodeGen/Passes.h>
33a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
34a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardusing namespace llvm;
35a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
3649fb99bd131a4ed89e6f55cf360f67618acafec4Tom Stellardextern "C" void LLVMInitializeAMDGPUTarget() {
3749fb99bd131a4ed89e6f55cf360f67618acafec4Tom Stellard  // Register the target
3849fb99bd131a4ed89e6f55cf360f67618acafec4Tom Stellard  RegisterTargetMachine<AMDGPUTargetMachine> X(TheAMDGPUTarget);
3949fb99bd131a4ed89e6f55cf360f67618acafec4Tom Stellard}
4049fb99bd131a4ed89e6f55cf360f67618acafec4Tom Stellard
41a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardAMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, StringRef TT,
42a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    StringRef CPU, StringRef FS,
43a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  TargetOptions Options,
44a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  Reloc::Model RM, CodeModel::Model CM,
45a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  CodeGenOpt::Level OptLevel
46a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard)
47a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard:
4849fb99bd131a4ed89e6f55cf360f67618acafec4Tom Stellard  LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OptLevel),
49a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  Subtarget(TT, CPU, FS),
5049fb99bd131a4ed89e6f55cf360f67618acafec4Tom Stellard  DataLayout(Subtarget.getDataLayout()),
5149fb99bd131a4ed89e6f55cf360f67618acafec4Tom Stellard  FrameLowering(TargetFrameLowering::StackGrowsUp,
5249fb99bd131a4ed89e6f55cf360f67618acafec4Tom Stellard      Subtarget.device()->getStackAlignment(), 0),
5349fb99bd131a4ed89e6f55cf360f67618acafec4Tom Stellard  IntrinsicInfo(this),
54cd287301ec598d2811f3f85c03d23bae01be2359Tom Stellard  InstrItins(&Subtarget.getInstrItineraryData()),
55a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  mDump(false)
56a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
57a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
58bcfc97dbf40c256ed59c2424e0c55b845f0f2569Tom Stellard  // TLInfo uses InstrInfo so it must be initialized after.
592f921101c0826dc52a2c69f85c3da0f7f6e8212aTom Stellard  if (Subtarget.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
60a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    InstrInfo = new R600InstrInfo(*this);
61a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    TLInfo = new R600TargetLowering(*this);
62a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  } else {
63a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    InstrInfo = new SIInstrInfo(*this);
64a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    TLInfo = new SITargetLowering(*this);
65a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
66a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
67a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
68a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardAMDGPUTargetMachine::~AMDGPUTargetMachine()
69a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
70a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
71a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
72a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardnamespace {
73a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardclass AMDGPUPassConfig : public TargetPassConfig {
74a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardpublic:
75a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  AMDGPUPassConfig(AMDGPUTargetMachine *TM, PassManagerBase &PM)
76a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    : TargetPassConfig(TM, PM) {}
77a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
78a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  AMDGPUTargetMachine &getAMDGPUTargetMachine() const {
79a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard    return getTM<AMDGPUTargetMachine>();
80a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
81a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
82a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  virtual bool addPreISel();
83a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  virtual bool addInstSelector();
84a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  virtual bool addPreRegAlloc();
85a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  virtual bool addPostRegAlloc();
86a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  virtual bool addPreSched2();
87a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  virtual bool addPreEmitPass();
88a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard};
89a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} // End of anonymous namespace
90a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
91a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardTargetPassConfig *AMDGPUTargetMachine::createPassConfig(PassManagerBase &PM) {
92a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return new AMDGPUPassConfig(this, PM);
93a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
94a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
95a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardbool
96a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardAMDGPUPassConfig::addPreISel()
97a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
98b72ab79d73b29ec087d90cf2c698adbab4db5defTom Stellard  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
992f921101c0826dc52a2c69f85c3da0f7f6e8212aTom Stellard  if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
100d742d812d82ef61de1f41a18c8251db9b001bdd1Tom Stellard    PM->add(createR600KernelParametersPass(
101a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard                     getAMDGPUTargetMachine().getTargetData()));
102a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
103a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return false;
104a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
105a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
106a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardbool AMDGPUPassConfig::addInstSelector() {
1072f921101c0826dc52a2c69f85c3da0f7f6e8212aTom Stellard  PM->add(createAMDGPUPeepholeOpt(*TM));
1082f921101c0826dc52a2c69f85c3da0f7f6e8212aTom Stellard  PM->add(createAMDGPUISelDag(getAMDGPUTargetMachine()));
109a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return false;
110a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
111a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
112a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardbool AMDGPUPassConfig::addPreRegAlloc() {
113b72ab79d73b29ec087d90cf2c698adbab4db5defTom Stellard  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
114a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1152f921101c0826dc52a2c69f85c3da0f7f6e8212aTom Stellard  if (ST.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
116d742d812d82ef61de1f41a18c8251db9b001bdd1Tom Stellard    PM->add(createSIAssignInterpRegsPass(*TM));
117a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  }
118d742d812d82ef61de1f41a18c8251db9b001bdd1Tom Stellard  PM->add(createAMDGPUConvertToISAPass(*TM));
119a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return false;
120a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
121a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
122a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardbool AMDGPUPassConfig::addPostRegAlloc() {
123a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return false;
124a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
125a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
126a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardbool AMDGPUPassConfig::addPreSched2() {
127565a4e2a8625c79bde0eacf674a4f633151eeb0eVincent Lejeune
128565a4e2a8625c79bde0eacf674a4f633151eeb0eVincent Lejeune  addPass(IfConverterID);
129a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return false;
130a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
131a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
132a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardbool AMDGPUPassConfig::addPreEmitPass() {
1332f921101c0826dc52a2c69f85c3da0f7f6e8212aTom Stellard  PM->add(createAMDGPUCFGPreparationPass(*TM));
1342f921101c0826dc52a2c69f85c3da0f7f6e8212aTom Stellard  PM->add(createAMDGPUCFGStructurizerPass(*TM));
135a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
13682a5d0c64142990236b40567561b6e99b7158216Tom Stellard  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
13782a5d0c64142990236b40567561b6e99b7158216Tom Stellard  if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
13882a5d0c64142990236b40567561b6e99b7158216Tom Stellard    PM->add(createR600ExpandSpecialInstrsPass(*TM));
13982a5d0c64142990236b40567561b6e99b7158216Tom Stellard    addPass(FinalizeMachineBundlesID);
14082a5d0c64142990236b40567561b6e99b7158216Tom Stellard  }
14182a5d0c64142990236b40567561b6e99b7158216Tom Stellard
142a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard  return false;
143a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
144a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
145