]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Analysis/CFGPrinter.cpp
MFV r314565,314567,314570:
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Analysis / CFGPrinter.cpp
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
20 #include "llvm/Analysis/CFGPrinter.h"
21 #include "llvm/Pass.h"
22 #include "llvm/Support/FileSystem.h"
23 using namespace llvm;
24
25 namespace {
26   struct CFGViewerLegacyPass : public FunctionPass {
27     static char ID; // Pass identifcation, replacement for typeid
28     CFGViewerLegacyPass() : FunctionPass(ID) {
29       initializeCFGViewerLegacyPassPass(*PassRegistry::getPassRegistry());
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 CFGViewerLegacyPass::ID = 0;
46 INITIALIZE_PASS(CFGViewerLegacyPass, "view-cfg", "View CFG of function", false, true)
47
48 PreservedAnalyses CFGViewerPass::run(Function &F,
49                                      FunctionAnalysisManager &AM) {
50   F.viewCFG();
51   return PreservedAnalyses::all();
52 }
53
54
55 namespace {
56   struct CFGOnlyViewerLegacyPass : public FunctionPass {
57     static char ID; // Pass identifcation, replacement for typeid
58     CFGOnlyViewerLegacyPass() : FunctionPass(ID) {
59       initializeCFGOnlyViewerLegacyPassPass(*PassRegistry::getPassRegistry());
60     }
61
62     bool runOnFunction(Function &F) override {
63       F.viewCFGOnly();
64       return false;
65     }
66
67     void print(raw_ostream &OS, const Module* = nullptr) const override {}
68
69     void getAnalysisUsage(AnalysisUsage &AU) const override {
70       AU.setPreservesAll();
71     }
72   };
73 }
74
75 char CFGOnlyViewerLegacyPass::ID = 0;
76 INITIALIZE_PASS(CFGOnlyViewerLegacyPass, "view-cfg-only",
77                 "View CFG of function (with no function bodies)", false, true)
78
79 PreservedAnalyses CFGOnlyViewerPass::run(Function &F,
80                                          FunctionAnalysisManager &AM) {
81   F.viewCFGOnly();
82   return PreservedAnalyses::all();
83 }
84
85 static void writeCFGToDotFile(Function &F) {
86   std::string Filename = ("cfg." + F.getName() + ".dot").str();
87   errs() << "Writing '" << Filename << "'...";
88
89   std::error_code EC;
90   raw_fd_ostream File(Filename, EC, sys::fs::F_Text);
91
92   if (!EC)
93     WriteGraph(File, (const Function*)&F);
94   else
95     errs() << "  error opening file for writing!";
96   errs() << "\n";
97 }
98
99 namespace {
100   struct CFGPrinterLegacyPass : public FunctionPass {
101     static char ID; // Pass identification, replacement for typeid
102     CFGPrinterLegacyPass() : FunctionPass(ID) {
103       initializeCFGPrinterLegacyPassPass(*PassRegistry::getPassRegistry());
104     }
105
106     bool runOnFunction(Function &F) override {
107       writeCFGToDotFile(F);
108       return false;
109     }
110
111     void print(raw_ostream &OS, const Module* = nullptr) const override {}
112
113     void getAnalysisUsage(AnalysisUsage &AU) const override {
114       AU.setPreservesAll();
115     }
116   };
117 }
118
119 char CFGPrinterLegacyPass::ID = 0;
120 INITIALIZE_PASS(CFGPrinterLegacyPass, "dot-cfg", "Print CFG of function to 'dot' file", 
121                 false, true)
122
123 PreservedAnalyses CFGPrinterPass::run(Function &F,
124                                       FunctionAnalysisManager &AM) {
125   writeCFGToDotFile(F);
126   return PreservedAnalyses::all();
127 }
128
129 namespace {
130   struct CFGOnlyPrinterLegacyPass : public FunctionPass {
131     static char ID; // Pass identification, replacement for typeid
132     CFGOnlyPrinterLegacyPass() : FunctionPass(ID) {
133       initializeCFGOnlyPrinterLegacyPassPass(*PassRegistry::getPassRegistry());
134     }
135
136     bool runOnFunction(Function &F) override {
137       writeCFGToDotFile(F);
138       return false;
139     }
140     void print(raw_ostream &OS, const Module* = nullptr) const override {}
141
142     void getAnalysisUsage(AnalysisUsage &AU) const override {
143       AU.setPreservesAll();
144     }
145   };
146 }
147
148 char CFGOnlyPrinterLegacyPass::ID = 0;
149 INITIALIZE_PASS(CFGOnlyPrinterLegacyPass, "dot-cfg-only",
150    "Print CFG of function to 'dot' file (with no function bodies)",
151    false, true)
152
153 PreservedAnalyses CFGOnlyPrinterPass::run(Function &F,
154                                           FunctionAnalysisManager &AM) {
155   writeCFGToDotFile(F);
156   return PreservedAnalyses::all();
157 }
158
159 /// viewCFG - This function is meant for use from the debugger.  You can just
160 /// say 'call F->viewCFG()' and a ghostview window should pop up from the
161 /// program, displaying the CFG of the current function.  This depends on there
162 /// being a 'dot' and 'gv' program in your path.
163 ///
164 void Function::viewCFG() const {
165   ViewGraph(this, "cfg" + getName());
166 }
167
168 /// viewCFGOnly - This function is meant for use from the debugger.  It works
169 /// just like viewCFG, but it does not include the contents of basic blocks
170 /// into the nodes, just the label.  If you are only interested in the CFG
171 /// this can make the graph smaller.
172 ///
173 void Function::viewCFGOnly() const {
174   ViewGraph(this, "cfg" + getName(), true);
175 }
176
177 FunctionPass *llvm::createCFGPrinterLegacyPassPass () {
178   return new CFGPrinterLegacyPass();
179 }
180
181 FunctionPass *llvm::createCFGOnlyPrinterLegacyPassPass () {
182   return new CFGOnlyPrinterLegacyPass();
183 }
184