149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===-- NVPTXTargetMachine.cpp - Define TargetMachine for NVPTX -----------===// 249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// The LLVM Compiler Infrastructure 449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// This file is distributed under the University of Illinois Open Source 649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// License. See LICENSE.TXT for details. 749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===----------------------------------------------------------------------===// 949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 1049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// Top-level implementation for the NVPTX target. 1149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski// 1249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski//===----------------------------------------------------------------------===// 1349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 1449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTXTargetMachine.h" 1549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "MCTargetDesc/NVPTXMCAsmInfo.h" 16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "NVPTX.h" 1749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "NVPTXAllocaHoisting.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "NVPTXLowerAggrCopies.h" 19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "NVPTXSplitBBatBar.h" 20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/OwningPtr.h" 2149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Analysis/Passes.h" 2249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Analysis/Verifier.h" 2349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Assembly/PrintModulePass.h" 2449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/CodeGen/AsmPrinter.h" 2549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/CodeGen/MachineFunctionAnalysis.h" 2649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/CodeGen/MachineModuleInfo.h" 2749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/CodeGen/Passes.h" 280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 2949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/MC/MCAsmInfo.h" 3049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/MC/MCInstrInfo.h" 3149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/MC/MCStreamer.h" 3249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/MC/MCSubtargetInfo.h" 33d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/PassManager.h" 34d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/CommandLine.h" 35d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/Debug.h" 36d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/FormattedStream.h" 37d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/TargetRegistry.h" 3849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Support/raw_ostream.h" 3949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Target/TargetInstrInfo.h" 4049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Target/TargetLowering.h" 4149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Target/TargetLoweringObjectFile.h" 4249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Target/TargetMachine.h" 4349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Target/TargetOptions.h" 4449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Target/TargetRegisterInfo.h" 4549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Target/TargetSubtargetInfo.h" 4649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski#include "llvm/Transforms/Scalar.h" 4749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 4849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskiusing namespace llvm; 4949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 5021fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinskinamespace llvm { 5121fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinskivoid initializeNVVMReflectPass(PassRegistry&); 527536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinskivoid initializeGenericToNVVMPass(PassRegistry&); 5321fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski} 5421fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski 5549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskiextern "C" void LLVMInitializeNVPTXTarget() { 5649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski // Register the target. 5749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski RegisterTargetMachine<NVPTXTargetMachine32> X(TheNVPTXTarget32); 5849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski RegisterTargetMachine<NVPTXTargetMachine64> Y(TheNVPTXTarget64); 5949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 6049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski RegisterMCAsmInfo<NVPTXMCAsmInfo> A(TheNVPTXTarget32); 6149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski RegisterMCAsmInfo<NVPTXMCAsmInfo> B(TheNVPTXTarget64); 6249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 6321fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski // FIXME: This pass is really intended to be invoked during IR optimization, 6421fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski // but it's very NVPTX-specific. 6521fdcb02716f5eae097abfd2f44e40563e90180aJustin Holewinski initializeNVVMReflectPass(*PassRegistry::getPassRegistry()); 667536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski initializeGenericToNVVMPass(*PassRegistry::getPassRegistry()); 6749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 6849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 693639ce2575660a0e6938d2e84e8bd9a738fd7051Justin HolewinskiNVPTXTargetMachine::NVPTXTargetMachine( 703639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski const Target &T, StringRef TT, StringRef CPU, StringRef FS, 713639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, 723639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski CodeGenOpt::Level OL, bool is64bit) 733639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), 743639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski Subtarget(TT, CPU, FS, is64bit), DL(Subtarget.getDataLayout()), 753639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski InstrInfo(*this), TLInfo(*this), TSInfo(*this), 763639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski FrameLowering( 774a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola *this, is64bit) /*FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0)*/ { 784a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola initAsmInfo(); 794a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola} 8049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 8149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskivoid NVPTXTargetMachine32::anchor() {} 8249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 833639ce2575660a0e6938d2e84e8bd9a738fd7051Justin HolewinskiNVPTXTargetMachine32::NVPTXTargetMachine32( 843639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski const Target &T, StringRef TT, StringRef CPU, StringRef FS, 853639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, 863639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski CodeGenOpt::Level OL) 873639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski : NVPTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} 8849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 8949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskivoid NVPTXTargetMachine64::anchor() {} 9049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 913639ce2575660a0e6938d2e84e8bd9a738fd7051Justin HolewinskiNVPTXTargetMachine64::NVPTXTargetMachine64( 923639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski const Target &T, StringRef TT, StringRef CPU, StringRef FS, 933639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, 943639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski CodeGenOpt::Level OL) 953639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski : NVPTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} 9649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 975c35290fa35ae234fed02496404cb0fc37e1c8a5Benjamin Kramernamespace { 9849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskiclass NVPTXPassConfig : public TargetPassConfig { 9949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskipublic: 10049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTXPassConfig(NVPTXTargetMachine *TM, PassManagerBase &PM) 1013639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinski : TargetPassConfig(TM, PM) {} 10249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 10349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTXTargetMachine &getNVPTXTargetMachine() const { 10449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return getTM<NVPTXTargetMachine>(); 10549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski } 10649683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 1077536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski virtual void addIRPasses(); 10849683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski virtual bool addInstSelector(); 10949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski virtual bool addPreRegAlloc(); 1105443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski virtual bool addPostRegAlloc(); 1115443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 112488401e9c995b6bfcc54fa7c54a5ec09e75d01a1Benjamin Kramer virtual FunctionPass *createTargetRegisterAllocator(bool) LLVM_OVERRIDE; 1135443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski virtual void addFastRegAlloc(FunctionPass *RegAllocPass); 1145443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski virtual void addOptimizedRegAlloc(FunctionPass *RegAllocPass); 11549683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski}; 1165c35290fa35ae234fed02496404cb0fc37e1c8a5Benjamin Kramer} // end anonymous namespace 11749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 11849683f3c961379fbc088871a5d6304950f1f1cbcJustin HolewinskiTargetPassConfig *NVPTXTargetMachine::createPassConfig(PassManagerBase &PM) { 11949683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski NVPTXPassConfig *PassConfig = new NVPTXPassConfig(this, PM); 12049683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return PassConfig; 12149683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 12249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 1237536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinskivoid NVPTXPassConfig::addIRPasses() { 1245443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // The following passes are known to not play well with virtual regs hanging 1255443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // around after register allocation (which in our case, is *all* registers). 1265443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // We explicitly disable them here. We do, however, need some functionality 1275443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // of the PrologEpilogCodeInserter pass, so we emulate that behavior in the 1285443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski // NVPTXPrologEpilog pass (see NVPTXPrologEpilogPass.cpp). 1295443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski disablePass(&PrologEpilogCodeInserterID); 1305443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski disablePass(&MachineCopyPropagationID); 1315443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski disablePass(&BranchFolderPassID); 1325443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1337536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski TargetPassConfig::addIRPasses(); 1347536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski addPass(createGenericToNVVMPass()); 1357536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski} 1367536ecf2916a6a986f0d328069e3a210f34d5ea7Justin Holewinski 13749683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinskibool NVPTXPassConfig::addInstSelector() { 138564fbf6aff8fb95646a1290078a37c2d4dbe629fBob Wilson addPass(createLowerAggrCopies()); 139564fbf6aff8fb95646a1290078a37c2d4dbe629fBob Wilson addPass(createSplitBBatBarPass()); 140564fbf6aff8fb95646a1290078a37c2d4dbe629fBob Wilson addPass(createAllocaHoisting()); 141564fbf6aff8fb95646a1290078a37c2d4dbe629fBob Wilson addPass(createNVPTXISelDag(getNVPTXTargetMachine(), getOptLevel())); 14249683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski return false; 14349683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski} 14449683f3c961379fbc088871a5d6304950f1f1cbcJustin Holewinski 1453639ce2575660a0e6938d2e84e8bd9a738fd7051Justin Holewinskibool NVPTXPassConfig::addPreRegAlloc() { return false; } 1465443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinskibool NVPTXPassConfig::addPostRegAlloc() { 1475443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski addPass(createNVPTXPrologEpilogPass()); 1485443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski return false; 1495443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski} 1505443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 151488401e9c995b6bfcc54fa7c54a5ec09e75d01a1Benjamin KramerFunctionPass *NVPTXPassConfig::createTargetRegisterAllocator(bool) { 152488401e9c995b6bfcc54fa7c54a5ec09e75d01a1Benjamin Kramer return 0; // No reg alloc 153488401e9c995b6bfcc54fa7c54a5ec09e75d01a1Benjamin Kramer} 154488401e9c995b6bfcc54fa7c54a5ec09e75d01a1Benjamin Kramer 1555443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinskivoid NVPTXPassConfig::addFastRegAlloc(FunctionPass *RegAllocPass) { 156488401e9c995b6bfcc54fa7c54a5ec09e75d01a1Benjamin Kramer assert(!RegAllocPass && "NVPTX uses no regalloc!"); 1575443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski addPass(&StrongPHIEliminationID); 1585443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski} 1595443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski 1605443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinskivoid NVPTXPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) { 161488401e9c995b6bfcc54fa7c54a5ec09e75d01a1Benjamin Kramer assert(!RegAllocPass && "NVPTX uses no regalloc!"); 1625443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski addPass(&StrongPHIEliminationID); 1635443e7d79044f3198f2da044f1b389b40d9bea6fJustin Holewinski} 164