Fix uninitialized variable
[llvm-core.git] / lib / Analysis / CFGPrinter.cpp
blob6d01e9d5d447b3a0f81bbe53d8bffa3f4ac2720a
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.
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.
19 //===----------------------------------------------------------------------===//
21 #include "llvm/Analysis/CFGPrinter.h"
22 #include "llvm/Pass.h"
23 #include "llvm/Support/FileSystem.h"
24 using namespace llvm;
26 static cl::opt<std::string> CFGFuncName(
27 "cfg-func-name", cl::Hidden,
28 cl::desc("The name of a function (or its substring)"
29 " whose CFG is viewed/printed."));
31 static cl::opt<std::string> CFGDotFilenamePrefix(
32 "cfg-dot-filename-prefix", cl::Hidden,
33 cl::desc("The prefix used for the CFG dot file names."));
35 namespace {
36 struct CFGViewerLegacyPass : public FunctionPass {
37 static char ID; // Pass identifcation, replacement for typeid
38 CFGViewerLegacyPass() : FunctionPass(ID) {
39 initializeCFGViewerLegacyPassPass(*PassRegistry::getPassRegistry());
42 bool runOnFunction(Function &F) override {
43 F.viewCFG();
44 return false;
47 void print(raw_ostream &OS, const Module* = nullptr) const override {}
49 void getAnalysisUsage(AnalysisUsage &AU) const override {
50 AU.setPreservesAll();
55 char CFGViewerLegacyPass::ID = 0;
56 INITIALIZE_PASS(CFGViewerLegacyPass, "view-cfg", "View CFG of function", false, true)
58 PreservedAnalyses CFGViewerPass::run(Function &F,
59 FunctionAnalysisManager &AM) {
60 F.viewCFG();
61 return PreservedAnalyses::all();
65 namespace {
66 struct CFGOnlyViewerLegacyPass : public FunctionPass {
67 static char ID; // Pass identifcation, replacement for typeid
68 CFGOnlyViewerLegacyPass() : FunctionPass(ID) {
69 initializeCFGOnlyViewerLegacyPassPass(*PassRegistry::getPassRegistry());
72 bool runOnFunction(Function &F) override {
73 F.viewCFGOnly();
74 return false;
77 void print(raw_ostream &OS, const Module* = nullptr) const override {}
79 void getAnalysisUsage(AnalysisUsage &AU) const override {
80 AU.setPreservesAll();
85 char CFGOnlyViewerLegacyPass::ID = 0;
86 INITIALIZE_PASS(CFGOnlyViewerLegacyPass, "view-cfg-only",
87 "View CFG of function (with no function bodies)", false, true)
89 PreservedAnalyses CFGOnlyViewerPass::run(Function &F,
90 FunctionAnalysisManager &AM) {
91 F.viewCFGOnly();
92 return PreservedAnalyses::all();
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 << "'...";
102 std::error_code EC;
103 raw_fd_ostream File(Filename, EC, sys::fs::F_Text);
105 if (!EC)
106 WriteGraph(File, (const Function*)&F, CFGOnly);
107 else
108 errs() << " error opening file for writing!";
109 errs() << "\n";
112 namespace {
113 struct CFGPrinterLegacyPass : public FunctionPass {
114 static char ID; // Pass identification, replacement for typeid
115 CFGPrinterLegacyPass() : FunctionPass(ID) {
116 initializeCFGPrinterLegacyPassPass(*PassRegistry::getPassRegistry());
119 bool runOnFunction(Function &F) override {
120 writeCFGToDotFile(F);
121 return false;
124 void print(raw_ostream &OS, const Module* = nullptr) const override {}
126 void getAnalysisUsage(AnalysisUsage &AU) const override {
127 AU.setPreservesAll();
132 char CFGPrinterLegacyPass::ID = 0;
133 INITIALIZE_PASS(CFGPrinterLegacyPass, "dot-cfg", "Print CFG of function to 'dot' file",
134 false, true)
136 PreservedAnalyses CFGPrinterPass::run(Function &F,
137 FunctionAnalysisManager &AM) {
138 writeCFGToDotFile(F);
139 return PreservedAnalyses::all();
142 namespace {
143 struct CFGOnlyPrinterLegacyPass : public FunctionPass {
144 static char ID; // Pass identification, replacement for typeid
145 CFGOnlyPrinterLegacyPass() : FunctionPass(ID) {
146 initializeCFGOnlyPrinterLegacyPassPass(*PassRegistry::getPassRegistry());
149 bool runOnFunction(Function &F) override {
150 writeCFGToDotFile(F, /*CFGOnly=*/true);
151 return false;
153 void print(raw_ostream &OS, const Module* = nullptr) const override {}
155 void getAnalysisUsage(AnalysisUsage &AU) const override {
156 AU.setPreservesAll();
161 char CFGOnlyPrinterLegacyPass::ID = 0;
162 INITIALIZE_PASS(CFGOnlyPrinterLegacyPass, "dot-cfg-only",
163 "Print CFG of function to 'dot' file (with no function bodies)",
164 false, true)
166 PreservedAnalyses CFGOnlyPrinterPass::run(Function &F,
167 FunctionAnalysisManager &AM) {
168 writeCFGToDotFile(F, /*CFGOnly=*/true);
169 return PreservedAnalyses::all();
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.
177 void Function::viewCFG() const {
178 if (!CFGFuncName.empty() && !getName().contains(CFGFuncName))
179 return;
180 ViewGraph(this, "cfg" + getName());
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.
188 void Function::viewCFGOnly() const {
189 if (!CFGFuncName.empty() && !getName().contains(CFGFuncName))
190 return;
191 ViewGraph(this, "cfg" + getName(), true);
194 FunctionPass *llvm::createCFGPrinterLegacyPassPass () {
195 return new CFGPrinterLegacyPass();
198 FunctionPass *llvm::createCFGOnlyPrinterLegacyPassPass () {
199 return new CFGOnlyPrinterLegacyPass();