1 //===-- AMDGPUTargetMachine.cpp - TargetMachine for hw codegen targets-----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// \brief The AMDGPU target machine contains all of the hardware specific
12 /// information needed to emit code for R600 and SI GPUs.
14 //===----------------------------------------------------------------------===//
16 #include "AMDGPUTargetMachine.h"
18 #include "R600ISelLowering.h"
19 #include "R600InstrInfo.h"
20 #include "SIISelLowering.h"
21 #include "SIInstrInfo.h"
22 #include "llvm/Analysis/Passes.h"
23 #include "llvm/Analysis/Verifier.h"
24 #include "llvm/CodeGen/MachineFunctionAnalysis.h"
25 #include "llvm/CodeGen/MachineModuleInfo.h"
26 #include "llvm/CodeGen/Passes.h"
27 #include "llvm/MC/MCAsmInfo.h"
28 #include "llvm/PassManager.h"
29 #include "llvm/Support/TargetRegistry.h"
30 #include "llvm/Support/raw_os_ostream.h"
31 #include "llvm/Transforms/IPO.h"
32 #include "llvm/Transforms/Scalar.h"
33 #include <llvm/CodeGen/Passes.h>
37 extern "C" void LLVMInitializeR600Target() {
38 // Register the target
39 RegisterTargetMachine<AMDGPUTargetMachine> X(TheAMDGPUTarget);
42 AMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, StringRef TT,
43 StringRef CPU, StringRef FS,
44 TargetOptions Options,
45 Reloc::Model RM, CodeModel::Model CM,
46 CodeGenOpt::Level OptLevel
49 LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OptLevel),
50 Subtarget(TT, CPU, FS),
51 Layout(Subtarget.getDataLayout()),
52 FrameLowering(TargetFrameLowering::StackGrowsUp,
53 Subtarget.device()->getStackAlignment(), 0),
55 InstrItins(&Subtarget.getInstrItineraryData()) {
56 // TLInfo uses InstrInfo so it must be initialized after.
57 if (Subtarget.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
58 InstrInfo = new R600InstrInfo(*this);
59 TLInfo = new R600TargetLowering(*this);
61 InstrInfo = new SIInstrInfo(*this);
62 TLInfo = new SITargetLowering(*this);
66 AMDGPUTargetMachine::~AMDGPUTargetMachine() {
70 class AMDGPUPassConfig : public TargetPassConfig {
72 AMDGPUPassConfig(AMDGPUTargetMachine *TM, PassManagerBase &PM)
73 : TargetPassConfig(TM, PM) {}
75 AMDGPUTargetMachine &getAMDGPUTargetMachine() const {
76 return getTM<AMDGPUTargetMachine>();
79 virtual bool addPreISel();
80 virtual bool addInstSelector();
81 virtual bool addPreRegAlloc();
82 virtual bool addPostRegAlloc();
83 virtual bool addPreSched2();
84 virtual bool addPreEmitPass();
86 } // End of anonymous namespace
88 TargetPassConfig *AMDGPUTargetMachine::createPassConfig(PassManagerBase &PM) {
89 return new AMDGPUPassConfig(this, PM);
93 AMDGPUPassConfig::addPreISel() {
94 const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
95 if (ST.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
96 addPass(createAMDGPUStructurizeCFGPass());
97 addPass(createSIAnnotateControlFlowPass());
102 bool AMDGPUPassConfig::addInstSelector() {
103 addPass(createAMDGPUPeepholeOpt(*TM));
104 addPass(createAMDGPUISelDag(getAMDGPUTargetMachine()));
108 bool AMDGPUPassConfig::addPreRegAlloc() {
109 const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
111 if (ST.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
112 addPass(createSIAssignInterpRegsPass(*TM));
114 addPass(createAMDGPUConvertToISAPass(*TM));
118 bool AMDGPUPassConfig::addPostRegAlloc() {
119 const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
121 if (ST.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
122 addPass(createSIInsertWaits(*TM));
127 bool AMDGPUPassConfig::addPreSched2() {
129 addPass(&IfConverterID);
133 bool AMDGPUPassConfig::addPreEmitPass() {
134 const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
135 if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
136 addPass(createAMDGPUCFGPreparationPass(*TM));
137 addPass(createAMDGPUCFGStructurizerPass(*TM));
138 addPass(createR600ExpandSpecialInstrsPass(*TM));
139 addPass(createR600LowerConstCopy(*TM));
140 addPass(&FinalizeMachineBundlesID);
142 addPass(createSILowerLiteralConstantsPass(*TM));
143 addPass(createSILowerControlFlowPass(*TM));