1249259Sdim//===-- AMDGPUTargetMachine.cpp - TargetMachine for hw codegen targets-----===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim/// \file 11249259Sdim/// \brief The AMDGPU target machine contains all of the hardware specific 12249259Sdim/// information needed to emit code for R600 and SI GPUs. 13249259Sdim// 14249259Sdim//===----------------------------------------------------------------------===// 15249259Sdim 16249259Sdim#include "AMDGPUTargetMachine.h" 17249259Sdim#include "AMDGPU.h" 18249259Sdim#include "R600ISelLowering.h" 19249259Sdim#include "R600InstrInfo.h" 20249259Sdim#include "R600MachineScheduler.h" 21249259Sdim#include "SIISelLowering.h" 22249259Sdim#include "SIInstrInfo.h" 23249259Sdim#include "llvm/Analysis/Passes.h" 24249259Sdim#include "llvm/Analysis/Verifier.h" 25249259Sdim#include "llvm/CodeGen/MachineFunctionAnalysis.h" 26249259Sdim#include "llvm/CodeGen/MachineModuleInfo.h" 27249259Sdim#include "llvm/CodeGen/Passes.h" 28249259Sdim#include "llvm/MC/MCAsmInfo.h" 29249259Sdim#include "llvm/PassManager.h" 30249259Sdim#include "llvm/Support/TargetRegistry.h" 31249259Sdim#include "llvm/Support/raw_os_ostream.h" 32249259Sdim#include "llvm/Transforms/IPO.h" 33249259Sdim#include "llvm/Transforms/Scalar.h" 34249259Sdim#include <llvm/CodeGen/Passes.h> 35249259Sdim 36249259Sdimusing namespace llvm; 37249259Sdim 38249259Sdimextern "C" void LLVMInitializeR600Target() { 39249259Sdim // Register the target 40249259Sdim RegisterTargetMachine<AMDGPUTargetMachine> X(TheAMDGPUTarget); 41249259Sdim} 42249259Sdim 43249259Sdimstatic ScheduleDAGInstrs *createR600MachineScheduler(MachineSchedContext *C) { 44249259Sdim return new ScheduleDAGMI(C, new R600SchedStrategy()); 45249259Sdim} 46249259Sdim 47249259Sdimstatic MachineSchedRegistry 48249259SdimSchedCustomRegistry("r600", "Run R600's custom scheduler", 49249259Sdim createR600MachineScheduler); 50249259Sdim 51249259SdimAMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, StringRef TT, 52249259Sdim StringRef CPU, StringRef FS, 53249259Sdim TargetOptions Options, 54249259Sdim Reloc::Model RM, CodeModel::Model CM, 55249259Sdim CodeGenOpt::Level OptLevel 56249259Sdim) 57249259Sdim: 58249259Sdim LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OptLevel), 59249259Sdim Subtarget(TT, CPU, FS), 60249259Sdim Layout(Subtarget.getDataLayout()), 61249259Sdim FrameLowering(TargetFrameLowering::StackGrowsUp, 62249259Sdim Subtarget.device()->getStackAlignment(), 0), 63249259Sdim IntrinsicInfo(this), 64249259Sdim InstrItins(&Subtarget.getInstrItineraryData()) { 65249259Sdim // TLInfo uses InstrInfo so it must be initialized after. 66249259Sdim if (Subtarget.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) { 67249259Sdim InstrInfo = new R600InstrInfo(*this); 68249259Sdim TLInfo = new R600TargetLowering(*this); 69249259Sdim } else { 70249259Sdim InstrInfo = new SIInstrInfo(*this); 71249259Sdim TLInfo = new SITargetLowering(*this); 72249259Sdim } 73249259Sdim} 74249259Sdim 75249259SdimAMDGPUTargetMachine::~AMDGPUTargetMachine() { 76249259Sdim} 77249259Sdim 78249259Sdimnamespace { 79249259Sdimclass AMDGPUPassConfig : public TargetPassConfig { 80249259Sdimpublic: 81249259Sdim AMDGPUPassConfig(AMDGPUTargetMachine *TM, PassManagerBase &PM) 82249259Sdim : TargetPassConfig(TM, PM) { 83249259Sdim const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 84249259Sdim if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) { 85249259Sdim enablePass(&MachineSchedulerID); 86249259Sdim MachineSchedRegistry::setDefault(createR600MachineScheduler); 87249259Sdim } 88249259Sdim } 89249259Sdim 90249259Sdim AMDGPUTargetMachine &getAMDGPUTargetMachine() const { 91249259Sdim return getTM<AMDGPUTargetMachine>(); 92249259Sdim } 93249259Sdim 94249259Sdim virtual bool addPreISel(); 95249259Sdim virtual bool addInstSelector(); 96249259Sdim virtual bool addPreRegAlloc(); 97249259Sdim virtual bool addPostRegAlloc(); 98249259Sdim virtual bool addPreSched2(); 99249259Sdim virtual bool addPreEmitPass(); 100249259Sdim}; 101249259Sdim} // End of anonymous namespace 102249259Sdim 103249259SdimTargetPassConfig *AMDGPUTargetMachine::createPassConfig(PassManagerBase &PM) { 104249259Sdim return new AMDGPUPassConfig(this, PM); 105249259Sdim} 106249259Sdim 107249259Sdimbool 108249259SdimAMDGPUPassConfig::addPreISel() { 109249259Sdim const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 110249259Sdim if (ST.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) { 111249259Sdim addPass(createAMDGPUStructurizeCFGPass()); 112249259Sdim addPass(createSIAnnotateControlFlowPass()); 113249259Sdim } 114249259Sdim return false; 115249259Sdim} 116249259Sdim 117249259Sdimbool AMDGPUPassConfig::addInstSelector() { 118249259Sdim addPass(createAMDGPUISelDag(getAMDGPUTargetMachine())); 119249259Sdim 120249259Sdim const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 121249259Sdim if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) { 122249259Sdim // This callbacks this pass uses are not implemented yet on SI. 123249259Sdim addPass(createAMDGPUIndirectAddressingPass(*TM)); 124249259Sdim } 125249259Sdim return false; 126249259Sdim} 127249259Sdim 128249259Sdimbool AMDGPUPassConfig::addPreRegAlloc() { 129249259Sdim addPass(createAMDGPUConvertToISAPass(*TM)); 130249259Sdim return false; 131249259Sdim} 132249259Sdim 133249259Sdimbool AMDGPUPassConfig::addPostRegAlloc() { 134249259Sdim const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 135249259Sdim 136249259Sdim if (ST.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) { 137249259Sdim addPass(createSIInsertWaits(*TM)); 138249259Sdim } 139249259Sdim return false; 140249259Sdim} 141249259Sdim 142249259Sdimbool AMDGPUPassConfig::addPreSched2() { 143249259Sdim 144249259Sdim addPass(&IfConverterID); 145249259Sdim return false; 146249259Sdim} 147249259Sdim 148249259Sdimbool AMDGPUPassConfig::addPreEmitPass() { 149249259Sdim const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 150249259Sdim if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) { 151249259Sdim addPass(createAMDGPUCFGPreparationPass(*TM)); 152249259Sdim addPass(createAMDGPUCFGStructurizerPass(*TM)); 153249259Sdim addPass(createR600EmitClauseMarkers(*TM)); 154249259Sdim addPass(createR600ExpandSpecialInstrsPass(*TM)); 155251662Sdim addPass(&FinalizeMachineBundlesID); 156251662Sdim addPass(createR600Packetizer(*TM)); 157249259Sdim addPass(createR600ControlFlowFinalizer(*TM)); 158249259Sdim } else { 159249259Sdim addPass(createSILowerControlFlowPass(*TM)); 160249259Sdim } 161249259Sdim 162249259Sdim return false; 163249259Sdim} 164249259Sdim 165