LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AMDGPUTargetMachine.cpp
Go to the documentation of this file.
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 /// \file
11 /// \brief The AMDGPU target machine contains all of the hardware specific
12 /// information needed to emit code for R600 and SI GPUs.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "AMDGPUTargetMachine.h"
17 #include "AMDGPU.h"
18 #include "R600ISelLowering.h"
19 #include "R600InstrInfo.h"
20 #include "R600MachineScheduler.h"
21 #include "SIISelLowering.h"
22 #include "SIInstrInfo.h"
23 #include "llvm/Analysis/Passes.h"
24 #include "llvm/Analysis/Verifier.h"
27 #include "llvm/CodeGen/Passes.h"
28 #include "llvm/MC/MCAsmInfo.h"
29 #include "llvm/PassManager.h"
32 #include "llvm/Transforms/IPO.h"
33 #include "llvm/Transforms/Scalar.h"
34 #include <llvm/CodeGen/Passes.h>
35 
36 
37 using namespace llvm;
38 
39 extern "C" void LLVMInitializeR600Target() {
40  // Register the target
42 }
43 
45  return new ScheduleDAGMI(C, new R600SchedStrategy());
46 }
47 
49 SchedCustomRegistry("r600", "Run R600's custom scheduler",
51 
53  StringRef CPU, StringRef FS,
54  TargetOptions Options,
56  CodeGenOpt::Level OptLevel
57 )
58 :
59  LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OptLevel),
60  Subtarget(TT, CPU, FS),
61  Layout(Subtarget.getDataLayout()),
62  FrameLowering(TargetFrameLowering::StackGrowsUp,
63  64 * 16 // Maximum stack alignment (long16)
64  , 0),
65  IntrinsicInfo(this),
66  InstrItins(&Subtarget.getInstrItineraryData()) {
67  // TLInfo uses InstrInfo so it must be initialized after.
69  InstrInfo.reset(new R600InstrInfo(*this));
70  TLInfo.reset(new R600TargetLowering(*this));
71  } else {
72  InstrInfo.reset(new SIInstrInfo(*this));
73  TLInfo.reset(new SITargetLowering(*this));
74  }
75  initAsmInfo();
76 }
77 
79 }
80 
81 namespace {
82 class AMDGPUPassConfig : public TargetPassConfig {
83 public:
84  AMDGPUPassConfig(AMDGPUTargetMachine *TM, PassManagerBase &PM)
85  : TargetPassConfig(TM, PM) {}
86 
87  AMDGPUTargetMachine &getAMDGPUTargetMachine() const {
88  return getTM<AMDGPUTargetMachine>();
89  }
90 
91  virtual ScheduleDAGInstrs *
92  createMachineScheduler(MachineSchedContext *C) const {
93  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
96  return 0;
97  }
98 
99  virtual bool addPreISel();
100  virtual bool addInstSelector();
101  virtual bool addPreRegAlloc();
102  virtual bool addPostRegAlloc();
103  virtual bool addPreSched2();
104  virtual bool addPreEmitPass();
105 };
106 } // End of anonymous namespace
107 
109  return new AMDGPUPassConfig(this, PM);
110 }
111 
112 //===----------------------------------------------------------------------===//
113 // AMDGPU Analysis Pass Setup
114 //===----------------------------------------------------------------------===//
115 
116 void AMDGPUTargetMachine::addAnalysisPasses(PassManagerBase &PM) {
117  // Add first the target-independent BasicTTI pass, then our AMDGPU pass. This
118  // allows the AMDGPU pass to delegate to the target independent layer when
119  // appropriate.
122 }
123 
124 bool
125 AMDGPUPassConfig::addPreISel() {
126  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
127  addPass(createFlattenCFGPass());
128  if (ST.IsIRStructurizerEnabled())
129  addPass(createStructurizeCFGPass());
131  addPass(createSinkingPass());
132  addPass(createSITypeRewriter());
134  } else {
136  }
137  return false;
138 }
139 
140 bool AMDGPUPassConfig::addInstSelector() {
141  addPass(createAMDGPUISelDag(getAMDGPUTargetMachine()));
142  return false;
143 }
144 
145 bool AMDGPUPassConfig::addPreRegAlloc() {
146  addPass(createAMDGPUConvertToISAPass(*TM));
147  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
148 
150  addPass(createR600VectorRegMerger(*TM));
151  } else {
152  addPass(createSIFixSGPRCopiesPass(*TM));
153  }
154  return false;
155 }
156 
157 bool AMDGPUPassConfig::addPostRegAlloc() {
158  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
159 
161  addPass(createSIInsertWaits(*TM));
162  }
163  return false;
164 }
165 
166 bool AMDGPUPassConfig::addPreSched2() {
167  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
168 
170  addPass(createR600EmitClauseMarkers(*TM));
171  if (ST.isIfCvtEnabled())
172  addPass(&IfConverterID);
174  addPass(createR600ClauseMergePass(*TM));
175  return false;
176 }
177 
178 bool AMDGPUPassConfig::addPreEmitPass() {
179  const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>();
183  addPass(&FinalizeMachineBundlesID);
184  addPass(createR600Packetizer(*TM));
186  } else {
187  addPass(createSILowerControlFlowPass(*TM));
188  }
189 
190  return false;
191 }
FunctionPass * createSIAnnotateControlFlowPass()
Create the annotation pass.
Interface definition for R600InstrInfo.
ImmutablePass * createAMDGPUTargetTransformInfoPass(const AMDGPUTargetMachine *TM)
Creates an AMDGPU-specific Target Transformation Info pass.
ImmutablePass * createBasicTargetTransformInfoPass(const TargetMachine *TM)
Create a basic TargetTransformInfo analysis pass.
enum Generation getGeneration() const
bool isIfCvtEnabled() const
FunctionPass * createAMDGPUCFGStructurizerPass(TargetMachine &tm)
R600 Machine Scheduler interface.
FunctionPass * createSIInsertWaits(TargetMachine &tm)
Target TheAMDGPUTarget
The target for the AMDGPU backend.
AMDGPUTargetMachine(const Target &T, StringRef TT, StringRef FS, StringRef CPU, TargetOptions Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL)
FunctionPass * createR600TextureIntrinsicsReplacer()
FunctionPass * createR600ExpandSpecialInstrsPass(TargetMachine &tm)
FunctionPass * createSinkingPass()
Definition: Sink.cpp:70
char & FinalizeMachineBundlesID
FunctionPass * createR600VectorRegMerger(TargetMachine &tm)
void LLVMInitializeR600Target()
FunctionPass * createSITypeRewriter()
FunctionPass * createR600ClauseMergePass(TargetMachine &tm)
FunctionPass * createSILowerControlFlowPass(TargetMachine &tm)
FunctionPass * createR600ControlFlowFinalizer(TargetMachine &tm)
FunctionPass * createSIFixSGPRCopiesPass(TargetMachine &tm)
FunctionPass * createFlattenCFGPass()
FunctionPass * createAMDGPUISelDag(TargetMachine &tm)
This pass converts a legalized DAG into a AMDGPU-specific.
FunctionPass * createR600EmitClauseMarkers(TargetMachine &tm)
SI DAG Lowering interface definition.
FunctionPass * createR600Packetizer(TargetMachine &tm)
The AMDGPU TargetMachine interface definition for hw codgen targets.
static ScheduleDAGInstrs * createR600MachineScheduler(MachineSchedContext *C)
virtual void addAnalysisPasses(PassManagerBase &PM)
Register R600 analysis passes with a pass manager.
Interface definition for SIInstrInfo.
bool IsIRStructurizerEnabled() const
R600 DAG Lowering interface definition.
virtual TargetPassConfig * createPassConfig(PassManagerBase &PM)
char & IfConverterID
IfConverter - This pass performs machine code if conversion.
static MachineSchedRegistry SchedCustomRegistry("r600","Run R600's custom scheduler", createR600MachineScheduler)
Pass * createStructurizeCFGPass()
Create the pass.
FunctionPass * createAMDGPUConvertToISAPass(TargetMachine &tm)
static RegisterPass< NVPTXAllocaHoisting > X("alloca-hoisting","Hoisting alloca instructions in non-entry ""blocks to the entry block")