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