llvm.org GIT mirror llvm / 83bfb55
[PM] Switch the CGSCC debug messages to use the standard LLVM debug printing techniques with a DEBUG_TYPE controlling them. It was a mistake to start re-purposing the pass manager `DebugLogging` variable for generic debug printing -- those logs are intended to be very minimal and primarily used for testing. More detailed and comprehensive logging doesn't make sense there (it would only make for brittle tests). Moreover, we kept forgetting to propagate the `DebugLogging` variable to various places making it also ineffective and/or unavailable. Switching to `DEBUG_TYPE` makes this a non-issue. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310695 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 2 years ago
5 changed file(s) with 77 addition(s) and 98 deletion(s). Raw diff Collapse all Expand all
9696 #include "llvm/IR/ValueHandle.h"
9797
9898 namespace llvm {
99
100 // Allow debug logging in this inline function.
101 #define DEBUG_TYPE "cgscc"
99102
100103 struct CGSCCUpdateResult;
101104
298301 class ModuleToPostOrderCGSCCPassAdaptor
299302 : public PassInfoMixin> {
300303 public:
301 explicit ModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass, bool DebugLogging = false)
302 : Pass(std::move(Pass)), DebugLogging(DebugLogging) {}
304 explicit ModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass)
305 : Pass(std::move(Pass)) {}
303306 // We have to explicitly define all the special member functions because MSVC
304307 // refuses to generate them.
305308 ModuleToPostOrderCGSCCPassAdaptor(
306309 const ModuleToPostOrderCGSCCPassAdaptor &Arg)
307 : Pass(Arg.Pass), DebugLogging(Arg.DebugLogging) {}
310 : Pass(Arg.Pass) {}
308311 ModuleToPostOrderCGSCCPassAdaptor(ModuleToPostOrderCGSCCPassAdaptor &&Arg)
309 : Pass(std::move(Arg.Pass)), DebugLogging(Arg.DebugLogging) {}
312 : Pass(std::move(Arg.Pass)) {}
310313 friend void swap(ModuleToPostOrderCGSCCPassAdaptor &LHS,
311314 ModuleToPostOrderCGSCCPassAdaptor &RHS) {
312315 using std::swap;
313316 swap(LHS.Pass, RHS.Pass);
314 swap(LHS.DebugLogging, RHS.DebugLogging);
315317 }
316318 ModuleToPostOrderCGSCCPassAdaptor &
317319 operator=(ModuleToPostOrderCGSCCPassAdaptor RHS) {
368370 do {
369371 LazyCallGraph::RefSCC *RC = RCWorklist.pop_back_val();
370372 if (InvalidRefSCCSet.count(RC)) {
371 if (DebugLogging)
372 dbgs() << "Skipping an invalid RefSCC...\n";
373 DEBUG(dbgs() << "Skipping an invalid RefSCC...\n");
373374 continue;
374375 }
375376
376377 assert(CWorklist.empty() &&
377378 "Should always start with an empty SCC worklist");
378379
379 if (DebugLogging)
380 dbgs() << "Running an SCC pass across the RefSCC: " << *RC << "\n";
380 DEBUG(dbgs() << "Running an SCC pass across the RefSCC: " << *RC
381 << "\n");
381382
382383 // Push the initial SCCs in reverse post-order as we'll pop off the the
383384 // back and so see this in post-order.
391392 // other RefSCCs should be queued above, so we just need to skip both
392393 // scenarios here.
393394 if (InvalidSCCSet.count(C)) {
394 if (DebugLogging)
395 dbgs() << "Skipping an invalid SCC...\n";
395 DEBUG(dbgs() << "Skipping an invalid SCC...\n");
396396 continue;
397397 }
398398 if (&C->getOuterRefSCC() != RC) {
399 if (DebugLogging)
400 dbgs() << "Skipping an SCC that is now part of some other "
401 "RefSCC...\n";
399 DEBUG(dbgs() << "Skipping an SCC that is now part of some other "
400 "RefSCC...\n");
402401 continue;
403402 }
404403
436435 // iterate there too.
437436 RC = UR.UpdatedRC ? UR.UpdatedRC : RC;
438437 C = UR.UpdatedC ? UR.UpdatedC : C;
439 if (DebugLogging && UR.UpdatedC)
440 dbgs() << "Re-running SCC passes after a refinement of the "
441 "current SCC: "
442 << *UR.UpdatedC << "\n";
438 if (UR.UpdatedC)
439 DEBUG(dbgs() << "Re-running SCC passes after a refinement of the "
440 "current SCC: "
441 << *UR.UpdatedC << "\n");
443442
444443 // Note that both `C` and `RC` may at this point refer to deleted,
445444 // invalid SCC and RefSCCs respectively. But we will short circuit
465464
466465 private:
467466 CGSCCPassT Pass;
468 bool DebugLogging;
469467 };
470468
471469 /// \brief A function to deduce a function pass type and wrap it in the
472470 /// templated adaptor.
473471 template
474472 ModuleToPostOrderCGSCCPassAdaptor
475 createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass, bool DebugLogging = false) {
476 return ModuleToPostOrderCGSCCPassAdaptor(std::move(Pass), DebugLogging);
473 createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass) {
474 return ModuleToPostOrderCGSCCPassAdaptor(std::move(Pass));
477475 }
478476
479477 /// A proxy from a \c FunctionAnalysisManager to an \c SCC.
522520 /// update result struct for the overall CGSCC walk.
523521 LazyCallGraph::SCC &updateCGAndAnalysisManagerForFunctionPass(
524522 LazyCallGraph &G, LazyCallGraph::SCC &C, LazyCallGraph::Node &N,
525 CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, bool DebugLogging = false);
523 CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR);
526524
527525 /// \brief Adaptor that maps from a SCC to its functions.
528526 ///
536534 class CGSCCToFunctionPassAdaptor
537535 : public PassInfoMixin> {
538536 public:
539 explicit CGSCCToFunctionPassAdaptor(FunctionPassT Pass, bool DebugLogging = false)
540 : Pass(std::move(Pass)), DebugLogging(DebugLogging) {}
537 explicit CGSCCToFunctionPassAdaptor(FunctionPassT Pass)
538 : Pass(std::move(Pass)) {}
541539 // We have to explicitly define all the special member functions because MSVC
542540 // refuses to generate them.
543541 CGSCCToFunctionPassAdaptor(const CGSCCToFunctionPassAdaptor &Arg)
544 : Pass(Arg.Pass), DebugLogging(Arg.DebugLogging) {}
542 : Pass(Arg.Pass) {}
545543 CGSCCToFunctionPassAdaptor(CGSCCToFunctionPassAdaptor &&Arg)
546 : Pass(std::move(Arg.Pass)), DebugLogging(Arg.DebugLogging) {}
544 : Pass(std::move(Arg.Pass)) {}
547545 friend void swap(CGSCCToFunctionPassAdaptor &LHS,
548546 CGSCCToFunctionPassAdaptor &RHS) {
549547 using std::swap;
550548 swap(LHS.Pass, RHS.Pass);
551 swap(LHS.DebugLogging, RHS.DebugLogging);
552549 }
553550 CGSCCToFunctionPassAdaptor &operator=(CGSCCToFunctionPassAdaptor RHS) {
554551 swap(*this, RHS);
571568 // a pointer we can overwrite.
572569 LazyCallGraph::SCC *CurrentC = &C;
573570
574 if (DebugLogging)
575 dbgs() << "Running function passes across an SCC: " << C << "\n";
571 DEBUG(dbgs() << "Running function passes across an SCC: " << C << "\n");
576572
577573 PreservedAnalyses PA = PreservedAnalyses::all();
578574 for (LazyCallGraph::Node *N : Nodes) {
598594 // a smaller, more refined SCC.
599595 auto PAC = PA.getChecker();
600596 if (!PAC.preserved() && !PAC.preservedSet>()) {
601 CurrentC = &updateCGAndAnalysisManagerForFunctionPass(
602 CG, *CurrentC, *N, AM, UR, DebugLogging);
597 CurrentC = &updateCGAndAnalysisManagerForFunctionPass(CG, *CurrentC, *N,
598 AM, UR);
603599 assert(
604600 CG.lookupSCC(*N) == CurrentC &&
605601 "Current SCC not updated to the SCC containing the current node!");
621617
622618 private:
623619 FunctionPassT Pass;
624 bool DebugLogging;
625620 };
626621
627622 /// \brief A function to deduce a function pass type and wrap it in the
628623 /// templated adaptor.
629624 template
630625 CGSCCToFunctionPassAdaptor
631 createCGSCCToFunctionPassAdaptor(FunctionPassT Pass, bool DebugLogging = false) {
632 return CGSCCToFunctionPassAdaptor(std::move(Pass),
633 DebugLogging);
626 createCGSCCToFunctionPassAdaptor(FunctionPassT Pass) {
627 return CGSCCToFunctionPassAdaptor(std::move(Pass));
634628 }
635629
636630 /// A helper that repeats an SCC pass each time an indirect call is refined to
651645 class DevirtSCCRepeatedPass
652646 : public PassInfoMixin> {
653647 public:
654 explicit DevirtSCCRepeatedPass(PassT Pass, int MaxIterations,
655 bool DebugLogging = false)
656 : Pass(std::move(Pass)), MaxIterations(MaxIterations),
657 DebugLogging(DebugLogging) {}
648 explicit DevirtSCCRepeatedPass(PassT Pass, int MaxIterations)
649 : Pass(std::move(Pass)), MaxIterations(MaxIterations) {}
658650
659651 /// Runs the wrapped pass up to \c MaxIterations on the SCC, iterating
660652 /// whenever an indirect call is refined.
732724 if (!F)
733725 return false;
734726
735 if (DebugLogging)
736 dbgs() << "Found devirutalized call from "
737 << CS.getParent()->getParent()->getName() << " to "
738 << F->getName() << "\n";
727 DEBUG(dbgs() << "Found devirutalized call from "
728 << CS.getParent()->getParent()->getName() << " to "
729 << F->getName() << "\n");
739730
740731 // We now have a direct call where previously we had an indirect call,
741732 // so iterate to process this devirtualization site.
769760
770761 // Otherwise, if we've already hit our max, we're done.
771762 if (Iteration >= MaxIterations) {
772 if (DebugLogging)
773 dbgs() << "Found another devirtualization after hitting the max "
774 "number of repetitions ("
775 << MaxIterations << ") on SCC: " << *C << "\n";
763 DEBUG(dbgs() << "Found another devirtualization after hitting the max "
764 "number of repetitions ("
765 << MaxIterations << ") on SCC: " << *C << "\n");
776766 PA.intersect(std::move(PassPA));
777767 break;
778768 }
779769
780 if (DebugLogging)
781 dbgs() << "Repeating an SCC pass after finding a devirtualization in: "
782 << *C << "\n";
770 DEBUG(dbgs()
771 << "Repeating an SCC pass after finding a devirtualization in: "
772 << *C << "\n");
783773
784774 // Move over the new call counts in preparation for iterating.
785775 CallCounts = std::move(NewCallCounts);
799789 private:
800790 PassT Pass;
801791 int MaxIterations;
802 bool DebugLogging;
803792 };
804793
805794 /// \brief A function to deduce a function pass type and wrap it in the
806795 /// templated adaptor.
807796 template
808 DevirtSCCRepeatedPass
809 createDevirtSCCRepeatedPass(PassT Pass, int MaxIterations,
810 bool DebugLogging = false) {
811 return DevirtSCCRepeatedPass(std::move(Pass), MaxIterations,
812 DebugLogging);
797 DevirtSCCRepeatedPass createDevirtSCCRepeatedPass(PassT Pass,
798 int MaxIterations) {
799 return DevirtSCCRepeatedPass(std::move(Pass), MaxIterations);
813800 }
801
802 // Clear out the debug logging macro.
803 #undef DEBUG_TYPE
814804 }
815805
816806 #endif
99 #include "llvm/Analysis/CGSCCPassManager.h"
1010 #include "llvm/IR/CallSite.h"
1111 #include "llvm/IR/InstIterator.h"
12
13 #define DEBUG_TYPE "cgscc"
1214
1315 using namespace llvm;
1416
321323 LazyCallGraph::SCC *
322324 incorporateNewSCCRange(const SCCRangeT &NewSCCRange, LazyCallGraph &G,
323325 LazyCallGraph::Node &N, LazyCallGraph::SCC *C,
324 CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR,
325 bool DebugLogging = false) {
326 CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR) {
326327 typedef LazyCallGraph::SCC SCC;
327328
328329 if (NewSCCRange.begin() == NewSCCRange.end())
330331
331332 // Add the current SCC to the worklist as its shape has changed.
332333 UR.CWorklist.insert(C);
333 if (DebugLogging)
334 dbgs() << "Enqueuing the existing SCC in the worklist:" << *C << "\n";
334 DEBUG(dbgs() << "Enqueuing the existing SCC in the worklist:" << *C << "\n");
335335
336336 SCC *OldC = C;
337337
367367 assert(C != &NewC && "No need to re-visit the current SCC!");
368368 assert(OldC != &NewC && "Already handled the original SCC!");
369369 UR.CWorklist.insert(&NewC);
370 if (DebugLogging)
371 dbgs() << "Enqueuing a newly formed SCC:" << NewC << "\n";
370 DEBUG(dbgs() << "Enqueuing a newly formed SCC:" << NewC << "\n");
372371
373372 // Ensure new SCCs' function analyses are updated.
374373 if (NeedFAMProxy)
384383
385384 LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass(
386385 LazyCallGraph &G, LazyCallGraph::SCC &InitialC, LazyCallGraph::Node &N,
387 CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, bool DebugLogging) {
386 CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR) {
388387 typedef LazyCallGraph::Node Node;
389388 typedef LazyCallGraph::Edge Edge;
390389 typedef LazyCallGraph::SCC SCC;
474473 } else {
475474 // Now update the call graph.
476475 C = incorporateNewSCCRange(RC->switchInternalEdgeToRef(N, E.getNode()),
477 G, N, C, AM, UR, DebugLogging);
476 G, N, C, AM, UR);
478477 }
479478 }
480479
494493 return false;
495494
496495 RC->removeOutgoingEdge(N, *TargetN);
497 if (DebugLogging)
498 dbgs() << "Deleting outgoing edge from '" << N
499 << "' to '" << TargetN << "'\n";
496 DEBUG(dbgs() << "Deleting outgoing edge from '" << N
497 << "' to '" << TargetN << "'\n");
500498 return true;
501499 }),
502500 DeadTargets.end());
527525 assert(NewRC != RC && "Should not encounter the current RefSCC further "
528526 "in the postorder list of new RefSCCs.");
529527 UR.RCWorklist.insert(NewRC);
530 if (DebugLogging)
531 dbgs() << "Enqueuing a new RefSCC in the update worklist: " << *NewRC
532 << "\n";
528 DEBUG(dbgs() << "Enqueuing a new RefSCC in the update worklist: "
529 << *NewRC << "\n");
533530 }
534531 }
535532
546543 assert(RC->isAncestorOf(TargetRC) &&
547544 "Cannot potentially form RefSCC cycles here!");
548545 RC->switchOutgoingEdgeToRef(N, *RefTarget);
549 if (DebugLogging)
550 dbgs() << "Switch outgoing call edge to a ref edge from '" << N
551 << "' to '" << *RefTarget << "'\n";
546 DEBUG(dbgs() << "Switch outgoing call edge to a ref edge from '" << N
547 << "' to '" << *RefTarget << "'\n");
552548 continue;
553549 }
554550
562558
563559 // Now update the call graph.
564560 C = incorporateNewSCCRange(RC->switchInternalEdgeToRef(N, *RefTarget), G, N,
565 C, AM, UR, DebugLogging);
561 C, AM, UR);
566562 }
567563
568564 // Now promote ref edges into call edges.
576572 assert(RC->isAncestorOf(TargetRC) &&
577573 "Cannot potentially form RefSCC cycles here!");
578574 RC->switchOutgoingEdgeToCall(N, *CallTarget);
579 if (DebugLogging)
580 dbgs() << "Switch outgoing ref edge to a call edge from '" << N
581 << "' to '" << *CallTarget << "'\n";
575 DEBUG(dbgs() << "Switch outgoing ref edge to a call edge from '" << N
576 << "' to '" << *CallTarget << "'\n");
582577 continue;
583578 }
584 if (DebugLogging)
585 dbgs() << "Switch an internal ref edge to a call edge from '" << N
586 << "' to '" << *CallTarget << "'\n";
579 DEBUG(dbgs() << "Switch an internal ref edge to a call edge from '" << N
580 << "' to '" << *CallTarget << "'\n");
587581
588582 // Otherwise we are switching an internal ref edge to a call edge. This
589583 // may merge away some SCCs, and we add those to the UpdateResult. We also
646640 // post-order sequence, and may end up observing more precise context to
647641 // optimize the current SCC.
648642 UR.CWorklist.insert(C);
649 if (DebugLogging)
650 dbgs() << "Enqueuing the existing SCC in the worklist: " << *C << "\n";
643 DEBUG(dbgs() << "Enqueuing the existing SCC in the worklist: " << *C
644 << "\n");
651645 // Enqueue in reverse order as we pop off the back of the worklist.
652646 for (SCC &MovedC : reverse(make_range(RC->begin() + InitialSCCIndex,
653647 RC->begin() + NewSCCIndex))) {
654648 UR.CWorklist.insert(&MovedC);
655 if (DebugLogging)
656 dbgs() << "Enqueuing a newly earlier in post-order SCC: " << MovedC
657 << "\n";
649 DEBUG(dbgs() << "Enqueuing a newly earlier in post-order SCC: "
650 << MovedC << "\n");
658651 }
659652 }
660653 }
655655 // in postorder (or bottom-up).
656656 MPM.addPass(
657657 createModuleToPostOrderCGSCCPassAdaptor(createDevirtSCCRepeatedPass(
658 std::move(MainCGPipeline), MaxDevirtIterations, DebugLogging)));
658 std::move(MainCGPipeline), MaxDevirtIterations)));
659659
660660 return MPM;
661661 }
12991299 if (!parseCGSCCPassPipeline(CGPM, InnerPipeline, VerifyEachPass,
13001300 DebugLogging))
13011301 return false;
1302 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM),
1303 DebugLogging));
1302 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
13041303 return true;
13051304 }
13061305 if (Name == "function") {
14101409 DebugLogging))
14111410 return false;
14121411 // Add the nested pass manager with the appropriate adaptor.
1413 CGPM.addPass(
1414 createCGSCCToFunctionPassAdaptor(std::move(FPM), DebugLogging));
1412 CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM)));
14151413 return true;
14161414 }
14171415 if (auto Count = parseRepeatPassName(Name)) {
14271425 if (!parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, VerifyEachPass,
14281426 DebugLogging))
14291427 return false;
1430 CGPM.addPass(createDevirtSCCRepeatedPass(std::move(NestedCGPM),
1431 *MaxRepetitions, DebugLogging));
1428 CGPM.addPass(
1429 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
14321430 return true;
14331431 }
14341432
2323 ; CHECK-CGSCC-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*(FunctionAnalysisManager|AnalysisManager<.*Function.*>).*}},{{.*}}Module>
2424 ; CHECK-CGSCC-PASS-NEXT: Running analysis: LazyCallGraphAnalysis
2525 ; CHECK-CGSCC-PASS-NEXT: Running analysis: TargetLibraryAnalysis
26 ; CHECK-CGSCC-PASS-NEXT: Running an SCC pass across the RefSCC: [(foo)]
2726 ; CHECK-CGSCC-PASS-NEXT: Starting CGSCC pass manager run
2827 ; CHECK-CGSCC-PASS-NEXT: Running pass: NoOpCGSCCPass
2928 ; CHECK-CGSCC-PASS-NEXT: Finished CGSCC pass manager run
408407 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*(FunctionAnalysisManager|AnalysisManager<.*Function.*>).*}},{{.*}}Module>
409408 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: LazyCallGraphAnalysis
410409 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: TargetLibraryAnalysis
411 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running an SCC pass across the RefSCC: [(foo)]
412410 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Starting CGSCC pass manager run
413411 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running pass: RepeatedPass
414412 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Starting CGSCC pass manager run
11671167 "dummy", &*H2F.begin()->begin());
11681168
11691169 // Now update the call graph.
1170 auto &NewC = updateCGAndAnalysisManagerForFunctionPass(
1171 CG, C, H2N, AM, UR, /*DebugLogging*/ true);
1170 auto &NewC =
1171 updateCGAndAnalysisManagerForFunctionPass(CG, C, H2N, AM, UR);
11721172 assert(&NewC != &C && "Should get a new SCC due to update!");
11731173 (void)&NewC;
11741174
12131213 (void)CallInst::Create(&H3F, {}, "", &*H2F.begin()->begin());
12141214
12151215 // Now update the call graph.
1216 auto &NewC = updateCGAndAnalysisManagerForFunctionPass(
1217 CG, C, H2N, AM, UR, /*DebugLogging*/ true);
1216 auto &NewC =
1217 updateCGAndAnalysisManagerForFunctionPass(CG, C, H2N, AM, UR);
12181218 assert(&NewC != &C && "Should get a new SCC due to update!");
12191219 (void)&NewC;
12201220