LLVM  10.0.0svn
CFGPrinter.cpp
Go to the documentation of this file.
1 //===- CFGPrinter.cpp - DOT printer for the control flow 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 a `-dot-cfg` analysis pass, which emits the
10 // `<prefix>.<fnname>.dot` file for each function in the program, with a graph
11 // of the CFG for that function. The default value for `<prefix>` is `cfg` but
12 // can be customized as needed.
13 //
14 // The other main feature of this file is that it implements the
15 // Function::viewCFG method, which is useful for debugging passes which operate
16 // on the CFG.
17 //
18 //===----------------------------------------------------------------------===//
19 
21 #include "llvm/Pass.h"
23 using namespace llvm;
24 
26  "cfg-func-name", cl::Hidden,
27  cl::desc("The name of a function (or its substring)"
28  " whose CFG is viewed/printed."));
29 
31  "cfg-dot-filename-prefix", cl::Hidden,
32  cl::desc("The prefix used for the CFG dot file names."));
33 
34 namespace {
35  struct CFGViewerLegacyPass : public FunctionPass {
36  static char ID; // Pass identifcation, replacement for typeid
37  CFGViewerLegacyPass() : FunctionPass(ID) {
39  }
40 
41  bool runOnFunction(Function &F) override {
42  F.viewCFG();
43  return false;
44  }
45 
46  void print(raw_ostream &OS, const Module* = nullptr) const override {}
47 
48  void getAnalysisUsage(AnalysisUsage &AU) const override {
49  AU.setPreservesAll();
50  }
51  };
52 }
53 
55 INITIALIZE_PASS(CFGViewerLegacyPass, "view-cfg", "View CFG of function", false, true)
56 
59  F.viewCFG();
60  return PreservedAnalyses::all();
61 }
62 
63 
64 namespace {
65  struct CFGOnlyViewerLegacyPass : public FunctionPass {
66  static char ID; // Pass identifcation, replacement for typeid
67  CFGOnlyViewerLegacyPass() : FunctionPass(ID) {
69  }
70 
71  bool runOnFunction(Function &F) override {
72  F.viewCFGOnly();
73  return false;
74  }
75 
76  void print(raw_ostream &OS, const Module* = nullptr) const override {}
77 
78  void getAnalysisUsage(AnalysisUsage &AU) const override {
79  AU.setPreservesAll();
80  }
81  };
82 }
83 
85 INITIALIZE_PASS(CFGOnlyViewerLegacyPass, "view-cfg-only",
86  "View CFG of function (with no function bodies)", false, true)
87 
90  F.viewCFGOnly();
91  return PreservedAnalyses::all();
92 }
93 
94 static void writeCFGToDotFile(Function &F, bool CFGOnly = false) {
95  if (!CFGFuncName.empty() && !F.getName().contains(CFGFuncName))
96  return;
97  std::string Filename =
98  (CFGDotFilenamePrefix + "." + F.getName() + ".dot").str();
99  errs() << "Writing '" << Filename << "'...";
100 
101  std::error_code EC;
102  raw_fd_ostream File(Filename, EC, sys::fs::F_Text);
103 
104  if (!EC)
105  WriteGraph(File, (const Function*)&F, CFGOnly);
106  else
107  errs() << " error opening file for writing!";
108  errs() << "\n";
109 }
110 
111 namespace {
112  struct CFGPrinterLegacyPass : public FunctionPass {
113  static char ID; // Pass identification, replacement for typeid
114  CFGPrinterLegacyPass() : FunctionPass(ID) {
116  }
117 
118  bool runOnFunction(Function &F) override {
120  return false;
121  }
122 
123  void print(raw_ostream &OS, const Module* = nullptr) const override {}
124 
125  void getAnalysisUsage(AnalysisUsage &AU) const override {
126  AU.setPreservesAll();
127  }
128  };
129 }
130 
131 char CFGPrinterLegacyPass::ID = 0;
132 INITIALIZE_PASS(CFGPrinterLegacyPass, "dot-cfg", "Print CFG of function to 'dot' file",
133  false, true)
134 
138  return PreservedAnalyses::all();
139 }
140 
141 namespace {
142  struct CFGOnlyPrinterLegacyPass : public FunctionPass {
143  static char ID; // Pass identification, replacement for typeid
144  CFGOnlyPrinterLegacyPass() : FunctionPass(ID) {
146  }
147 
148  bool runOnFunction(Function &F) override {
149  writeCFGToDotFile(F, /*CFGOnly=*/true);
150  return false;
151  }
152  void print(raw_ostream &OS, const Module* = nullptr) const override {}
153 
154  void getAnalysisUsage(AnalysisUsage &AU) const override {
155  AU.setPreservesAll();
156  }
157  };
158 }
159 
161 INITIALIZE_PASS(CFGOnlyPrinterLegacyPass, "dot-cfg-only",
162  "Print CFG of function to 'dot' file (with no function bodies)",
163  false, true)
164 
167  writeCFGToDotFile(F, /*CFGOnly=*/true);
168  return PreservedAnalyses::all();
169 }
170 
171 /// viewCFG - This function is meant for use from the debugger. You can just
172 /// say 'call F->viewCFG()' and a ghostview window should pop up from the
173 /// program, displaying the CFG of the current function. This depends on there
174 /// being a 'dot' and 'gv' program in your path.
175 ///
176 void Function::viewCFG() const {
177  if (!CFGFuncName.empty() && !getName().contains(CFGFuncName))
178  return;
179  ViewGraph(this, "cfg" + getName());
180 }
181 
182 /// viewCFGOnly - This function is meant for use from the debugger. It works
183 /// just like viewCFG, but it does not include the contents of basic blocks
184 /// into the nodes, just the label. If you are only interested in the CFG
185 /// this can make the graph smaller.
186 ///
187 void Function::viewCFGOnly() const {
188  if (!CFGFuncName.empty() && !getName().contains(CFGFuncName))
189  return;
190  ViewGraph(this, "cfg" + getName(), true);
191 }
192 
194  return new CFGPrinterLegacyPass();
195 }
196 
198  return new CFGOnlyPrinterLegacyPass();
199 }
200 
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents lattice values for constants.
Definition: AllocatorList.h:23
static cl::opt< std::string > CFGFuncName("cfg-func-name", cl::Hidden, cl::desc("The name of a function (or its substring)" " whose CFG is viewed/printed."))
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
FunctionPass * createCFGPrinterLegacyPassPass()
Definition: CFGPrinter.cpp:193
static void writeCFGToDotFile(Function &F, bool CFGOnly=false)
Definition: CFGPrinter.cpp:94
static cl::opt< std::string > CFGDotFilenamePrefix("cfg-dot-filename-prefix", cl::Hidden, cl::desc("The prefix used for the CFG dot file names."))
F(f)
INITIALIZE_PASS(CFGOnlyViewerLegacyPass, "view-cfg-only", "View CFG of function (with no function bodies)", false, true) PreservedAnalyses CFGOnlyViewerPass
Definition: CFGPrinter.cpp:85
*ViewGraph Emit a dot run run gv on the postscript *then cleanup For use from the debugger *void ViewGraph(const GraphType &G, const Twine &Name, bool ShortNames=false, const Twine &Title="", GraphProgram::Name Program=GraphProgram::DOT)
Definition: GraphWriter.h:366
void initializeCFGOnlyPrinterLegacyPassPass(PassRegistry &)
static StringRef getName(Value *V)
void viewCFG() const
viewCFG - This function is meant for use from the debugger.
Definition: CFGPrinter.cpp:176
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
Definition: GraphWriter.h:309
static bool runOnFunction(Function &F, bool PostInlining)
void viewCFGOnly() const
viewCFGOnly - This function is meant for use from the debugger.
Definition: CFGPrinter.cpp:187
FunctionPass * createCFGOnlyPrinterLegacyPassPass()
Definition: CFGPrinter.cpp:197
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:153
Instrumentation for Order File
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
LLVM_NODISCARD bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Definition: StringRef.h:432
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:159
void setPreservesAll()
Set by analyses that do not transform their input at all.
void initializeCFGViewerLegacyPassPass(PassRegistry &)
void initializeCFGPrinterLegacyPassPass(PassRegistry &)
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:365
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:214
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
A container for analyses that lazily runs them and caches their results.
void initializeCFGOnlyViewerLegacyPassPass(PassRegistry &)