llvm.org GIT mirror llvm / 3c95d9c
[PM] Push the debug option for the new pass manager into the opt tool and expose the necessary hooks in the API directly. This makes it much cleaner for example to log the usage of a pass manager from a library. It also makes it more obvious that this functionality isn't "optional" or "asserts-only" for the pass manager. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225841 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 4 years ago
5 changed file(s) with 70 addition(s) and 52 deletion(s). Raw diff Collapse all Expand all
5454
5555 class Module;
5656 class Function;
57
58 namespace detail {
59
60 // Declare our debug option here so we can refer to it from templates.
61 extern cl::opt DebugPM;
62
63 } // End detail namespace
6457
6558 /// \brief An abstract set of preserved analyses following a transformation pass
6659 /// run.
184177 /// runs.
185178 template class PassManager {
186179 public:
180 /// \brief Construct a pass manager.
181 ///
182 /// It can be passed a flag to get debug logging as the passes are run.
183 PassManager(bool DebugLogging = false) : DebugLogging(DebugLogging) {}
187184 // We have to explicitly define all the special member functions because MSVC
188185 // refuses to generate them.
189 PassManager() {}
190 PassManager(PassManager &&Arg) : Passes(std::move(Arg.Passes)) {}
186 PassManager(PassManager &&Arg)
187 : Passes(std::move(Arg.Passes)),
188 DebugLogging(std::move(Arg.DebugLogging)) {}
191189 PassManager &operator=(PassManager &&RHS) {
192190 Passes = std::move(RHS.Passes);
191 DebugLogging = std::move(RHS.DebugLogging);
193192 return *this;
194193 }
195194
197196 PreservedAnalyses run(IRUnitT &IR, AnalysisManager *AM = nullptr) {
198197 PreservedAnalyses PA = PreservedAnalyses::all();
199198
200 if (detail::DebugPM)
199 if (DebugLogging)
201200 dbgs() << "Starting pass manager run.\n";
202201
203202 for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
204 if (detail::DebugPM)
203 if (DebugLogging)
205204 dbgs() << "Running pass: " << Passes[Idx]->name() << "\n";
206205
207206 PreservedAnalyses PassPA = Passes[Idx]->run(IR, AM);
225224 //IR.getContext().yield();
226225 }
227226
228 if (detail::DebugPM)
227 if (DebugLogging)
229228 dbgs() << "Finished pass manager run.\n";
230229
231230 return PA;
245244 PassManager &operator=(const PassManager &) LLVM_DELETED_FUNCTION;
246245
247246 std::vector> Passes;
247
248 /// \brief Flag indicating whether we should do debug logging.
249 bool DebugLogging;
248250 };
249251
250252 /// \brief Convenience typedef for a pass manager over modules.
411413 public:
412414 // Most public APIs are inherited from the CRTP base class.
413415
416 /// \brief Construct an empty analysis manager.
417 ///
418 /// A flag can be passed to indicate that the manager should perform debug
419 /// logging.
420 AnalysisManager(bool DebugLogging = false) : DebugLogging(DebugLogging) {}
421
414422 // We have to explicitly define all the special member functions because MSVC
415423 // refuses to generate them.
416 AnalysisManager() {}
417424 AnalysisManager(AnalysisManager &&Arg)
418425 : BaseT(std::move(static_cast(Arg))),
419 AnalysisResults(std::move(Arg.AnalysisResults)) {}
426 AnalysisResults(std::move(Arg.AnalysisResults)),
427 DebugLogging(std::move(Arg.DebugLogging)) {}
420428 AnalysisManager &operator=(AnalysisManager &&RHS) {
421429 BaseT::operator=(std::move(static_cast(RHS)));
422430 AnalysisResults = std::move(RHS.AnalysisResults);
431 DebugLogging = std::move(RHS.DebugLogging);
423432 return *this;
424433 }
425434
457466 // run it to produce a result, which we then add to the cache.
458467 if (Inserted) {
459468 auto &P = this->lookupPass(PassID);
460 if (detail::DebugPM)
469 if (DebugLogging)
461470 dbgs() << "Running analysis: " << P.name() << "\n";
462471 AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
463472 ResultList.emplace_back(PassID, P.run(IR, this));
481490 if (RI == AnalysisResults.end())
482491 return;
483492
484 if (detail::DebugPM)
493 if (DebugLogging)
485494 dbgs() << "Invalidating analysis: " << this->lookupPass(PassID).name()
486495 << "\n";
487496 AnalysisResultLists[&IR].erase(RI->second);
494503 if (PA.areAllPreserved())
495504 return std::move(PA);
496505
497 if (detail::DebugPM)
506 if (DebugLogging)
498507 dbgs() << "Invalidating all non-preserved analyses for: "
499508 << IR.getName() << "\n";
500509
511520 // necessary. The analysis pass can return false if no action on the part
512521 // of the analysis manager is required for this invalidation event.
513522 if (I->second->invalidate(IR, PA)) {
514 if (detail::DebugPM)
523 if (DebugLogging)
515524 dbgs() << "Invalidating analysis: " << this->lookupPass(PassID).name()
516525 << "\n";
517526
561570 /// \brief Map from an analysis ID and function to a particular cached
562571 /// analysis result.
563572 AnalysisResultMapT AnalysisResults;
573
574 /// \brief A flag indicating whether debug logging is enabled.
575 bool DebugLogging;
564576 };
565577
566578 /// \brief Convenience typedef for the Module analysis manager.
1111 #include "llvm/IR/PassManager.h"
1212
1313 using namespace llvm;
14 using llvm::detail::DebugPM;
15
16 cl::opt llvm::detail::DebugPM(
17 "debug-pass-manager", cl::Hidden,
18 cl::desc("Print pass management debugging information"));
1914
2015 char FunctionAnalysisManagerModuleProxy::PassID;
2116
2929 using namespace llvm;
3030 using namespace opt_tool;
3131
32 static cl::opt
33 DebugPM("debug-pass-manager", cl::Hidden,
34 cl::desc("Print pass management debugging information"));
35
3236 bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M,
3337 tool_output_file *Out, StringRef PassPipeline,
3438 OutputKind OK, VerifierKind VK) {
35 FunctionAnalysisManager FAM;
36 CGSCCAnalysisManager CGAM;
37 ModuleAnalysisManager MAM;
39 FunctionAnalysisManager FAM(DebugPM);
40 CGSCCAnalysisManager CGAM(DebugPM);
41 ModuleAnalysisManager MAM(DebugPM);
3842
3943 // Register all the basic analyses with the managers.
4044 registerModuleAnalyses(MAM);
4953 FAM.registerPass(CGSCCAnalysisManagerFunctionProxy(CGAM));
5054 FAM.registerPass(ModuleAnalysisManagerFunctionProxy(MAM));
5155
52 ModulePassManager MPM;
56 ModulePassManager MPM(DebugPM);
5357 if (VK > VK_NoVerifier)
5458 MPM.addPass(VerifierPass());
5559
56 if (!parsePassPipeline(MPM, PassPipeline, VK == VK_VerifyEachPass)) {
60 if (!parsePassPipeline(MPM, PassPipeline, VK == VK_VerifyEachPass, DebugPM)) {
5761 errs() << Arg0 << ": unable to parse pass pipeline description.\n";
5862 return false;
5963 }
195195
196196 static bool parseFunctionPassPipeline(FunctionPassManager &FPM,
197197 StringRef &PipelineText,
198 bool VerifyEachPass) {
198 bool VerifyEachPass, bool DebugLogging) {
199199 for (;;) {
200200 // Parse nested pass managers by recursing.
201201 if (PipelineText.startswith("function(")) {
202 FunctionPassManager NestedFPM;
202 FunctionPassManager NestedFPM(DebugLogging);
203203
204204 // Parse the inner pipeline inte the nested manager.
205205 PipelineText = PipelineText.substr(strlen("function("));
206 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
206 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
207 DebugLogging) ||
207208 PipelineText.empty())
208209 return false;
209210 assert(PipelineText[0] == ')');
231232 }
232233
233234 static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
234 StringRef &PipelineText,
235 bool VerifyEachPass) {
235 StringRef &PipelineText, bool VerifyEachPass,
236 bool DebugLogging) {
236237 for (;;) {
237238 // Parse nested pass managers by recursing.
238239 if (PipelineText.startswith("cgscc(")) {
239 CGSCCPassManager NestedCGPM;
240 CGSCCPassManager NestedCGPM(DebugLogging);
240241
241242 // Parse the inner pipeline into the nested manager.
242243 PipelineText = PipelineText.substr(strlen("cgscc("));
243 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) ||
244 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
245 DebugLogging) ||
244246 PipelineText.empty())
245247 return false;
246248 assert(PipelineText[0] == ')');
249251 // Add the nested pass manager with the appropriate adaptor.
250252 CGPM.addPass(std::move(NestedCGPM));
251253 } else if (PipelineText.startswith("function(")) {
252 FunctionPassManager NestedFPM;
254 FunctionPassManager NestedFPM(DebugLogging);
253255
254256 // Parse the inner pipeline inte the nested manager.
255257 PipelineText = PipelineText.substr(strlen("function("));
256 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
258 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
259 DebugLogging) ||
257260 PipelineText.empty())
258261 return false;
259262 assert(PipelineText[0] == ')');
281284
282285 static bool parseModulePassPipeline(ModulePassManager &MPM,
283286 StringRef &PipelineText,
284 bool VerifyEachPass) {
287 bool VerifyEachPass, bool DebugLogging) {
285288 for (;;) {
286289 // Parse nested pass managers by recursing.
287290 if (PipelineText.startswith("module(")) {
288 ModulePassManager NestedMPM;
291 ModulePassManager NestedMPM(DebugLogging);
289292
290293 // Parse the inner pipeline into the nested manager.
291294 PipelineText = PipelineText.substr(strlen("module("));
292 if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass) ||
295 if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass,
296 DebugLogging) ||
293297 PipelineText.empty())
294298 return false;
295299 assert(PipelineText[0] == ')');
298302 // Now add the nested manager as a module pass.
299303 MPM.addPass(std::move(NestedMPM));
300304 } else if (PipelineText.startswith("cgscc(")) {
301 CGSCCPassManager NestedCGPM;
305 CGSCCPassManager NestedCGPM(DebugLogging);
302306
303307 // Parse the inner pipeline inte the nested manager.
304308 PipelineText = PipelineText.substr(strlen("cgscc("));
305 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) ||
309 if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
310 DebugLogging) ||
306311 PipelineText.empty())
307312 return false;
308313 assert(PipelineText[0] == ')');
312317 MPM.addPass(
313318 createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
314319 } else if (PipelineText.startswith("function(")) {
315 FunctionPassManager NestedFPM;
320 FunctionPassManager NestedFPM(DebugLogging);
316321
317322 // Parse the inner pipeline inte the nested manager.
318323 PipelineText = PipelineText.substr(strlen("function("));
319 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
324 if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
325 DebugLogging) ||
320326 PipelineText.empty())
321327 return false;
322328 assert(PipelineText[0] == ')');
347353 // FIXME: Should this routine accept a TargetMachine or require the caller to
348354 // pre-populate the analysis managers with target-specific stuff?
349355 bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
350 bool VerifyEachPass) {
356 bool VerifyEachPass, bool DebugLogging) {
351357 // By default, try to parse the pipeline as-if it were within an implicit
352358 // 'module(...)' pass pipeline. If this will parse at all, it needs to
353359 // consume the entire string.
354 if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass))
360 if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
355361 return PipelineText.empty();
356362
357363 // This isn't parsable as a module pipeline, look for the end of a pass name
364370 // If this looks like a CGSCC pass, parse the whole thing as a CGSCC
365371 // pipeline.
366372 if (isCGSCCPassName(FirstName)) {
367 CGSCCPassManager CGPM;
368 if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) ||
373 CGSCCPassManager CGPM(DebugLogging);
374 if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
375 DebugLogging) ||
369376 !PipelineText.empty())
370377 return false;
371378 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
375382 // Similarly, if this looks like a Function pass, parse the whole thing as
376383 // a Function pipelien.
377384 if (isFunctionPassName(FirstName)) {
378 FunctionPassManager FPM;
379 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
385 FunctionPassManager FPM(DebugLogging);
386 if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
387 DebugLogging) ||
380388 !PipelineText.empty())
381389 return false;
382390 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
7171 /// an error. You cannot mix different levels implicitly, you must explicitly
7272 /// form a pass manager in which to nest passes.
7373 bool parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
74 bool VerifyEachPass = true);
75
74 bool VerifyEachPass = true, bool DebugLogging = false);
7675 }
7776
7877 #endif