llvm.org GIT mirror llvm / 516023a
CodeGen/LLVMTargetMachine: Refactor ISel pass construction; NFCI - Move ISel (and pre-isel) pass construction into TargetPassConfig - Extract AsmPrinter construction into a helper function Putting the ISel code into TargetPassConfig seems a lot more natural and both changes together make make it easier to build custom pipelines involving .mir in an upcoming commit. This moves MachineModuleInfo to an earlier place in the pass pipeline which shouldn't have any effect. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304754 91177308-0d34-0410-b5e6-96231b3b80d8 Matthias Braun 3 years ago
6 changed file(s) with 166 addition(s) and 145 deletion(s). Raw diff Collapse all Expand all
118118 /// callers.
119119 bool RequireCodeGenSCCOrder;
120120
121 /// Add the actual instruction selection passes. This does not include
122 /// preparation passes on IR.
123 bool addCoreISelPasses();
124
121125 public:
122126 TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm);
123127 // Dummy constructor.
205209 /// has not be overriden on the command line with '-regalloc=...'
206210 bool usingDefaultRegAlloc() const;
207211
212 /// High level function that adds all passes necessary to go from llvm IR
213 /// representation to the MI representation.
214 /// Adds IR based lowering and target specific optimization passes and finally
215 /// the core instruction selection passes.
216 /// \returns true if an error occured, false otherwise.
217 bool addISelPasses();
218
208219 /// Add common target configurable passes that perform LLVM IR to IR
209220 /// transforms following machine independent optimization.
210221 virtual void addIRPasses();
304304 /// remove this at some point and always enable the verifier when
305305 /// EXPENSIVE_CHECKS is enabled.
306306 virtual bool isMachineVerifierClean() const { return true; }
307
308 /// \brief Adds an AsmPrinter pass to the pipeline that prints assembly or
309 /// machine code from the MI representation.
310 bool addAsmPrinter(PassManagerBase &PM, raw_pwrite_stream &Out,
311 CodeGenFileType FileTYpe, MCContext &Context);
307312 };
308313
309314 } // end namespace llvm
3434 #include "llvm/Transforms/Scalar.h"
3535 using namespace llvm;
3636
37 // Enable or disable FastISel. Both options are needed, because
38 // FastISel is enabled by default with -fast, and we wish to be
39 // able to enable or disable fast-isel independently from -O0.
40 static cl::opt
41 EnableFastISelOption("fast-isel", cl::Hidden,
42 cl::desc("Enable the \"fast\" instruction selector"));
43
44 static cl::opt
45 EnableGlobalISel("global-isel", cl::Hidden,
46 cl::desc("Enable the \"global\" instruction selector"));
47
4837 void LLVMTargetMachine::initAsmInfo() {
4938 MRI = TheTarget.createMCRegInfo(getTargetTriple().str());
5039 MII = TheTarget.createMCInstrInfo();
116105 // Set PassConfig options provided by TargetMachine.
117106 PassConfig->setDisableVerify(DisableVerify);
118107 PM.add(PassConfig);
119
120 // When in emulated TLS mode, add the LowerEmuTLS pass.
121 if (TM->Options.EmulatedTLS)
122 PM.add(createLowerEmuTLSPass());
123
124 PM.add(createPreISelIntrinsicLoweringPass());
125
126 // Add internal analysis passes from the target machine.
127 PM.add(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));
128
129 PassConfig->addIRPasses();
130
131 PassConfig->addCodeGenPrepare();
132
133 PassConfig->addPassesToHandleExceptions();
134
135 PassConfig->addISelPrepare();
136
137108 MachineModuleInfo *MMI = new MachineModuleInfo(TM);
138109 MMI->setMachineFunctionInitializer(MFInitializer);
139110 PM.add(MMI);
140111
141 // Enable FastISel with -fast, but allow that to be overridden.
142 TM->setO0WantsFastISel(EnableFastISelOption != cl::BOU_FALSE);
143 if (EnableFastISelOption == cl::BOU_TRUE ||
144 (TM->getOptLevel() == CodeGenOpt::None &&
145 TM->getO0WantsFastISel()))
146 TM->setFastISel(true);
147
148 // Ask the target for an isel.
149 // Enable GlobalISel if the target wants to, but allow that to be overriden.
150 if (EnableGlobalISel == cl::BOU_TRUE || (EnableGlobalISel == cl::BOU_UNSET &&
151 PassConfig->isGlobalISelEnabled())) {
152 if (PassConfig->addIRTranslator())
153 return nullptr;
154
155 PassConfig->addPreLegalizeMachineIR();
156
157 if (PassConfig->addLegalizeMachineIR())
158 return nullptr;
159
160 // Before running the register bank selector, ask the target if it
161 // wants to run some passes.
162 PassConfig->addPreRegBankSelect();
163
164 if (PassConfig->addRegBankSelect())
165 return nullptr;
166
167 PassConfig->addPreGlobalInstructionSelect();
168
169 if (PassConfig->addGlobalInstructionSelect())
170 return nullptr;
171
172 // Pass to reset the MachineFunction if the ISel failed.
173 PM.add(createResetMachineFunctionPass(
174 PassConfig->reportDiagnosticWhenGlobalISelFallback(),
175 PassConfig->isGlobalISelAbortEnabled()));
176
177 // Provide a fallback path when we do not want to abort on
178 // not-yet-supported input.
179 if (!PassConfig->isGlobalISelAbortEnabled() &&
180 PassConfig->addInstSelector())
181 return nullptr;
182
183 } else if (PassConfig->addInstSelector())
112 if (PassConfig->addISelPasses())
184113 return nullptr;
185
186114 PassConfig->addMachinePasses();
187
188115 PassConfig->setInitialized();
189116
190117 return &MMI->getContext();
118 }
119
120 bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,
121 raw_pwrite_stream &Out, CodeGenFileType FileType,
122 MCContext &Context) {
123 if (Options.MCOptions.MCSaveTempLabels)
124 Context.setAllowTemporaryLabels(false);
125
126 const MCSubtargetInfo &STI = *getMCSubtargetInfo();
127 const MCAsmInfo &MAI = *getMCAsmInfo();
128 const MCRegisterInfo &MRI = *getMCRegisterInfo();
129 const MCInstrInfo &MII = *getMCInstrInfo();
130
131 std::unique_ptr AsmStreamer;
132
133 switch (FileType) {
134 case CGFT_AssemblyFile: {
135 MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter(
136 getTargetTriple(), MAI.getAssemblerDialect(), MAI, MII, MRI);
137
138 // Create a code emitter if asked to show the encoding.
139 MCCodeEmitter *MCE = nullptr;
140 if (Options.MCOptions.ShowMCEncoding)
141 MCE = getTarget().createMCCodeEmitter(MII, MRI, Context);
142
143 MCAsmBackend *MAB =
144 getTarget().createMCAsmBackend(MRI, getTargetTriple().str(), TargetCPU,
145 Options.MCOptions);
146 auto FOut = llvm::make_unique(Out);
147 MCStreamer *S = getTarget().createAsmStreamer(
148 Context, std::move(FOut), Options.MCOptions.AsmVerbose,
149 Options.MCOptions.MCUseDwarfDirectory, InstPrinter, MCE, MAB,
150 Options.MCOptions.ShowMCInst);
151 AsmStreamer.reset(S);
152 break;
153 }
154 case CGFT_ObjectFile: {
155 // Create the code emitter for the target if it exists. If not, .o file
156 // emission fails.
157 MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, Context);
158 MCAsmBackend *MAB =
159 getTarget().createMCAsmBackend(MRI, getTargetTriple().str(), TargetCPU,
160 Options.MCOptions);
161 if (!MCE || !MAB)
162 return true;
163
164 // Don't waste memory on names of temp labels.
165 Context.setUseNamesOnTempLabels(false);
166
167 Triple T(getTargetTriple().str());
168 AsmStreamer.reset(getTarget().createMCObjectStreamer(
169 T, Context, *MAB, Out, MCE, STI, Options.MCOptions.MCRelaxAll,
170 Options.MCOptions.MCIncrementalLinkerCompatible,
171 /*DWARFMustBeAtTheEnd*/ true));
172 break;
173 }
174 case CGFT_Null:
175 // The Null output is intended for use for performance analysis and testing,
176 // not real users.
177 AsmStreamer.reset(getTarget().createNullStreamer(Context));
178 break;
179 }
180
181 // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
182 FunctionPass *Printer =
183 getTarget().createAsmPrinter(*this, std::move(AsmStreamer));
184 if (!Printer)
185 return true;
186
187 PM.add(Printer);
188 return false;
191189 }
192190
193191 bool LLVMTargetMachine::addPassesToEmitFile(
204202
205203 if (StopBefore || StopAfter) {
206204 PM.add(createPrintMIRPass(Out));
207 return false;
208 }
209
210 if (Options.MCOptions.MCSaveTempLabels)
211 Context->setAllowTemporaryLabels(false);
212
213 const MCSubtargetInfo &STI = *getMCSubtargetInfo();
214 const MCAsmInfo &MAI = *getMCAsmInfo();
215 const MCRegisterInfo &MRI = *getMCRegisterInfo();
216 const MCInstrInfo &MII = *getMCInstrInfo();
217
218 std::unique_ptr AsmStreamer;
219
220 switch (FileType) {
221 case CGFT_AssemblyFile: {
222 MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter(
223 getTargetTriple(), MAI.getAssemblerDialect(), MAI, MII, MRI);
224
225 // Create a code emitter if asked to show the encoding.
226 MCCodeEmitter *MCE = nullptr;
227 if (Options.MCOptions.ShowMCEncoding)
228 MCE = getTarget().createMCCodeEmitter(MII, MRI, *Context);
229
230 MCAsmBackend *MAB =
231 getTarget().createMCAsmBackend(MRI, getTargetTriple().str(), TargetCPU,
232 Options.MCOptions);
233 auto FOut = llvm::make_unique(Out);
234 MCStreamer *S = getTarget().createAsmStreamer(
235 *Context, std::move(FOut), Options.MCOptions.AsmVerbose,
236 Options.MCOptions.MCUseDwarfDirectory, InstPrinter, MCE, MAB,
237 Options.MCOptions.ShowMCInst);
238 AsmStreamer.reset(S);
239 break;
240 }
241 case CGFT_ObjectFile: {
242 // Create the code emitter for the target if it exists. If not, .o file
243 // emission fails.
244 MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, *Context);
245 MCAsmBackend *MAB =
246 getTarget().createMCAsmBackend(MRI, getTargetTriple().str(), TargetCPU,
247 Options.MCOptions);
248 if (!MCE || !MAB)
205 } else {
206 if (addAsmPrinter(PM, Out, FileType, *Context))
249207 return true;
250
251 // Don't waste memory on names of temp labels.
252 Context->setUseNamesOnTempLabels(false);
253
254 Triple T(getTargetTriple().str());
255 AsmStreamer.reset(getTarget().createMCObjectStreamer(
256 T, *Context, *MAB, Out, MCE, STI, Options.MCOptions.MCRelaxAll,
257 Options.MCOptions.MCIncrementalLinkerCompatible,
258 /*DWARFMustBeAtTheEnd*/ true));
259 break;
260 }
261 case CGFT_Null:
262 // The Null output is intended for use for performance analysis and testing,
263 // not real users.
264 AsmStreamer.reset(getTarget().createNullStreamer(*Context));
265 break;
266 }
267
268 // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
269 FunctionPass *Printer =
270 getTarget().createAsmPrinter(*this, std::move(AsmStreamer));
271 if (!Printer)
272 return true;
273
274 PM.add(Printer);
208 }
209
275210 PM.add(createFreeMachineFunctionPass());
276
277211 return false;
278212 }
279213
1919 #include "llvm/Analysis/CallGraphSCCPass.h"
2020 #include "llvm/Analysis/Passes.h"
2121 #include "llvm/Analysis/ScopedNoAliasAA.h"
22 #include "llvm/Analysis/TargetTransformInfo.h"
2223 #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
2324 #include "llvm/CodeGen/MachineFunctionPass.h"
2425 #include "llvm/CodeGen/RegAllocRegistry.h"
9495 static cl::opt EnableMachineOutliner("enable-machine-outliner",
9596 cl::Hidden,
9697 cl::desc("Enable machine outliner"));
98 // Enable or disable FastISel. Both options are needed, because
99 // FastISel is enabled by default with -fast, and we wish to be
100 // able to enable or disable fast-isel independently from -O0.
101 static cl::opt
102 EnableFastISelOption("fast-isel", cl::Hidden,
103 cl::desc("Enable the \"fast\" instruction selector"));
104
105 static cl::opt
106 EnableGlobalISel("global-isel", cl::Hidden,
107 cl::desc("Enable the \"global\" instruction selector"));
97108
98109 static cl::opt
99110 PrintMachineInstrs("print-machineinstrs", cl::ValueOptional,
570581 addPass(createVerifierPass());
571582 }
572583
584 bool TargetPassConfig::addCoreISelPasses() {
585 // Enable FastISel with -fast, but allow that to be overridden.
586 TM->setO0WantsFastISel(EnableFastISelOption != cl::BOU_FALSE);
587 if (EnableFastISelOption == cl::BOU_TRUE ||
588 (TM->getOptLevel() == CodeGenOpt::None && TM->getO0WantsFastISel()))
589 TM->setFastISel(true);
590
591 // Ask the target for an isel.
592 // Enable GlobalISel if the target wants to, but allow that to be overriden.
593 if (EnableGlobalISel == cl::BOU_TRUE ||
594 (EnableGlobalISel == cl::BOU_UNSET && isGlobalISelEnabled())) {
595 if (addIRTranslator())
596 return true;
597
598 addPreLegalizeMachineIR();
599
600 if (addLegalizeMachineIR())
601 return true;
602
603 // Before running the register bank selector, ask the target if it
604 // wants to run some passes.
605 addPreRegBankSelect();
606
607 if (addRegBankSelect())
608 return true;
609
610 addPreGlobalInstructionSelect();
611
612 if (addGlobalInstructionSelect())
613 return true;
614
615 // Pass to reset the MachineFunction if the ISel failed.
616 addPass(createResetMachineFunctionPass(
617 reportDiagnosticWhenGlobalISelFallback(), isGlobalISelAbortEnabled()));
618
619 // Provide a fallback path when we do not want to abort on
620 // not-yet-supported input.
621 if (!isGlobalISelAbortEnabled() && addInstSelector())
622 return true;
623
624 } else if (addInstSelector())
625 return true;
626
627 return false;
628 }
629
630 bool TargetPassConfig::addISelPasses() {
631 if (TM->Options.EmulatedTLS)
632 addPass(createLowerEmuTLSPass());
633
634 addPass(createPreISelIntrinsicLoweringPass());
635 addPass(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));
636 addIRPasses();
637 addCodeGenPrepare();
638 addPassesToHandleExceptions();
639 addISelPrepare();
640
641 return addCoreISelPasses();
642 }
643
573644 /// -regalloc=... command line option.
574645 static FunctionPass *useDefaultRegisterAllocator() { return nullptr; }
575646 static cl::opt
99 ; STOP-BEFORE-NOT: Loop Strength Reduction
1010
1111 ; RUN: llc < %s -debug-pass=Structure -start-after=loop-reduce -o /dev/null 2>&1 | FileCheck %s -check-prefix=START-AFTER
12 ; START-AFTER: -machine-branch-prob -pre-isel-intrinsic-lowering
12 ; START-AFTER: -machine-branch-prob -gc-lowering
1313 ; START-AFTER: FunctionPass Manager
1414 ; START-AFTER-NEXT: Lower Garbage Collection Instructions
1515
1616 ; RUN: llc < %s -debug-pass=Structure -start-before=loop-reduce -o /dev/null 2>&1 | FileCheck %s -check-prefix=START-BEFORE
17 ; START-BEFORE: -machine-branch-prob -pre-isel-intrinsic-lowering
17 ; START-BEFORE: -machine-branch-prob -domtree
1818 ; START-BEFORE: FunctionPass Manager
1919 ; START-BEFORE: Loop Strength Reduction
2020 ; START-BEFORE-NEXT: Lower Garbage Collection Instructions
44 ; CHECK-LABEL: Pass Arguments:
55 ; CHECK-NEXT: Target Library Information
66 ; CHECK-NEXT: Target Pass Configuration
7 ; CHECK-NEXT: Machine Module Information
78 ; CHECK-NEXT: Target Transform Information
89 ; CHECK-NEXT: Type-Based Alias Analysis
910 ; CHECK-NEXT: Scoped NoAlias Alias Analysis
1011 ; CHECK-NEXT: Assumption Cache Tracker
1112 ; CHECK-NEXT: Create Garbage Collector Module Metadata
12 ; CHECK-NEXT: Machine Module Information
1313 ; CHECK-NEXT: Machine Branch Probability Analysis
1414 ; CHECK-NEXT: ModulePass Manager
1515 ; CHECK-NEXT: Pre-ISel Intrinsic Lowering