LLVM API Documentation
00001 //===-- AMDGPUTargetMachine.cpp - TargetMachine for hw codegen targets-----===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 /// \file 00011 /// \brief The AMDGPU target machine contains all of the hardware specific 00012 /// information needed to emit code for R600 and SI GPUs. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #include "AMDGPUTargetMachine.h" 00017 #include "AMDGPU.h" 00018 #include "R600ISelLowering.h" 00019 #include "R600InstrInfo.h" 00020 #include "R600MachineScheduler.h" 00021 #include "SIISelLowering.h" 00022 #include "SIInstrInfo.h" 00023 #include "llvm/Analysis/Passes.h" 00024 #include "llvm/CodeGen/MachineFunctionAnalysis.h" 00025 #include "llvm/CodeGen/MachineModuleInfo.h" 00026 #include "llvm/CodeGen/Passes.h" 00027 #include "llvm/IR/Verifier.h" 00028 #include "llvm/MC/MCAsmInfo.h" 00029 #include "llvm/PassManager.h" 00030 #include "llvm/Support/TargetRegistry.h" 00031 #include "llvm/Support/raw_os_ostream.h" 00032 #include "llvm/Transforms/IPO.h" 00033 #include "llvm/Transforms/Scalar.h" 00034 #include <llvm/CodeGen/Passes.h> 00035 00036 using namespace llvm; 00037 00038 extern "C" void LLVMInitializeR600Target() { 00039 // Register the target 00040 RegisterTargetMachine<AMDGPUTargetMachine> X(TheAMDGPUTarget); 00041 } 00042 00043 static ScheduleDAGInstrs *createR600MachineScheduler(MachineSchedContext *C) { 00044 return new ScheduleDAGMILive(C, make_unique<R600SchedStrategy>()); 00045 } 00046 00047 static MachineSchedRegistry 00048 SchedCustomRegistry("r600", "Run R600's custom scheduler", 00049 createR600MachineScheduler); 00050 00051 AMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, StringRef TT, 00052 StringRef CPU, StringRef FS, 00053 TargetOptions Options, Reloc::Model RM, 00054 CodeModel::Model CM, 00055 CodeGenOpt::Level OptLevel) 00056 : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OptLevel), 00057 Subtarget(TT, CPU, FS, *this), IntrinsicInfo() { 00058 setRequiresStructuredCFG(true); 00059 initAsmInfo(); 00060 } 00061 00062 AMDGPUTargetMachine::~AMDGPUTargetMachine() { 00063 } 00064 00065 namespace { 00066 class AMDGPUPassConfig : public TargetPassConfig { 00067 public: 00068 AMDGPUPassConfig(AMDGPUTargetMachine *TM, PassManagerBase &PM) 00069 : TargetPassConfig(TM, PM) {} 00070 00071 AMDGPUTargetMachine &getAMDGPUTargetMachine() const { 00072 return getTM<AMDGPUTargetMachine>(); 00073 } 00074 00075 ScheduleDAGInstrs * 00076 createMachineScheduler(MachineSchedContext *C) const override { 00077 const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 00078 if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) 00079 return createR600MachineScheduler(C); 00080 return nullptr; 00081 } 00082 00083 void addCodeGenPrepare() override; 00084 bool addPreISel() override; 00085 bool addInstSelector() override; 00086 bool addPreRegAlloc() override; 00087 bool addPostRegAlloc() override; 00088 bool addPreSched2() override; 00089 bool addPreEmitPass() override; 00090 }; 00091 } // End of anonymous namespace 00092 00093 TargetPassConfig *AMDGPUTargetMachine::createPassConfig(PassManagerBase &PM) { 00094 return new AMDGPUPassConfig(this, PM); 00095 } 00096 00097 //===----------------------------------------------------------------------===// 00098 // AMDGPU Analysis Pass Setup 00099 //===----------------------------------------------------------------------===// 00100 00101 void AMDGPUTargetMachine::addAnalysisPasses(PassManagerBase &PM) { 00102 // Add first the target-independent BasicTTI pass, then our AMDGPU pass. This 00103 // allows the AMDGPU pass to delegate to the target independent layer when 00104 // appropriate. 00105 PM.add(createBasicTargetTransformInfoPass(this)); 00106 PM.add(createAMDGPUTargetTransformInfoPass(this)); 00107 } 00108 00109 void AMDGPUPassConfig::addCodeGenPrepare() { 00110 const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 00111 if (ST.isPromoteAllocaEnabled()) { 00112 addPass(createAMDGPUPromoteAlloca(ST)); 00113 addPass(createSROAPass()); 00114 } 00115 00116 TargetPassConfig::addCodeGenPrepare(); 00117 } 00118 00119 bool 00120 AMDGPUPassConfig::addPreISel() { 00121 const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 00122 addPass(createFlattenCFGPass()); 00123 if (ST.IsIRStructurizerEnabled()) 00124 addPass(createStructurizeCFGPass()); 00125 if (ST.getGeneration() >= AMDGPUSubtarget::SOUTHERN_ISLANDS) { 00126 addPass(createSinkingPass()); 00127 addPass(createSITypeRewriter()); 00128 addPass(createSIAnnotateControlFlowPass()); 00129 } else { 00130 addPass(createR600TextureIntrinsicsReplacer()); 00131 } 00132 return false; 00133 } 00134 00135 bool AMDGPUPassConfig::addInstSelector() { 00136 addPass(createAMDGPUISelDag(getAMDGPUTargetMachine())); 00137 addPass(createSILowerI1CopiesPass()); 00138 return false; 00139 } 00140 00141 bool AMDGPUPassConfig::addPreRegAlloc() { 00142 const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 00143 00144 if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) { 00145 addPass(createR600VectorRegMerger(*TM)); 00146 } else { 00147 addPass(createSIFixSGPRCopiesPass(*TM)); 00148 // SIFixSGPRCopies can generate a lot of duplicate instructions, 00149 // so we need to run MachineCSE afterwards. 00150 addPass(&MachineCSEID); 00151 addPass(createSIShrinkInstructionsPass()); 00152 initializeSIFixSGPRLiveRangesPass(*PassRegistry::getPassRegistry()); 00153 insertPass(&RegisterCoalescerID, &SIFixSGPRLiveRangesID); 00154 } 00155 return false; 00156 } 00157 00158 bool AMDGPUPassConfig::addPostRegAlloc() { 00159 const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 00160 00161 addPass(createSIShrinkInstructionsPass()); 00162 if (ST.getGeneration() > AMDGPUSubtarget::NORTHERN_ISLANDS) { 00163 addPass(createSIInsertWaits(*TM)); 00164 } 00165 return false; 00166 } 00167 00168 bool AMDGPUPassConfig::addPreSched2() { 00169 const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 00170 00171 if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) 00172 addPass(createR600EmitClauseMarkers()); 00173 if (ST.isIfCvtEnabled()) 00174 addPass(&IfConverterID); 00175 if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) 00176 addPass(createR600ClauseMergePass(*TM)); 00177 return false; 00178 } 00179 00180 bool AMDGPUPassConfig::addPreEmitPass() { 00181 const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 00182 if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) { 00183 addPass(createAMDGPUCFGStructurizerPass()); 00184 addPass(createR600ExpandSpecialInstrsPass(*TM)); 00185 addPass(&FinalizeMachineBundlesID); 00186 addPass(createR600Packetizer(*TM)); 00187 addPass(createR600ControlFlowFinalizer(*TM)); 00188 } else { 00189 addPass(createSILowerControlFlowPass(*TM)); 00190 } 00191 00192 return false; 00193 }