Home | History | Annotate | Download | only in radeon
      1 //===-- AMDGPUTargetMachine.cpp - TargetMachine for hw codegen targets-----===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // The AMDGPU target machine contains all of the hardware specific information
     11 // needed to emit code for R600 and SI GPUs.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "AMDGPUTargetMachine.h"
     16 #include "AMDGPU.h"
     17 #include "R600ISelLowering.h"
     18 #include "R600InstrInfo.h"
     19 #include "SIISelLowering.h"
     20 #include "SIInstrInfo.h"
     21 #include "llvm/Analysis/Passes.h"
     22 #include "llvm/Analysis/Verifier.h"
     23 #include "llvm/CodeGen/MachineFunctionAnalysis.h"
     24 #include "llvm/CodeGen/MachineModuleInfo.h"
     25 #include "llvm/CodeGen/Passes.h"
     26 #include "llvm/MC/MCAsmInfo.h"
     27 #include "llvm/PassManager.h"
     28 #include "llvm/Support/TargetRegistry.h"
     29 #include "llvm/Support/raw_os_ostream.h"
     30 #include "llvm/Transforms/IPO.h"
     31 #include "llvm/Transforms/Scalar.h"
     32 #include <llvm/CodeGen/Passes.h>
     33 
     34 using namespace llvm;
     35 
     36 extern "C" void LLVMInitializeAMDGPUTarget() {
     37   // Register the target
     38   RegisterTargetMachine<AMDGPUTargetMachine> X(TheAMDGPUTarget);
     39 }
     40 
     41 AMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, StringRef TT,
     42     StringRef CPU, StringRef FS,
     43   TargetOptions Options,
     44   Reloc::Model RM, CodeModel::Model CM,
     45   CodeGenOpt::Level OptLevel
     46 )
     47 :
     48   LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OptLevel),
     49   Subtarget(TT, CPU, FS),
     50   DataLayout(Subtarget.getDataLayout()),
     51   FrameLowering(TargetFrameLowering::StackGrowsUp,
     52       Subtarget.device()->getStackAlignment(), 0),
     53   IntrinsicInfo(this),
     54   InstrItins(&Subtarget.getInstrItineraryData()),
     55   mDump(false)
     56 
     57 {
     58   // TLInfo uses InstrInfo so it must be initialized after.
     59   if (Subtarget.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
     60     InstrInfo = new R600InstrInfo(*this);
     61     TLInfo = new R600TargetLowering(*this);
     62   } else {
     63     InstrInfo = new SIInstrInfo(*this);
     64     TLInfo = new SITargetLowering(*this);
     65   }
     66 }
     67 
     68 AMDGPUTargetMachine::~AMDGPUTargetMachine()
     69 {
     70 }
     71 
     72 namespace {
     73 class AMDGPUPassConfig : public TargetPassConfig {
     74 public:
     75   AMDGPUPassConfig(AMDGPUTargetMachine *TM, PassManagerBase &PM)
     76     : TargetPassConfig(TM, PM) {}
     77 
     78   AMDGPUTargetMachine &getAMDGPUTargetMachine() const {
     79     return getTM<AMDGPUTargetMachine>();
     80   }
     81 
     82   virtual bool addPreISel();
     83   virtual bool addInstSelector();
     84   virtual bool addPreRegAlloc();
     85   virtual bool addPostRegAlloc();
     86   virtual bool addPreSched2();
     87   virtual bool addPreEmitPass();
     88 };
     89 } // End of anonymous namespace
     90 
     91 TargetPassConfig *AMDGPUTargetMachine::createPassConfig(PassManagerBase &PM) {
     92   return new AMDGPUPassConfig(this, PM);
     93 }
     94 
     95 bool
     96 AMDGPUPassConfig::addPreISel()
     97 {
     98   const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
     99   if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
    100     PM->add(createR600KernelParametersPass(
    101                      getAMDGPUTargetMachine().getTargetData()));
    102   }
    103   return false;
    104 }
    105 
    106 bool AMDGPUPassConfig::addInstSelector() {
    107   PM->add(createAMDGPUPeepholeOpt(*TM));
    108   PM->add(createAMDGPUISelDag(getAMDGPUTargetMachine()));
    109   return false;
    110 }
    111 
    112 bool AMDGPUPassConfig::addPreRegAlloc() {
    113   const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
    114 
    115   if (ST.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
    116     PM->add(createSIAssignInterpRegsPass(*TM));
    117   }
    118   PM->add(createAMDGPUConvertToISAPass(*TM));
    119   return false;
    120 }
    121 
    122 bool AMDGPUPassConfig::addPostRegAlloc() {
    123   return false;
    124 }
    125 
    126 bool AMDGPUPassConfig::addPreSched2() {
    127 
    128   addPass(IfConverterID);
    129   return false;
    130 }
    131 
    132 bool AMDGPUPassConfig::addPreEmitPass() {
    133   PM->add(createAMDGPUCFGPreparationPass(*TM));
    134   PM->add(createAMDGPUCFGStructurizerPass(*TM));
    135 
    136   const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
    137   if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
    138     PM->add(createR600ExpandSpecialInstrsPass(*TM));
    139     addPass(FinalizeMachineBundlesID);
    140   }
    141 
    142   return false;
    143 }
    144 
    145