1239310Sdim//===-- NVPTXTargetMachine.cpp - Define TargetMachine for NVPTX -----------===//
2239310Sdim//
3239310Sdim//                     The LLVM Compiler Infrastructure
4239310Sdim//
5239310Sdim// This file is distributed under the University of Illinois Open Source
6239310Sdim// License. See LICENSE.TXT for details.
7239310Sdim//
8239310Sdim//===----------------------------------------------------------------------===//
9239310Sdim//
10239310Sdim// Top-level implementation for the NVPTX target.
11239310Sdim//
12239310Sdim//===----------------------------------------------------------------------===//
13239310Sdim
14239310Sdim#include "NVPTXTargetMachine.h"
15252723Sdim#include "MCTargetDesc/NVPTXMCAsmInfo.h"
16239310Sdim#include "NVPTX.h"
17252723Sdim#include "NVPTXAllocaHoisting.h"
18252723Sdim#include "NVPTXLowerAggrCopies.h"
19239310Sdim#include "NVPTXSplitBBatBar.h"
20252723Sdim#include "llvm/ADT/OwningPtr.h"
21239310Sdim#include "llvm/Analysis/Passes.h"
22239310Sdim#include "llvm/Analysis/Verifier.h"
23239310Sdim#include "llvm/Assembly/PrintModulePass.h"
24239310Sdim#include "llvm/CodeGen/AsmPrinter.h"
25239310Sdim#include "llvm/CodeGen/MachineFunctionAnalysis.h"
26239310Sdim#include "llvm/CodeGen/MachineModuleInfo.h"
27239310Sdim#include "llvm/CodeGen/Passes.h"
28252723Sdim#include "llvm/IR/DataLayout.h"
29239310Sdim#include "llvm/MC/MCAsmInfo.h"
30239310Sdim#include "llvm/MC/MCInstrInfo.h"
31239310Sdim#include "llvm/MC/MCStreamer.h"
32239310Sdim#include "llvm/MC/MCSubtargetInfo.h"
33252723Sdim#include "llvm/PassManager.h"
34252723Sdim#include "llvm/Support/CommandLine.h"
35252723Sdim#include "llvm/Support/Debug.h"
36252723Sdim#include "llvm/Support/FormattedStream.h"
37239310Sdim#include "llvm/Support/TargetRegistry.h"
38239310Sdim#include "llvm/Support/raw_ostream.h"
39239310Sdim#include "llvm/Target/TargetInstrInfo.h"
40239310Sdim#include "llvm/Target/TargetLowering.h"
41239310Sdim#include "llvm/Target/TargetLoweringObjectFile.h"
42239310Sdim#include "llvm/Target/TargetMachine.h"
43239310Sdim#include "llvm/Target/TargetOptions.h"
44239310Sdim#include "llvm/Target/TargetRegisterInfo.h"
45239310Sdim#include "llvm/Target/TargetSubtargetInfo.h"
46239310Sdim#include "llvm/Transforms/Scalar.h"
47239310Sdim
48239310Sdimusing namespace llvm;
49239310Sdim
50252723Sdimnamespace llvm {
51252723Sdimvoid initializeNVVMReflectPass(PassRegistry&);
52252723Sdimvoid initializeGenericToNVVMPass(PassRegistry&);
53252723Sdim}
54239310Sdim
55239310Sdimextern "C" void LLVMInitializeNVPTXTarget() {
56239310Sdim  // Register the target.
57239310Sdim  RegisterTargetMachine<NVPTXTargetMachine32> X(TheNVPTXTarget32);
58239310Sdim  RegisterTargetMachine<NVPTXTargetMachine64> Y(TheNVPTXTarget64);
59239310Sdim
60252723Sdim  // FIXME: This pass is really intended to be invoked during IR optimization,
61252723Sdim  // but it's very NVPTX-specific.
62252723Sdim  initializeNVVMReflectPass(*PassRegistry::getPassRegistry());
63252723Sdim  initializeGenericToNVVMPass(*PassRegistry::getPassRegistry());
64239310Sdim}
65239310Sdim
66252723SdimNVPTXTargetMachine::NVPTXTargetMachine(
67252723Sdim    const Target &T, StringRef TT, StringRef CPU, StringRef FS,
68252723Sdim    const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM,
69252723Sdim    CodeGenOpt::Level OL, bool is64bit)
70252723Sdim    : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
71252723Sdim      Subtarget(TT, CPU, FS, is64bit), DL(Subtarget.getDataLayout()),
72252723Sdim      InstrInfo(*this), TLInfo(*this), TSInfo(*this),
73252723Sdim      FrameLowering(
74263509Sdim          *this, is64bit) /*FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0)*/ {
75263509Sdim  initAsmInfo();
76263509Sdim}
77239310Sdim
78239310Sdimvoid NVPTXTargetMachine32::anchor() {}
79239310Sdim
80252723SdimNVPTXTargetMachine32::NVPTXTargetMachine32(
81252723Sdim    const Target &T, StringRef TT, StringRef CPU, StringRef FS,
82252723Sdim    const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM,
83252723Sdim    CodeGenOpt::Level OL)
84252723Sdim    : NVPTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
85239310Sdim
86239310Sdimvoid NVPTXTargetMachine64::anchor() {}
87239310Sdim
88252723SdimNVPTXTargetMachine64::NVPTXTargetMachine64(
89252723Sdim    const Target &T, StringRef TT, StringRef CPU, StringRef FS,
90252723Sdim    const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM,
91252723Sdim    CodeGenOpt::Level OL)
92252723Sdim    : NVPTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
93239310Sdim
94263509Sdimnamespace {
95239310Sdimclass NVPTXPassConfig : public TargetPassConfig {
96239310Sdimpublic:
97239310Sdim  NVPTXPassConfig(NVPTXTargetMachine *TM, PassManagerBase &PM)
98252723Sdim      : TargetPassConfig(TM, PM) {}
99239310Sdim
100239310Sdim  NVPTXTargetMachine &getNVPTXTargetMachine() const {
101239310Sdim    return getTM<NVPTXTargetMachine>();
102239310Sdim  }
103239310Sdim
104252723Sdim  virtual void addIRPasses();
105239310Sdim  virtual bool addInstSelector();
106239310Sdim  virtual bool addPreRegAlloc();
107263509Sdim  virtual bool addPostRegAlloc();
108263509Sdim
109263509Sdim  virtual FunctionPass *createTargetRegisterAllocator(bool) LLVM_OVERRIDE;
110263509Sdim  virtual void addFastRegAlloc(FunctionPass *RegAllocPass);
111263509Sdim  virtual void addOptimizedRegAlloc(FunctionPass *RegAllocPass);
112239310Sdim};
113263509Sdim} // end anonymous namespace
114239310Sdim
115239310SdimTargetPassConfig *NVPTXTargetMachine::createPassConfig(PassManagerBase &PM) {
116239310Sdim  NVPTXPassConfig *PassConfig = new NVPTXPassConfig(this, PM);
117239310Sdim  return PassConfig;
118239310Sdim}
119239310Sdim
120252723Sdimvoid NVPTXPassConfig::addIRPasses() {
121263509Sdim  // The following passes are known to not play well with virtual regs hanging
122263509Sdim  // around after register allocation (which in our case, is *all* registers).
123263509Sdim  // We explicitly disable them here.  We do, however, need some functionality
124263509Sdim  // of the PrologEpilogCodeInserter pass, so we emulate that behavior in the
125263509Sdim  // NVPTXPrologEpilog pass (see NVPTXPrologEpilogPass.cpp).
126263509Sdim  disablePass(&PrologEpilogCodeInserterID);
127263509Sdim  disablePass(&MachineCopyPropagationID);
128263509Sdim  disablePass(&BranchFolderPassID);
129263509Sdim  disablePass(&TailDuplicateID);
130263509Sdim
131252723Sdim  TargetPassConfig::addIRPasses();
132252723Sdim  addPass(createGenericToNVVMPass());
133252723Sdim}
134252723Sdim
135239310Sdimbool NVPTXPassConfig::addInstSelector() {
136239310Sdim  addPass(createLowerAggrCopies());
137239310Sdim  addPass(createSplitBBatBarPass());
138239310Sdim  addPass(createAllocaHoisting());
139239310Sdim  addPass(createNVPTXISelDag(getNVPTXTargetMachine(), getOptLevel()));
140239310Sdim  return false;
141239310Sdim}
142239310Sdim
143252723Sdimbool NVPTXPassConfig::addPreRegAlloc() { return false; }
144263509Sdimbool NVPTXPassConfig::addPostRegAlloc() {
145263509Sdim  addPass(createNVPTXPrologEpilogPass());
146263509Sdim  return false;
147263509Sdim}
148263509Sdim
149263509SdimFunctionPass *NVPTXPassConfig::createTargetRegisterAllocator(bool) {
150263509Sdim  return 0; // No reg alloc
151263509Sdim}
152263509Sdim
153263509Sdimvoid NVPTXPassConfig::addFastRegAlloc(FunctionPass *RegAllocPass) {
154263509Sdim  assert(!RegAllocPass && "NVPTX uses no regalloc!");
155263509Sdim  addPass(&PHIEliminationID);
156263509Sdim  addPass(&TwoAddressInstructionPassID);
157263509Sdim}
158263509Sdim
159263509Sdimvoid NVPTXPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) {
160263509Sdim  assert(!RegAllocPass && "NVPTX uses no regalloc!");
161263509Sdim
162263509Sdim  addPass(&ProcessImplicitDefsID);
163263509Sdim  addPass(&LiveVariablesID);
164263509Sdim  addPass(&MachineLoopInfoID);
165263509Sdim  addPass(&PHIEliminationID);
166263509Sdim
167263509Sdim  addPass(&TwoAddressInstructionPassID);
168263509Sdim  addPass(&RegisterCoalescerID);
169263509Sdim
170263509Sdim  // PreRA instruction scheduling.
171263509Sdim  if (addPass(&MachineSchedulerID))
172263509Sdim    printAndVerify("After Machine Scheduling");
173263509Sdim
174263509Sdim
175263509Sdim  addPass(&StackSlotColoringID);
176263509Sdim
177263509Sdim  // FIXME: Needs physical registers
178263509Sdim  //addPass(&PostRAMachineLICMID);
179263509Sdim
180263509Sdim  printAndVerify("After StackSlotColoring");
181263509Sdim}
182