blob: 5a14e8accdd4641ad1fe50cd7ff4b4c414fa5a23 [file] [log] [blame]
Nick Lewyckyf7a3c502010-09-07 18:14:24 +00001//===-- PTXTargetMachine.cpp - Define TargetMachine for PTX ---------------===//
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// Top-level implementation for the PTX target.
11//
12//===----------------------------------------------------------------------===//
13
14#include "PTX.h"
15#include "PTXTargetMachine.h"
Eric Christopher50880d02010-09-18 18:52:28 +000016#include "llvm/PassManager.h"
Justin Holewinski40466cc2011-09-22 16:45:37 +000017#include "llvm/Analysis/Passes.h"
18#include "llvm/Analysis/Verifier.h"
19#include "llvm/Assembly/PrintModulePass.h"
20#include "llvm/ADT/OwningPtr.h"
21#include "llvm/CodeGen/AsmPrinter.h"
22#include "llvm/CodeGen/MachineFunctionAnalysis.h"
23#include "llvm/CodeGen/MachineModuleInfo.h"
24#include "llvm/CodeGen/Passes.h"
25#include "llvm/MC/MCAsmInfo.h"
26#include "llvm/MC/MCInstrInfo.h"
27#include "llvm/MC/MCStreamer.h"
28#include "llvm/MC/MCSubtargetInfo.h"
Evan Cheng3e74d6f2011-08-24 18:08:43 +000029#include "llvm/Support/TargetRegistry.h"
Che-Liang Chiouf48817c2011-03-02 07:36:48 +000030#include "llvm/Support/raw_ostream.h"
Justin Holewinski40466cc2011-09-22 16:45:37 +000031#include "llvm/Target/TargetData.h"
32#include "llvm/Target/TargetInstrInfo.h"
33#include "llvm/Target/TargetLowering.h"
34#include "llvm/Target/TargetLoweringObjectFile.h"
35#include "llvm/Target/TargetMachine.h"
36#include "llvm/Target/TargetOptions.h"
37#include "llvm/Target/TargetRegisterInfo.h"
38#include "llvm/Target/TargetSubtargetInfo.h"
39#include "llvm/Transforms/Scalar.h"
40#include "llvm/Support/Debug.h"
41#include "llvm/Support/TargetRegistry.h"
42
Nick Lewyckyf7a3c502010-09-07 18:14:24 +000043
44using namespace llvm;
45
Rafael Espindolaa484f2c2010-11-28 14:48:34 +000046namespace llvm {
47 MCStreamer *createPTXAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
Rafael Espindola89b93722010-12-10 07:39:47 +000048 bool isVerboseAsm, bool useLoc,
Nick Lewycky44d798d2011-10-17 23:05:28 +000049 bool useCFI, bool useDwarfDirectory,
Rafael Espindolaa484f2c2010-11-28 14:48:34 +000050 MCInstPrinter *InstPrint,
51 MCCodeEmitter *CE,
Evan Cheng78c10ee2011-07-25 23:24:55 +000052 MCAsmBackend *MAB,
Bill Wendlinge266ce62011-06-17 20:55:01 +000053 bool ShowInst);
Rafael Espindolaa484f2c2010-11-28 14:48:34 +000054}
55
Eric Christopher50880d02010-09-18 18:52:28 +000056extern "C" void LLVMInitializePTXTarget() {
Justin Holewinskie1fee482011-04-20 15:37:17 +000057
58 RegisterTargetMachine<PTX32TargetMachine> X(ThePTX32Target);
59 RegisterTargetMachine<PTX64TargetMachine> Y(ThePTX64Target);
60
Justin Holewinskie1fee482011-04-20 15:37:17 +000061 TargetRegistry::RegisterAsmStreamer(ThePTX32Target, createPTXAsmStreamer);
62 TargetRegistry::RegisterAsmStreamer(ThePTX64Target, createPTXAsmStreamer);
Nick Lewyckyf7a3c502010-09-07 18:14:24 +000063}
64
Che-Liang Chiouf48817c2011-03-02 07:36:48 +000065namespace {
Che-Liang Chiou31c488c2011-03-02 07:58:46 +000066 const char* DataLayout32 =
67 "e-p:32:32-i64:32:32-f64:32:32-v128:32:128-v64:32:64-n32:64";
68 const char* DataLayout64 =
69 "e-p:64:64-i64:32:32-f64:32:32-v128:32:128-v64:32:64-n32:64";
Che-Liang Chiouf48817c2011-03-02 07:36:48 +000070}
71
Anton Korobeynikov16c29b52011-01-10 12:39:04 +000072// DataLayout and FrameLowering are filled with dummy data
Nick Lewyckyf7a3c502010-09-07 18:14:24 +000073PTXTargetMachine::PTXTargetMachine(const Target &T,
Evan Cheng34ad6db2011-07-20 07:51:56 +000074 StringRef TT, StringRef CPU, StringRef FS,
Nick Lewycky8a8d4792011-12-02 22:16:29 +000075 const TargetOptions &Options,
Evan Cheng34ad6db2011-07-20 07:51:56 +000076 Reloc::Model RM, CodeModel::Model CM,
Evan Chengb95fc312011-11-16 08:38:26 +000077 CodeGenOpt::Level OL,
Evan Cheng34ad6db2011-07-20 07:51:56 +000078 bool is64Bit)
Nick Lewycky8a8d4792011-12-02 22:16:29 +000079 : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
Justin Holewinskie1fee482011-04-20 15:37:17 +000080 DataLayout(is64Bit ? DataLayout64 : DataLayout32),
Evan Cheng276365d2011-06-30 01:53:36 +000081 Subtarget(TT, CPU, FS, is64Bit),
Anton Korobeynikov16c29b52011-01-10 12:39:04 +000082 FrameLowering(Subtarget),
Che-Liang Chiou31c488c2011-03-02 07:58:46 +000083 InstrInfo(*this),
Justin Holewinskibc97f442011-09-26 18:57:27 +000084 TSInfo(*this),
Che-Liang Chiou31c488c2011-03-02 07:58:46 +000085 TLInfo(*this) {
Eric Christopher50880d02010-09-18 18:52:28 +000086}
87
David Blaikie2d24e2a2011-12-20 02:50:00 +000088void PTX32TargetMachine::anchor() { }
89
Evan Cheng43966132011-07-19 06:37:02 +000090PTX32TargetMachine::PTX32TargetMachine(const Target &T, StringRef TT,
91 StringRef CPU, StringRef FS,
Nick Lewycky8a8d4792011-12-02 22:16:29 +000092 const TargetOptions &Options,
Evan Chengb95fc312011-11-16 08:38:26 +000093 Reloc::Model RM, CodeModel::Model CM,
94 CodeGenOpt::Level OL)
Nick Lewycky8a8d4792011-12-02 22:16:29 +000095 : PTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {
Justin Holewinskie1fee482011-04-20 15:37:17 +000096}
97
David Blaikie2d24e2a2011-12-20 02:50:00 +000098void PTX64TargetMachine::anchor() { }
99
Evan Cheng43966132011-07-19 06:37:02 +0000100PTX64TargetMachine::PTX64TargetMachine(const Target &T, StringRef TT,
101 StringRef CPU, StringRef FS,
Nick Lewycky8a8d4792011-12-02 22:16:29 +0000102 const TargetOptions &Options,
Evan Chengb95fc312011-11-16 08:38:26 +0000103 Reloc::Model RM, CodeModel::Model CM,
104 CodeGenOpt::Level OL)
Nick Lewycky8a8d4792011-12-02 22:16:29 +0000105 : PTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {
Justin Holewinskie1fee482011-04-20 15:37:17 +0000106}
107
Andrew Trick843ee2e2012-02-03 05:12:41 +0000108namespace {
109/// PTX Code Generator Pass Configuration Options.
110class PTXPassConfig : public TargetPassConfig {
111public:
Andrew Trick061efcf2012-02-04 02:56:59 +0000112 PTXPassConfig(PTXTargetMachine *TM, PassManagerBase &PM)
113 : TargetPassConfig(TM, PM) {}
Andrew Trick843ee2e2012-02-03 05:12:41 +0000114
115 PTXTargetMachine &getPTXTargetMachine() const {
116 return getTM<PTXTargetMachine>();
117 }
118
119 bool addInstSelector();
120 bool addPostRegAlloc();
121 bool addCodeGenPasses(MCContext *&OutContext);
122};
123} // namespace
124
Andrew Trick061efcf2012-02-04 02:56:59 +0000125TargetPassConfig *PTXTargetMachine::createPassConfig(PassManagerBase &PM) {
126 return new PTXPassConfig(this, PM);
Andrew Trick843ee2e2012-02-03 05:12:41 +0000127}
128
129bool PTXPassConfig::addInstSelector() {
130 PM.add(createPTXISelDag(getPTXTargetMachine(), getOptLevel()));
Che-Liang Chiouad83c1d2011-01-01 10:50:37 +0000131 return false;
132}
133
Andrew Trick843ee2e2012-02-03 05:12:41 +0000134bool PTXPassConfig::addPostRegAlloc() {
Che-Liang Chiouad83c1d2011-01-01 10:50:37 +0000135 // PTXMFInfoExtract must after register allocation!
Andrew Trick843ee2e2012-02-03 05:12:41 +0000136 //PM.add(createPTXMFInfoExtract(getPTXTargetMachine()));
Eric Christopher50880d02010-09-18 18:52:28 +0000137 return false;
Nick Lewyckyf7a3c502010-09-07 18:14:24 +0000138}
Justin Holewinski40466cc2011-09-22 16:45:37 +0000139
140bool PTXTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
141 formatted_raw_ostream &Out,
142 CodeGenFileType FileType,
Justin Holewinski40466cc2011-09-22 16:45:37 +0000143 bool DisableVerify) {
144 // This is mostly based on LLVMTargetMachine::addPassesToEmitFile
145
146 // Add common CodeGen passes.
147 MCContext *Context = 0;
Andrew Trick061efcf2012-02-04 02:56:59 +0000148
149 // FIXME: soon this will be converted to use the exposed TargetPassConfig API.
150 OwningPtr<PTXPassConfig> PassConfig(
151 static_cast<PTXPassConfig*>(createPassConfig(PM)));
152
153 PassConfig->setDisableVerify(DisableVerify);
154
Andrew Trick843ee2e2012-02-03 05:12:41 +0000155 if (PassConfig->addCodeGenPasses(Context))
Justin Holewinski40466cc2011-09-22 16:45:37 +0000156 return true;
157 assert(Context != 0 && "Failed to get MCContext");
158
159 if (hasMCSaveTempLabels())
160 Context->setAllowTemporaryLabels(false);
161
162 const MCAsmInfo &MAI = *getMCAsmInfo();
163 const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
164 OwningPtr<MCStreamer> AsmStreamer;
165
166 switch (FileType) {
Justin Holewinski40466cc2011-09-22 16:45:37 +0000167 case CGFT_AssemblyFile: {
168 MCInstPrinter *InstPrinter =
169 getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI, STI);
170
171 // Create a code emitter if asked to show the encoding.
172 MCCodeEmitter *MCE = 0;
173 MCAsmBackend *MAB = 0;
174
175 MCStreamer *S = getTarget().createAsmStreamer(*Context, Out,
176 true, /* verbose asm */
177 hasMCUseLoc(),
178 hasMCUseCFI(),
Nick Lewycky44d798d2011-10-17 23:05:28 +0000179 hasMCUseDwarfDirectory(),
Justin Holewinski40466cc2011-09-22 16:45:37 +0000180 InstPrinter,
181 MCE, MAB,
182 false /* show MC encoding */);
183 AsmStreamer.reset(S);
184 break;
185 }
186 case CGFT_ObjectFile: {
187 llvm_unreachable("Object file emission is not supported with PTX");
188 }
189 case CGFT_Null:
190 // The Null output is intended for use for performance analysis and testing,
191 // not real users.
192 AsmStreamer.reset(createNullStreamer(*Context));
193 break;
194 }
195
Justin Holewinski40466cc2011-09-22 16:45:37 +0000196 // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
197 FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer);
198 if (Printer == 0)
199 return true;
200
201 // If successful, createAsmPrinter took ownership of AsmStreamer.
202 AsmStreamer.take();
203
204 PM.add(Printer);
205
206 PM.add(createGCInfoDeleter());
207 return false;
208}
209
Andrew Trick843ee2e2012-02-03 05:12:41 +0000210bool PTXPassConfig::addCodeGenPasses(MCContext *&OutContext) {
Justin Holewinski40466cc2011-09-22 16:45:37 +0000211 // Add standard LLVM codegen passes.
212 // This is derived from LLVMTargetMachine::addCommonCodeGenPasses, with some
213 // modifications for the PTX target.
214
215 // Standard LLVM-Level Passes.
216
217 // Basic AliasAnalysis support.
218 // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that
219 // BasicAliasAnalysis wins if they disagree. This is intended to help
220 // support "obvious" type-punning idioms.
221 PM.add(createTypeBasedAliasAnalysisPass());
222 PM.add(createBasicAliasAnalysisPass());
223
224 // Before running any passes, run the verifier to determine if the input
225 // coming from the front-end and/or optimizer is valid.
226 if (!DisableVerify)
227 PM.add(createVerifierPass());
228
229 // Run loop strength reduction before anything else.
Evan Chengb95fc312011-11-16 08:38:26 +0000230 if (getOptLevel() != CodeGenOpt::None) {
Justin Holewinski40466cc2011-09-22 16:45:37 +0000231 PM.add(createLoopStrengthReducePass(getTargetLowering()));
232 //PM.add(createPrintFunctionPass("\n\n*** Code after LSR ***\n", &dbgs()));
233 }
234
235 PM.add(createGCLoweringPass());
236
237 // Make sure that no unreachable blocks are instruction selected.
238 PM.add(createUnreachableBlockEliminationPass());
239
240 PM.add(createLowerInvokePass(getTargetLowering()));
241 // The lower invoke pass may create unreachable code. Remove it.
242 PM.add(createUnreachableBlockEliminationPass());
243
Evan Chengb95fc312011-11-16 08:38:26 +0000244 if (getOptLevel() != CodeGenOpt::None)
Justin Holewinski40466cc2011-09-22 16:45:37 +0000245 PM.add(createCodeGenPreparePass(getTargetLowering()));
246
247 PM.add(createStackProtectorPass(getTargetLowering()));
248
Andrew Trick843ee2e2012-02-03 05:12:41 +0000249 addPreISel();
Justin Holewinski40466cc2011-09-22 16:45:37 +0000250
251 //PM.add(createPrintFunctionPass("\n\n"
252 // "*** Final LLVM Code input to ISel ***\n",
253 // &dbgs()));
254
255 // All passes which modify the LLVM IR are now complete; run the verifier
256 // to ensure that the IR is valid.
257 if (!DisableVerify)
258 PM.add(createVerifierPass());
259
260 // Standard Lower-Level Passes.
261
262 // Install a MachineModuleInfo class, which is an immutable pass that holds
263 // all the per-module stuff we're generating, including MCContext.
Andrew Trick843ee2e2012-02-03 05:12:41 +0000264 MachineModuleInfo *MMI = new MachineModuleInfo(*TM->getMCAsmInfo(),
265 *TM->getRegisterInfo(),
Justin Holewinski05591be2011-09-22 16:45:43 +0000266 &getTargetLowering()->getObjFileLowering());
Justin Holewinski40466cc2011-09-22 16:45:37 +0000267 PM.add(MMI);
268 OutContext = &MMI->getContext(); // Return the MCContext specifically by-ref.
269
270 // Set up a MachineFunction for the rest of CodeGen to work on.
Andrew Trick843ee2e2012-02-03 05:12:41 +0000271 PM.add(new MachineFunctionAnalysis(*TM));
Justin Holewinski40466cc2011-09-22 16:45:37 +0000272
273 // Ask the target for an isel.
Andrew Trick843ee2e2012-02-03 05:12:41 +0000274 if (addInstSelector())
Justin Holewinski40466cc2011-09-22 16:45:37 +0000275 return true;
276
277 // Print the instruction selected machine code...
Andrew Trick843ee2e2012-02-03 05:12:41 +0000278 printAndVerify("After Instruction Selection");
Justin Holewinski40466cc2011-09-22 16:45:37 +0000279
280 // Expand pseudo-instructions emitted by ISel.
281 PM.add(createExpandISelPseudosPass());
282
283 // Pre-ra tail duplication.
Evan Chengb95fc312011-11-16 08:38:26 +0000284 if (getOptLevel() != CodeGenOpt::None) {
Justin Holewinski40466cc2011-09-22 16:45:37 +0000285 PM.add(createTailDuplicatePass(true));
Andrew Trick843ee2e2012-02-03 05:12:41 +0000286 printAndVerify("After Pre-RegAlloc TailDuplicate");
Justin Holewinski40466cc2011-09-22 16:45:37 +0000287 }
288
289 // Optimize PHIs before DCE: removing dead PHI cycles may make more
290 // instructions dead.
Evan Chengb95fc312011-11-16 08:38:26 +0000291 if (getOptLevel() != CodeGenOpt::None)
Justin Holewinski40466cc2011-09-22 16:45:37 +0000292 PM.add(createOptimizePHIsPass());
293
294 // If the target requests it, assign local variables to stack slots relative
295 // to one another and simplify frame index references where possible.
296 PM.add(createLocalStackSlotAllocationPass());
297
Evan Chengb95fc312011-11-16 08:38:26 +0000298 if (getOptLevel() != CodeGenOpt::None) {
Justin Holewinski40466cc2011-09-22 16:45:37 +0000299 // With optimization, dead code should already be eliminated. However
300 // there is one known exception: lowered code for arguments that are only
301 // used by tail calls, where the tail calls reuse the incoming stack
302 // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll).
303 PM.add(createDeadMachineInstructionElimPass());
Andrew Trick843ee2e2012-02-03 05:12:41 +0000304 printAndVerify("After codegen DCE pass");
Justin Holewinski40466cc2011-09-22 16:45:37 +0000305
306 PM.add(createMachineLICMPass());
307 PM.add(createMachineCSEPass());
308 PM.add(createMachineSinkingPass());
Andrew Trick843ee2e2012-02-03 05:12:41 +0000309 printAndVerify("After Machine LICM, CSE and Sinking passes");
Justin Holewinski40466cc2011-09-22 16:45:37 +0000310
311 PM.add(createPeepholeOptimizerPass());
Andrew Trick843ee2e2012-02-03 05:12:41 +0000312 printAndVerify("After codegen peephole optimization pass");
Justin Holewinski40466cc2011-09-22 16:45:37 +0000313 }
314
315 // Run pre-ra passes.
Andrew Trick843ee2e2012-02-03 05:12:41 +0000316 if (addPreRegAlloc())
317 printAndVerify("After PreRegAlloc passes");
Justin Holewinski40466cc2011-09-22 16:45:37 +0000318
319 // Perform register allocation.
320 PM.add(createPTXRegisterAllocator());
Andrew Trick843ee2e2012-02-03 05:12:41 +0000321 printAndVerify("After Register Allocation");
Justin Holewinski40466cc2011-09-22 16:45:37 +0000322
323 // Perform stack slot coloring and post-ra machine LICM.
Evan Chengb95fc312011-11-16 08:38:26 +0000324 if (getOptLevel() != CodeGenOpt::None) {
Justin Holewinski40466cc2011-09-22 16:45:37 +0000325 // FIXME: Re-enable coloring with register when it's capable of adding
326 // kill markers.
327 PM.add(createStackSlotColoringPass(false));
328
329 // FIXME: Post-RA LICM has asserts that fire on virtual registers.
330 // Run post-ra machine LICM to hoist reloads / remats.
331 //if (!DisablePostRAMachineLICM)
332 // PM.add(createMachineLICMPass(false));
333
Andrew Trick843ee2e2012-02-03 05:12:41 +0000334 printAndVerify("After StackSlotColoring and postra Machine LICM");
Justin Holewinski40466cc2011-09-22 16:45:37 +0000335 }
336
337 // Run post-ra passes.
Andrew Trick843ee2e2012-02-03 05:12:41 +0000338 if (addPostRegAlloc())
339 printAndVerify("After PostRegAlloc passes");
Justin Holewinski40466cc2011-09-22 16:45:37 +0000340
Jakob Stoklund Olesen74e2d6e2011-09-25 16:46:08 +0000341 PM.add(createExpandPostRAPseudosPass());
Andrew Trick843ee2e2012-02-03 05:12:41 +0000342 printAndVerify("After ExpandPostRAPseudos");
Justin Holewinski40466cc2011-09-22 16:45:37 +0000343
344 // Insert prolog/epilog code. Eliminate abstract frame index references...
345 PM.add(createPrologEpilogCodeInserter());
Andrew Trick843ee2e2012-02-03 05:12:41 +0000346 printAndVerify("After PrologEpilogCodeInserter");
Justin Holewinski40466cc2011-09-22 16:45:37 +0000347
348 // Run pre-sched2 passes.
Andrew Trick843ee2e2012-02-03 05:12:41 +0000349 if (addPreSched2())
350 printAndVerify("After PreSched2 passes");
Justin Holewinski40466cc2011-09-22 16:45:37 +0000351
352 // Second pass scheduler.
Evan Chengb95fc312011-11-16 08:38:26 +0000353 if (getOptLevel() != CodeGenOpt::None) {
354 PM.add(createPostRAScheduler(getOptLevel()));
Andrew Trick843ee2e2012-02-03 05:12:41 +0000355 printAndVerify("After PostRAScheduler");
Justin Holewinski40466cc2011-09-22 16:45:37 +0000356 }
357
358 // Branch folding must be run after regalloc and prolog/epilog insertion.
Evan Chengb95fc312011-11-16 08:38:26 +0000359 if (getOptLevel() != CodeGenOpt::None) {
Justin Holewinski40466cc2011-09-22 16:45:37 +0000360 PM.add(createBranchFoldingPass(getEnableTailMergeDefault()));
Andrew Trick843ee2e2012-02-03 05:12:41 +0000361 printNoVerify("After BranchFolding");
Justin Holewinski40466cc2011-09-22 16:45:37 +0000362 }
363
364 // Tail duplication.
Evan Chengb95fc312011-11-16 08:38:26 +0000365 if (getOptLevel() != CodeGenOpt::None) {
Justin Holewinski40466cc2011-09-22 16:45:37 +0000366 PM.add(createTailDuplicatePass(false));
Andrew Trick843ee2e2012-02-03 05:12:41 +0000367 printNoVerify("After TailDuplicate");
Justin Holewinski40466cc2011-09-22 16:45:37 +0000368 }
369
370 PM.add(createGCMachineCodeAnalysisPass());
371
372 //if (PrintGCInfo)
373 // PM.add(createGCInfoPrinter(dbgs()));
374
Evan Chengb95fc312011-11-16 08:38:26 +0000375 if (getOptLevel() != CodeGenOpt::None) {
Justin Holewinski40466cc2011-09-22 16:45:37 +0000376 PM.add(createCodePlacementOptPass());
Andrew Trick843ee2e2012-02-03 05:12:41 +0000377 printNoVerify("After CodePlacementOpt");
Justin Holewinski40466cc2011-09-22 16:45:37 +0000378 }
379
Andrew Trick843ee2e2012-02-03 05:12:41 +0000380 if (addPreEmitPass())
381 printNoVerify("After PreEmit passes");
Justin Holewinski40466cc2011-09-22 16:45:37 +0000382
Andrew Trick843ee2e2012-02-03 05:12:41 +0000383 PM.add(createPTXMFInfoExtract(getPTXTargetMachine(), getOptLevel()));
384 PM.add(createPTXFPRoundingModePass(getPTXTargetMachine(), getOptLevel()));
Justin Holewinski6b8990d2011-09-26 16:20:25 +0000385
Justin Holewinski40466cc2011-09-22 16:45:37 +0000386 return false;
387}