llvm.org GIT mirror llvm / 79114cd
Feature generic option to setup start/stop-after/before This patch refactors the code used in llc such that all the users of the addPassesToEmitFile API have access to a homogeneous way of handling start/stop-after/before options right out of the box. Previously each user would have needed to duplicate this logic and set up its own options. NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299282 91177308-0d34-0410-b5e6-96231b3b80d8 Quentin Colombet 3 years ago
4 changed file(s) with 158 addition(s) and 54 deletion(s). Raw diff Collapse all Expand all
9494 const TargetOptions DefaultOptions;
9595 mutable TargetOptions Options;
9696
97 /// Provide a generic way to handle the Start/Stop After/Before
98 /// parameters of addPassesToEmitFile.
99 /// @{
100 /// Name of the commandline option to set the StartAfter parameter.
101 static const char *StartAfterOptName;
102 /// Name of the commandline option to set the StartAfter parameter.
103 static const char *StartBeforeOptName;
104 /// Name of the commandline option to set the StopAfter parameter.
105 static const char *StopAfterOptName;
106 /// Name of the commandline option to set the StopBefore parameter.
107 static const char *StopBeforeOptName;
108
109 /// Enum of the different options available to control the pipeline
110 /// when emitting a file (addPassesToEmitFile).
111 enum PipelineControlOption {
112 StartAfter,
113 StartBefore,
114 StopAfter,
115 StopBefore,
116 LastPipelineControlOption = StopBefore
117 };
118
119 /// Helper method to get the pass ID of the Start/Stop After/Before
120 /// passes from the generic options.
121 /// \p Kind defines which pass ID we look for.
122 ///
123 /// This uses getPassID with the value of the related option as
124 /// PassName. In other words, \see getPassID for the usage of
125 /// \p AbortIfNotRegistered.
126 static AnalysisID getPassIDForOption(PipelineControlOption Kind,
127 bool AbortIfNotRegistered = true);
128
129 /// Helper method to get the pass ID of \p PassName.
130 /// This is a simple wrapper around getPassInfo.
131 static AnalysisID getPassID(StringRef PassName,
132 bool AbortIfNotRegistered = true);
133
134 /// Helper method to get the pass ID of the StartAfter generic option.
135 /// \see getPassIDForOption.
136 static AnalysisID getStartAfterID(bool AbortIfNotRegistered = true) {
137 return getPassIDForOption(TargetMachine::StartAfter, AbortIfNotRegistered);
138 }
139
140 /// Helper method to get the pass ID of the StartBefore generic option.
141 /// \see getPassIDForOption.
142 static AnalysisID getStartBeforeID(bool AbortIfNotRegistered = true) {
143 return getPassIDForOption(TargetMachine::StartBefore, AbortIfNotRegistered);
144 }
145
146 /// Helper method to get the pass ID of the StopAfter generic option.
147 /// \see getPassIDForOption.
148 static AnalysisID getStopAfterID(bool AbortIfNotRegistered = true) {
149 return getPassIDForOption(TargetMachine::StopAfter, AbortIfNotRegistered);
150 }
151
152 /// Helper method to get the pass ID of the StopBefore generic option.
153 /// \see getPassIDForOption.
154 static AnalysisID getStopBeforeID(bool AbortIfNotRegistered = true) {
155 return getPassIDForOption(TargetMachine::StopBefore, AbortIfNotRegistered);
156 }
157
158 /// Helper method to get the PassInfo of \p PassName
159 /// \p AbortIfNotRegistered will abort the process if the name of
160 /// the pass specified with the related option hasn't been found.
161 /// This parameter has no effect if the option was not set.
162 ///
163 /// \pre The pass registry has been initialized.
164 ///
165 /// \return The PassInfo of \p PassName or nullptr if PassName is empty
166 /// or this pass does not exist.
167 static const PassInfo *getPassInfo(StringRef PassName,
168 bool AbortIfNotRegistered = true);
169 /// @}
170
97171 TargetMachine(const TargetMachine &) = delete;
98172 void operator=(const TargetMachine &) = delete;
99173 virtual ~TargetMachine();
224298 /// supported, or false on success.
225299 virtual bool addPassesToEmitFile(
226300 PassManagerBase &, raw_pwrite_stream &, CodeGenFileType,
227 bool /*DisableVerify*/ = true, AnalysisID /*StartBefore*/ = nullptr,
228 AnalysisID /*StartAfter*/ = nullptr, AnalysisID /*StopBefore*/ = nullptr,
229 AnalysisID /*StopAfter*/ = nullptr,
301 bool /*DisableVerify*/ = true,
302 AnalysisID StartBefore = getStartBeforeID(),
303 AnalysisID StartAfter = getStartAfterID(),
304 AnalysisID StopBefore = getStopBeforeID(),
305 AnalysisID StopAfter = getStopAfterID(),
230306 MachineFunctionInitializer * /*MFInitializer*/ = nullptr) {
231307 return true;
232308 }
286362 /// emitted. Typically this will involve several steps of code generation.
287363 bool addPassesToEmitFile(
288364 PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType,
289 bool DisableVerify = true, AnalysisID StartBefore = nullptr,
290 AnalysisID StartAfter = nullptr, AnalysisID StopBefore = nullptr,
291 AnalysisID StopAfter = nullptr,
365 bool DisableVerify = true, AnalysisID StartBefore = getStartBeforeID(),
366 AnalysisID StartAfter = getStartAfterID(),
367 AnalysisID StopBefore = getStopBeforeID(),
368 AnalysisID StopAfter = getStopAfterID(),
292369 MachineFunctionInitializer *MFInitializer = nullptr) override;
293370
294371 /// Add passes to the specified pass manager to get machine code emitted with
3030 #include "llvm/Target/TargetSubtargetInfo.h"
3131 using namespace llvm;
3232
33 const char *TargetMachine::StartAfterOptName = "start-after";
34 const char *TargetMachine::StartBeforeOptName = "start-before";
35 const char *TargetMachine::StopAfterOptName = "stop-after";
36 const char *TargetMachine::StopBeforeOptName = "stop-before";
37
38 static cl::opt
39 StartAfterOpt(StringRef(TargetMachine::StartAfterOptName),
40 cl::desc("Resume compilation after a specific pass"),
41 cl::value_desc("pass-name"), cl::init(""));
42
43 static cl::opt
44 StartBeforeOpt(StringRef(TargetMachine::StartBeforeOptName),
45 cl::desc("Resume compilation before a specific pass"),
46 cl::value_desc("pass-name"), cl::init(""));
47
48 static cl::opt
49 StopAfterOpt(StringRef(TargetMachine::StopAfterOptName),
50 cl::desc("Stop compilation after a specific pass"),
51 cl::value_desc("pass-name"), cl::init(""));
52
53 static cl::opt
54 StopBeforeOpt(StringRef(TargetMachine::StopBeforeOptName),
55 cl::desc("Stop compilation before a specific pass"),
56 cl::value_desc("pass-name"), cl::init(""));
57
3358 cl::opt EnableIPRA("enable-ipra", cl::init(false), cl::Hidden,
3459 cl::desc("Enable interprocedural register allocation "
3560 "to reduce load/store at procedure calls."));
5378 delete MRI;
5479 delete MII;
5580 delete STI;
81 }
82
83 AnalysisID TargetMachine::getPassIDForOption(PipelineControlOption Kind,
84 bool AbortIfNotRegistered) {
85 static cl::opt *PassNames[] = {&StartAfterOpt, &StartBeforeOpt,
86 &StopAfterOpt, &StopBeforeOpt};
87 #define CHECK_OPT(OPTNAME) \
88 assert(PassNames[TargetMachine::OPTNAME] == &OPTNAME##Opt && \
89 "Static array is messed up for " #OPTNAME);
90 CHECK_OPT(StartAfter);
91 CHECK_OPT(StartBefore);
92 CHECK_OPT(StopAfter);
93 CHECK_OPT(StopBefore);
94 static_assert(LastPipelineControlOption == 3,
95 "The check before needs to be updated");
96 return getPassID(*PassNames[Kind], AbortIfNotRegistered);
97 }
98
99 const PassInfo *TargetMachine::getPassInfo(StringRef PassName,
100 bool AbortIfNotRegistered) {
101 if (PassName.empty())
102 return nullptr;
103
104 const PassRegistry &PR = *PassRegistry::getPassRegistry();
105 const PassInfo *PI = PR.getPassInfo(PassName);
106 if (!PI && AbortIfNotRegistered) {
107 errs() << "\"" << PassName << "\" pass is not registered.\n";
108 exit(1);
109 }
110 return PI;
111 }
112
113 AnalysisID TargetMachine::getPassID(StringRef PassName,
114 bool AbortIfNotRegistered) {
115 const PassInfo *PI = getPassInfo(PassName, AbortIfNotRegistered);
116 return PI ? PI->getTypeInfo() : nullptr;
56117 }
57118
58119 bool TargetMachine::isPositionIndependent() const {
2323 ; RUN: not llc < %s -stop-before=nonexistent -o /dev/null 2>&1 | FileCheck %s -check-prefix=NONEXISTENT-STOP-BEFORE
2424 ; RUN: not llc < %s -start-after=nonexistent -o /dev/null 2>&1 | FileCheck %s -check-prefix=NONEXISTENT-START-AFTER
2525 ; RUN: not llc < %s -stop-after=nonexistent -o /dev/null 2>&1 | FileCheck %s -check-prefix=NONEXISTENT-STOP-AFTER
26 ; NONEXISTENT-START-BEFORE: start-before pass is not registered.
27 ; NONEXISTENT-STOP-BEFORE: stop-before pass is not registered.
28 ; NONEXISTENT-START-AFTER: start-after pass is not registered.
29 ; NONEXISTENT-STOP-AFTER: stop-after pass is not registered.
26 ; NONEXISTENT-START-BEFORE: "nonexistent" pass is not registered.
27 ; NONEXISTENT-STOP-BEFORE: "nonexistent" pass is not registered.
28 ; NONEXISTENT-START-AFTER: "nonexistent" pass is not registered.
29 ; NONEXISTENT-STOP-AFTER: "nonexistent" pass is not registered.
3030
3131 ; RUN: not llc < %s -start-before=loop-reduce -start-after=loop-reduce -o /dev/null 2>&1 | FileCheck %s -check-prefix=DOUBLE-START
3232 ; RUN: not llc < %s -stop-before=loop-reduce -stop-after=loop-reduce -o /dev/null 2>&1 | FileCheck %s -check-prefix=DOUBLE-STOP
117117 cl::desc("Discard names from Value (other than GlobalValue)."),
118118 cl::init(false), cl::Hidden);
119119
120 static cl::opt StopBefore("stop-before",
121 cl::desc("Stop compilation before a specific pass"),
122 cl::value_desc("pass-name"), cl::init(""));
123
124 static cl::opt StopAfter("stop-after",
125 cl::desc("Stop compilation after a specific pass"),
126 cl::value_desc("pass-name"), cl::init(""));
127
128 static cl::opt StartBefore("start-before",
129 cl::desc("Resume compilation before a specific pass"),
130 cl::value_desc("pass-name"), cl::init(""));
131
132 static cl::opt StartAfter("start-after",
133 cl::desc("Resume compilation after a specific pass"),
134 cl::value_desc("pass-name"), cl::init(""));
135
136120 static cl::list IncludeDirs("I", cl::desc("include search path"));
137121
138122 static cl::opt PassRemarksWithHotness(
337321
338322 static bool addPass(PassManagerBase &PM, const char *argv0,
339323 StringRef PassName, TargetPassConfig &TPC) {
340 if (PassName == "none")
324 if (PassName.empty() || PassName == "none")
341325 return false;
342326
343 const PassRegistry *PR = PassRegistry::getPassRegistry();
344 const PassInfo *PI = PR->getPassInfo(PassName);
345 if (!PI) {
346 errs() << argv0 << ": run-pass " << PassName << " is not registered.\n";
347 return true;
348 }
327 const PassInfo *PI =
328 TargetMachine::getPassInfo(PassName, /*AbortIfNotRegistered=*/true);
329 assert(PI && "We should have aborted in the previous call in that case");
349330
350331 Pass *P;
351332 if (PI->getTargetMachineCtor())
361342 TPC.printAndVerify(Banner);
362343
363344 return false;
364 }
365
366 static AnalysisID getPassID(const char *argv0, const char *OptionName,
367 StringRef PassName) {
368 if (PassName.empty())
369 return nullptr;
370
371 const PassRegistry &PR = *PassRegistry::getPassRegistry();
372 const PassInfo *PI = PR.getPassInfo(PassName);
373 if (!PI) {
374 errs() << argv0 << ": " << OptionName << " pass is not registered.\n";
375 exit(1);
376 }
377 return PI->getTypeInfo();
378345 }
379346
380347 static int compileModule(char **argv, LLVMContext &Context) {
508475 OS = BOS.get();
509476 }
510477
478 AnalysisID StartBeforeID = TargetMachine::getStartBeforeID();
479 AnalysisID StartAfterID = TargetMachine::getStartAfterID();
480 AnalysisID StopAfterID = TargetMachine::getStopAfterID();
481 AnalysisID StopBeforeID = TargetMachine::getStopBeforeID();
482
511483 if (!RunPassNames->empty()) {
512 if (!StartAfter.empty() || !StopAfter.empty() || !StartBefore.empty() ||
513 !StopBefore.empty()) {
484 if (StartAfterID || StopAfterID || StartBeforeID || StopBeforeID) {
514485 errs() << argv[0] << ": start-after and/or stop-after passes are "
515486 "redundant when run-pass is specified.\n";
516487 return 1;
533504 }
534505 PM.add(createPrintMIRPass(*OS));
535506 } else {
536 const char *argv0 = argv[0];
537 AnalysisID StartBeforeID = getPassID(argv0, "start-before", StartBefore);
538 AnalysisID StartAfterID = getPassID(argv0, "start-after", StartAfter);
539 AnalysisID StopAfterID = getPassID(argv0, "stop-after", StopAfter);
540 AnalysisID StopBeforeID = getPassID(argv0, "stop-before", StopBefore);
541507
542508 if (StartBeforeID && StartAfterID) {
543509 errs() << argv[0] << ": -start-before and -start-after specified!\n";