1 //===-- NVPTXTargetMachine.cpp - Define TargetMachine for NVPTX -----------===// 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 // Top-level implementation for the NVPTX target. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "NVPTXTargetMachine.h" 15 #include "MCTargetDesc/NVPTXMCAsmInfo.h" 16 #include "NVPTX.h" 17 #include "NVPTXAllocaHoisting.h" 18 #include "NVPTXLowerAggrCopies.h" 19 #include "NVPTXTargetObjectFile.h" 20 #include "NVPTXTargetTransformInfo.h" 21 #include "llvm/Analysis/Passes.h" 22 #include "llvm/CodeGen/AsmPrinter.h" 23 #include "llvm/CodeGen/MachineFunctionAnalysis.h" 24 #include "llvm/CodeGen/MachineModuleInfo.h" 25 #include "llvm/CodeGen/Passes.h" 26 #include "llvm/IR/DataLayout.h" 27 #include "llvm/IR/IRPrintingPasses.h" 28 #include "llvm/IR/LegacyPassManager.h" 29 #include "llvm/IR/Verifier.h" 30 #include "llvm/MC/MCAsmInfo.h" 31 #include "llvm/MC/MCInstrInfo.h" 32 #include "llvm/MC/MCStreamer.h" 33 #include "llvm/MC/MCSubtargetInfo.h" 34 #include "llvm/Support/CommandLine.h" 35 #include "llvm/Support/Debug.h" 36 #include "llvm/Support/FormattedStream.h" 37 #include "llvm/Support/TargetRegistry.h" 38 #include "llvm/Support/raw_ostream.h" 39 #include "llvm/Target/TargetInstrInfo.h" 40 #include "llvm/Target/TargetLowering.h" 41 #include "llvm/Target/TargetLoweringObjectFile.h" 42 #include "llvm/Target/TargetMachine.h" 43 #include "llvm/Target/TargetOptions.h" 44 #include "llvm/Target/TargetRegisterInfo.h" 45 #include "llvm/Target/TargetSubtargetInfo.h" 46 #include "llvm/Transforms/Scalar.h" 47 48 using namespace llvm; 49 50 namespace llvm { 51 void initializeNVVMReflectPass(PassRegistry&); 52 void initializeGenericToNVVMPass(PassRegistry&); 53 void initializeNVPTXAllocaHoistingPass(PassRegistry &); 54 void initializeNVPTXAssignValidGlobalNamesPass(PassRegistry&); 55 void initializeNVPTXFavorNonGenericAddrSpacesPass(PassRegistry &); 56 void initializeNVPTXLowerKernelArgsPass(PassRegistry &); 57 } 58 59 extern "C" void LLVMInitializeNVPTXTarget() { 60 // Register the target. 61 RegisterTargetMachine<NVPTXTargetMachine32> X(TheNVPTXTarget32); 62 RegisterTargetMachine<NVPTXTargetMachine64> Y(TheNVPTXTarget64); 63 64 // FIXME: This pass is really intended to be invoked during IR optimization, 65 // but it's very NVPTX-specific. 66 initializeNVVMReflectPass(*PassRegistry::getPassRegistry()); 67 initializeGenericToNVVMPass(*PassRegistry::getPassRegistry()); 68 initializeNVPTXAllocaHoistingPass(*PassRegistry::getPassRegistry()); 69 initializeNVPTXAssignValidGlobalNamesPass(*PassRegistry::getPassRegistry()); 70 initializeNVPTXFavorNonGenericAddrSpacesPass( 71 *PassRegistry::getPassRegistry()); 72 initializeNVPTXLowerKernelArgsPass(*PassRegistry::getPassRegistry()); 73 } 74 75 static std::string computeDataLayout(bool is64Bit) { 76 std::string Ret = "e"; 77 78 if (!is64Bit) 79 Ret += "-p:32:32"; 80 81 Ret += "-i64:64-v16:16-v32:32-n16:32:64"; 82 83 return Ret; 84 } 85 86 NVPTXTargetMachine::NVPTXTargetMachine(const Target &T, const Triple &TT, 87 StringRef CPU, StringRef FS, 88 const TargetOptions &Options, 89 Reloc::Model RM, CodeModel::Model CM, 90 CodeGenOpt::Level OL, bool is64bit) 91 : LLVMTargetMachine(T, computeDataLayout(is64bit), TT, CPU, FS, Options, RM, 92 CM, OL), 93 is64bit(is64bit), TLOF(make_unique<NVPTXTargetObjectFile>()), 94 Subtarget(TT, CPU, FS, *this) { 95 if (TT.getOS() == Triple::NVCL) 96 drvInterface = NVPTX::NVCL; 97 else 98 drvInterface = NVPTX::CUDA; 99 initAsmInfo(); 100 } 101 102 NVPTXTargetMachine::~NVPTXTargetMachine() {} 103 104 void NVPTXTargetMachine32::anchor() {} 105 106 NVPTXTargetMachine32::NVPTXTargetMachine32(const Target &T, const Triple &TT, 107 StringRef CPU, StringRef FS, 108 const TargetOptions &Options, 109 Reloc::Model RM, CodeModel::Model CM, 110 CodeGenOpt::Level OL) 111 : NVPTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} 112 113 void NVPTXTargetMachine64::anchor() {} 114 115 NVPTXTargetMachine64::NVPTXTargetMachine64(const Target &T, const Triple &TT, 116 StringRef CPU, StringRef FS, 117 const TargetOptions &Options, 118 Reloc::Model RM, CodeModel::Model CM, 119 CodeGenOpt::Level OL) 120 : NVPTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} 121 122 namespace { 123 class NVPTXPassConfig : public TargetPassConfig { 124 public: 125 NVPTXPassConfig(NVPTXTargetMachine *TM, PassManagerBase &PM) 126 : TargetPassConfig(TM, PM) {} 127 128 NVPTXTargetMachine &getNVPTXTargetMachine() const { 129 return getTM<NVPTXTargetMachine>(); 130 } 131 132 void addIRPasses() override; 133 bool addInstSelector() override; 134 void addPostRegAlloc() override; 135 void addMachineSSAOptimization() override; 136 137 FunctionPass *createTargetRegisterAllocator(bool) override; 138 void addFastRegAlloc(FunctionPass *RegAllocPass) override; 139 void addOptimizedRegAlloc(FunctionPass *RegAllocPass) override; 140 }; 141 } // end anonymous namespace 142 143 TargetPassConfig *NVPTXTargetMachine::createPassConfig(PassManagerBase &PM) { 144 NVPTXPassConfig *PassConfig = new NVPTXPassConfig(this, PM); 145 return PassConfig; 146 } 147 148 TargetIRAnalysis NVPTXTargetMachine::getTargetIRAnalysis() { 149 return TargetIRAnalysis( 150 [this](Function &) { return TargetTransformInfo(NVPTXTTIImpl(this)); }); 151 } 152 153 void NVPTXPassConfig::addIRPasses() { 154 // The following passes are known to not play well with virtual regs hanging 155 // around after register allocation (which in our case, is *all* registers). 156 // We explicitly disable them here. We do, however, need some functionality 157 // of the PrologEpilogCodeInserter pass, so we emulate that behavior in the 158 // NVPTXPrologEpilog pass (see NVPTXPrologEpilogPass.cpp). 159 disablePass(&PrologEpilogCodeInserterID); 160 disablePass(&MachineCopyPropagationID); 161 disablePass(&BranchFolderPassID); 162 disablePass(&TailDuplicateID); 163 164 addPass(createNVPTXImageOptimizerPass()); 165 TargetPassConfig::addIRPasses(); 166 addPass(createNVPTXAssignValidGlobalNamesPass()); 167 addPass(createGenericToNVVMPass()); 168 addPass(createNVPTXLowerKernelArgsPass(&getNVPTXTargetMachine())); 169 addPass(createNVPTXFavorNonGenericAddrSpacesPass()); 170 // NVPTXLowerKernelArgs emits alloca for byval parameters which can often 171 // be eliminated by SROA. We do not run SROA right after NVPTXLowerKernelArgs 172 // because we plan to merge NVPTXLowerKernelArgs and 173 // NVPTXFavorNonGenericAddrSpaces into one pass. 174 addPass(createSROAPass()); 175 // FavorNonGenericAddrSpaces shortcuts unnecessary addrspacecasts, and leave 176 // them unused. We could remove dead code in an ad-hoc manner, but that 177 // requires manual work and might be error-prone. 178 addPass(createDeadCodeEliminationPass()); 179 addPass(createSeparateConstOffsetFromGEPPass()); 180 // ReassociateGEPs exposes more opportunites for SLSR. See 181 // the example in reassociate-geps-and-slsr.ll. 182 addPass(createStraightLineStrengthReducePass()); 183 // SeparateConstOffsetFromGEP and SLSR creates common expressions which GVN or 184 // EarlyCSE can reuse. GVN generates significantly better code than EarlyCSE 185 // for some of our benchmarks. 186 if (getOptLevel() == CodeGenOpt::Aggressive) 187 addPass(createGVNPass()); 188 else 189 addPass(createEarlyCSEPass()); 190 // Run NaryReassociate after EarlyCSE/GVN to be more effective. 191 addPass(createNaryReassociatePass()); 192 // NaryReassociate on GEPs creates redundant common expressions, so run 193 // EarlyCSE after it. 194 addPass(createEarlyCSEPass()); 195 } 196 197 bool NVPTXPassConfig::addInstSelector() { 198 const NVPTXSubtarget &ST = *getTM<NVPTXTargetMachine>().getSubtargetImpl(); 199 200 addPass(createLowerAggrCopies()); 201 addPass(createAllocaHoisting()); 202 addPass(createNVPTXISelDag(getNVPTXTargetMachine(), getOptLevel())); 203 204 if (!ST.hasImageHandles()) 205 addPass(createNVPTXReplaceImageHandlesPass()); 206 207 return false; 208 } 209 210 void NVPTXPassConfig::addPostRegAlloc() { 211 addPass(createNVPTXPrologEpilogPass(), false); 212 } 213 214 FunctionPass *NVPTXPassConfig::createTargetRegisterAllocator(bool) { 215 return nullptr; // No reg alloc 216 } 217 218 void NVPTXPassConfig::addFastRegAlloc(FunctionPass *RegAllocPass) { 219 assert(!RegAllocPass && "NVPTX uses no regalloc!"); 220 addPass(&PHIEliminationID); 221 addPass(&TwoAddressInstructionPassID); 222 } 223 224 void NVPTXPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) { 225 assert(!RegAllocPass && "NVPTX uses no regalloc!"); 226 227 addPass(&ProcessImplicitDefsID); 228 addPass(&LiveVariablesID); 229 addPass(&MachineLoopInfoID); 230 addPass(&PHIEliminationID); 231 232 addPass(&TwoAddressInstructionPassID); 233 addPass(&RegisterCoalescerID); 234 235 // PreRA instruction scheduling. 236 if (addPass(&MachineSchedulerID)) 237 printAndVerify("After Machine Scheduling"); 238 239 240 addPass(&StackSlotColoringID); 241 242 // FIXME: Needs physical registers 243 //addPass(&PostRAMachineLICMID); 244 245 printAndVerify("After StackSlotColoring"); 246 } 247 248 void NVPTXPassConfig::addMachineSSAOptimization() { 249 // Pre-ra tail duplication. 250 if (addPass(&EarlyTailDuplicateID)) 251 printAndVerify("After Pre-RegAlloc TailDuplicate"); 252 253 // Optimize PHIs before DCE: removing dead PHI cycles may make more 254 // instructions dead. 255 addPass(&OptimizePHIsID); 256 257 // This pass merges large allocas. StackSlotColoring is a different pass 258 // which merges spill slots. 259 addPass(&StackColoringID); 260 261 // If the target requests it, assign local variables to stack slots relative 262 // to one another and simplify frame index references where possible. 263 addPass(&LocalStackSlotAllocationID); 264 265 // With optimization, dead code should already be eliminated. However 266 // there is one known exception: lowered code for arguments that are only 267 // used by tail calls, where the tail calls reuse the incoming stack 268 // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll). 269 addPass(&DeadMachineInstructionElimID); 270 printAndVerify("After codegen DCE pass"); 271 272 // Allow targets to insert passes that improve instruction level parallelism, 273 // like if-conversion. Such passes will typically need dominator trees and 274 // loop info, just like LICM and CSE below. 275 if (addILPOpts()) 276 printAndVerify("After ILP optimizations"); 277 278 addPass(&MachineLICMID); 279 addPass(&MachineCSEID); 280 281 addPass(&MachineSinkingID); 282 printAndVerify("After Machine LICM, CSE and Sinking passes"); 283 284 addPass(&PeepholeOptimizerID); 285 printAndVerify("After codegen peephole optimization pass"); 286 } 287