Merging r258386:
[oota-llvm.git] / lib / Target / AMDGPU / AMDGPUTargetMachine.cpp
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 "AMDGPUTargetObjectFile.h"
18 #include "AMDGPU.h"
19 #include "AMDGPUTargetTransformInfo.h"
20 #include "R600ISelLowering.h"
21 #include "R600InstrInfo.h"
22 #include "R600MachineScheduler.h"
23 #include "SIISelLowering.h"
24 #include "SIInstrInfo.h"
25 #include "llvm/Analysis/Passes.h"
26 #include "llvm/CodeGen/MachineFunctionAnalysis.h"
27 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
28 #include "llvm/CodeGen/MachineModuleInfo.h"
29 #include "llvm/CodeGen/Passes.h"
30 #include "llvm/IR/Verifier.h"
31 #include "llvm/MC/MCAsmInfo.h"
32 #include "llvm/IR/LegacyPassManager.h"
33 #include "llvm/Support/TargetRegistry.h"
34 #include "llvm/Support/raw_os_ostream.h"
35 #include "llvm/Transforms/IPO.h"
36 #include "llvm/Transforms/Scalar.h"
37 #include <llvm/CodeGen/Passes.h>
38
39 using namespace llvm;
40
41 extern "C" void LLVMInitializeAMDGPUTarget() {
42   // Register the target
43   RegisterTargetMachine<R600TargetMachine> X(TheAMDGPUTarget);
44   RegisterTargetMachine<GCNTargetMachine> Y(TheGCNTarget);
45
46   PassRegistry *PR = PassRegistry::getPassRegistry();
47   initializeSILowerI1CopiesPass(*PR);
48   initializeSIFixSGPRCopiesPass(*PR);
49   initializeSIFoldOperandsPass(*PR);
50   initializeSIFixSGPRLiveRangesPass(*PR);
51   initializeSIFixControlFlowLiveIntervalsPass(*PR);
52   initializeSILoadStoreOptimizerPass(*PR);
53   initializeAMDGPUAnnotateKernelFeaturesPass(*PR);
54   initializeAMDGPUAnnotateUniformValuesPass(*PR);
55 }
56
57 static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
58   if (TT.getOS() == Triple::AMDHSA)
59     return make_unique<AMDGPUHSATargetObjectFile>();
60
61   return make_unique<AMDGPUTargetObjectFile>();
62 }
63
64 static ScheduleDAGInstrs *createR600MachineScheduler(MachineSchedContext *C) {
65   return new ScheduleDAGMILive(C, make_unique<R600SchedStrategy>());
66 }
67
68 static MachineSchedRegistry
69 R600SchedRegistry("r600", "Run R600's custom scheduler",
70                    createR600MachineScheduler);
71
72 static MachineSchedRegistry
73 SISchedRegistry("si", "Run SI's custom scheduler",
74                 createSIMachineScheduler);
75
76 static std::string computeDataLayout(const Triple &TT) {
77   std::string Ret = "e-p:32:32";
78
79   if (TT.getArch() == Triple::amdgcn) {
80     // 32-bit private, local, and region pointers. 64-bit global and constant.
81     Ret += "-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-p24:64:64";
82   }
83
84   Ret += "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256"
85          "-v512:512-v1024:1024-v2048:2048-n32:64";
86
87   return Ret;
88 }
89
90 AMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, const Triple &TT,
91                                          StringRef CPU, StringRef FS,
92                                          TargetOptions Options, Reloc::Model RM,
93                                          CodeModel::Model CM,
94                                          CodeGenOpt::Level OptLevel)
95     : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, RM, CM,
96                         OptLevel),
97       TLOF(createTLOF(getTargetTriple())), Subtarget(TT, CPU, FS, *this),
98       IntrinsicInfo() {
99   setRequiresStructuredCFG(true);
100   initAsmInfo();
101 }
102
103 AMDGPUTargetMachine::~AMDGPUTargetMachine() { }
104
105 //===----------------------------------------------------------------------===//
106 // R600 Target Machine (R600 -> Cayman)
107 //===----------------------------------------------------------------------===//
108
109 R600TargetMachine::R600TargetMachine(const Target &T, const Triple &TT,
110                                      StringRef FS, StringRef CPU,
111                                      TargetOptions Options, Reloc::Model RM,
112                                      CodeModel::Model CM, CodeGenOpt::Level OL)
113     : AMDGPUTargetMachine(T, TT, FS, CPU, Options, RM, CM, OL) {}
114
115 //===----------------------------------------------------------------------===//
116 // GCN Target Machine (SI+)
117 //===----------------------------------------------------------------------===//
118
119 GCNTargetMachine::GCNTargetMachine(const Target &T, const Triple &TT,
120                                    StringRef FS, StringRef CPU,
121                                    TargetOptions Options, Reloc::Model RM,
122                                    CodeModel::Model CM, CodeGenOpt::Level OL)
123     : AMDGPUTargetMachine(T, TT, FS, CPU, Options, RM, CM, OL) {}
124
125 //===----------------------------------------------------------------------===//
126 // AMDGPU Pass Setup
127 //===----------------------------------------------------------------------===//
128
129 namespace {
130 class AMDGPUPassConfig : public TargetPassConfig {
131 public:
132   AMDGPUPassConfig(TargetMachine *TM, PassManagerBase &PM)
133     : TargetPassConfig(TM, PM) {
134
135     // Exceptions and StackMaps are not supported, so these passes will never do
136     // anything.
137     disablePass(&StackMapLivenessID);
138     disablePass(&FuncletLayoutID);
139   }
140
141   AMDGPUTargetMachine &getAMDGPUTargetMachine() const {
142     return getTM<AMDGPUTargetMachine>();
143   }
144
145   ScheduleDAGInstrs *
146   createMachineScheduler(MachineSchedContext *C) const override {
147     const AMDGPUSubtarget &ST = *getAMDGPUTargetMachine().getSubtargetImpl();
148     if (ST.getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS)
149       return createR600MachineScheduler(C);
150     else if (ST.enableSIScheduler())
151       return createSIMachineScheduler(C);
152     return nullptr;
153   }
154
155   void addIRPasses() override;
156   void addCodeGenPrepare() override;
157   bool addPreISel() override;
158   bool addInstSelector() override;
159   bool addGCPasses() override;
160 };
161
162 class R600PassConfig : public AMDGPUPassConfig {
163 public:
164   R600PassConfig(TargetMachine *TM, PassManagerBase &PM)
165     : AMDGPUPassConfig(TM, PM) { }
166
167   bool addPreISel() override;
168   void addPreRegAlloc() override;
169   void addPreSched2() override;
170   void addPreEmitPass() override;
171 };
172
173 class GCNPassConfig : public AMDGPUPassConfig {
174 public:
175   GCNPassConfig(TargetMachine *TM, PassManagerBase &PM)
176     : AMDGPUPassConfig(TM, PM) { }
177   bool addPreISel() override;
178   bool addInstSelector() override;
179   void addFastRegAlloc(FunctionPass *RegAllocPass) override;
180   void addOptimizedRegAlloc(FunctionPass *RegAllocPass) override;
181   void addPreRegAlloc() override;
182   void addPostRegAlloc() override;
183   void addPreSched2() override;
184   void addPreEmitPass() override;
185 };
186
187 } // End of anonymous namespace
188
189 TargetIRAnalysis AMDGPUTargetMachine::getTargetIRAnalysis() {
190   return TargetIRAnalysis([this](const Function &F) {
191     return TargetTransformInfo(
192         AMDGPUTTIImpl(this, F.getParent()->getDataLayout()));
193   });
194 }
195
196 void AMDGPUPassConfig::addIRPasses() {
197   // Function calls are not supported, so make sure we inline everything.
198   addPass(createAMDGPUAlwaysInlinePass());
199   addPass(createAlwaysInlinerPass());
200   // We need to add the barrier noop pass, otherwise adding the function
201   // inlining pass will cause all of the PassConfigs passes to be run
202   // one function at a time, which means if we have a nodule with two
203   // functions, then we will generate code for the first function
204   // without ever running any passes on the second.
205   addPass(createBarrierNoopPass());
206
207   // Handle uses of OpenCL image2d_t, image3d_t and sampler_t arguments.
208   addPass(createAMDGPUOpenCLImageTypeLoweringPass());
209
210   TargetPassConfig::addIRPasses();
211 }
212
213 void AMDGPUPassConfig::addCodeGenPrepare() {
214   const AMDGPUSubtarget &ST = *getAMDGPUTargetMachine().getSubtargetImpl();
215   if (ST.isPromoteAllocaEnabled()) {
216     addPass(createAMDGPUPromoteAlloca(ST));
217     addPass(createSROAPass());
218   }
219   TargetPassConfig::addCodeGenPrepare();
220 }
221
222 bool
223 AMDGPUPassConfig::addPreISel() {
224   const AMDGPUSubtarget &ST = *getAMDGPUTargetMachine().getSubtargetImpl();
225   addPass(createFlattenCFGPass());
226   if (ST.IsIRStructurizerEnabled())
227     addPass(createStructurizeCFGPass());
228   return false;
229 }
230
231 bool AMDGPUPassConfig::addInstSelector() {
232   addPass(createAMDGPUISelDag(getAMDGPUTargetMachine()));
233   return false;
234 }
235
236 bool AMDGPUPassConfig::addGCPasses() {
237   // Do nothing. GC is not supported.
238   return false;
239 }
240
241 //===----------------------------------------------------------------------===//
242 // R600 Pass Setup
243 //===----------------------------------------------------------------------===//
244
245 bool R600PassConfig::addPreISel() {
246   AMDGPUPassConfig::addPreISel();
247   addPass(createR600TextureIntrinsicsReplacer());
248   return false;
249 }
250
251 void R600PassConfig::addPreRegAlloc() {
252   addPass(createR600VectorRegMerger(*TM));
253 }
254
255 void R600PassConfig::addPreSched2() {
256   const AMDGPUSubtarget &ST = *getAMDGPUTargetMachine().getSubtargetImpl();
257   addPass(createR600EmitClauseMarkers(), false);
258   if (ST.isIfCvtEnabled())
259     addPass(&IfConverterID, false);
260   addPass(createR600ClauseMergePass(*TM), false);
261 }
262
263 void R600PassConfig::addPreEmitPass() {
264   addPass(createAMDGPUCFGStructurizerPass(), false);
265   addPass(createR600ExpandSpecialInstrsPass(*TM), false);
266   addPass(&FinalizeMachineBundlesID, false);
267   addPass(createR600Packetizer(*TM), false);
268   addPass(createR600ControlFlowFinalizer(*TM), false);
269 }
270
271 TargetPassConfig *R600TargetMachine::createPassConfig(PassManagerBase &PM) {
272   return new R600PassConfig(this, PM);
273 }
274
275 //===----------------------------------------------------------------------===//
276 // GCN Pass Setup
277 //===----------------------------------------------------------------------===//
278
279 bool GCNPassConfig::addPreISel() {
280   AMDGPUPassConfig::addPreISel();
281
282   // FIXME: We need to run a pass to propagate the attributes when calls are
283   // supported.
284   addPass(&AMDGPUAnnotateKernelFeaturesID);
285
286   addPass(createSinkingPass());
287   addPass(createSITypeRewriter());
288   addPass(createSIAnnotateControlFlowPass());
289   addPass(createAMDGPUAnnotateUniformValues());
290
291   return false;
292 }
293
294 bool GCNPassConfig::addInstSelector() {
295   AMDGPUPassConfig::addInstSelector();
296   addPass(createSILowerI1CopiesPass());
297   addPass(&SIFixSGPRCopiesID);
298   addPass(createSIFoldOperandsPass());
299   return false;
300 }
301
302 void GCNPassConfig::addPreRegAlloc() {
303   const AMDGPUSubtarget &ST = *getAMDGPUTargetMachine().getSubtargetImpl();
304
305   // This needs to be run directly before register allocation because
306   // earlier passes might recompute live intervals.
307   // TODO: handle CodeGenOpt::None; fast RA ignores spill weights set by the pass
308   if (getOptLevel() > CodeGenOpt::None) {
309     insertPass(&MachineSchedulerID, &SIFixControlFlowLiveIntervalsID);
310   }
311
312   if (getOptLevel() > CodeGenOpt::None && ST.loadStoreOptEnabled()) {
313     // Don't do this with no optimizations since it throws away debug info by
314     // merging nonadjacent loads.
315
316     // This should be run after scheduling, but before register allocation. It
317     // also need extra copies to the address operand to be eliminated.
318     insertPass(&MachineSchedulerID, &SILoadStoreOptimizerID);
319     insertPass(&MachineSchedulerID, &RegisterCoalescerID);
320   }
321   addPass(createSIShrinkInstructionsPass(), false);
322 }
323
324 void GCNPassConfig::addFastRegAlloc(FunctionPass *RegAllocPass) {
325   addPass(&SIFixSGPRLiveRangesID);
326   TargetPassConfig::addFastRegAlloc(RegAllocPass);
327 }
328
329 void GCNPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) {
330   // We want to run this after LiveVariables is computed to avoid computing them
331   // twice.
332   // FIXME: We shouldn't disable the verifier here. r249087 introduced a failure
333   // that needs to be fixed.
334   insertPass(&LiveVariablesID, &SIFixSGPRLiveRangesID, /*VerifyAfter=*/false);
335   TargetPassConfig::addOptimizedRegAlloc(RegAllocPass);
336 }
337
338 void GCNPassConfig::addPostRegAlloc() {
339   addPass(createSIShrinkInstructionsPass(), false);
340 }
341
342 void GCNPassConfig::addPreSched2() {
343 }
344
345 void GCNPassConfig::addPreEmitPass() {
346   addPass(createSIInsertWaits(*TM), false);
347   addPass(createSILowerControlFlowPass(*TM), false);
348 }
349
350 TargetPassConfig *GCNTargetMachine::createPassConfig(PassManagerBase &PM) {
351   return new GCNPassConfig(this, PM);
352 }