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