]> granicus.if.org Git - llvm/commitdiff
Add a super basic LazyCallGraph DOT printer.
authorSean Silva <chisophugis@gmail.com>
Sat, 18 Jun 2016 09:17:32 +0000 (09:17 +0000)
committerSean Silva <chisophugis@gmail.com>
Sat, 18 Jun 2016 09:17:32 +0000 (09:17 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273082 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/LazyCallGraph.h
lib/Analysis/LazyCallGraph.cpp
lib/Passes/PassRegistry.def

index 3e63bf59f6cbdf1ddbb9287f695a1a8306ca45d2..34d854c78feb197df32aaee93fdc02f224f139d2 100644 (file)
@@ -925,6 +925,18 @@ public:
   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
index 36425c99adc97edb8a8ca6866f864ee1c1e65241..a153333e79a8e4ddc5436a8f2032a4a7abb471b7 100644 (file)
@@ -14,6 +14,7 @@
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/GraphWriter.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
@@ -1545,3 +1546,34 @@ PreservedAnalyses LazyCallGraphPrinterPass::run(Module &M,
 
   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();
+}
index e84f3933db8045e62148cf8c9b094e4fc80e1973..18b50ddcc20232fa5d43dd315096c6094c4a73ed 100644 (file)
@@ -57,6 +57,7 @@ MODULE_PASS("print-profile-summary", ProfileSummaryPrinterPass(dbgs()))
 MODULE_PASS("print-callgraph", CallGraphPrinterPass(dbgs()))
 MODULE_PASS("print", PrintModulePass(dbgs()))
 MODULE_PASS("print-lcg", LazyCallGraphPrinterPass(dbgs()))
+MODULE_PASS("print-lcg-dot", LazyCallGraphDOTPrinterPass(dbgs()))
 MODULE_PASS("rpo-functionattrs", ReversePostOrderFunctionAttrsPass())
 MODULE_PASS("sample-profile", SampleProfileLoaderPass())
 MODULE_PASS("strip-dead-prototypes", StripDeadPrototypesPass())