AMDGPUTargetMachine.cpp revision 235318a578b3d7772a60590c7e76791ed6d1a78e
1//===-- AMDGPUTargetMachine.cpp - TargetMachine for hw codegen targets-----===//
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// The AMDGPU target machine contains all of the hardware specific information
11// needed to emit code for R600 and SI GPUs.
12//
13//===----------------------------------------------------------------------===//
14
15#include "AMDGPUTargetMachine.h"
16#include "AMDGPU.h"
17#include "R600ISelLowering.h"
18#include "R600InstrInfo.h"
19#include "SIISelLowering.h"
20#include "SIInstrInfo.h"
21#include "llvm/Analysis/Passes.h"
22#include "llvm/Analysis/Verifier.h"
23#include "llvm/CodeGen/MachineFunctionAnalysis.h"
24#include "llvm/CodeGen/MachineModuleInfo.h"
25#include "llvm/CodeGen/Passes.h"
26#include "llvm/MC/MCAsmInfo.h"
27#include "llvm/PassManager.h"
28#include "llvm/Support/TargetRegistry.h"
29#include "llvm/Support/raw_os_ostream.h"
30#include "llvm/Transforms/IPO.h"
31#include "llvm/Transforms/Scalar.h"
32#include <llvm/CodeGen/Passes.h>
33
34using namespace llvm;
35
36extern "C" void LLVMInitializeAMDGPUTarget() {
37  // Register the target
38  RegisterTargetMachine<AMDGPUTargetMachine> X(TheAMDGPUTarget);
39}
40
41AMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, StringRef TT,
42    StringRef CPU, StringRef FS,
43  TargetOptions Options,
44  Reloc::Model RM, CodeModel::Model CM,
45  CodeGenOpt::Level OptLevel
46)
47:
48  LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OptLevel),
49  Subtarget(TT, CPU, FS),
50  DataLayout(Subtarget.getDataLayout()),
51  FrameLowering(TargetFrameLowering::StackGrowsUp,
52      Subtarget.device()->getStackAlignment(), 0),
53  IntrinsicInfo(this),
54  InstrItins(&Subtarget.getInstrItineraryData()),
55  mDump(false)
56
57{
58  // TLInfo uses InstrInfo so it must be initialized after.
59  if (Subtarget.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
60    InstrInfo = new R600InstrInfo(*this);
61    TLInfo = new R600TargetLowering(*this);
62  } else {
63    InstrInfo = new SIInstrInfo(*this);
64    TLInfo = new SITargetLowering(*this);
65  }
66}
67
68AMDGPUTargetMachine::~AMDGPUTargetMachine()
69{
70}
71
72bool AMDGPUTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
73                                              formatted_raw_ostream &Out,
74                                              CodeGenFileType FileType,
75                                              bool DisableVerify) {
76
77  const AMDGPUSubtarget &STM = getSubtarget<AMDGPUSubtarget>();
78  std::string gpu = STM.getDeviceName();
79  if (gpu == "SI") {
80    return LLVMTargetMachine::addPassesToEmitFile(PM, Out, FileType,
81                                                     DisableVerify);
82  } else if (Subtarget.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
83    // XXX: Hack here addPassesToEmitFile will fail, but this is Ok since we are
84    // only using it to access addPassesToGenerateCode()
85    bool fail = LLVMTargetMachine::addPassesToEmitFile(PM, Out, FileType,
86                                                     DisableVerify);
87    assert(fail);
88    PM.add(createR600CodeEmitterPass(Out));
89  } else {
90    abort();
91    return true;
92  }
93  PM.add(createGCInfoDeleter());
94
95  return false;
96}
97
98namespace {
99class AMDGPUPassConfig : public TargetPassConfig {
100public:
101  AMDGPUPassConfig(AMDGPUTargetMachine *TM, PassManagerBase &PM)
102    : TargetPassConfig(TM, PM) {}
103
104  AMDGPUTargetMachine &getAMDGPUTargetMachine() const {
105    return getTM<AMDGPUTargetMachine>();
106  }
107
108  virtual bool addPreISel();
109  virtual bool addInstSelector();
110  virtual bool addPreRegAlloc();
111  virtual bool addPostRegAlloc();
112  virtual bool addPreSched2();
113  virtual bool addPreEmitPass();
114};
115} // End of anonymous namespace
116
117TargetPassConfig *AMDGPUTargetMachine::createPassConfig(PassManagerBase &PM) {
118  return new AMDGPUPassConfig(this, PM);
119}
120
121bool
122AMDGPUPassConfig::addPreISel()
123{
124  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
125  if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
126    PM->add(createR600KernelParametersPass(
127                     getAMDGPUTargetMachine().getTargetData()));
128  }
129  return false;
130}
131
132bool AMDGPUPassConfig::addInstSelector() {
133  PM->add(createAMDGPUPeepholeOpt(*TM));
134  PM->add(createAMDGPUISelDag(getAMDGPUTargetMachine()));
135  return false;
136}
137
138bool AMDGPUPassConfig::addPreRegAlloc() {
139  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
140
141  if (ST.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
142    PM->add(createSIAssignInterpRegsPass(*TM));
143  }
144  PM->add(createAMDGPUConvertToISAPass(*TM));
145  return false;
146}
147
148bool AMDGPUPassConfig::addPostRegAlloc() {
149  return false;
150}
151
152bool AMDGPUPassConfig::addPreSched2() {
153
154  addPass(IfConverterID);
155  return false;
156}
157
158bool AMDGPUPassConfig::addPreEmitPass() {
159  PM->add(createAMDGPUCFGPreparationPass(*TM));
160  PM->add(createAMDGPUCFGStructurizerPass(*TM));
161
162  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
163  if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
164    PM->add(createR600ExpandSpecialInstrsPass(*TM));
165    addPass(FinalizeMachineBundlesID);
166  }
167
168  return false;
169}
170
171