LLVM  14.0.0git
CallPrinter.cpp
Go to the documentation of this file.
1 //===- CallPrinter.cpp - DOT printer for call graph -----------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines '-dot-callgraph', which emit a callgraph.<fnname>.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 
23 #include "llvm/InitializePasses.h"
24 #include "llvm/ADT/DenseMap.h"
25 #include "llvm/ADT/SmallSet.h"
26 
27 using namespace llvm;
28 
29 // This option shows static (relative) call counts.
30 // FIXME:
31 // Need to show real counts when profile data is available
32 static cl::opt<bool> ShowHeatColors("callgraph-heat-colors", cl::init(false),
33  cl::Hidden,
34  cl::desc("Show heat colors in call-graph"));
35 
36 static cl::opt<bool>
37  ShowEdgeWeight("callgraph-show-weights", cl::init(false), cl::Hidden,
38  cl::desc("Show edges labeled with weights"));
39 
40 static cl::opt<bool>
41  CallMultiGraph("callgraph-multigraph", cl::init(false), cl::Hidden,
42  cl::desc("Show call-multigraph (do not remove parallel edges)"));
43 
45  "callgraph-dot-filename-prefix", cl::Hidden,
46  cl::desc("The prefix used for the CallGraph dot file names."));
47 
48 namespace llvm {
49 
51 private:
52  Module *M;
53  CallGraph *CG;
55  uint64_t MaxFreq;
56 
57 public:
59 
62  : M(M), CG(CG), LookupBFI(LookupBFI) {
63  MaxFreq = 0;
64 
65  for (Function &F : M->getFunctionList()) {
66  uint64_t localSumFreq = 0;
68  for (User *U : F.users())
69  if (isa<CallInst>(U))
70  Callers.insert(cast<Instruction>(U)->getFunction());
71  for (Function *Caller : Callers)
72  localSumFreq += getNumOfCalls(*Caller, F);
73  if (localSumFreq >= MaxFreq)
74  MaxFreq = localSumFreq;
75  Freq[&F] = localSumFreq;
76  }
77  if (!CallMultiGraph)
78  removeParallelEdges();
79  }
80 
81  Module *getModule() const { return M; }
82 
83  CallGraph *getCallGraph() const { return CG; }
84 
85  uint64_t getFreq(const Function *F) { return Freq[F]; }
86 
87  uint64_t getMaxFreq() { return MaxFreq; }
88 
89 private:
90  void removeParallelEdges() {
91  for (auto &I : (*CG)) {
92  CallGraphNode *Node = I.second.get();
93 
94  bool FoundParallelEdge = true;
95  while (FoundParallelEdge) {
97  FoundParallelEdge = false;
98  for (auto CI = Node->begin(), CE = Node->end(); CI != CE; CI++) {
99  if (!(Visited.insert(CI->second->getFunction())).second) {
100  FoundParallelEdge = true;
101  Node->removeCallEdge(CI);
102  break;
103  }
104  }
105  }
106  }
107  }
108 };
109 
110 template <>
114  // Start at the external node!
115  return CGInfo->getCallGraph()->getExternalCallingNode();
116  }
117 
118  typedef std::pair<const Function *const, std::unique_ptr<CallGraphNode>>
120  static const CallGraphNode *CGGetValuePtr(const PairTy &P) {
121  return P.second.get();
122  }
123 
124  // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
125  typedef mapped_iterator<CallGraph::const_iterator, decltype(&CGGetValuePtr)>
127 
129  return nodes_iterator(CGInfo->getCallGraph()->begin(), &CGGetValuePtr);
130  }
132  return nodes_iterator(CGInfo->getCallGraph()->end(), &CGGetValuePtr);
133  }
134 };
135 
136 template <>
138 
140 
141  static std::string getGraphName(CallGraphDOTInfo *CGInfo) {
142  return "Call graph: " +
143  std::string(CGInfo->getModule()->getModuleIdentifier());
144  }
145 
146  static bool isNodeHidden(const CallGraphNode *Node,
147  const CallGraphDOTInfo *CGInfo) {
148  if (CallMultiGraph || Node->getFunction())
149  return false;
150  return true;
151  }
152 
153  std::string getNodeLabel(const CallGraphNode *Node,
154  CallGraphDOTInfo *CGInfo) {
155  if (Node == CGInfo->getCallGraph()->getExternalCallingNode())
156  return "external caller";
157  if (Node == CGInfo->getCallGraph()->getCallsExternalNode())
158  return "external callee";
159 
160  if (Function *Func = Node->getFunction())
161  return std::string(Func->getName());
162  return "external node";
163  }
165  return P.second;
166  }
167 
168  // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
170  decltype(&CGGetValuePtr)>
172 
174  CallGraphDOTInfo *CGInfo) {
175  if (!ShowEdgeWeight)
176  return "";
177 
178  Function *Caller = Node->getFunction();
179  if (Caller == nullptr || Caller->isDeclaration())
180  return "";
181 
182  Function *Callee = (*I)->getFunction();
183  if (Callee == nullptr)
184  return "";
185 
186  uint64_t Counter = getNumOfCalls(*Caller, *Callee);
187  double Width =
188  1 + 2 * (double(Counter) / CGInfo->getMaxFreq());
189  std::string Attrs = "label=\"" + std::to_string(Counter) +
190  "\" penwidth=" + std::to_string(Width);
191  return Attrs;
192  }
193 
194  std::string getNodeAttributes(const CallGraphNode *Node,
195  CallGraphDOTInfo *CGInfo) {
196  Function *F = Node->getFunction();
197  if (F == nullptr)
198  return "";
199  std::string attrs;
200  if (ShowHeatColors) {
201  uint64_t freq = CGInfo->getFreq(F);
202  std::string color = getHeatColor(freq, CGInfo->getMaxFreq());
203  std::string edgeColor = (freq <= (CGInfo->getMaxFreq() / 2))
204  ? getHeatColor(0)
205  : getHeatColor(1);
206  attrs = "color=\"" + edgeColor + "ff\", style=filled, fillcolor=\"" +
207  color + "80\"";
208  }
209  return attrs;
210  }
211 };
212 
213 } // end llvm namespace
214 
215 namespace {
216 // Viewer
217 class CallGraphViewer : public ModulePass {
218 public:
219  static char ID;
220  CallGraphViewer() : ModulePass(ID) {}
221 
222  void getAnalysisUsage(AnalysisUsage &AU) const override;
223  bool runOnModule(Module &M) override;
224 };
225 
226 void CallGraphViewer::getAnalysisUsage(AnalysisUsage &AU) const {
229  AU.setPreservesAll();
230 }
231 
232 bool CallGraphViewer::runOnModule(Module &M) {
233  auto LookupBFI = [this](Function &F) {
234  return &this->getAnalysis<BlockFrequencyInfoWrapperPass>(F).getBFI();
235  };
236 
237  CallGraph CG(M);
238  CallGraphDOTInfo CFGInfo(&M, &CG, LookupBFI);
239 
240  std::string Title =
242  ViewGraph(&CFGInfo, "callgraph", true, Title);
243 
244  return false;
245 }
246 
247 // DOT Printer
248 
249 class CallGraphDOTPrinter : public ModulePass {
250 public:
251  static char ID;
252  CallGraphDOTPrinter() : ModulePass(ID) {}
253 
254  void getAnalysisUsage(AnalysisUsage &AU) const override;
255  bool runOnModule(Module &M) override;
256 };
257 
258 void CallGraphDOTPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
261  AU.setPreservesAll();
262 }
263 
264 bool CallGraphDOTPrinter::runOnModule(Module &M) {
265  auto LookupBFI = [this](Function &F) {
266  return &this->getAnalysis<BlockFrequencyInfoWrapperPass>(F).getBFI();
267  };
268 
269  std::string Filename;
270  if (!CallGraphDotFilenamePrefix.empty())
271  Filename = (CallGraphDotFilenamePrefix + ".callgraph.dot");
272  else
273  Filename = (std::string(M.getModuleIdentifier()) + ".callgraph.dot");
274  errs() << "Writing '" << Filename << "'...";
275 
276  std::error_code EC;
277  raw_fd_ostream File(Filename, EC, sys::fs::OF_Text);
278 
279  CallGraph CG(M);
280  CallGraphDOTInfo CFGInfo(&M, &CG, LookupBFI);
281 
282  if (!EC)
283  WriteGraph(File, &CFGInfo);
284  else
285  errs() << " error opening file for writing!";
286  errs() << "\n";
287 
288  return false;
289 }
290 
291 } // end anonymous namespace
292 
293 char CallGraphViewer::ID = 0;
294 INITIALIZE_PASS(CallGraphViewer, "view-callgraph", "View call graph", false,
295  false)
296 
297 char CallGraphDOTPrinter::ID = 0;
298 INITIALIZE_PASS(CallGraphDOTPrinter, "dot-callgraph",
299  "Print call graph to 'dot' file", false, false)
300 
301 // Create methods available outside of this file, to use them
302 // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
303 // the link time optimization.
304 
305 ModulePass *llvm::createCallGraphViewerPass() { return new CallGraphViewer(); }
306 
308  return new CallGraphDOTPrinter();
309 }
Attrs
Function Attrs
Definition: README_ALTIVEC.txt:215
llvm::DOTGraphTraits< CallGraphDOTInfo * >::DOTGraphTraits
DOTGraphTraits(bool isSimple=false)
Definition: CallPrinter.cpp:139
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::CallGraph::getExternalCallingNode
CallGraphNode * getExternalCallingNode() const
Returns the CallGraphNode which is used to represent undetermined calls into the callgraph.
Definition: CallGraph.h:128
llvm::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:238
llvm::Function
Definition: Function.h:62
getFunction
static Function * getFunction(Constant *C)
Definition: Evaluator.cpp:250
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::BlockFrequencyInfoWrapperPass
Legacy analysis pass which computes BlockFrequencyInfo.
Definition: BlockFrequencyInfo.h:138
llvm::CallGraphNode::CallRecord
std::pair< Optional< WeakTrackingVH >, CallGraphNode * > CallRecord
A pair of the calling instruction (a call or invoke) and the call graph node being called.
Definition: CallGraph.h:179
double
into xmm2 addss xmm2 xmm1 xmm3 addss xmm3 movaps xmm0 unpcklps xmm0 ret seems silly when it could just be one addps Expand libm rounding functions main should enable SSE DAZ mode and other fast SSE modes Think about doing i64 math in SSE regs on x86 This testcase should have no SSE instructions in and only one load from a constant double
Definition: README-SSE.txt:85
llvm::CallGraphDOTInfo
Definition: CallPrinter.cpp:50
llvm::CallGraphDOTInfo::LookupBFI
std::function< BlockFrequencyInfo *(Function &)> LookupBFI
Definition: CallPrinter.cpp:58
llvm::CallGraphDOTInfo::CallGraphDOTInfo
CallGraphDOTInfo(Module *M, CallGraph *CG, function_ref< BlockFrequencyInfo *(Function &)> LookupBFI)
Definition: CallPrinter.cpp:60
llvm::CallGraph
The basic data container for the call graph of a Module of IR.
Definition: CallGraph.h:73
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
to
Should compile to
Definition: README.txt:449
DenseMap.h
llvm::DOTGraphTraits< CallGraphDOTInfo * >::CGGetValuePtr
static const CallGraphNode * CGGetValuePtr(CallGraphNode::CallRecord P)
Definition: CallPrinter.cpp:164
llvm::CallGraphDOTInfo::getFreq
uint64_t getFreq(const Function *F)
Definition: CallPrinter.cpp:85
llvm::SmallSet
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
llvm::mapped_iterator
Definition: STLExtras.h:277
ShowEdgeWeight
static cl::opt< bool > ShowEdgeWeight("callgraph-show-weights", cl::init(false), cl::Hidden, cl::desc("Show edges labeled with weights"))
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:893
llvm::ViewGraph
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.
Definition: GraphWriter.h:430
freq
block freq
Definition: BlockFrequencyInfo.cpp:301
llvm::getHeatColor
std::string getHeatColor(uint64_t freq, uint64_t maxFreq)
Definition: HeatUtils.cpp:61
attrs
function attrs
Definition: FunctionAttrs.cpp:1885
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::GraphTraits< CallGraphDOTInfo * >::PairTy
std::pair< const Function *const, std::unique_ptr< CallGraphNode > > PairTy
Definition: CallPrinter.cpp:119
CommandLine.h
llvm::BlockFrequencyInfo
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Definition: BlockFrequencyInfo.h:37
llvm::GraphTraits< CallGraphDOTInfo * >::CGGetValuePtr
static const CallGraphNode * CGGetValuePtr(const PairTy &P)
Definition: CallPrinter.cpp:120
llvm::createCallGraphViewerPass
ModulePass * createCallGraphViewerPass()
llvm::User
Definition: User.h:44
llvm::CallGraph::end
iterator end()
Definition: CallGraph.h:108
callgraph
print callgraph
Definition: CallGraph.cpp:390
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
false
Definition: StackSlotColoring.cpp:142
llvm::DOTGraphTraits< CallGraphDOTInfo * >::getNodeAttributes
std::string getNodeAttributes(const CallGraphNode *Node, CallGraphDOTInfo *CGInfo)
Definition: CallPrinter.cpp:194
llvm::CallGraph::const_iterator
FunctionMapTy::const_iterator const_iterator
Definition: CallGraph.h:99
llvm::CallGraphNode
A node in the call graph for a module.
Definition: CallGraph.h:167
llvm::DOTGraphTraits< CallGraphDOTInfo * >::nodes_iterator
mapped_iterator< CallGraphNode::const_iterator, decltype(&CGGetValuePtr)> nodes_iterator
Definition: CallPrinter.cpp:171
CallMultiGraph
static cl::opt< bool > CallMultiGraph("callgraph-multigraph", cl::init(false), cl::Hidden, cl::desc("Show call-multigraph (do not remove parallel edges)"))
llvm::DOTGraphTraits
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to 'dot...
Definition: DOTGraphTraits.h:166
llvm::DOTGraphTraits< CallGraphDOTInfo * >::getEdgeAttributes
std::string getEdgeAttributes(const CallGraphNode *Node, nodes_iterator I, CallGraphDOTInfo *CGInfo)
Definition: CallPrinter.cpp:173
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:168
llvm::DOTGraphTraits< CallGraphDOTInfo * >::getGraphName
static std::string getGraphName(CallGraphDOTInfo *CGInfo)
Definition: CallPrinter.cpp:141
llvm::GraphTraits< CallGraphDOTInfo * >::nodes_begin
static nodes_iterator nodes_begin(CallGraphDOTInfo *CGInfo)
Definition: CallPrinter.cpp:128
llvm::cl::opt< bool >
file
dot regions Print regions of function to dot file(with no function bodies)"
CallPrinter.h
BranchProbabilityInfo.h
uint64_t
llvm::sys::fs::OF_Text
@ OF_Text
The file should be opened in text mode on platforms like z/OS that make this distinction.
Definition: FileSystem.h:761
llvm::DenseMap
Definition: DenseMap.h:714
llvm::DefaultDOTGraphTraits::getGraphName
static std::string getGraphName(const GraphType &)
getGraphName - Return the label for the graph as a whole.
Definition: DOTGraphTraits.h:44
I
#define I(x, y, z)
Definition: MD5.cpp:59
call
S is passed via registers r2 But gcc stores them to the and then reload them to and r3 before issuing the call(r0 contains the address of the format string)
Definition: README.txt:190
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:441
CallGraphDotFilenamePrefix
static cl::opt< std::string > CallGraphDotFilenamePrefix("callgraph-dot-filename-prefix", cl::Hidden, cl::desc("The prefix used for the CallGraph dot file names."))
HeatUtils.h
llvm::GraphTraits< CallGraphDOTInfo * >::nodes_iterator
mapped_iterator< CallGraph::const_iterator, decltype(&CGGetValuePtr)> nodes_iterator
Definition: CallPrinter.cpp:126
llvm::codeview::CompileSym2Flags::EC
@ EC
llvm::WriteGraph
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
Definition: GraphWriter.h:362
llvm::Module::getModuleIdentifier
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
Definition: Module.h:227
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:83
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::CallGraphNode::const_iterator
std::vector< CallRecord >::const_iterator const_iterator
Definition: CallGraph.h:195
BlockFrequencyInfo.h
llvm::SmallSet::insert
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:180
llvm::raw_fd_ostream
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:443
Callee
amdgpu Simplify well known AMD library false FunctionCallee Callee
Definition: AMDGPULibCalls.cpp:206
llvm::tgtok::dot
@ dot
Definition: TGLexer.h:43
llvm::DOTGraphTraits< CallGraphDOTInfo * >::isNodeHidden
static bool isNodeHidden(const CallGraphNode *Node, const CallGraphDOTInfo *CGInfo)
Definition: CallPrinter.cpp:146
llvm::AnalysisUsage::setPreservesAll
void setPreservesAll()
Set by analyses that do not transform their input at all.
Definition: PassAnalysisSupport.h:130
llvm::CallGraphDOTInfo::getCallGraph
CallGraph * getCallGraph() const
Definition: CallPrinter.cpp:83
llvm::createCallGraphDOTPrinterPass
ModulePass * createCallGraphDOTPrinterPass()
Definition: CallPrinter.cpp:307
llvm::DOTGraphTraits< CallGraphDOTInfo * >::getNodeLabel
std::string getNodeLabel(const CallGraphNode *Node, CallGraphDOTInfo *CGInfo)
Definition: CallPrinter.cpp:153
ShowHeatColors
static cl::opt< bool > ShowHeatColors("callgraph-heat-colors", cl::init(false), cl::Hidden, cl::desc("Show heat colors in call-graph"))
DOTGraphTraitsPass.h
llvm::CallGraphDOTInfo::getModule
Module * getModule() const
Definition: CallPrinter.cpp:81
isSimple
static bool isSimple(Instruction *I)
Definition: SLPVectorizer.cpp:561
llvm::AMDGPU::Hwreg::Width
Width
Definition: SIDefines.h:413
CallGraph.h
llvm::GraphTraits< const CallGraphNode * >
Definition: CallGraph.h:439
llvm::GraphTraits< CallGraphDOTInfo * >::nodes_end
static nodes_iterator nodes_end(CallGraphDOTInfo *CGInfo)
Definition: CallPrinter.cpp:131
llvm::to_string
std::string to_string(const T &Value)
Definition: ScopedPrinter.h:63
llvm::DefaultDOTGraphTraits
DefaultDOTGraphTraits - This class provides the default implementations of all of the DOTGraphTraits ...
Definition: DOTGraphTraits.h:28
llvm::Pass::getAnalysisUsage
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: Pass.cpp:93
llvm::CallGraphDOTInfo::getMaxFreq
uint64_t getMaxFreq()
Definition: CallPrinter.cpp:87
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
llvm::GraphTraits
Definition: GraphTraits.h:35
llvm::cl::desc
Definition: CommandLine.h:412
graph
print Print a call graph
Definition: CallGraph.cpp:391
llvm::GraphTraits< CallGraphDOTInfo * >::getEntryNode
static NodeRef getEntryNode(CallGraphDOTInfo *CGInfo)
Definition: CallPrinter.cpp:113
llvm::CallGraph::getCallsExternalNode
CallGraphNode * getCallsExternalNode() const
Definition: CallGraph.h:130
llvm::CallGraph::begin
iterator begin()
Definition: CallGraph.h:107
INITIALIZE_PASS
INITIALIZE_PASS(CallGraphViewer, "view-callgraph", "View call graph", false, false) char CallGraphDOTPrinter INITIALIZE_PASS(CallGraphDOTPrinter, "dot-callgraph", "Print call graph to 'dot' file", false, false) ModulePass *llvm
Definition: CallPrinter.cpp:298
InitializePasses.h
File
Instrumentation for Order File
Definition: InstrOrderFile.cpp:205
llvm::getNumOfCalls
uint64_t getNumOfCalls(Function &callerFunction, Function &calledFunction)
Definition: HeatUtils.cpp:39
SmallSet.h
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38
INITIALIZE_PASS
TargetPassConfig.
Definition: TargetPassConfig.cpp:359