[llvm] r273961 - [PM] Improve the debugging and logging facilities of the CGSCC bits of
Davide Italiano via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 5 17:18:43 PDT 2016
On Mon, Jun 27, 2016 at 4:26 PM, Chandler Carruth via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: chandlerc
> Date: Mon Jun 27 18:26:08 2016
> New Revision: 273961
>
> URL: http://llvm.org/viewvc/llvm-project?rev=273961&view=rev
> Log:
> [PM] Improve the debugging and logging facilities of the CGSCC bits of
> the new pass manager.
>
> This adds operator<< overloads for the various bits of the
> LazyCallGraph, dump methods for use from the debugger, and debug logging
> using them to the CGSCC pass manager.
>
> Having this was essential for debugging the call graph update patch, and
> I've extracted what I could from that patch here to minimize the delta.
>
> Modified:
> llvm/trunk/include/llvm/Analysis/CGSCCPassManager.h
> llvm/trunk/include/llvm/Analysis/LazyCallGraph.h
> llvm/trunk/lib/Analysis/LazyCallGraph.cpp
> llvm/trunk/lib/Passes/PassBuilder.cppHi Hi
> llvm/trunk/test/Other/new-pass-manager.ll
>
Hi Chandler, this breaks the build with GCC6. Can you please take a look?
Thanks!
[756/2768] Building CXX object
lib/Analysis/CMakeFiles/LLVMAnalysis.dir/LazyCallGraph.cpp.o
../lib/Analysis/LazyCallGraph.cpp:123:14: warning: ‘llvm::raw_ostream&
llvm::operator<<(llvm::raw_ostream&, const
llvm::LazyCallGraph::Node&)’ has not been declared within llvm
raw_ostream &llvm::operator<<(raw_ostream &OS, const LazyCallGraph::Node &N) {
^~~~
In file included from ../lib/Analysis/LazyCallGraph.cpp:10:0:
../include/llvm/Analysis/LazyCallGraph.h:227:25: note: only here as a friend
friend raw_ostream &operator<<(raw_ostream &OS, const Node &N);
^~~~~~~~
../lib/Analysis/LazyCallGraph.cpp:184:14: warning: ‘llvm::raw_ostream&
llvm::operator<<(llvm::raw_ostream&, const llvm::LazyCallGraph::SCC&)’
has not been declared within llvm
raw_ostream &llvm::operator<<(raw_ostream &OS, const LazyCallGraph::SCC &C) {
^~~~
In file included from ../lib/Analysis/LazyCallGraph.cpp:10:0:
../include/llvm/Analysis/LazyCallGraph.h:367:25: note: only here as a friend
friend raw_ostream &operator<<(raw_ostream &OS, const SCC &C);
^~~~~~~~
../lib/Analysis/LazyCallGraph.cpp:227:14: warning: ‘llvm::raw_ostream&
llvm::operator<<(llvm::raw_ostream&, const
llvm::LazyCallGraph::RefSCC&)’ has not been declared within llvm
raw_ostream &llvm::operator<<(raw_ostream &OS,
^~~~
In file included from ../lib/Analysis/LazyCallGraph.cpp:10:0:
../include/llvm/Analysis/LazyCallGraph.h:439:25: note: only here as a friend
friend raw_ostream &operator<<(raw_ostream &OS, const RefSCC &RC);
^~~~~~~~
> Modified: llvm/trunk/include/llvm/Analysis/CGSCCPassManager.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/CGSCCPassManager.h?rev=273961&r1=273960&r2=273961&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Analysis/CGSCCPassManager.h (original)
> +++ llvm/trunk/include/llvm/Analysis/CGSCCPassManager.h Mon Jun 27 18:26:08 2016
> @@ -67,19 +67,20 @@ template <typename CGSCCPassT>
> class ModuleToPostOrderCGSCCPassAdaptor
> : public PassInfoMixin<ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>> {
> public:
> - explicit ModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass)
> - : Pass(std::move(Pass)) {}
> + explicit ModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass, bool DebugLogging = false)
> + : Pass(std::move(Pass)), DebugLogging(DebugLogging) {}
> // We have to explicitly define all the special member functions because MSVC
> // refuses to generate them.
> ModuleToPostOrderCGSCCPassAdaptor(
> const ModuleToPostOrderCGSCCPassAdaptor &Arg)
> - : Pass(Arg.Pass) {}
> + : Pass(Arg.Pass), DebugLogging(Arg.DebugLogging) {}
> ModuleToPostOrderCGSCCPassAdaptor(ModuleToPostOrderCGSCCPassAdaptor &&Arg)
> - : Pass(std::move(Arg.Pass)) {}
> + : Pass(std::move(Arg.Pass)), DebugLogging(Arg.DebugLogging) {}
> friend void swap(ModuleToPostOrderCGSCCPassAdaptor &LHS,
> ModuleToPostOrderCGSCCPassAdaptor &RHS) {
> using std::swap;
> swap(LHS.Pass, RHS.Pass);
> + swap(LHS.DebugLogging, RHS.DebugLogging);
> }
> ModuleToPostOrderCGSCCPassAdaptor &
> operator=(ModuleToPostOrderCGSCCPassAdaptor RHS) {
> @@ -97,8 +98,11 @@ public:
> LazyCallGraph &CG = AM.getResult<LazyCallGraphAnalysis>(M);
>
> PreservedAnalyses PA = PreservedAnalyses::all();
> - for (LazyCallGraph::RefSCC &OuterC : CG.postorder_ref_sccs())
> - for (LazyCallGraph::SCC &C : OuterC) {
> + for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs()) {
> + if (DebugLogging)
> + dbgs() << "Running an SCC pass across the RefSCC: " << RC << "\n";
> +
> + for (LazyCallGraph::SCC &C : RC) {
> PreservedAnalyses PassPA = Pass.run(C, CGAM);
>
> // We know that the CGSCC pass couldn't have invalidated any other
> @@ -115,6 +119,7 @@ public:
> // analyses will eventually occur when the module pass completes.
> PA.intersect(std::move(PassPA));
> }
> + }
>
> // By definition we preserve the proxy. This precludes *any* invalidation
> // of CGSCC analyses by the proxy, but that's OK because we've taken
> @@ -126,14 +131,15 @@ public:
>
> 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) {
> - return ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>(std::move(Pass));
> +createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass, bool DebugLogging = false) {
> + return ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>(std::move(Pass), DebugLogging);
> }
>
> extern template class InnerAnalysisManagerProxy<FunctionAnalysisManager,
> @@ -159,18 +165,19 @@ template <typename FunctionPassT>
> class CGSCCToFunctionPassAdaptor
> : public PassInfoMixin<CGSCCToFunctionPassAdaptor<FunctionPassT>> {
> public:
> - explicit CGSCCToFunctionPassAdaptor(FunctionPassT Pass)
> - : Pass(std::move(Pass)) {}
> + explicit CGSCCToFunctionPassAdaptor(FunctionPassT Pass, bool DebugLogging = false)
> + : Pass(std::move(Pass)), DebugLogging(DebugLogging) {}
> // We have to explicitly define all the special member functions because MSVC
> // refuses to generate them.
> CGSCCToFunctionPassAdaptor(const CGSCCToFunctionPassAdaptor &Arg)
> - : Pass(Arg.Pass) {}
> + : Pass(Arg.Pass), DebugLogging(Arg.DebugLogging) {}
> CGSCCToFunctionPassAdaptor(CGSCCToFunctionPassAdaptor &&Arg)
> - : Pass(std::move(Arg.Pass)) {}
> + : Pass(std::move(Arg.Pass)), DebugLogging(Arg.DebugLogging) {}
> 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);
> @@ -183,6 +190,9 @@ public:
> FunctionAnalysisManager &FAM =
> AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C).getManager();
>
> + if (DebugLogging)
> + dbgs() << "Running function passes across an SCC: " << C << "\n";
> +
> PreservedAnalyses PA = PreservedAnalyses::all();
> for (LazyCallGraph::Node &N : C) {
> PreservedAnalyses PassPA = Pass.run(N.getFunction(), FAM);
> @@ -211,14 +221,16 @@ public:
>
> 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) {
> - return CGSCCToFunctionPassAdaptor<FunctionPassT>(std::move(Pass));
> +createCGSCCToFunctionPassAdaptor(FunctionPassT Pass, bool DebugLogging = false) {
> + return CGSCCToFunctionPassAdaptor<FunctionPassT>(std::move(Pass),
> + DebugLogging);
> }
> }
>
>
> Modified: llvm/trunk/include/llvm/Analysis/LazyCallGraph.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LazyCallGraph.h?rev=273961&r1=273960&r2=273961&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Analysis/LazyCallGraph.h (original)
> +++ llvm/trunk/include/llvm/Analysis/LazyCallGraph.h Mon Jun 27 18:26:08 2016
> @@ -48,6 +48,7 @@
> #include "llvm/IR/Module.h"
> #include "llvm/IR/PassManager.h"
> #include "llvm/Support/Allocator.h"
> +#include "llvm/Support/raw_ostream.h"
> #include <iterator>
> #include <utility>
>
> @@ -222,6 +223,12 @@ public:
> /// Internal helper to remove the edge to the given function.
> void removeEdgeInternal(Function &ChildF);
>
> + /// Print the name of this node's function.
> + friend raw_ostream &operator<<(raw_ostream &OS, const Node &N);
> +
> + /// Dump the name of this node's function to stderr.
> + void dump() const;
> +
> public:
> LazyCallGraph &getGraph() const { return *G; }
>
> @@ -353,6 +360,15 @@ public:
> Nodes.clear();
> }
>
> + /// Print a short descrtiption useful for debugging or logging.
> + ///
> + /// We print the function names in the SCC wrapped in '()'s and skipping
> + /// the middle functions if there are a large number.
> + friend raw_ostream &operator<<(raw_ostream &OS, const SCC &C);
> +
> + /// Dump a short description of this SCC to stderr.
> + void dump() const;
> +
> #ifndef NDEBUG
> /// Verify invariants about the SCC.
> ///
> @@ -373,25 +389,15 @@ public:
>
> RefSCC &getOuterRefSCC() const { return *OuterRefSCC; }
>
> - /// Short name useful for debugging or logging.
> + /// Provide a short name by printing this SCC to a std::string.
> ///
> - /// We use the name of the first function in the SCC to name the SCC for
> - /// the purposes of debugging and logging.
> + /// This copes with the fact that we don't have a name per-se for an SCC
> + /// while still making the use of this in debugging and logging useful.
> std::string getName() const {
> std::string Name;
> - int i = 0;
> - for (Node &N : *this) {
> - if (i > 0)
> - Name += ", ";
> - // Elide the inner elements if there are too many.
> - if (i > 8) {
> - Name += "..., ";
> - Name += Nodes.back()->getFunction().getName().str();
> - break;
> - }
> - Name += N.getFunction().getName().str();
> - ++i;
> - }
> + raw_string_ostream OS(Name);
> + OS << *this;
> + OS.flush();
> return Name;
> }
> };
> @@ -426,6 +432,15 @@ public:
> /// formRefSCCFast on the graph itself.
> RefSCC(LazyCallGraph &G);
>
> + /// Print a short description useful for debugging or logging.
> + ///
> + /// We print the SCCs wrapped in '[]'s and skipping the middle SCCs if
> + /// there are a large number.
> + friend raw_ostream &operator<<(raw_ostream &OS, const RefSCC &RC);
> +
> + /// Dump a short description of this RefSCC to stderr.
> + void dump() const;
> +
> #ifndef NDEBUG
> /// Verify invariants about the RefSCC and all its SCCs.
> ///
> @@ -477,12 +492,16 @@ public:
> /// Test if this RefSCC is a descendant of \a C.
> bool isDescendantOf(const RefSCC &C) const;
>
> - /// Short name useful for debugging or logging.
> + /// Provide a short name by printing this SCC to a std::string.
> ///
> - /// We use the name of the first function in the SCC to name the SCC for
> - /// the purposes of debugging and logging.
> - StringRef getName() const {
> - return begin()->begin()->getFunction().getName();
> + /// This copes with the fact that we don't have a name per-se for an SCC
> + /// while still making the use of this in debugging and logging useful.
> + std::string getName() const {
> + std::string Name;
> + raw_string_ostream OS(Name);
> + OS << *this;
> + OS.flush();
> + return Name;
> }
>
> ///@{
>
> Modified: llvm/trunk/lib/Analysis/LazyCallGraph.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyCallGraph.cpp?rev=273961&r1=273960&r2=273961&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Analysis/LazyCallGraph.cpp (original)
> +++ llvm/trunk/lib/Analysis/LazyCallGraph.cpp Mon Jun 27 18:26:08 2016
> @@ -120,6 +120,14 @@ void LazyCallGraph::Node::removeEdgeInte
> EdgeIndexMap.erase(IndexMapI);
> }
>
> +raw_ostream &llvm::operator<<(raw_ostream &OS, const LazyCallGraph::Node &N) {
> + return OS << N.F.getName();
> +}
> +
> +void LazyCallGraph::Node::dump() const {
> + dbgs() << *this << '\n';
> +}
> +
> LazyCallGraph::LazyCallGraph(Module &M) : NextDFSNumber(0) {
> DEBUG(dbgs() << "Building CG for module: " << M.getModuleIdentifier()
> << "\n");
> @@ -173,6 +181,28 @@ LazyCallGraph &LazyCallGraph::operator=(
> return *this;
> }
>
> +raw_ostream &llvm::operator<<(raw_ostream &OS, const LazyCallGraph::SCC &C) {
> + OS << '(';
> + int i = 0;
> + for (LazyCallGraph::Node &N : C) {
> + if (i > 0)
> + OS << ", ";
> + // Elide the inner elements if there are too many.
> + if (i > 8) {
> + OS << "..., " << *C.Nodes.back();
> + break;
> + }
> + OS << N;
> + ++i;
> + }
> + OS << ')';
> + return OS;
> +}
> +
> +void LazyCallGraph::SCC::dump() const {
> + dbgs() << *this << '\n';
> +}
> +
> #ifndef NDEBUG
> void LazyCallGraph::SCC::verify() {
> assert(OuterRefSCC && "Can't have a null RefSCC!");
> @@ -194,6 +224,29 @@ void LazyCallGraph::SCC::verify() {
>
> LazyCallGraph::RefSCC::RefSCC(LazyCallGraph &G) : G(&G) {}
>
> +raw_ostream &llvm::operator<<(raw_ostream &OS,
> + const LazyCallGraph::RefSCC &RC) {
> + OS << '[';
> + int i = 0;
> + for (LazyCallGraph::SCC &C : RC) {
> + if (i > 0)
> + OS << ", ";
> + // Elide the inner elements if there are too many.
> + if (i > 4) {
> + OS << "..., " << *RC.SCCs.back();
> + break;
> + }
> + OS << C;
> + ++i;
> + }
> + OS << ']';
> + return OS;
> +}
> +
> +void LazyCallGraph::RefSCC::dump() const {
> + dbgs() << *this << '\n';
> +}
> +
> #ifndef NDEBUG
> void LazyCallGraph::RefSCC::verify() {
> assert(G && "Can't have a null graph!");
>
> Modified: llvm/trunk/lib/Passes/PassBuilder.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassBuilder.cpp?rev=273961&r1=273960&r2=273961&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Passes/PassBuilder.cpp (original)
> +++ llvm/trunk/lib/Passes/PassBuilder.cpp Mon Jun 27 18:26:08 2016
> @@ -561,7 +561,8 @@ bool PassBuilder::parseCGSCCPassPipeline
> PipelineText = PipelineText.substr(1);
>
> // Add the nested pass manager with the appropriate adaptor.
> - CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM)));
> + CGPM.addPass(
> + createCGSCCToFunctionPassAdaptor(std::move(NestedFPM), DebugLogging));
> } else {
> // Otherwise try to parse a pass name.
> size_t End = PipelineText.find_first_of(",)");
> @@ -627,8 +628,8 @@ bool PassBuilder::parseModulePassPipelin
> PipelineText = PipelineText.substr(1);
>
> // Add the nested pass manager with the appropriate adaptor.
> - MPM.addPass(
> - createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
> + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM),
> + DebugLogging));
> } else if (PipelineText.startswith("function(")) {
> FunctionPassManager NestedFPM(DebugLogging);
>
> @@ -689,7 +690,7 @@ bool PassBuilder::parsePassPipeline(Modu
> DebugLogging) ||
> !PipelineText.empty())
> return false;
> - MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
> + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM), DebugLogging));
> return true;
> }
>
>
> Modified: llvm/trunk/test/Other/new-pass-manager.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pass-manager.ll?rev=273961&r1=273960&r2=273961&view=diff
> ==============================================================================
> --- llvm/trunk/test/Other/new-pass-manager.ll (original)
> +++ llvm/trunk/test/Other/new-pass-manager.ll Mon Jun 27 18:26:08 2016
> @@ -22,6 +22,7 @@
> ; CHECK-CGSCC-PASS-NEXT: Running pass: ModuleToPostOrderCGSCCPassAdaptor
> ; CHECK-CGSCC-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}>
> ; CHECK-CGSCC-PASS-NEXT: Running analysis: LazyCallGraphAnalysis
> +; CHECK-CGSCC-PASS-NEXT: Running an SCC pass across the RefSCC: [(foo)]
> ; CHECK-CGSCC-PASS-NEXT: Starting llvm::LazyCallGraph::SCC pass manager run
> ; CHECK-CGSCC-PASS-NEXT: Running pass: NoOpCGSCCPass
> ; CHECK-CGSCC-PASS-NEXT: Finished llvm::LazyCallGraph::SCC pass manager run
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
--
Davide
"There are no solved problems; there are only problems that are more
or less solved" -- Henri Poincare
More information about the llvm-commits
mailing list