LLVM  8.0.1
CFGPrinter.cpp
Go to the documentation of this file.
1 //===- CFGPrinter.cpp - DOT printer for the control flow graph ------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines a `-dot-cfg` analysis pass, which emits the
11 // `<prefix>.<fnname>.dot` file for each function in the program, with a graph
12 // of the CFG for that function. The default value for `<prefix>` is `cfg` but
13 // can be customized as needed.
14 //
15 // The other main feature of this file is that it implements the
16 // Function::viewCFG method, which is useful for debugging passes which operate
17 // on the CFG.
18 //
19 //===----------------------------------------------------------------------===//
20 
22 #include "llvm/Pass.h"
24 using namespace llvm;
25 
27  "cfg-func-name", cl::Hidden,
28  cl::desc("The name of a function (or its substring)"
29  " whose CFG is viewed/printed."));
30 
32  "cfg-dot-filename-prefix", cl::Hidden,
33  cl::desc("The prefix used for the CFG dot file names."));
34 
35 namespace {
36  struct CFGViewerLegacyPass : public FunctionPass {
37  static char ID; // Pass identifcation, replacement for typeid
38  CFGViewerLegacyPass() : FunctionPass(ID) {
40  }
41 
42  bool runOnFunction(Function &F) override {
43  F.viewCFG();
44  return false;
45  }
46 
47  void print(raw_ostream &OS, const Module* = nullptr) const override {}
48 
49  void getAnalysisUsage(AnalysisUsage &AU) const override {
50  AU.setPreservesAll();
51  }
52  };
53 }
54 
56 INITIALIZE_PASS(CFGViewerLegacyPass, "view-cfg", "View CFG of function", false, true)
57 
60  F.viewCFG();
61  return PreservedAnalyses::all();
62 }
63 
64 
65 namespace {
66  struct CFGOnlyViewerLegacyPass : public FunctionPass {
67  static char ID; // Pass identifcation, replacement for typeid
68  CFGOnlyViewerLegacyPass() : FunctionPass(ID) {
70  }
71 
72  bool runOnFunction(Function &F) override {
73  F.viewCFGOnly();
74  return false;
75  }
76 
77  void print(raw_ostream &OS, const Module* = nullptr) const override {}
78 
79  void getAnalysisUsage(AnalysisUsage &AU) const override {
80  AU.setPreservesAll();
81  }
82  };
83 }
84 
86 INITIALIZE_PASS(CFGOnlyViewerLegacyPass, "view-cfg-only",
87  "View CFG of function (with no function bodies)", false, true)
88 
91  F.viewCFGOnly();
92  return PreservedAnalyses::all();
93 }
94 
95 static void writeCFGToDotFile(Function &F, bool CFGOnly = false) {
96  if (!CFGFuncName.empty() && !F.getName().contains(CFGFuncName))
97  return;
98  std::string Filename =
99  (CFGDotFilenamePrefix + "." + F.getName() + ".dot").str();
100  errs() << "Writing '" << Filename << "'...";
101 
102  std::error_code EC;
103  raw_fd_ostream File(Filename, EC, sys::fs::F_Text);
104 
105  if (!EC)
106  WriteGraph(File, (const Function*)&F, CFGOnly);
107  else
108  errs() << " error opening file for writing!";
109  errs() << "\n";
110 }
111 
112 namespace {
113  struct CFGPrinterLegacyPass : public FunctionPass {
114  static char ID; // Pass identification, replacement for typeid
115  CFGPrinterLegacyPass() : FunctionPass(ID) {
117  }
118 
119  bool runOnFunction(Function &F) override {
121  return false;
122  }
123 
124  void print(raw_ostream &OS, const Module* = nullptr) const override {}
125 
126  void getAnalysisUsage(AnalysisUsage &AU) const override {
127  AU.setPreservesAll();
128  }
129  };
130 }
131 
132 char CFGPrinterLegacyPass::ID = 0;
133 INITIALIZE_PASS(CFGPrinterLegacyPass, "dot-cfg", "Print CFG of function to 'dot' file",
134  false, true)
135 
139  return PreservedAnalyses::all();
140 }
141 
142 namespace {
143  struct CFGOnlyPrinterLegacyPass : public FunctionPass {
144  static char ID; // Pass identification, replacement for typeid
145  CFGOnlyPrinterLegacyPass() : FunctionPass(ID) {
147  }
148 
149  bool runOnFunction(Function &F) override {
150  writeCFGToDotFile(F, /*CFGOnly=*/true);
151  return false;
152  }
153  void print(raw_ostream &OS, const Module* = nullptr) const override {}
154 
155  void getAnalysisUsage(AnalysisUsage &AU) const override {
156  AU.setPreservesAll();
157  }
158  };
159 }
160 
162 INITIALIZE_PASS(CFGOnlyPrinterLegacyPass, "dot-cfg-only",
163  "Print CFG of function to 'dot' file (with no function bodies)",
164  false, true)
165 
168  writeCFGToDotFile(F, /*CFGOnly=*/true);
169  return PreservedAnalyses::all();
170 }
171 
172 /// viewCFG - This function is meant for use from the debugger. You can just
173 /// say 'call F->viewCFG()' and a ghostview window should pop up from the
174 /// program, displaying the CFG of the current function. This depends on there
175 /// being a 'dot' and 'gv' program in your path.
176 ///
177 void Function::viewCFG() const {
178  if (!CFGFuncName.empty() && !getName().contains(CFGFuncName))
179  return;
180  ViewGraph(this, "cfg" + getName());
181 }
182 
183 /// viewCFGOnly - This function is meant for use from the debugger. It works
184 /// just like viewCFG, but it does not include the contents of basic blocks
185 /// into the nodes, just the label. If you are only interested in the CFG
186 /// this can make the graph smaller.
187 ///
188 void Function::viewCFGOnly() const {
189  if (!CFGFuncName.empty() && !getName().contains(CFGFuncName))
190  return;
191  ViewGraph(this, "cfg" + getName(), true);
192 }
193 
195  return new CFGPrinterLegacyPass();
196 }
197 
199  return new CFGOnlyPrinterLegacyPass();
200 }
201 
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:24
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Definition: StringRef.h:448
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:194
static void writeCFGToDotFile(Function &F, bool CFGOnly=false)
Definition: CFGPrinter.cpp:95
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:86
*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:367
void initializeCFGOnlyPrinterLegacyPassPass(PassRegistry &)
static StringRef getName(Value *V)
void viewCFG() const
viewCFG - This function is meant for use from the debugger.
Definition: CFGPrinter.cpp:177
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
Definition: GraphWriter.h:310
static bool runOnFunction(Function &F, bool PostInlining)
void viewCFGOnly() const
viewCFGOnly - This function is meant for use from the debugger.
Definition: CFGPrinter.cpp:188
FunctionPass * createCFGOnlyPrinterLegacyPassPass()
Definition: CFGPrinter.cpp:198
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:154
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:285
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:160
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:366
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:46
A container for analyses that lazily runs them and caches their results.
void initializeCFGOnlyViewerLegacyPassPass(PassRegistry &)