Add a super basic LazyCallGraph DOT printer.
Access it through -passes=print-lcg-dot Let me know any suggestions for changing the rendering; I'm not particularly attached to what is implemented here. llvm-svn: 273082
This commit is contained in:
parent
a466a7cf62
commit
7cb30664fc
|
@ -925,6 +925,18 @@ public:
|
||||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// A pass which prints the call graph as a DOT file to a \c raw_ostream.
|
||||||
|
///
|
||||||
|
/// This is primarily useful for visualization purposes.
|
||||||
|
class LazyCallGraphDOTPrinterPass
|
||||||
|
: public PassInfoMixin<LazyCallGraphDOTPrinterPass> {
|
||||||
|
raw_ostream &OS;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit LazyCallGraphDOTPrinterPass(raw_ostream &OS);
|
||||||
|
|
||||||
|
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "llvm/IR/Instructions.h"
|
#include "llvm/IR/Instructions.h"
|
||||||
#include "llvm/IR/PassManager.h"
|
#include "llvm/IR/PassManager.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
#include "llvm/Support/GraphWriter.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
@ -1545,3 +1546,34 @@ PreservedAnalyses LazyCallGraphPrinterPass::run(Module &M,
|
||||||
|
|
||||||
return PreservedAnalyses::all();
|
return PreservedAnalyses::all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LazyCallGraphDOTPrinterPass::LazyCallGraphDOTPrinterPass(raw_ostream &OS)
|
||||||
|
: OS(OS) {}
|
||||||
|
|
||||||
|
static void printNodeDOT(raw_ostream &OS, LazyCallGraph::Node &N) {
|
||||||
|
std::string Name = "\"" + DOT::EscapeString(N.getFunction().getName()) + "\"";
|
||||||
|
|
||||||
|
for (const LazyCallGraph::Edge &E : N) {
|
||||||
|
OS << " " << Name << " -> \""
|
||||||
|
<< DOT::EscapeString(E.getFunction().getName()) << "\"";
|
||||||
|
if (!E.isCall()) // It is a ref edge.
|
||||||
|
OS << " [style=dashed,label=\"ref\"]";
|
||||||
|
OS << ";\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
OS << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
PreservedAnalyses LazyCallGraphDOTPrinterPass::run(Module &M,
|
||||||
|
ModuleAnalysisManager &AM) {
|
||||||
|
LazyCallGraph &G = AM.getResult<LazyCallGraphAnalysis>(M);
|
||||||
|
|
||||||
|
OS << "digraph \"" << DOT::EscapeString(M.getModuleIdentifier()) << "\" {\n";
|
||||||
|
|
||||||
|
for (Function &F : M)
|
||||||
|
printNodeDOT(OS, G.get(F));
|
||||||
|
|
||||||
|
OS << "}\n";
|
||||||
|
|
||||||
|
return PreservedAnalyses::all();
|
||||||
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@ MODULE_PASS("print-profile-summary", ProfileSummaryPrinterPass(dbgs()))
|
||||||
MODULE_PASS("print-callgraph", CallGraphPrinterPass(dbgs()))
|
MODULE_PASS("print-callgraph", CallGraphPrinterPass(dbgs()))
|
||||||
MODULE_PASS("print", PrintModulePass(dbgs()))
|
MODULE_PASS("print", PrintModulePass(dbgs()))
|
||||||
MODULE_PASS("print-lcg", LazyCallGraphPrinterPass(dbgs()))
|
MODULE_PASS("print-lcg", LazyCallGraphPrinterPass(dbgs()))
|
||||||
|
MODULE_PASS("print-lcg-dot", LazyCallGraphDOTPrinterPass(dbgs()))
|
||||||
MODULE_PASS("rpo-functionattrs", ReversePostOrderFunctionAttrsPass())
|
MODULE_PASS("rpo-functionattrs", ReversePostOrderFunctionAttrsPass())
|
||||||
MODULE_PASS("sample-profile", SampleProfileLoaderPass())
|
MODULE_PASS("sample-profile", SampleProfileLoaderPass())
|
||||||
MODULE_PASS("strip-dead-prototypes", StripDeadPrototypesPass())
|
MODULE_PASS("strip-dead-prototypes", StripDeadPrototypesPass())
|
||||||
|
|
Loading…
Reference in New Issue