Skip to content

Commit

Permalink
[PM] Switch the CGSCC debug messages to use the standard LLVM debug
Browse files Browse the repository at this point in the history
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.

llvm-svn: 310695
  • Loading branch information
chandlerc committed Aug 11, 2017
1 parent 9d07ae7 commit 19913b2
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 98 deletions.
102 changes: 46 additions & 56 deletions llvm/include/llvm/Analysis/CGSCCPassManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@

namespace llvm {

// Allow debug logging in this inline function.
#define DEBUG_TYPE "cgscc"

struct CGSCCUpdateResult;

/// Extern template declaration for the analysis set for this IR unit.
Expand Down Expand Up @@ -299,20 +302,19 @@ template <typename CGSCCPassT>
class ModuleToPostOrderCGSCCPassAdaptor
: public PassInfoMixin<ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>> {
public:
explicit ModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass, bool DebugLogging = false)
: Pass(std::move(Pass)), DebugLogging(DebugLogging) {}
explicit ModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass)
: Pass(std::move(Pass)) {}
// We have to explicitly define all the special member functions because MSVC
// refuses to generate them.
ModuleToPostOrderCGSCCPassAdaptor(
const ModuleToPostOrderCGSCCPassAdaptor &Arg)
: Pass(Arg.Pass), DebugLogging(Arg.DebugLogging) {}
: Pass(Arg.Pass) {}
ModuleToPostOrderCGSCCPassAdaptor(ModuleToPostOrderCGSCCPassAdaptor &&Arg)
: Pass(std::move(Arg.Pass)), DebugLogging(Arg.DebugLogging) {}
: Pass(std::move(Arg.Pass)) {}
friend void swap(ModuleToPostOrderCGSCCPassAdaptor &LHS,
ModuleToPostOrderCGSCCPassAdaptor &RHS) {
using std::swap;
swap(LHS.Pass, RHS.Pass);
swap(LHS.DebugLogging, RHS.DebugLogging);
}
ModuleToPostOrderCGSCCPassAdaptor &
operator=(ModuleToPostOrderCGSCCPassAdaptor RHS) {
Expand Down Expand Up @@ -369,16 +371,15 @@ class ModuleToPostOrderCGSCCPassAdaptor
do {
LazyCallGraph::RefSCC *RC = RCWorklist.pop_back_val();
if (InvalidRefSCCSet.count(RC)) {
if (DebugLogging)
dbgs() << "Skipping an invalid RefSCC...\n";
DEBUG(dbgs() << "Skipping an invalid RefSCC...\n");
continue;
}

assert(CWorklist.empty() &&
"Should always start with an empty SCC worklist");

if (DebugLogging)
dbgs() << "Running an SCC pass across the RefSCC: " << *RC << "\n";
DEBUG(dbgs() << "Running an SCC pass across the RefSCC: " << *RC
<< "\n");

// Push the initial SCCs in reverse post-order as we'll pop off the the
// back and so see this in post-order.
Expand All @@ -392,14 +393,12 @@ class ModuleToPostOrderCGSCCPassAdaptor
// other RefSCCs should be queued above, so we just need to skip both
// scenarios here.
if (InvalidSCCSet.count(C)) {
if (DebugLogging)
dbgs() << "Skipping an invalid SCC...\n";
DEBUG(dbgs() << "Skipping an invalid SCC...\n");
continue;
}
if (&C->getOuterRefSCC() != RC) {
if (DebugLogging)
dbgs() << "Skipping an SCC that is now part of some other "
"RefSCC...\n";
DEBUG(dbgs() << "Skipping an SCC that is now part of some other "
"RefSCC...\n");
continue;
}

Expand Down Expand Up @@ -437,10 +436,10 @@ class ModuleToPostOrderCGSCCPassAdaptor
// iterate there too.
RC = UR.UpdatedRC ? UR.UpdatedRC : RC;
C = UR.UpdatedC ? UR.UpdatedC : C;
if (DebugLogging && UR.UpdatedC)
dbgs() << "Re-running SCC passes after a refinement of the "
"current SCC: "
<< *UR.UpdatedC << "\n";
if (UR.UpdatedC)
DEBUG(dbgs() << "Re-running SCC passes after a refinement of the "
"current SCC: "
<< *UR.UpdatedC << "\n");

// Note that both `C` and `RC` may at this point refer to deleted,
// invalid SCC and RefSCCs respectively. But we will short circuit
Expand All @@ -466,15 +465,14 @@ class ModuleToPostOrderCGSCCPassAdaptor

private:
CGSCCPassT Pass;
bool DebugLogging;
};

/// \brief A function to deduce a function pass type and wrap it in the
/// templated adaptor.
template <typename CGSCCPassT>
ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>
createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass, bool DebugLogging = false) {
return ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>(std::move(Pass), DebugLogging);
createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass) {
return ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>(std::move(Pass));
}

/// A proxy from a \c FunctionAnalysisManager to an \c SCC.
Expand Down Expand Up @@ -523,7 +521,7 @@ typedef OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>
/// update result struct for the overall CGSCC walk.
LazyCallGraph::SCC &updateCGAndAnalysisManagerForFunctionPass(
LazyCallGraph &G, LazyCallGraph::SCC &C, LazyCallGraph::Node &N,
CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, bool DebugLogging = false);
CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR);

/// \brief Adaptor that maps from a SCC to its functions.
///
Expand All @@ -537,19 +535,18 @@ template <typename FunctionPassT>
class CGSCCToFunctionPassAdaptor
: public PassInfoMixin<CGSCCToFunctionPassAdaptor<FunctionPassT>> {
public:
explicit CGSCCToFunctionPassAdaptor(FunctionPassT Pass, bool DebugLogging = false)
: Pass(std::move(Pass)), DebugLogging(DebugLogging) {}
explicit CGSCCToFunctionPassAdaptor(FunctionPassT Pass)
: Pass(std::move(Pass)) {}
// We have to explicitly define all the special member functions because MSVC
// refuses to generate them.
CGSCCToFunctionPassAdaptor(const CGSCCToFunctionPassAdaptor &Arg)
: Pass(Arg.Pass), DebugLogging(Arg.DebugLogging) {}
: Pass(Arg.Pass) {}
CGSCCToFunctionPassAdaptor(CGSCCToFunctionPassAdaptor &&Arg)
: Pass(std::move(Arg.Pass)), DebugLogging(Arg.DebugLogging) {}
: Pass(std::move(Arg.Pass)) {}
friend void swap(CGSCCToFunctionPassAdaptor &LHS,
CGSCCToFunctionPassAdaptor &RHS) {
using std::swap;
swap(LHS.Pass, RHS.Pass);
swap(LHS.DebugLogging, RHS.DebugLogging);
}
CGSCCToFunctionPassAdaptor &operator=(CGSCCToFunctionPassAdaptor RHS) {
swap(*this, RHS);
Expand All @@ -572,8 +569,7 @@ class CGSCCToFunctionPassAdaptor
// a pointer we can overwrite.
LazyCallGraph::SCC *CurrentC = &C;

if (DebugLogging)
dbgs() << "Running function passes across an SCC: " << C << "\n";
DEBUG(dbgs() << "Running function passes across an SCC: " << C << "\n");

PreservedAnalyses PA = PreservedAnalyses::all();
for (LazyCallGraph::Node *N : Nodes) {
Expand All @@ -599,8 +595,8 @@ class CGSCCToFunctionPassAdaptor
// a smaller, more refined SCC.
auto PAC = PA.getChecker<LazyCallGraphAnalysis>();
if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Module>>()) {
CurrentC = &updateCGAndAnalysisManagerForFunctionPass(
CG, *CurrentC, *N, AM, UR, DebugLogging);
CurrentC = &updateCGAndAnalysisManagerForFunctionPass(CG, *CurrentC, *N,
AM, UR);
assert(
CG.lookupSCC(*N) == CurrentC &&
"Current SCC not updated to the SCC containing the current node!");
Expand All @@ -622,16 +618,14 @@ class CGSCCToFunctionPassAdaptor

private:
FunctionPassT Pass;
bool DebugLogging;
};

/// \brief A function to deduce a function pass type and wrap it in the
/// templated adaptor.
template <typename FunctionPassT>
CGSCCToFunctionPassAdaptor<FunctionPassT>
createCGSCCToFunctionPassAdaptor(FunctionPassT Pass, bool DebugLogging = false) {
return CGSCCToFunctionPassAdaptor<FunctionPassT>(std::move(Pass),
DebugLogging);
createCGSCCToFunctionPassAdaptor(FunctionPassT Pass) {
return CGSCCToFunctionPassAdaptor<FunctionPassT>(std::move(Pass));
}

/// A helper that repeats an SCC pass each time an indirect call is refined to
Expand All @@ -652,10 +646,8 @@ template <typename PassT>
class DevirtSCCRepeatedPass
: public PassInfoMixin<DevirtSCCRepeatedPass<PassT>> {
public:
explicit DevirtSCCRepeatedPass(PassT Pass, int MaxIterations,
bool DebugLogging = false)
: Pass(std::move(Pass)), MaxIterations(MaxIterations),
DebugLogging(DebugLogging) {}
explicit DevirtSCCRepeatedPass(PassT Pass, int MaxIterations)
: Pass(std::move(Pass)), MaxIterations(MaxIterations) {}

/// Runs the wrapped pass up to \c MaxIterations on the SCC, iterating
/// whenever an indirect call is refined.
Expand Down Expand Up @@ -733,10 +725,9 @@ class DevirtSCCRepeatedPass
if (!F)
return false;

if (DebugLogging)
dbgs() << "Found devirutalized call from "
<< CS.getParent()->getParent()->getName() << " to "
<< F->getName() << "\n";
DEBUG(dbgs() << "Found devirutalized call from "
<< CS.getParent()->getParent()->getName() << " to "
<< F->getName() << "\n");

// We now have a direct call where previously we had an indirect call,
// so iterate to process this devirtualization site.
Expand Down Expand Up @@ -770,17 +761,16 @@ class DevirtSCCRepeatedPass

// Otherwise, if we've already hit our max, we're done.
if (Iteration >= MaxIterations) {
if (DebugLogging)
dbgs() << "Found another devirtualization after hitting the max "
"number of repetitions ("
<< MaxIterations << ") on SCC: " << *C << "\n";
DEBUG(dbgs() << "Found another devirtualization after hitting the max "
"number of repetitions ("
<< MaxIterations << ") on SCC: " << *C << "\n");
PA.intersect(std::move(PassPA));
break;
}

if (DebugLogging)
dbgs() << "Repeating an SCC pass after finding a devirtualization in: "
<< *C << "\n";
DEBUG(dbgs()
<< "Repeating an SCC pass after finding a devirtualization in: "
<< *C << "\n");

// Move over the new call counts in preparation for iterating.
CallCounts = std::move(NewCallCounts);
Expand All @@ -800,18 +790,18 @@ class DevirtSCCRepeatedPass
private:
PassT Pass;
int MaxIterations;
bool DebugLogging;
};

/// \brief A function to deduce a function pass type and wrap it in the
/// templated adaptor.
template <typename PassT>
DevirtSCCRepeatedPass<PassT>
createDevirtSCCRepeatedPass(PassT Pass, int MaxIterations,
bool DebugLogging = false) {
return DevirtSCCRepeatedPass<PassT>(std::move(Pass), MaxIterations,
DebugLogging);
DevirtSCCRepeatedPass<PassT> createDevirtSCCRepeatedPass(PassT Pass,
int MaxIterations) {
return DevirtSCCRepeatedPass<PassT>(std::move(Pass), MaxIterations);
}

// Clear out the debug logging macro.
#undef DEBUG_TYPE
}

#endif
51 changes: 22 additions & 29 deletions llvm/lib/Analysis/CGSCCPassManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "llvm/IR/CallSite.h"
#include "llvm/IR/InstIterator.h"

#define DEBUG_TYPE "cgscc"

using namespace llvm;

// Explicit template instantiations and specialization defininitions for core
Expand Down Expand Up @@ -322,17 +324,15 @@ template <typename SCCRangeT>
LazyCallGraph::SCC *
incorporateNewSCCRange(const SCCRangeT &NewSCCRange, LazyCallGraph &G,
LazyCallGraph::Node &N, LazyCallGraph::SCC *C,
CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR,
bool DebugLogging = false) {
CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR) {
typedef LazyCallGraph::SCC SCC;

if (NewSCCRange.begin() == NewSCCRange.end())
return C;

// Add the current SCC to the worklist as its shape has changed.
UR.CWorklist.insert(C);
if (DebugLogging)
dbgs() << "Enqueuing the existing SCC in the worklist:" << *C << "\n";
DEBUG(dbgs() << "Enqueuing the existing SCC in the worklist:" << *C << "\n");

SCC *OldC = C;

Expand Down Expand Up @@ -368,8 +368,7 @@ incorporateNewSCCRange(const SCCRangeT &NewSCCRange, LazyCallGraph &G,
assert(C != &NewC && "No need to re-visit the current SCC!");
assert(OldC != &NewC && "Already handled the original SCC!");
UR.CWorklist.insert(&NewC);
if (DebugLogging)
dbgs() << "Enqueuing a newly formed SCC:" << NewC << "\n";
DEBUG(dbgs() << "Enqueuing a newly formed SCC:" << NewC << "\n");

// Ensure new SCCs' function analyses are updated.
if (NeedFAMProxy)
Expand All @@ -385,7 +384,7 @@ incorporateNewSCCRange(const SCCRangeT &NewSCCRange, LazyCallGraph &G,

LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass(
LazyCallGraph &G, LazyCallGraph::SCC &InitialC, LazyCallGraph::Node &N,
CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, bool DebugLogging) {
CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR) {
typedef LazyCallGraph::Node Node;
typedef LazyCallGraph::Edge Edge;
typedef LazyCallGraph::SCC SCC;
Expand Down Expand Up @@ -475,7 +474,7 @@ LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass(
} else {
// Now update the call graph.
C = incorporateNewSCCRange(RC->switchInternalEdgeToRef(N, E.getNode()),
G, N, C, AM, UR, DebugLogging);
G, N, C, AM, UR);
}
}

Expand All @@ -495,9 +494,8 @@ LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass(
return false;

RC->removeOutgoingEdge(N, *TargetN);
if (DebugLogging)
dbgs() << "Deleting outgoing edge from '" << N
<< "' to '" << TargetN << "'\n";
DEBUG(dbgs() << "Deleting outgoing edge from '" << N
<< "' to '" << TargetN << "'\n");
return true;
}),
DeadTargets.end());
Expand Down Expand Up @@ -528,9 +526,8 @@ LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass(
assert(NewRC != RC && "Should not encounter the current RefSCC further "
"in the postorder list of new RefSCCs.");
UR.RCWorklist.insert(NewRC);
if (DebugLogging)
dbgs() << "Enqueuing a new RefSCC in the update worklist: " << *NewRC
<< "\n";
DEBUG(dbgs() << "Enqueuing a new RefSCC in the update worklist: "
<< *NewRC << "\n");
}
}

Expand All @@ -547,9 +544,8 @@ LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass(
assert(RC->isAncestorOf(TargetRC) &&
"Cannot potentially form RefSCC cycles here!");
RC->switchOutgoingEdgeToRef(N, *RefTarget);
if (DebugLogging)
dbgs() << "Switch outgoing call edge to a ref edge from '" << N
<< "' to '" << *RefTarget << "'\n";
DEBUG(dbgs() << "Switch outgoing call edge to a ref edge from '" << N
<< "' to '" << *RefTarget << "'\n");
continue;
}

Expand All @@ -563,7 +559,7 @@ LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass(

// Now update the call graph.
C = incorporateNewSCCRange(RC->switchInternalEdgeToRef(N, *RefTarget), G, N,
C, AM, UR, DebugLogging);
C, AM, UR);
}

// Now promote ref edges into call edges.
Expand All @@ -577,14 +573,12 @@ LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass(
assert(RC->isAncestorOf(TargetRC) &&
"Cannot potentially form RefSCC cycles here!");
RC->switchOutgoingEdgeToCall(N, *CallTarget);
if (DebugLogging)
dbgs() << "Switch outgoing ref edge to a call edge from '" << N
<< "' to '" << *CallTarget << "'\n";
DEBUG(dbgs() << "Switch outgoing ref edge to a call edge from '" << N
<< "' to '" << *CallTarget << "'\n");
continue;
}
if (DebugLogging)
dbgs() << "Switch an internal ref edge to a call edge from '" << N
<< "' to '" << *CallTarget << "'\n";
DEBUG(dbgs() << "Switch an internal ref edge to a call edge from '" << N
<< "' to '" << *CallTarget << "'\n");

// Otherwise we are switching an internal ref edge to a call edge. This
// may merge away some SCCs, and we add those to the UpdateResult. We also
Expand Down Expand Up @@ -647,15 +641,14 @@ LazyCallGraph::SCC &llvm::updateCGAndAnalysisManagerForFunctionPass(
// post-order sequence, and may end up observing more precise context to
// optimize the current SCC.
UR.CWorklist.insert(C);
if (DebugLogging)
dbgs() << "Enqueuing the existing SCC in the worklist: " << *C << "\n";
DEBUG(dbgs() << "Enqueuing the existing SCC in the worklist: " << *C
<< "\n");
// Enqueue in reverse order as we pop off the back of the worklist.
for (SCC &MovedC : reverse(make_range(RC->begin() + InitialSCCIndex,
RC->begin() + NewSCCIndex))) {
UR.CWorklist.insert(&MovedC);
if (DebugLogging)
dbgs() << "Enqueuing a newly earlier in post-order SCC: " << MovedC
<< "\n";
DEBUG(dbgs() << "Enqueuing a newly earlier in post-order SCC: "
<< MovedC << "\n");
}
}
}
Expand Down

0 comments on commit 19913b2

Please sign in to comment.