LLVM  8.0.0svn
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 // cfg.<fnname>.dot file for each function in the program, with a graph of the
12 // CFG for that function.
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 
30 namespace {
31  struct CFGViewerLegacyPass : public FunctionPass {
32  static char ID; // Pass identifcation, replacement for typeid
33  CFGViewerLegacyPass() : FunctionPass(ID) {
35  }
36 
37  bool runOnFunction(Function &F) override {
38  F.viewCFG();
39  return false;
40  }
41 
42  void print(raw_ostream &OS, const Module* = nullptr) const override {}
43 
44  void getAnalysisUsage(AnalysisUsage &AU) const override {
45  AU.setPreservesAll();
46  }
47  };
48 }
49 
51 INITIALIZE_PASS(CFGViewerLegacyPass, "view-cfg", "View CFG of function", false, true)
52 
55  F.viewCFG();
56  return PreservedAnalyses::all();
57 }
58 
59 
60 namespace {
61  struct CFGOnlyViewerLegacyPass : public FunctionPass {
62  static char ID; // Pass identifcation, replacement for typeid
63  CFGOnlyViewerLegacyPass() : FunctionPass(ID) {
65  }
66 
67  bool runOnFunction(Function &F) override {
68  F.viewCFGOnly();
69  return false;
70  }
71 
72  void print(raw_ostream &OS, const Module* = nullptr) const override {}
73 
74  void getAnalysisUsage(AnalysisUsage &AU) const override {
75  AU.setPreservesAll();
76  }
77  };
78 }
79 
81 INITIALIZE_PASS(CFGOnlyViewerLegacyPass, "view-cfg-only",
82  "View CFG of function (with no function bodies)", false, true)
83 
86  F.viewCFGOnly();
87  return PreservedAnalyses::all();
88 }
89 
90 static void writeCFGToDotFile(Function &F, bool CFGOnly = false) {
91  if (!CFGFuncName.empty() && !F.getName().contains(CFGFuncName))
92  return;
93  std::string Filename = ("cfg." + F.getName() + ".dot").str();
94  errs() << "Writing '" << Filename << "'...";
95 
96  std::error_code EC;
97  raw_fd_ostream File(Filename, EC, sys::fs::F_Text);
98 
99  if (!EC)
100  WriteGraph(File, (const Function*)&F, CFGOnly);
101  else
102  errs() << " error opening file for writing!";
103  errs() << "\n";
104 }
105 
106 namespace {
107  struct CFGPrinterLegacyPass : public FunctionPass {
108  static char ID; // Pass identification, replacement for typeid
109  CFGPrinterLegacyPass() : FunctionPass(ID) {
111  }
112 
113  bool runOnFunction(Function &F) override {
115  return false;
116  }
117 
118  void print(raw_ostream &OS, const Module* = nullptr) const override {}
119 
120  void getAnalysisUsage(AnalysisUsage &AU) const override {
121  AU.setPreservesAll();
122  }
123  };
124 }
125 
126 char CFGPrinterLegacyPass::ID = 0;
127 INITIALIZE_PASS(CFGPrinterLegacyPass, "dot-cfg", "Print CFG of function to 'dot' file",
128  false, true)
129 
133  return PreservedAnalyses::all();
134 }
135 
136 namespace {
137  struct CFGOnlyPrinterLegacyPass : public FunctionPass {
138  static char ID; // Pass identification, replacement for typeid
139  CFGOnlyPrinterLegacyPass() : FunctionPass(ID) {
141  }
142 
143  bool runOnFunction(Function &F) override {
144  writeCFGToDotFile(F, /*CFGOnly=*/true);
145  return false;
146  }
147  void print(raw_ostream &OS, const Module* = nullptr) const override {}
148 
149  void getAnalysisUsage(AnalysisUsage &AU) const override {
150  AU.setPreservesAll();
151  }
152  };
153 }
154 
156 INITIALIZE_PASS(CFGOnlyPrinterLegacyPass, "dot-cfg-only",
157  "Print CFG of function to 'dot' file (with no function bodies)",
158  false, true)
159 
162  writeCFGToDotFile(F, /*CFGOnly=*/true);
163  return PreservedAnalyses::all();
164 }
165 
166 /// viewCFG - This function is meant for use from the debugger. You can just
167 /// say 'call F->viewCFG()' and a ghostview window should pop up from the
168 /// program, displaying the CFG of the current function. This depends on there
169 /// being a 'dot' and 'gv' program in your path.
170 ///
171 void Function::viewCFG() const {
172  if (!CFGFuncName.empty() && !getName().contains(CFGFuncName))
173  return;
174  ViewGraph(this, "cfg" + getName());
175 }
176 
177 /// viewCFGOnly - This function is meant for use from the debugger. It works
178 /// just like viewCFG, but it does not include the contents of basic blocks
179 /// into the nodes, just the label. If you are only interested in the CFG
180 /// this can make the graph smaller.
181 ///
182 void Function::viewCFGOnly() const {
183  if (!CFGFuncName.empty() && !getName().contains(CFGFuncName))
184  return;
185  ViewGraph(this, "cfg" + getName(), true);
186 }
187 
189  return new CFGPrinterLegacyPass();
190 }
191 
193  return new CFGOnlyPrinterLegacyPass();
194 }
195 
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...
Compute iterated dominance frontiers using a linear time algorithm.
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:63
FunctionPass * createCFGPrinterLegacyPassPass()
Definition: CFGPrinter.cpp:188
static void writeCFGToDotFile(Function &F, bool CFGOnly=false)
Definition: CFGPrinter.cpp:90
F(f)
INITIALIZE_PASS(CFGOnlyViewerLegacyPass, "view-cfg-only", "View CFG of function (with no function bodies)", false, true) PreservedAnalyses CFGOnlyViewerPass
Definition: CFGPrinter.cpp:81
void initializeCFGOnlyPrinterLegacyPassPass(PassRegistry &)
static StringRef getName(Value *V)
void viewCFG() const
viewCFG - This function is meant for use from the debugger.
Definition: CFGPrinter.cpp:171
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:182
FunctionPass * createCFGOnlyPrinterLegacyPassPass()
Definition: CFGPrinter.cpp:192
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)
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 &#39;dot&#39;, run gv on the postscript file, then cleanup.
Definition: GraphWriter.h:348
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:224
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 &)