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 36263508Sdim 37249259Sdimusing namespace llvm; 38249259Sdim 39249259Sdimextern "C" void LLVMInitializeR600Target() { 40249259Sdim // Register the target 41249259Sdim RegisterTargetMachine<AMDGPUTargetMachine> X(TheAMDGPUTarget); 42249259Sdim} 43249259Sdim 44249259Sdimstatic ScheduleDAGInstrs *createR600MachineScheduler(MachineSchedContext *C) { 45249259Sdim return new ScheduleDAGMI(C, new R600SchedStrategy()); 46249259Sdim} 47249259Sdim 48249259Sdimstatic MachineSchedRegistry 49249259SdimSchedCustomRegistry("r600", "Run R600's custom scheduler", 50249259Sdim createR600MachineScheduler); 51249259Sdim 52249259SdimAMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, StringRef TT, 53249259Sdim StringRef CPU, StringRef FS, 54249259Sdim TargetOptions Options, 55249259Sdim Reloc::Model RM, CodeModel::Model CM, 56249259Sdim CodeGenOpt::Level OptLevel 57249259Sdim) 58249259Sdim: 59249259Sdim LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OptLevel), 60249259Sdim Subtarget(TT, CPU, FS), 61249259Sdim Layout(Subtarget.getDataLayout()), 62249259Sdim FrameLowering(TargetFrameLowering::StackGrowsUp, 63263508Sdim 64 * 16 // Maximum stack alignment (long16) 64263508Sdim , 0), 65249259Sdim IntrinsicInfo(this), 66249259Sdim InstrItins(&Subtarget.getInstrItineraryData()) { 67249259Sdim // TLInfo uses InstrInfo so it must be initialized after. 68263508Sdim if (Subtarget.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) { 69263508Sdim InstrInfo.reset(new R600InstrInfo(*this)); 70263508Sdim TLInfo.reset(new R600TargetLowering(*this)); 71249259Sdim } else { 72263508Sdim InstrInfo.reset(new SIInstrInfo(*this)); 73263508Sdim TLInfo.reset(new SITargetLowering(*this)); 74249259Sdim } 75263508Sdim initAsmInfo(); 76249259Sdim} 77249259Sdim 78249259SdimAMDGPUTargetMachine::~AMDGPUTargetMachine() { 79249259Sdim} 80249259Sdim 81249259Sdimnamespace { 82249259Sdimclass AMDGPUPassConfig : public TargetPassConfig { 83249259Sdimpublic: 84249259Sdim AMDGPUPassConfig(AMDGPUTargetMachine *TM, PassManagerBase &PM) 85263508Sdim : TargetPassConfig(TM, PM) {} 86249259Sdim 87249259Sdim AMDGPUTargetMachine &getAMDGPUTargetMachine() const { 88249259Sdim return getTM<AMDGPUTargetMachine>(); 89249259Sdim } 90249259Sdim 91263508Sdim virtual ScheduleDAGInstrs * 92263508Sdim createMachineScheduler(MachineSchedContext *C) const { 93263508Sdim const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 94263508Sdim if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) 95263508Sdim return createR600MachineScheduler(C); 96263508Sdim return 0; 97263508Sdim } 98263508Sdim 99249259Sdim virtual bool addPreISel(); 100249259Sdim virtual bool addInstSelector(); 101249259Sdim virtual bool addPreRegAlloc(); 102249259Sdim virtual bool addPostRegAlloc(); 103249259Sdim virtual bool addPreSched2(); 104249259Sdim virtual bool addPreEmitPass(); 105249259Sdim}; 106249259Sdim} // End of anonymous namespace 107249259Sdim 108249259SdimTargetPassConfig *AMDGPUTargetMachine::createPassConfig(PassManagerBase &PM) { 109249259Sdim return new AMDGPUPassConfig(this, PM); 110249259Sdim} 111249259Sdim 112263508Sdim//===----------------------------------------------------------------------===// 113263508Sdim// AMDGPU Analysis Pass Setup 114263508Sdim//===----------------------------------------------------------------------===// 115263508Sdim 116263508Sdimvoid AMDGPUTargetMachine::addAnalysisPasses(PassManagerBase &PM) { 117263508Sdim // Add first the target-independent BasicTTI pass, then our AMDGPU pass. This 118263508Sdim // allows the AMDGPU pass to delegate to the target independent layer when 119263508Sdim // appropriate. 120263508Sdim PM.add(createBasicTargetTransformInfoPass(this)); 121263508Sdim PM.add(createAMDGPUTargetTransformInfoPass(this)); 122263508Sdim} 123263508Sdim 124249259Sdimbool 125249259SdimAMDGPUPassConfig::addPreISel() { 126249259Sdim const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 127263508Sdim addPass(createFlattenCFGPass()); 128263508Sdim if (ST.IsIRStructurizerEnabled()) 129263508Sdim addPass(createStructurizeCFGPass()); 130263508Sdim if (ST.getGeneration() > AMDGPUSubtarget::NORTHERN_ISLANDS) { 131263508Sdim addPass(createSinkingPass()); 132263508Sdim addPass(createSITypeRewriter()); 133249259Sdim addPass(createSIAnnotateControlFlowPass()); 134263508Sdim } else { 135263508Sdim addPass(createR600TextureIntrinsicsReplacer()); 136249259Sdim } 137249259Sdim return false; 138249259Sdim} 139249259Sdim 140249259Sdimbool AMDGPUPassConfig::addInstSelector() { 141249259Sdim addPass(createAMDGPUISelDag(getAMDGPUTargetMachine())); 142249259Sdim return false; 143249259Sdim} 144249259Sdim 145249259Sdimbool AMDGPUPassConfig::addPreRegAlloc() { 146249259Sdim addPass(createAMDGPUConvertToISAPass(*TM)); 147263508Sdim const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 148263508Sdim 149263508Sdim if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) { 150263508Sdim addPass(createR600VectorRegMerger(*TM)); 151263508Sdim } else { 152263508Sdim addPass(createSIFixSGPRCopiesPass(*TM)); 153263508Sdim } 154249259Sdim return false; 155249259Sdim} 156249259Sdim 157249259Sdimbool AMDGPUPassConfig::addPostRegAlloc() { 158249259Sdim const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 159249259Sdim 160263508Sdim if (ST.getGeneration() > AMDGPUSubtarget::NORTHERN_ISLANDS) { 161249259Sdim addPass(createSIInsertWaits(*TM)); 162249259Sdim } 163249259Sdim return false; 164249259Sdim} 165249259Sdim 166249259Sdimbool AMDGPUPassConfig::addPreSched2() { 167263508Sdim const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 168249259Sdim 169263508Sdim if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) 170263508Sdim addPass(createR600EmitClauseMarkers(*TM)); 171263508Sdim if (ST.isIfCvtEnabled()) 172263508Sdim addPass(&IfConverterID); 173263508Sdim if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) 174263508Sdim addPass(createR600ClauseMergePass(*TM)); 175249259Sdim return false; 176249259Sdim} 177249259Sdim 178249259Sdimbool AMDGPUPassConfig::addPreEmitPass() { 179249259Sdim const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 180263508Sdim if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) { 181249259Sdim addPass(createAMDGPUCFGStructurizerPass(*TM)); 182249259Sdim addPass(createR600ExpandSpecialInstrsPass(*TM)); 183251662Sdim addPass(&FinalizeMachineBundlesID); 184251662Sdim addPass(createR600Packetizer(*TM)); 185249259Sdim addPass(createR600ControlFlowFinalizer(*TM)); 186249259Sdim } else { 187249259Sdim addPass(createSILowerControlFlowPass(*TM)); 188249259Sdim } 189249259Sdim 190249259Sdim return false; 191249259Sdim} 192