LLVM: lib/Analysis/CallPrinter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
27
28using namespace llvm;
29
30namespace llvm {
31template struct GraphTraits;
32}
33
34
35
36
39 cl::desc("Show heat colors in call-graph"));
40
43 cl::desc("Show edges labeled with weights"));
44
47 cl::desc("Show call-multigraph (do not remove parallel edges)"));
48
50 "callgraph-dot-filename-prefix", cl::Hidden,
51 cl::desc("The prefix used for the CallGraph dot file names."));
52
53namespace llvm {
54
56private:
61
62public:
64
68 MaxFreq = 0;
69
70 for (Function &F : M->getFunctionList()) {
71 uint64_t localSumFreq = 0;
72 SmallPtrSet<Function *, 16> Callers;
73 for (User *U : F.users())
74 if (isa(U))
75 Callers.insert(cast(U)->getFunction());
76 for (Function *Caller : Callers)
77 localSumFreq += getNumOfCalls(*Caller, F);
78 if (localSumFreq >= MaxFreq)
79 MaxFreq = localSumFreq;
80 Freq[&F] = localSumFreq;
81 }
83 removeParallelEdges();
84 }
85
87
89
91
93
94private:
95 void removeParallelEdges() {
96 for (auto &I : (*CG)) {
98
99 bool FoundParallelEdge = true;
100 while (FoundParallelEdge) {
102 FoundParallelEdge = false;
103 for (auto CI = Node->begin(), CE = Node->end(); CI != CE; CI++) {
104 if (!(Visited.insert(CI->second->getFunction())).second) {
105 FoundParallelEdge = true;
106 Node->removeCallEdge(CI);
107 break;
108 }
109 }
110 }
111 }
112 }
113};
114
115template <>
122
123 typedef std::pair<const Function *const, std::unique_ptr>
126 return P.second.get();
127 }
128
129
132
139};
140
141template <>
143
145
147 return "Call graph: " +
149 }
150
154 return false;
155 return true;
156 }
157
161 return "external caller";
163 return "external callee";
164
166 return std::string(Func->getName());
167 return "external node";
168 }
170 return P.second;
171 }
172
173
175 decltype(&CGGetValuePtr)>
177
181 return "";
182
184 if (Caller == nullptr || Caller->isDeclaration())
185 return "";
186
187 Function *Callee = (*I)->getFunction();
188 if (Callee == nullptr)
189 return "";
190
192 double Width =
193 1 + 2 * (double(Counter) / CGInfo->getMaxFreq());
194 std::string Attrs = "label=\"" + std::to_string(Counter) +
195 "\" penwidth=" + std::to_string(Width);
196 return Attrs;
197 }
198
202 if (F == nullptr)
203 return "";
204 std::string attrs;
208 std::string edgeColor = (freq <= (CGInfo->getMaxFreq() / 2))
211 attrs = "color=\"" + edgeColor + "ff\", style=filled, fillcolor=\"" +
212 color + "80\"";
213 }
214 return attrs;
215 }
216};
217
218}
219
220namespace {
221void doCallGraphDOTPrinting(
222 Module &M, function_ref<BlockFrequencyInfo *(Function &)> LookupBFI) {
226 else
227 Filename = (std::string(M.getModuleIdentifier()) + ".callgraph.dot");
229
230 std::error_code EC;
232
233 CallGraph CG(M);
234 CallGraphDOTInfo CFGInfo(&M, &CG, LookupBFI);
235
236 if (!EC)
238 else
239 errs() << " error opening file for writing!";
240 errs() << "\n";
241}
242
243void viewCallGraph(Module &M,
244 function_ref<BlockFrequencyInfo *(Function &)> LookupBFI) {
245 CallGraph CG(M);
246 CallGraphDOTInfo CFGInfo(&M, &CG, LookupBFI);
247
248 std::string Title =
250 ViewGraph(&CFGInfo, "callgraph", true, Title);
251}
252}
253
254namespace llvm {
259
262 };
263
264 doCallGraphDOTPrinting(M, LookupBFI);
265
267}
268
271
274
277 };
278
279 viewCallGraph(M, LookupBFI);
280
282}
283}
284
285namespace {
286
287class CallGraphViewer : public ModulePass {
288public:
289 static char ID;
291
292 void getAnalysisUsage(AnalysisUsage &AU) const override;
293 bool runOnModule(Module &M) override;
294};
295
296void CallGraphViewer::getAnalysisUsage(AnalysisUsage &AU) const {
297 ModulePass::getAnalysisUsage(AU);
298 AU.addRequired();
300}
301
302bool CallGraphViewer::runOnModule(Module &M) {
303 auto LookupBFI = [this](Function &F) {
304 return &this->getAnalysis(F).getBFI();
305 };
306
307 viewCallGraph(M, LookupBFI);
308
309 return false;
310}
311
312
313
314class CallGraphDOTPrinter : public ModulePass {
315public:
316 static char ID;
317 CallGraphDOTPrinter() : ModulePass(ID) {}
318
319 void getAnalysisUsage(AnalysisUsage &AU) const override;
320 bool runOnModule(Module &M) override;
321};
322
323void CallGraphDOTPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
324 ModulePass::getAnalysisUsage(AU);
325 AU.addRequired();
327}
328
329bool CallGraphDOTPrinter::runOnModule(Module &M) {
330 auto LookupBFI = [this](Function &F) {
331 return &this->getAnalysis(F).getBFI();
332 };
333
334 doCallGraphDOTPrinting(M, LookupBFI);
335
336 return false;
337}
338
339}
340
341char CallGraphViewer::ID = 0;
342INITIALIZE_PASS(CallGraphViewer, "view-callgraph", "View call graph", false,
343 false)
344
345char CallGraphDOTPrinter::ID = 0;
347 "Print call graph to 'dot' file", false, false)
348
349
350
351
352
354
356 return new CallGraphDOTPrinter();
357}
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
static cl::opt< bool > ShowHeatColors("callgraph-heat-colors", cl::init(false), cl::Hidden, cl::desc("Show heat colors in call-graph"))
static cl::opt< bool > ShowEdgeWeight("callgraph-show-weights", cl::init(false), cl::Hidden, cl::desc("Show edges labeled with weights"))
static cl::opt< bool > CallMultiGraph("callgraph-multigraph", cl::init(false), cl::Hidden, cl::desc("Show call-multigraph (do not remove parallel edges)"))
static cl::opt< std::string > CallGraphDotFilenamePrefix("callgraph-dot-filename-prefix", cl::Hidden, cl::desc("The prefix used for the CallGraph dot file names."))
This file defines the DenseMap class.
Module.h This file contains the declarations for the Module class.
Machine Check Debug Module
FunctionAnalysisManager FAM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Definition CallPrinter.cpp:55
CallGraph * getCallGraph() const
Definition CallPrinter.cpp:88
std::function< BlockFrequencyInfo *(Function &)> LookupBFI
Definition CallPrinter.cpp:63
Module * getModule() const
Definition CallPrinter.cpp:86
uint64_t getMaxFreq()
Definition CallPrinter.cpp:92
uint64_t getFreq(const Function *F)
Definition CallPrinter.cpp:90
CallGraphDOTInfo(Module *M, CallGraph *CG, function_ref< BlockFrequencyInfo *(Function &)> LookupBFI)
Definition CallPrinter.cpp:65
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Definition CallPrinter.cpp:255
A node in the call graph for a module.
std::vector< CallRecord >::const_iterator const_iterator
std::pair< std::optional< WeakTrackingVH >, CallGraphNode * > CallRecord
A pair of the calling instruction (a call or invoke) and the call graph node being called.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Definition CallPrinter.cpp:269
The basic data container for the call graph of a Module of IR.
FunctionMapTy::const_iterator const_iterator
CallGraphNode * getCallsExternalNode() const
CallGraphNode * getExternalCallingNode() const
Returns the CallGraphNode which is used to represent undetermined calls into the callgraph.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
A Module instance is used to store all the information related to an LLVM module.
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
An efficient, type-erasing, non-owning reference to a callable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
@ OF_Text
The file should be opened in text mode on platforms like z/OS that make this distinction.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI ModulePass * createCallGraphDOTPrinterPass()
Definition CallPrinter.cpp:355
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
LLVM_ABI uint64_t getNumOfCalls(const Function &CallerFunction, const Function &CalledFunction)
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVM_ABI std::string getHeatColor(uint64_t Freq, uint64_t MaxFreq)
void ViewGraph(const GraphType &G, const Twine &Name, bool ShortNames=false, const Twine &Title="", GraphProgram::Name Program=GraphProgram::DOT)
ViewGraph - Emit a dot graph, run 'dot', run gv on the postscript file, then cleanup.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI ModulePass * createCallGraphViewerPass()
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
DOTGraphTraits(bool isSimple=false)
Definition CallPrinter.cpp:144
std::string getNodeAttributes(const CallGraphNode *Node, CallGraphDOTInfo *CGInfo)
Definition CallPrinter.cpp:199
static std::string getGraphName(CallGraphDOTInfo *CGInfo)
Definition CallPrinter.cpp:146
mapped_iterator< CallGraphNode::const_iterator, decltype(&CGGetValuePtr)> nodes_iterator
Definition CallPrinter.cpp:176
static const CallGraphNode * CGGetValuePtr(CallGraphNode::CallRecord P)
Definition CallPrinter.cpp:169
static bool isNodeHidden(const CallGraphNode *Node, const CallGraphDOTInfo *CGInfo)
Definition CallPrinter.cpp:151
std::string getEdgeAttributes(const CallGraphNode *Node, nodes_iterator I, CallGraphDOTInfo *CGInfo)
Definition CallPrinter.cpp:178
std::string getNodeLabel(const CallGraphNode *Node, CallGraphDOTInfo *CGInfo)
Definition CallPrinter.cpp:158
DefaultDOTGraphTraits(bool simple=false)
static std::string getGraphName(const GraphType &)
getGraphName - Return the label for the graph as a whole.
static NodeRef getEntryNode(CallGraphDOTInfo *CGInfo)
Definition CallPrinter.cpp:118
mapped_iterator< CallGraph::const_iterator, decltype(&CGGetValuePtr)> nodes_iterator
Definition CallPrinter.cpp:131
static const CallGraphNode * CGGetValuePtr(const PairTy &P)
Definition CallPrinter.cpp:125
static nodes_iterator nodes_begin(CallGraphDOTInfo *CGInfo)
Definition CallPrinter.cpp:133
std::pair< const Function *const, std::unique_ptr< CallGraphNode > > PairTy
Definition CallPrinter.cpp:124
static nodes_iterator nodes_end(CallGraphDOTInfo *CGInfo)
Definition CallPrinter.cpp:136
typename CallGraphDOTInfo *::UnknownGraphTypeError NodeRef