1292915Sdim//===- CallPrinter.cpp - DOT printer for call graph -----------------------===// 2292915Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6292915Sdim// 7292915Sdim//===----------------------------------------------------------------------===// 8292915Sdim// 9292915Sdim// This file defines '-dot-callgraph', which emit a callgraph.<fnname>.dot 10292915Sdim// containing the call graph of a module. 11292915Sdim// 12292915Sdim// There is also a pass available to directly call dotty ('-view-callgraph'). 13292915Sdim// 14292915Sdim//===----------------------------------------------------------------------===// 15292915Sdim 16321369Sdim#include "llvm/Analysis/CallPrinter.h" 17292915Sdim#include "llvm/Analysis/CallGraph.h" 18292915Sdim#include "llvm/Analysis/DOTGraphTraitsPass.h" 19360784Sdim#include "llvm/InitializePasses.h" 20292915Sdim 21292915Sdimusing namespace llvm; 22292915Sdim 23292915Sdimnamespace llvm { 24292915Sdim 25292915Sdimtemplate <> struct DOTGraphTraits<CallGraph *> : public DefaultDOTGraphTraits { 26292915Sdim DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} 27292915Sdim 28292915Sdim static std::string getGraphName(CallGraph *Graph) { return "Call graph"; } 29292915Sdim 30292915Sdim std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) { 31292915Sdim if (Function *Func = Node->getFunction()) 32292915Sdim return Func->getName(); 33292915Sdim 34292915Sdim return "external node"; 35292915Sdim } 36292915Sdim}; 37292915Sdim 38292915Sdimstruct AnalysisCallGraphWrapperPassTraits { 39292915Sdim static CallGraph *getGraph(CallGraphWrapperPass *P) { 40292915Sdim return &P->getCallGraph(); 41292915Sdim } 42292915Sdim}; 43292915Sdim 44292915Sdim} // end llvm namespace 45292915Sdim 46292915Sdimnamespace { 47292915Sdim 48292915Sdimstruct CallGraphViewer 49292915Sdim : public DOTGraphTraitsModuleViewer<CallGraphWrapperPass, true, CallGraph *, 50292915Sdim AnalysisCallGraphWrapperPassTraits> { 51292915Sdim static char ID; 52292915Sdim 53292915Sdim CallGraphViewer() 54292915Sdim : DOTGraphTraitsModuleViewer<CallGraphWrapperPass, true, CallGraph *, 55292915Sdim AnalysisCallGraphWrapperPassTraits>( 56292915Sdim "callgraph", ID) { 57292915Sdim initializeCallGraphViewerPass(*PassRegistry::getPassRegistry()); 58292915Sdim } 59292915Sdim}; 60292915Sdim 61309124Sdimstruct CallGraphDOTPrinter : public DOTGraphTraitsModulePrinter< 62292915Sdim CallGraphWrapperPass, true, CallGraph *, 63292915Sdim AnalysisCallGraphWrapperPassTraits> { 64292915Sdim static char ID; 65292915Sdim 66309124Sdim CallGraphDOTPrinter() 67292915Sdim : DOTGraphTraitsModulePrinter<CallGraphWrapperPass, true, CallGraph *, 68292915Sdim AnalysisCallGraphWrapperPassTraits>( 69292915Sdim "callgraph", ID) { 70309124Sdim initializeCallGraphDOTPrinterPass(*PassRegistry::getPassRegistry()); 71292915Sdim } 72292915Sdim}; 73292915Sdim 74292915Sdim} // end anonymous namespace 75292915Sdim 76292915Sdimchar CallGraphViewer::ID = 0; 77292915SdimINITIALIZE_PASS(CallGraphViewer, "view-callgraph", "View call graph", false, 78292915Sdim false) 79292915Sdim 80309124Sdimchar CallGraphDOTPrinter::ID = 0; 81309124SdimINITIALIZE_PASS(CallGraphDOTPrinter, "dot-callgraph", 82292915Sdim "Print call graph to 'dot' file", false, false) 83292915Sdim 84292915Sdim// Create methods available outside of this file, to use them 85292915Sdim// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by 86292915Sdim// the link time optimization. 87292915Sdim 88292915SdimModulePass *llvm::createCallGraphViewerPass() { return new CallGraphViewer(); } 89292915Sdim 90309124SdimModulePass *llvm::createCallGraphDOTPrinterPass() { 91309124Sdim return new CallGraphDOTPrinter(); 92292915Sdim} 93