1185377Ssam//===-- AMDGPUTargetMachine.cpp - TargetMachine for hw codegen targets-----===// 2185377Ssam// 3185377Ssam// The LLVM Compiler Infrastructure 4185377Ssam// 5185377Ssam// This file is distributed under the University of Illinois Open Source 6185377Ssam// License. See LICENSE.TXT for details. 7185377Ssam// 8185377Ssam//===----------------------------------------------------------------------===// 9185377Ssam// 10185377Ssam/// \file 11185377Ssam/// \brief The AMDGPU target machine contains all of the hardware specific 12185377Ssam/// information needed to emit code for R600 and SI GPUs. 13185377Ssam// 14185377Ssam//===----------------------------------------------------------------------===// 15185377Ssam 16185377Ssam#include "AMDGPUTargetMachine.h" 17185377Ssam#include "AMDGPU.h" 18185377Ssam#include "R600ISelLowering.h" 19185377Ssam#include "R600InstrInfo.h" 20185377Ssam#include "R600MachineScheduler.h" 21185377Ssam#include "SIISelLowering.h" 22185377Ssam#include "SIInstrInfo.h" 23185377Ssam#include "llvm/Analysis/Passes.h" 24185377Ssam#include "llvm/Analysis/Verifier.h" 25185377Ssam#include "llvm/CodeGen/MachineFunctionAnalysis.h" 26185377Ssam#include "llvm/CodeGen/MachineModuleInfo.h" 27185377Ssam#include "llvm/CodeGen/Passes.h" 28185377Ssam#include "llvm/MC/MCAsmInfo.h" 29185377Ssam#include "llvm/PassManager.h" 30185377Ssam#include "llvm/Support/TargetRegistry.h" 31185377Ssam#include "llvm/Support/raw_os_ostream.h" 32185377Ssam#include "llvm/Transforms/IPO.h" 33185377Ssam#include "llvm/Transforms/Scalar.h" 34185377Ssam#include <llvm/CodeGen/Passes.h> 35185377Ssam 36185377Ssam 37185377Ssamusing namespace llvm; 38185377Ssam 39185377Ssamextern "C" void LLVMInitializeR600Target() { 40185377Ssam // Register the target 41185377Ssam RegisterTargetMachine<AMDGPUTargetMachine> X(TheAMDGPUTarget); 42185377Ssam} 43185377Ssam 44185377Ssamstatic ScheduleDAGInstrs *createR600MachineScheduler(MachineSchedContext *C) { 45185377Ssam return new ScheduleDAGMI(C, new R600SchedStrategy()); 46185377Ssam} 47185377Ssam 48185377Ssamstatic MachineSchedRegistry 49185377SsamSchedCustomRegistry("r600", "Run R600's custom scheduler", 50185377Ssam createR600MachineScheduler); 51185377Ssam 52185377SsamAMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, StringRef TT, 53185377Ssam StringRef CPU, StringRef FS, 54185377Ssam TargetOptions Options, 55185377Ssam Reloc::Model RM, CodeModel::Model CM, 56185377Ssam CodeGenOpt::Level OptLevel 57185377Ssam) 58185377Ssam: 59185377Ssam LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OptLevel), 60185377Ssam Subtarget(TT, CPU, FS), 61185377Ssam Layout(Subtarget.getDataLayout()), 62185377Ssam FrameLowering(TargetFrameLowering::StackGrowsUp, 63185377Ssam 64 * 16 // Maximum stack alignment (long16) 64185377Ssam , 0), 65185377Ssam IntrinsicInfo(this), 66185377Ssam InstrItins(&Subtarget.getInstrItineraryData()) { 67185377Ssam // TLInfo uses InstrInfo so it must be initialized after. 68185377Ssam if (Subtarget.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) { 69185377Ssam InstrInfo.reset(new R600InstrInfo(*this)); 70185377Ssam TLInfo.reset(new R600TargetLowering(*this)); 71185377Ssam } else { 72185377Ssam InstrInfo.reset(new SIInstrInfo(*this)); 73185377Ssam TLInfo.reset(new SITargetLowering(*this)); 74185377Ssam } 75185377Ssam initAsmInfo(); 76185377Ssam} 77185377Ssam 78185377SsamAMDGPUTargetMachine::~AMDGPUTargetMachine() { 79185377Ssam} 80185377Ssam 81185377Ssamnamespace { 82185377Ssamclass AMDGPUPassConfig : public TargetPassConfig { 83185377Ssampublic: 84185377Ssam AMDGPUPassConfig(AMDGPUTargetMachine *TM, PassManagerBase &PM) 85185377Ssam : TargetPassConfig(TM, PM) {} 86185377Ssam 87185377Ssam AMDGPUTargetMachine &getAMDGPUTargetMachine() const { 88185377Ssam return getTM<AMDGPUTargetMachine>(); 89185377Ssam } 90185377Ssam 91185377Ssam virtual ScheduleDAGInstrs * 92185377Ssam createMachineScheduler(MachineSchedContext *C) const { 93185377Ssam const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 94185377Ssam if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) 95185377Ssam return createR600MachineScheduler(C); 96185377Ssam return 0; 97185377Ssam } 98185377Ssam 99185377Ssam virtual bool addPreISel(); 100185377Ssam virtual bool addInstSelector(); 101185377Ssam virtual bool addPreRegAlloc(); 102185377Ssam virtual bool addPostRegAlloc(); 103185377Ssam virtual bool addPreSched2(); 104185377Ssam virtual bool addPreEmitPass(); 105185377Ssam}; 106185377Ssam} // End of anonymous namespace 107185377Ssam 108185377SsamTargetPassConfig *AMDGPUTargetMachine::createPassConfig(PassManagerBase &PM) { 109185377Ssam return new AMDGPUPassConfig(this, PM); 110185377Ssam} 111185377Ssam 112185377Ssam//===----------------------------------------------------------------------===// 113185377Ssam// AMDGPU Analysis Pass Setup 114185377Ssam//===----------------------------------------------------------------------===// 115185377Ssam 116185377Ssamvoid AMDGPUTargetMachine::addAnalysisPasses(PassManagerBase &PM) { 117185377Ssam // Add first the target-independent BasicTTI pass, then our AMDGPU pass. This 118185377Ssam // allows the AMDGPU pass to delegate to the target independent layer when 119185377Ssam // appropriate. 120185377Ssam PM.add(createBasicTargetTransformInfoPass(this)); 121185377Ssam PM.add(createAMDGPUTargetTransformInfoPass(this)); 122185377Ssam} 123185377Ssam 124185377Ssambool 125185377SsamAMDGPUPassConfig::addPreISel() { 126185377Ssam const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 127185377Ssam addPass(createFlattenCFGPass()); 128185377Ssam if (ST.IsIRStructurizerEnabled()) 129185377Ssam addPass(createStructurizeCFGPass()); 130185377Ssam if (ST.getGeneration() > AMDGPUSubtarget::NORTHERN_ISLANDS) { 131185377Ssam addPass(createSinkingPass()); 132185377Ssam addPass(createSITypeRewriter()); 133185377Ssam addPass(createSIAnnotateControlFlowPass()); 134185377Ssam } else { 135185377Ssam addPass(createR600TextureIntrinsicsReplacer()); 136185377Ssam } 137185377Ssam return false; 138185377Ssam} 139185377Ssam 140185377Ssambool AMDGPUPassConfig::addInstSelector() { 141185377Ssam addPass(createAMDGPUISelDag(getAMDGPUTargetMachine())); 142185377Ssam return false; 143185377Ssam} 144185377Ssam 145185377Ssambool AMDGPUPassConfig::addPreRegAlloc() { 146185377Ssam addPass(createAMDGPUConvertToISAPass(*TM)); 147185377Ssam const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 148185377Ssam 149185377Ssam if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) { 150185377Ssam addPass(createR600VectorRegMerger(*TM)); 151185377Ssam } else { 152185377Ssam addPass(createSIFixSGPRCopiesPass(*TM)); 153185377Ssam } 154185377Ssam return false; 155185377Ssam} 156185377Ssam 157185377Ssambool AMDGPUPassConfig::addPostRegAlloc() { 158185377Ssam const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 159185377Ssam 160185377Ssam if (ST.getGeneration() > AMDGPUSubtarget::NORTHERN_ISLANDS) { 161185377Ssam addPass(createSIInsertWaits(*TM)); 162185377Ssam } 163185377Ssam return false; 164185377Ssam} 165185377Ssam 166185377Ssambool AMDGPUPassConfig::addPreSched2() { 167185377Ssam const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 168185377Ssam 169185377Ssam if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) 170185377Ssam addPass(createR600EmitClauseMarkers(*TM)); 171185377Ssam if (ST.isIfCvtEnabled()) 172185377Ssam addPass(&IfConverterID); 173185377Ssam if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) 174185377Ssam addPass(createR600ClauseMergePass(*TM)); 175185377Ssam return false; 176185377Ssam} 177185377Ssam 178185377Ssambool AMDGPUPassConfig::addPreEmitPass() { 179185377Ssam const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 180185377Ssam if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) { 181185377Ssam addPass(createAMDGPUCFGStructurizerPass(*TM)); 182185377Ssam addPass(createR600ExpandSpecialInstrsPass(*TM)); 183185377Ssam addPass(&FinalizeMachineBundlesID); 184185377Ssam addPass(createR600Packetizer(*TM)); 185185377Ssam addPass(createR600ControlFlowFinalizer(*TM)); 186185377Ssam } else { 187185377Ssam addPass(createSILowerControlFlowPass(*TM)); 188185377Ssam } 189185377Ssam 190185377Ssam return false; 191185377Ssam} 192185377Ssam