llvm.org GIT mirror llvm / a125cac
Added -view-callgraph module pass. -dot-callgraph similarly follows a standard module pass pattern. Patch by Speziale Ettore! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172220 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Trick 6 years ago
7 changed file(s) with 208 addition(s) and 99 deletion(s). Raw diff Collapse all Expand all
0 //===-- CallPrinter.h - Call graph printer external interface ----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines external functions that can be called to explicitly
10 // instantiate the call graph printer.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_ANALYSIS_CALLPRINTER_H
15 #define LLVM_ANALYSIS_CALLPRINTER_H
16
17 namespace llvm {
18
19 class ModulePass;
20
21 ModulePass *createCallGraphViewerPass();
22 ModulePass *createCallGraphPrinterPass();
23
24 } // end namespace llvm
25
26 #endif
1717 #include "llvm/Pass.h"
1818
1919 namespace llvm {
20
2021 template
21 struct DOTGraphTraitsViewer : public FunctionPass {
22 std::string Name;
23
24 DOTGraphTraitsViewer(std::string GraphName, char &ID) : FunctionPass(ID) {
25 Name = GraphName;
26 }
22 class DOTGraphTraitsViewer : public FunctionPass {
23 public:
24 DOTGraphTraitsViewer(llvm::StringRef GraphName, char &ID)
25 : FunctionPass(ID), Name(GraphName) {}
2726
2827 virtual bool runOnFunction(Function &F) {
29 Analysis *Graph;
30 std::string Title, GraphName;
31 Graph = &getAnalysis();
32 GraphName = DOTGraphTraits::getGraphName(Graph);
33 Title = GraphName + " for '" + F.getName().str() + "' function";
28 Analysis *Graph = &getAnalysis();
29 std::string GraphName = DOTGraphTraits::getGraphName(Graph);
30 std::string Title = GraphName + " for '" + F.getName().str() + "' function";
31
3432 ViewGraph(Graph, Name, Simple, Title);
3533
3634 return false;
4038 AU.setPreservesAll();
4139 AU.addRequired();
4240 }
41
42 private:
43 std::string Name;
4344 };
4445
4546 template
46 struct DOTGraphTraitsPrinter : public FunctionPass {
47
48 std::string Name;
49
50 DOTGraphTraitsPrinter(std::string GraphName, char &ID)
51 : FunctionPass(ID) {
52 Name = GraphName;
53 }
47 class DOTGraphTraitsPrinter : public FunctionPass {
48 public:
49 DOTGraphTraitsPrinter(llvm::StringRef GraphName, char &ID)
50 : FunctionPass(ID), Name(GraphName) {}
5451
5552 virtual bool runOnFunction(Function &F) {
56 Analysis *Graph;
53 Analysis *Graph = &getAnalysis();
5754 std::string Filename = Name + "." + F.getName().str() + ".dot";
55 std::string ErrorInfo;
56
5857 errs() << "Writing '" << Filename << "'...";
5958
60 std::string ErrorInfo;
6159 raw_fd_ostream File(Filename.c_str(), ErrorInfo);
62 Graph = &getAnalysis();
63
64 std::string Title, GraphName;
65 GraphName = DOTGraphTraits::getGraphName(Graph);
66 Title = GraphName + " for '" + F.getName().str() + "' function";
60 std::string GraphName = DOTGraphTraits::getGraphName(Graph);
61 std::string Title = GraphName + " for '" + F.getName().str() + "' function";
6762
6863 if (ErrorInfo.empty())
6964 WriteGraph(File, Graph, Simple, Title);
7065 else
7166 errs() << " error opening file for writing!";
7267 errs() << "\n";
68
7369 return false;
7470 }
7571
7773 AU.setPreservesAll();
7874 AU.addRequired();
7975 }
76
77 private:
78 std::string Name;
8079 };
81 }
80
81 template
82 class DOTGraphTraitsModuleViewer : public ModulePass {
83 public:
84 DOTGraphTraitsModuleViewer(llvm::StringRef GraphName, char &ID)
85 : ModulePass(ID), Name(GraphName) {}
86
87 virtual bool runOnModule(Module &M) {
88 Analysis *Graph = &getAnalysis();
89 std::string Title = DOTGraphTraits::getGraphName(Graph);
90
91 ViewGraph(Graph, Name, Simple, Title);
92
93 return false;
94 }
95
96 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
97 AU.setPreservesAll();
98 AU.addRequired();
99 }
100
101 private:
102 std::string Name;
103 };
104
105 template
106 class DOTGraphTraitsModulePrinter : public ModulePass {
107 public:
108 DOTGraphTraitsModulePrinter(llvm::StringRef GraphName, char &ID)
109 : ModulePass(ID), Name(GraphName) {}
110
111 virtual bool runOnModule(Module &M) {
112 Analysis *Graph = &getAnalysis();
113 std::string Filename = Name + ".dot";
114 std::string ErrorInfo;
115
116 errs() << "Writing '" << Filename << "'...";
117
118 raw_fd_ostream File(Filename.c_str(), ErrorInfo);
119 std::string Title = DOTGraphTraits::getGraphName(Graph);
120
121 if (ErrorInfo.empty())
122 WriteGraph(File, Graph, Simple, Title);
123 else
124 errs() << " error opening file for writing!";
125 errs() << "\n";
126
127 return false;
128 }
129
130 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
131 AU.setPreservesAll();
132 AU.addRequired();
133 }
134
135 private:
136 std::string Name;
137 };
138
139 } // end namespace llvm
140
82141 #endif
7676 void initializeBranchFolderPassPass(PassRegistry&);
7777 void initializeBranchProbabilityInfoPass(PassRegistry&);
7878 void initializeBreakCriticalEdgesPass(PassRegistry&);
79 void initializeCallGraphPrinterPass(PassRegistry&);
80 void initializeCallGraphViewerPass(PassRegistry&);
7981 void initializeCFGOnlyPrinterPass(PassRegistry&);
8082 void initializeCFGOnlyViewerPass(PassRegistry&);
8183 void initializeCFGPrinterPass(PassRegistry&);
1515 #define LLVM_LINKALLPASSES_H
1616
1717 #include "llvm/Analysis/AliasSetTracker.h"
18 #include "llvm/Analysis/CallPrinter.h"
1819 #include "llvm/Analysis/DomPrinter.h"
1920 #include "llvm/Analysis/FindUsedTypes.h"
2021 #include "llvm/Analysis/IntervalPartition.h"
5657 (void) llvm::createBlockPlacementPass();
5758 (void) llvm::createBoundsCheckingPass();
5859 (void) llvm::createBreakCriticalEdgesPass();
60 (void) llvm::createCallGraphPrinterPass();
61 (void) llvm::createCallGraphViewerPass();
5962 (void) llvm::createCFGSimplificationPass();
6063 (void) llvm::createConstantMergePass();
6164 (void) llvm::createConstantPropagationPass();
0 //===- CallPrinter.cpp - DOT printer for call graph -----------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines '-dot-callgraph', which emit a callgraph..dot
10 // containing the call graph of a module.
11 //
12 // There is also a pass available to directly call dotty ('-view-callgraph').
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "llvm/Analysis/CallGraph.h"
17 #include "llvm/Analysis/CallPrinter.h"
18 #include "llvm/Analysis/DOTGraphTraitsPass.h"
19
20 using namespace llvm;
21
22 namespace llvm {
23
24 template<>
25 struct DOTGraphTraits : public DefaultDOTGraphTraits {
26 DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
27
28 static std::string getGraphName(CallGraph *Graph) {
29 return "Call graph";
30 }
31
32 std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) {
33 if (Function *Func = Node->getFunction())
34 return Func->getName();
35
36 return "external node";
37 }
38 };
39
40 } // end llvm namespace
41
42 namespace {
43
44 struct CallGraphViewer
45 : public DOTGraphTraitsModuleViewer {
46 static char ID;
47
48 CallGraphViewer()
49 : DOTGraphTraitsModuleViewer("callgraph", ID) {
50 initializeCallGraphViewerPass(*PassRegistry::getPassRegistry());
51 }
52 };
53
54 struct CallGraphPrinter
55 : public DOTGraphTraitsModulePrinter {
56 static char ID;
57
58 CallGraphPrinter()
59 : DOTGraphTraitsModulePrinter("callgraph", ID) {
60 initializeCallGraphPrinterPass(*PassRegistry::getPassRegistry());
61 }
62 };
63
64 } // end anonymous namespace
65
66 char CallGraphViewer::ID = 0;
67 INITIALIZE_PASS(CallGraphViewer, "view-callgraph",
68 "View call graph",
69 false, false)
70
71 char CallGraphPrinter::ID = 0;
72 INITIALIZE_PASS(CallGraphPrinter, "dot-callgraph",
73 "Print call graph to 'dot' file",
74 false, false)
75
76 // Create methods available outside of this file, to use them
77 // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
78 // the link time optimization.
79
80 ModulePass *llvm::createCallGraphViewerPass() {
81 return new CallGraphViewer();
82 }
83
84 ModulePass *llvm::createCallGraphPrinterPass() {
85 return new CallGraphPrinter();
86 }
1919 void llvm::initializeIPA(PassRegistry &Registry) {
2020 initializeBasicCallGraphPass(Registry);
2121 initializeCallGraphAnalysisGroup(Registry);
22 initializeCallGraphPrinterPass(Registry);
23 initializeCallGraphViewerPass(Registry);
2224 initializeFindUsedTypesPass(Registry);
2325 initializeGlobalsModRefPass(Registry);
2426 }
1313 //
1414 //===----------------------------------------------------------------------===//
1515
16 #include "llvm/Analysis/CallGraph.h"
1716 #include "llvm/Analysis/Dominators.h"
18 #include "llvm/IR/Value.h"
1917 #include "llvm/Pass.h"
20 #include "llvm/Support/GraphWriter.h"
21 #include "llvm/Support/ToolOutputFile.h"
18
2219 using namespace llvm;
23
24 template
25 static void WriteGraphToFile(raw_ostream &O, const std::string &GraphName,
26 const GraphType >) {
27 std::string Filename = GraphName + ".dot";
28 O << "Writing '" << Filename << "'...";
29 std::string ErrInfo;
30 tool_output_file F(Filename.c_str(), ErrInfo);
31
32 if (ErrInfo.empty()) {
33 WriteGraph(F.os(), GT);
34 F.os().close();
35 if (!F.os().has_error()) {
36 O << "\n";
37 F.keep();
38 return;
39 }
40 }
41 O << " error opening file for writing!\n";
42 F.os().clear_error();
43 }
44
45
46 //===----------------------------------------------------------------------===//
47 // Call Graph Printer
48 //===----------------------------------------------------------------------===//
49
50 namespace llvm {
51 template<>
52 struct DOTGraphTraits : public DefaultDOTGraphTraits {
53
54 DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
55
56 static std::string getGraphName(CallGraph *F) {
57 return "Call Graph";
58 }
59
60 static std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) {
61 if (Node->getFunction())
62 return ((Value*)Node->getFunction())->getName();
63 return "external node";
64 }
65 };
66 }
67
68
69 namespace {
70 struct CallGraphPrinter : public ModulePass {
71 static char ID; // Pass ID, replacement for typeid
72 CallGraphPrinter() : ModulePass(ID) {}
73
74 virtual bool runOnModule(Module &M) {
75 WriteGraphToFile(llvm::errs(), "callgraph", &getAnalysis());
76 return false;
77 }
78
79 void print(raw_ostream &OS, const llvm::Module*) const {}
80
81 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
82 AU.addRequired();
83 AU.setPreservesAll();
84 }
85 };
86 }
87
88 char CallGraphPrinter::ID = 0;
89 static RegisterPass P2("dot-callgraph",
90 "Print Call Graph to 'dot' file");
9120
9221 //===----------------------------------------------------------------------===//
9322 // DomInfoPrinter Pass