1f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===-- AMDGPUTargetMachine.cpp - TargetMachine for hw codegen targets-----===// 2f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 3f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// The LLVM Compiler Infrastructure 4f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 5f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// This file is distributed under the University of Illinois Open Source 6f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// License. See LICENSE.TXT for details. 7f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 8f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 9f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 10f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// \file 11f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// \brief The AMDGPU target machine contains all of the hardware specific 12f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// information needed to emit code for R600 and SI GPUs. 13f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 14f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 15f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 16f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "AMDGPUTargetMachine.h" 17f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "AMDGPU.h" 18f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "R600ISelLowering.h" 19f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "R600InstrInfo.h" 2062f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune#include "R600MachineScheduler.h" 21f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "SIISelLowering.h" 22f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "SIInstrInfo.h" 23f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Analysis/Passes.h" 24f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Analysis/Verifier.h" 25f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/MachineFunctionAnalysis.h" 26f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/MachineModuleInfo.h" 27f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/CodeGen/Passes.h" 28f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/MC/MCAsmInfo.h" 29f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/PassManager.h" 30f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Support/TargetRegistry.h" 31f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Support/raw_os_ostream.h" 32f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Transforms/IPO.h" 33f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Transforms/Scalar.h" 34f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include <llvm/CodeGen/Passes.h> 35f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 36f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardusing namespace llvm; 37f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 38f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardextern "C" void LLVMInitializeR600Target() { 39f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // Register the target 40f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard RegisterTargetMachine<AMDGPUTargetMachine> X(TheAMDGPUTarget); 41f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 42f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 4362f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeunestatic ScheduleDAGInstrs *createR600MachineScheduler(MachineSchedContext *C) { 4462f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune return new ScheduleDAGMI(C, new R600SchedStrategy()); 4562f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune} 4662f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune 4762f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeunestatic MachineSchedRegistry 4862f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent LejeuneSchedCustomRegistry("r600", "Run R600's custom scheduler", 4962f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune createR600MachineScheduler); 5062f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune 51f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardAMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, StringRef TT, 52f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard StringRef CPU, StringRef FS, 53f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard TargetOptions Options, 54f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Reloc::Model RM, CodeModel::Model CM, 55f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard CodeGenOpt::Level OptLevel 56f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard) 57f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard: 58f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OptLevel), 59f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Subtarget(TT, CPU, FS), 60f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Layout(Subtarget.getDataLayout()), 613ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard FrameLowering(TargetFrameLowering::StackGrowsUp, 16 // Stack Alignment 623ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard , 0), 63f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard IntrinsicInfo(this), 64f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard InstrItins(&Subtarget.getInstrItineraryData()) { 65f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // TLInfo uses InstrInfo so it must be initialized after. 663ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard if (Subtarget.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) { 675110102f9f7e7ddcd74d3bce1e5de3f898ba5e7fRafael Espindola InstrInfo.reset(new R600InstrInfo(*this)); 685110102f9f7e7ddcd74d3bce1e5de3f898ba5e7fRafael Espindola TLInfo.reset(new R600TargetLowering(*this)); 69f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 705110102f9f7e7ddcd74d3bce1e5de3f898ba5e7fRafael Espindola InstrInfo.reset(new SIInstrInfo(*this)); 715110102f9f7e7ddcd74d3bce1e5de3f898ba5e7fRafael Espindola TLInfo.reset(new SITargetLowering(*this)); 72f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 734a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola initAsmInfo(); 74f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 75f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 76f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardAMDGPUTargetMachine::~AMDGPUTargetMachine() { 77f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 78f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 79f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardnamespace { 80f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardclass AMDGPUPassConfig : public TargetPassConfig { 81f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardpublic: 82f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPUPassConfig(AMDGPUTargetMachine *TM, PassManagerBase &PM) 8362f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune : TargetPassConfig(TM, PM) { 8462f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 853ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) { 8662f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune enablePass(&MachineSchedulerID); 8762f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune MachineSchedRegistry::setDefault(createR600MachineScheduler); 8862f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune } 8962f38ca141f87ff3ed9334fbe6a5e1c45d40ca86Vincent Lejeune } 90f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 91f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard AMDGPUTargetMachine &getAMDGPUTargetMachine() const { 92f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return getTM<AMDGPUTargetMachine>(); 93f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 94f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard virtual bool addPreISel(); 95f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard virtual bool addInstSelector(); 96f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard virtual bool addPreRegAlloc(); 97f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard virtual bool addPostRegAlloc(); 98f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard virtual bool addPreSched2(); 99f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard virtual bool addPreEmitPass(); 100f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}; 101f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} // End of anonymous namespace 102f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 103f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardTargetPassConfig *AMDGPUTargetMachine::createPassConfig(PassManagerBase &PM) { 104f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return new AMDGPUPassConfig(this, PM); 105f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 106f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 10757e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard//===----------------------------------------------------------------------===// 10857e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard// AMDGPU Analysis Pass Setup 10957e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard//===----------------------------------------------------------------------===// 11057e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard 11157e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellardvoid AMDGPUTargetMachine::addAnalysisPasses(PassManagerBase &PM) { 11257e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard // Add first the target-independent BasicTTI pass, then our AMDGPU pass. This 11357e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard // allows the AMDGPU pass to delegate to the target independent layer when 11457e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard // appropriate. 11557e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard PM.add(createBasicTargetTransformInfoPass(this)); 11657e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard PM.add(createAMDGPUTargetTransformInfoPass(this)); 11757e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard} 11857e6b2d1f3de0bf459e96f7038e692d624f7e580Tom Stellard 119f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool 120f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardAMDGPUPassConfig::addPreISel() { 1216b7d99d47321ebb478b22afd2e317fe89d2149dbTom Stellard const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 12201d7203ef8316fdd71c3cec59f8e68fb869e0dbfTom Stellard addPass(createFlattenCFGPass()); 1233ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard if (ST.getGeneration() > AMDGPUSubtarget::NORTHERN_ISLANDS) { 124ad966ea7a81a538425d5319f6d8568e460639e54Matt Arsenault addPass(createStructurizeCFGPass()); 1256b7d99d47321ebb478b22afd2e317fe89d2149dbTom Stellard addPass(createSIAnnotateControlFlowPass()); 126d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune } else { 127d3293b49f9c7af741d2edd3062499fb50db0e89bVincent Lejeune addPass(createR600TextureIntrinsicsReplacer()); 1286b7d99d47321ebb478b22afd2e317fe89d2149dbTom Stellard } 129f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 130f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 131f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 132f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUPassConfig::addInstSelector() { 133f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addPass(createAMDGPUISelDag(getAMDGPUTargetMachine())); 134c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard 135c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 1363ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) { 137c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard // This callbacks this pass uses are not implemented yet on SI. 138c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard addPass(createAMDGPUIndirectAddressingPass(*TM)); 139c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard } 140f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 141f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 142f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 143f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUPassConfig::addPreRegAlloc() { 144f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addPass(createAMDGPUConvertToISAPass(*TM)); 145f3d6e32c09ac73b49628f5ec7066af5eca2737b5Vincent Lejeune const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 1463ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard 1473ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) { 148f3d6e32c09ac73b49628f5ec7066af5eca2737b5Vincent Lejeune addPass(createR600VectorRegMerger(*TM)); 1493492eefa4b2509c87598678a6977074a3f6a50e6Tom Stellard } else { 1503492eefa4b2509c87598678a6977074a3f6a50e6Tom Stellard addPass(createSIFixSGPRCopiesPass(*TM)); 151f3d6e32c09ac73b49628f5ec7066af5eca2737b5Vincent Lejeune } 152f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 153f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 154f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 155f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUPassConfig::addPostRegAlloc() { 15682d3d4524f2595b2dce617e963b6d67876b4f9baTom Stellard const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 15782d3d4524f2595b2dce617e963b6d67876b4f9baTom Stellard 1583ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard if (ST.getGeneration() > AMDGPUSubtarget::NORTHERN_ISLANDS) { 15982d3d4524f2595b2dce617e963b6d67876b4f9baTom Stellard addPass(createSIInsertWaits(*TM)); 16082d3d4524f2595b2dce617e963b6d67876b4f9baTom Stellard } 161f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 162f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 163f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 164f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUPassConfig::addPreSched2() { 165f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 166f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 167f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) { 168f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune addPass(createR600EmitClauseMarkers(*TM)); 169f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune } 170f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addPass(&IfConverterID); 171f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 172f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 173f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 174f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool AMDGPUPassConfig::addPreEmitPass() { 175f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); 1763ff0abfaabc2c7f604d490be587b9c27e7c91ac0Tom Stellard if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) { 1776b7d99d47321ebb478b22afd2e317fe89d2149dbTom Stellard addPass(createAMDGPUCFGStructurizerPass(*TM)); 178f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addPass(createR600ExpandSpecialInstrsPass(*TM)); 179f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addPass(&FinalizeMachineBundlesID); 18025f259cde28860ea76c2f5628010968945a28edbVincent Lejeune addPass(createR600Packetizer(*TM)); 18125f259cde28860ea76c2f5628010968945a28edbVincent Lejeune addPass(createR600ControlFlowFinalizer(*TM)); 182f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else { 183f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard addPass(createSILowerControlFlowPass(*TM)); 184f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 185f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 186f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return false; 187f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 188f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 189