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"
15249423Sdim#include "MCTargetDesc/NVPTXMCAsmInfo.h"
16239310Sdim#include "NVPTX.h"
17249423Sdim#include "NVPTXAllocaHoisting.h"
18249423Sdim#include "NVPTXLowerAggrCopies.h"
19239310Sdim#include "NVPTXSplitBBatBar.h"
20249423Sdim#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"
28249423Sdim#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"
33249423Sdim#include "llvm/PassManager.h"
34249423Sdim#include "llvm/Support/CommandLine.h"
35249423Sdim#include "llvm/Support/Debug.h"
36249423Sdim#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
50249423Sdimnamespace llvm {
51249423Sdimvoid initializeNVVMReflectPass(PassRegistry&);
52251662Sdimvoid initializeGenericToNVVMPass(PassRegistry&);
53249423Sdim}
54239310Sdim
55239310Sdimextern "C" void LLVMInitializeNVPTXTarget() {
56239310Sdim  // Register the target.
57239310Sdim  RegisterTargetMachine<NVPTXTargetMachine32> X(TheNVPTXTarget32);
58239310Sdim  RegisterTargetMachine<NVPTXTargetMachine64> Y(TheNVPTXTarget64);
59239310Sdim
60249423Sdim  // FIXME: This pass is really intended to be invoked during IR optimization,
61249423Sdim  // but it's very NVPTX-specific.
62249423Sdim  initializeNVVMReflectPass(*PassRegistry::getPassRegistry());
63251662Sdim  initializeGenericToNVVMPass(*PassRegistry::getPassRegistry());
64239310Sdim}
65239310Sdim
66249423SdimNVPTXTargetMachine::NVPTXTargetMachine(
67249423Sdim    const Target &T, StringRef TT, StringRef CPU, StringRef FS,
68249423Sdim    const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM,
69249423Sdim    CodeGenOpt::Level OL, bool is64bit)
70249423Sdim    : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
71249423Sdim      Subtarget(TT, CPU, FS, is64bit), DL(Subtarget.getDataLayout()),
72249423Sdim      InstrInfo(*this), TLInfo(*this), TSInfo(*this),
73249423Sdim      FrameLowering(
74263508Sdim          *this, is64bit) /*FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0)*/ {
75263508Sdim  initAsmInfo();
76263508Sdim}
77239310Sdim
78239310Sdimvoid NVPTXTargetMachine32::anchor() {}
79239310Sdim
80249423SdimNVPTXTargetMachine32::NVPTXTargetMachine32(
81249423Sdim    const Target &T, StringRef TT, StringRef CPU, StringRef FS,
82249423Sdim    const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM,
83249423Sdim    CodeGenOpt::Level OL)
84249423Sdim    : NVPTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
85239310Sdim
86239310Sdimvoid NVPTXTargetMachine64::anchor() {}
87239310Sdim
88249423SdimNVPTXTargetMachine64::NVPTXTargetMachine64(
89249423Sdim    const Target &T, StringRef TT, StringRef CPU, StringRef FS,
90249423Sdim    const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM,
91249423Sdim    CodeGenOpt::Level OL)
92249423Sdim    : NVPTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
93239310Sdim
94263508Sdimnamespace {
95239310Sdimclass NVPTXPassConfig : public TargetPassConfig {
96239310Sdimpublic:
97239310Sdim  NVPTXPassConfig(NVPTXTargetMachine *TM, PassManagerBase &PM)
98249423Sdim      : TargetPassConfig(TM, PM) {}
99239310Sdim
100239310Sdim  NVPTXTargetMachine &getNVPTXTargetMachine() const {
101239310Sdim    return getTM<NVPTXTargetMachine>();
102239310Sdim  }
103239310Sdim
104251662Sdim  virtual void addIRPasses();
105239310Sdim  virtual bool addInstSelector();
106239310Sdim  virtual bool addPreRegAlloc();
107263508Sdim  virtual bool addPostRegAlloc();
108263508Sdim
109263508Sdim  virtual FunctionPass *createTargetRegisterAllocator(bool) LLVM_OVERRIDE;
110263508Sdim  virtual void addFastRegAlloc(FunctionPass *RegAllocPass);
111263508Sdim  virtual void addOptimizedRegAlloc(FunctionPass *RegAllocPass);
112239310Sdim};
113263508Sdim} // end anonymous namespace
114239310Sdim
115239310SdimTargetPassConfig *NVPTXTargetMachine::createPassConfig(PassManagerBase &PM) {
116239310Sdim  NVPTXPassConfig *PassConfig = new NVPTXPassConfig(this, PM);
117239310Sdim  return PassConfig;
118239310Sdim}
119239310Sdim
120251662Sdimvoid NVPTXPassConfig::addIRPasses() {
121263508Sdim  // The following passes are known to not play well with virtual regs hanging
122263508Sdim  // around after register allocation (which in our case, is *all* registers).
123263508Sdim  // We explicitly disable them here.  We do, however, need some functionality
124263508Sdim  // of the PrologEpilogCodeInserter pass, so we emulate that behavior in the
125263508Sdim  // NVPTXPrologEpilog pass (see NVPTXPrologEpilogPass.cpp).
126263508Sdim  disablePass(&PrologEpilogCodeInserterID);
127263508Sdim  disablePass(&MachineCopyPropagationID);
128263508Sdim  disablePass(&BranchFolderPassID);
129263508Sdim  disablePass(&TailDuplicateID);
130263508Sdim
131251662Sdim  TargetPassConfig::addIRPasses();
132251662Sdim  addPass(createGenericToNVVMPass());
133251662Sdim}
134251662Sdim
135239310Sdimbool NVPTXPassConfig::addInstSelector() {
136239310Sdim  addPass(createLowerAggrCopies());
137239310Sdim  addPass(createSplitBBatBarPass());
138239310Sdim  addPass(createAllocaHoisting());
139239310Sdim  addPass(createNVPTXISelDag(getNVPTXTargetMachine(), getOptLevel()));
140239310Sdim  return false;
141239310Sdim}
142239310Sdim
143249423Sdimbool NVPTXPassConfig::addPreRegAlloc() { return false; }
144263508Sdimbool NVPTXPassConfig::addPostRegAlloc() {
145263508Sdim  addPass(createNVPTXPrologEpilogPass());
146263508Sdim  return false;
147263508Sdim}
148263508Sdim
149263508SdimFunctionPass *NVPTXPassConfig::createTargetRegisterAllocator(bool) {
150263508Sdim  return 0; // No reg alloc
151263508Sdim}
152263508Sdim
153263508Sdimvoid NVPTXPassConfig::addFastRegAlloc(FunctionPass *RegAllocPass) {
154263508Sdim  assert(!RegAllocPass && "NVPTX uses no regalloc!");
155263508Sdim  addPass(&PHIEliminationID);
156263508Sdim  addPass(&TwoAddressInstructionPassID);
157263508Sdim}
158263508Sdim
159263508Sdimvoid NVPTXPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) {
160263508Sdim  assert(!RegAllocPass && "NVPTX uses no regalloc!");
161263508Sdim
162263508Sdim  addPass(&ProcessImplicitDefsID);
163263508Sdim  addPass(&LiveVariablesID);
164263508Sdim  addPass(&MachineLoopInfoID);
165263508Sdim  addPass(&PHIEliminationID);
166263508Sdim
167263508Sdim  addPass(&TwoAddressInstructionPassID);
168263508Sdim  addPass(&RegisterCoalescerID);
169263508Sdim
170263508Sdim  // PreRA instruction scheduling.
171263508Sdim  if (addPass(&MachineSchedulerID))
172263508Sdim    printAndVerify("After Machine Scheduling");
173263508Sdim
174263508Sdim
175263508Sdim  addPass(&StackSlotColoringID);
176263508Sdim
177263508Sdim  // FIXME: Needs physical registers
178263508Sdim  //addPass(&PostRAMachineLICMID);
179263508Sdim
180263508Sdim  printAndVerify("After StackSlotColoring");
181263508Sdim}
182