LLVM API Documentation

AMDGPUTargetMachine.cpp
Go to the documentation of this file.
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 }