LLVM  3.7.0
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 
25 namespace {
26  struct CFGViewer : public FunctionPass {
27  static char ID; // Pass identifcation, replacement for typeid
28  CFGViewer() : FunctionPass(ID) {
30  }
31 
32  bool runOnFunction(Function &F) override {
33  F.viewCFG();
34  return false;
35  }
36 
37  void print(raw_ostream &OS, const Module* = nullptr) const override {}
38 
39  void getAnalysisUsage(AnalysisUsage &AU) const override {
40  AU.setPreservesAll();
41  }
42  };
43 }
44 
45 char CFGViewer::ID = 0;
46 INITIALIZE_PASS(CFGViewer, "view-cfg", "View CFG of function", false, true)
47 
48 namespace {
49  struct CFGOnlyViewer : public FunctionPass {
50  static char ID; // Pass identifcation, replacement for typeid
51  CFGOnlyViewer() : FunctionPass(ID) {
53  }
54 
55  bool runOnFunction(Function &F) override {
56  F.viewCFGOnly();
57  return false;
58  }
59 
60  void print(raw_ostream &OS, const Module* = nullptr) const override {}
61 
62  void getAnalysisUsage(AnalysisUsage &AU) const override {
63  AU.setPreservesAll();
64  }
65  };
66 }
67 
68 char CFGOnlyViewer::ID = 0;
69 INITIALIZE_PASS(CFGOnlyViewer, "view-cfg-only",
70  "View CFG of function (with no function bodies)", false, true)
71 
72 namespace {
73  struct CFGPrinter : public FunctionPass {
74  static char ID; // Pass identification, replacement for typeid
75  CFGPrinter() : FunctionPass(ID) {
77  }
78 
79  bool runOnFunction(Function &F) override {
80  std::string Filename = ("cfg." + F.getName() + ".dot").str();
81  errs() << "Writing '" << Filename << "'...";
82 
83  std::error_code EC;
84  raw_fd_ostream File(Filename, EC, sys::fs::F_Text);
85 
86  if (!EC)
87  WriteGraph(File, (const Function*)&F);
88  else
89  errs() << " error opening file for writing!";
90  errs() << "\n";
91  return false;
92  }
93 
94  void print(raw_ostream &OS, const Module* = nullptr) const override {}
95 
96  void getAnalysisUsage(AnalysisUsage &AU) const override {
97  AU.setPreservesAll();
98  }
99  };
100 }
101 
102 char CFGPrinter::ID = 0;
103 INITIALIZE_PASS(CFGPrinter, "dot-cfg", "Print CFG of function to 'dot' file",
104  false, true)
105 
106 namespace {
107  struct CFGOnlyPrinter : public FunctionPass {
108  static char ID; // Pass identification, replacement for typeid
109  CFGOnlyPrinter() : FunctionPass(ID) {
111  }
112 
113  bool runOnFunction(Function &F) override {
114  std::string Filename = ("cfg." + F.getName() + ".dot").str();
115  errs() << "Writing '" << Filename << "'...";
116 
117  std::error_code EC;
118  raw_fd_ostream File(Filename, EC, sys::fs::F_Text);
119 
120  if (!EC)
121  WriteGraph(File, (const Function*)&F, true);
122  else
123  errs() << " error opening file for writing!";
124  errs() << "\n";
125  return false;
126  }
127  void print(raw_ostream &OS, const Module* = nullptr) const override {}
128 
129  void getAnalysisUsage(AnalysisUsage &AU) const override {
130  AU.setPreservesAll();
131  }
132  };
133 }
134 
135 char CFGOnlyPrinter::ID = 0;
136 INITIALIZE_PASS(CFGOnlyPrinter, "dot-cfg-only",
137  "Print CFG of function to 'dot' file (with no function bodies)",
138  false, true)
139 
140 /// viewCFG - This function is meant for use from the debugger. You can just
141 /// say 'call F->viewCFG()' and a ghostview window should pop up from the
142 /// program, displaying the CFG of the current function. This depends on there
143 /// being a 'dot' and 'gv' program in your path.
144 ///
145 void Function::viewCFG() const {
146  ViewGraph(this, "cfg" + getName());
147 }
148 
149 /// viewCFGOnly - This function is meant for use from the debugger. It works
150 /// just like viewCFG, but it does not include the contents of basic blocks
151 /// into the nodes, just the label. If you are only interested in the CFG
152 /// this can make the graph smaller.
153 ///
154 void Function::viewCFGOnly() const {
155  ViewGraph(this, "cfg" + getName(), true);
156 }
157 
159  return new CFGPrinter();
160 }
161 
163  return new CFGOnlyPrinter();
164 }
165 
void viewCFGOnly() const
viewCFGOnly - This function is meant for use from the debugger.
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...
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:114
F(f)
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:188
static StringRef getName(Value *V)
void viewCFG() const
viewCFG - This function is meant for use from the debugger.
FunctionPass * createCFGPrinterPass()
Definition: CFGPrinter.cpp:158
void initializeCFGOnlyPrinterPass(PassRegistry &)
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
Definition: GraphWriter.h:309
INITIALIZE_PASS(CFGOnlyViewer,"view-cfg-only","View CFG of function (with no function bodies)", false, true) namespace
Definition: CFGPrinter.cpp:69
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:294
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 'dot', run gv on the postscript file, then cleanup.
Definition: GraphWriter.h:348
void initializeCFGPrinterPass(PassRegistry &)
void initializeCFGOnlyViewerPass(PassRegistry &)
void setPreservesAll()
Set by analyses that do not transform their input at all.
The file should be opened in text mode on platforms that make this distinction.
Definition: FileSystem.h:592
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:345
FunctionPass * createCFGOnlyPrinterPass()
Definition: CFGPrinter.cpp:162
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38