AMDGPUTargetMachine.cpp revision 90bd1d52bbf95947955a66ec67f5f6c7dc87119a
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
72namespace {
73class AMDGPUPassConfig : public TargetPassConfig {
74public:
75  AMDGPUPassConfig(AMDGPUTargetMachine *TM, PassManagerBase &PM)
76    : TargetPassConfig(TM, PM) {}
77
78  AMDGPUTargetMachine &getAMDGPUTargetMachine() const {
79    return getTM<AMDGPUTargetMachine>();
80  }
81
82  virtual bool addPreISel();
83  virtual bool addInstSelector();
84  virtual bool addPreRegAlloc();
85  virtual bool addPostRegAlloc();
86  virtual bool addPreSched2();
87  virtual bool addPreEmitPass();
88};
89} // End of anonymous namespace
90
91TargetPassConfig *AMDGPUTargetMachine::createPassConfig(PassManagerBase &PM) {
92  return new AMDGPUPassConfig(this, PM);
93}
94
95bool
96AMDGPUPassConfig::addPreISel()
97{
98  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
99  if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
100    PM->add(createR600KernelParametersPass(
101                     getAMDGPUTargetMachine().getTargetData()));
102  }
103  return false;
104}
105
106bool AMDGPUPassConfig::addInstSelector() {
107  PM->add(createAMDGPUPeepholeOpt(*TM));
108  PM->add(createAMDGPUISelDag(getAMDGPUTargetMachine()));
109  return false;
110}
111
112bool AMDGPUPassConfig::addPreRegAlloc() {
113  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
114
115  if (ST.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
116    PM->add(createSIAssignInterpRegsPass(*TM));
117  }
118  PM->add(createAMDGPUConvertToISAPass(*TM));
119  return false;
120}
121
122bool AMDGPUPassConfig::addPostRegAlloc() {
123  return false;
124}
125
126bool AMDGPUPassConfig::addPreSched2() {
127
128  addPass(IfConverterID);
129  return false;
130}
131
132bool AMDGPUPassConfig::addPreEmitPass() {
133  PM->add(createAMDGPUCFGPreparationPass(*TM));
134  PM->add(createAMDGPUCFGStructurizerPass(*TM));
135
136  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
137  if (ST.device()->getGeneration() <= AMDGPUDeviceInfo::HD6XXX) {
138    PM->add(createR600ExpandSpecialInstrsPass(*TM));
139    addPass(FinalizeMachineBundlesID);
140  }
141
142  return false;
143}
144
145