1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
//===----------------------------------------------------------------------===//
// The LLVM analyze utility
//
// This utility is designed to print out the results of running various analysis
// passes on a program. This is useful for understanding a program, or for
// debugging an analysis pass.
//
// analyze --help - Output information about command line switches
// analyze --quiet - Do not print analysis name before output
//
//===----------------------------------------------------------------------===//
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Bytecode/Reader.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/Support/PassNameParser.h"
#include <algorithm>
struct ModulePassPrinter : public Pass {
const PassInfo *PassToPrint;
ModulePassPrinter(const PassInfo *PI) : PassToPrint(PI) {}
virtual bool run(Module &M) {
std::cout << "Printing Analysis info for Pass "
<< PassToPrint->getPassName() << ":\n";
getAnalysis<Pass>(PassToPrint).print(std::cout, &M);
// Get and print pass...
return false;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired(PassToPrint);
AU.setPreservesAll();
}
};
struct FunctionPassPrinter : public FunctionPass {
const PassInfo *PassToPrint;
FunctionPassPrinter(const PassInfo *PI) : PassToPrint(PI) {}
virtual bool runOnFunction(Function &F) {
std::cout << "Printing Analysis info for function '" << F.getName()
<< "': Pass " << PassToPrint->getPassName() << ":\n";
getAnalysis<Pass>(PassToPrint).print(std::cout, F.getParent());
// Get and print pass...
return false;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired(PassToPrint);
AU.setPreservesAll();
}
};
struct BasicBlockPassPrinter : public BasicBlockPass {
const PassInfo *PassToPrint;
BasicBlockPassPrinter(const PassInfo *PI) : PassToPrint(PI) {}
virtual bool runOnBasicBlock(BasicBlock &BB) {
std::cout << "Printing Analysis info for BasicBlock '" << BB.getName()
<< "': Pass " << PassToPrint->getPassName() << ":\n";
getAnalysis<Pass>(PassToPrint).print(std::cout, BB.getParent()->getParent());
// Get and print pass...
return false;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired(PassToPrint);
AU.setPreservesAll();
}
};
static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"),
cl::value_desc("filename"));
static cl::opt<bool> Quiet("q", cl::desc("Don't print analysis pass names"));
static cl::alias QuietA("quiet", cl::desc("Alias for -q"),
cl::aliasopt(Quiet));
// The AnalysesList is automatically populated with registered Passes by the
// PassNameParser.
//
static cl::list<const PassInfo*, bool,
FilteredPassNameParser<PassInfo::Analysis> >
AnalysesList(cl::desc("Analyses available:"));
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm analysis printer tool\n");
Module *CurMod = 0;
try {
CurMod = ParseBytecodeFile(InputFilename);
if (!CurMod && !(CurMod = ParseAssemblyFile(InputFilename))){
std::cerr << argv[0] << ": input file didn't read correctly.\n";
return 1;
}
} catch (const ParseException &E) {
std::cerr << argv[0] << ": " << E.getMessage() << "\n";
return 1;
}
// Create a PassManager to hold and optimize the collection of passes we are
// about to build...
//
PassManager Passes;
// Create a new optimization pass for each one specified on the command line
for (unsigned i = 0; i < AnalysesList.size(); ++i) {
const PassInfo *Analysis = AnalysesList[i];
if (Analysis->getNormalCtor()) {
Pass *P = Analysis->getNormalCtor()();
Passes.add(P);
if (BasicBlockPass *BBP = dynamic_cast<BasicBlockPass*>(P))
Passes.add(new BasicBlockPassPrinter(Analysis));
else if (FunctionPass *FP = dynamic_cast<FunctionPass*>(P))
Passes.add(new FunctionPassPrinter(Analysis));
else
Passes.add(new ModulePassPrinter(Analysis));
} else
cerr << argv[0] << ": cannot create pass: "
<< Analysis->getPassName() << "\n";
}
Passes.run(*CurMod);
delete CurMod;
return 0;
}
|