38 const AnalysisOptions &Opts;
52 for (
Function &
F : M->getFunctionList()) {
53 uint64_t localSumFreq = 0;
54 SmallPtrSet<Function *, 16> Callers;
55 for (User *U : F.users())
57 Callers.insert(cast<Instruction>(U)->getFunction());
58 for (Function *Caller : Callers)
59 localSumFreq += getNumOfCalls(*Caller, F);
60 if (localSumFreq >= MaxFreq)
61 MaxFreq = localSumFreq;
62 Freq[&F] = localSumFreq;
64 if (!Opts.callgraph_multigraph)
65 removeParallelEdges();
68 const AnalysisOptions &
getOpts()
const {
return Opts; }
79 void removeParallelEdges() {
80 for (
auto &
I : (*CG)) {
83 bool FoundParallelEdge =
true;
84 while (FoundParallelEdge) {
86 FoundParallelEdge =
false;
87 for (
auto CI =
Node->begin(), CE =
Node->end(); CI != CE; CI++) {
88 if (!(Visited.
insert(CI->second->getFunction())).second) {
89 FoundParallelEdge =
true;
90 Node->removeCallEdge(CI);
107 typedef std::pair<const Function *const, std::unique_ptr<CallGraphNode>>
110 return P.second.get();
131 return "Call graph: " +
137 if (CGInfo->
getOpts().callgraph_multigraph ||
Node->getFunction())
145 return "external caller";
147 return "external callee";
150 return std::string(Func->getName());
151 return "external node";
159 decltype(&CGGetValuePtr)>
164 if (!CGInfo->
getOpts().callgraph_show_weights)
168 if (Caller ==
nullptr || Caller->isDeclaration())
171 Function *Callee = (*I)->getFunction();
172 if (Callee ==
nullptr)
177 1 + 2 * (double(Counter) / CGInfo->
getMaxFreq());
178 std::string Attrs =
"label=\"" + std::to_string(Counter) +
179 "\" penwidth=" + std::to_string(Width);
189 if (CGInfo->
getOpts().callgraph_heat_colors) {
195 attrs =
"color=\"" + edgeColor +
"ff\", style=filled, fillcolor=\"" +
205void doCallGraphDOTPrinting(
206 Module &M, function_ref<BlockFrequencyInfo *(
Function &)> LookupBFI) {
212 Filename = (std::string(
M.getModuleIdentifier()) +
".callgraph.dot");
219 CallGraphDOTInfo CFGInfo(&M, &CG, LookupBFI);
224 errs() <<
" error opening file for writing!";
228void viewCallGraph(
Module &M,
229 function_ref<BlockFrequencyInfo *(
Function &)> LookupBFI) {
231 CallGraphDOTInfo CFGInfo(&M, &CG, LookupBFI);
235 ViewGraph(&CFGInfo,
"callgraph",
true, Title);
249 doCallGraphDOTPrinting(M, LookupBFI);
264 viewCallGraph(M, LookupBFI);
277 void getAnalysisUsage(AnalysisUsage &AU)
const override;
278 bool runOnModule(
Module &M)
override;
281void CallGraphViewer::getAnalysisUsage(
AnalysisUsage &AU)
const {
282 ModulePass::getAnalysisUsage(AU);
287bool CallGraphViewer::runOnModule(
Module &M) {
289 return &this->getAnalysis<BlockFrequencyInfoWrapperPass>(
F).getBFI();
292 viewCallGraph(M, LookupBFI);
299class CallGraphDOTPrinter :
public ModulePass {
302 CallGraphDOTPrinter() : ModulePass(
ID) {}
304 void getAnalysisUsage(AnalysisUsage &AU)
const override;
305 bool runOnModule(
Module &M)
override;
308void CallGraphDOTPrinter::getAnalysisUsage(AnalysisUsage &AU)
const {
309 ModulePass::getAnalysisUsage(AU);
314bool CallGraphDOTPrinter::runOnModule(
Module &M) {
316 return &this->getAnalysis<BlockFrequencyInfoWrapperPass>(
F).getBFI();
319 doCallGraphDOTPrinting(M, LookupBFI);
326char CallGraphViewer::ID = 0;
327INITIALIZE_PASS(CallGraphViewer,
"view-callgraph",
"View call graph",
false,
330char CallGraphDOTPrinter::ID = 0;
332 "Print call graph to 'dot' file",
false,
false)
341 return new CallGraphDOTPrinter();
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
This file defines the DenseMap class.
Module.h This file contains the declarations for the Module class.
Machine Check Debug Module
static constexpr StringLiteral Filename
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...
CallGraph * getCallGraph() const
std::function< BlockFrequencyInfo *(Function &)> LookupBFI
Module * getModule() const
const AnalysisOptions & getOpts() const
uint64_t getFreq(const Function *F)
CallGraphDOTInfo(Module *M, CallGraph *CG, function_ref< BlockFrequencyInfo *(Function &)> LookupBFI)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
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)
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.
@ 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()
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="")
const AnalysisOptions & getAnalysisOptions(const LLVMContext &C)
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)
std::string getNodeAttributes(const CallGraphNode *Node, CallGraphDOTInfo *CGInfo)
static std::string getGraphName(CallGraphDOTInfo *CGInfo)
mapped_iterator< CallGraphNode::const_iterator, decltype(&CGGetValuePtr)> nodes_iterator
static const CallGraphNode * CGGetValuePtr(CallGraphNode::CallRecord P)
static bool isNodeHidden(const CallGraphNode *Node, const CallGraphDOTInfo *CGInfo)
std::string getEdgeAttributes(const CallGraphNode *Node, nodes_iterator I, CallGraphDOTInfo *CGInfo)
std::string getNodeLabel(const CallGraphNode *Node, CallGraphDOTInfo *CGInfo)
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)
mapped_iterator< CallGraph::const_iterator, decltype(&CGGetValuePtr)> nodes_iterator
static const CallGraphNode * CGGetValuePtr(const PairTy &P)
static nodes_iterator nodes_begin(CallGraphDOTInfo *CGInfo)
std::pair< const Function *const, std::unique_ptr< CallGraphNode > > PairTy
static nodes_iterator nodes_end(CallGraphDOTInfo *CGInfo)
typename CallGraphDOTInfo *::UnknownGraphTypeError NodeRef