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