blob: d9423e4c65ebfd98c66ebddbfce83c72444db8e6 [file] [log] [blame]
Chris Lattnerfa6db4b2002-01-31 00:46:09 +00001//===----------------------------------------------------------------------===//
Chris Lattner4ec35ab2002-04-28 16:21:53 +00002// The LLVM analyze utility
Chris Lattnerf3dc2c92001-07-03 15:30:38 +00003//
4// This utility is designed to print out the results of running various analysis
5// passes on a program. This is useful for understanding a program, or for
6// debugging an analysis pass.
7//
8// analyze --help - Output information about command line switches
9// analyze --quiet - Do not print analysis name before output
10//
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000011//===----------------------------------------------------------------------===//
Chris Lattnerf3dc2c92001-07-03 15:30:38 +000012
Chris Lattnerf3dc2c92001-07-03 15:30:38 +000013#include "llvm/Module.h"
Chris Lattnerdf89f6e2001-12-03 17:27:42 +000014#include "llvm/iPHINode.h"
Chris Lattner8bfa89c2002-04-08 22:04:24 +000015#include "llvm/Type.h"
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000016#include "llvm/PassManager.h"
Chris Lattnerf3dc2c92001-07-03 15:30:38 +000017#include "llvm/Bytecode/Reader.h"
18#include "llvm/Assembly/Parser.h"
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000019#include "llvm/Assembly/PrintModulePass.h"
Chris Lattner8bfa89c2002-04-08 22:04:24 +000020#include "llvm/Assembly/Writer.h"
Chris Lattnerb3122592001-09-14 01:42:42 +000021#include "llvm/Analysis/InstForest.h"
Chris Lattner1546bff2001-07-20 19:16:29 +000022#include "llvm/Analysis/Expressions.h"
Chris Lattner75deac62001-11-26 19:18:11 +000023#include "llvm/Analysis/InductionVariable.h"
Chris Lattner221d6882002-02-12 21:07:25 +000024#include "llvm/Support/InstIterator.h"
Chris Lattner9a740fd2002-07-27 01:08:50 +000025#include "llvm/Support/PassNameParser.h"
Chris Lattnerc4199ec2001-09-28 00:07:36 +000026#include <algorithm>
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000027
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000028using std::ostream;
Chris Lattnerf3dc2c92001-07-03 15:30:38 +000029
Chris Lattner9a740fd2002-07-27 01:08:50 +000030#if 0
Chris Lattner1546bff2001-07-20 19:16:29 +000031
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000032template <class PassType, class PassName>
33class PassPrinter; // Do not implement
34
35template <class PassName>
36class PassPrinter<Pass, PassName> : public Pass {
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000037 const AnalysisID ID;
38public:
Chris Lattner50e3f882002-07-22 02:10:07 +000039 PassPrinter(AnalysisID id) : ID(id) {}
Chris Lattner96c466b2002-04-29 14:57:45 +000040
41 const char *getPassName() const { return "IP Pass Printer"; }
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000042
Chris Lattner0b12b5f2002-06-25 16:13:21 +000043 virtual bool run(Module &M) {
Chris Lattnerbc132d62002-03-26 22:43:12 +000044 printPass(getAnalysis<PassName>(ID), std::cout, M);
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000045 return false;
Chris Lattner1546bff2001-07-20 19:16:29 +000046 }
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000047
Chris Lattnerf57b8452002-04-27 06:56:12 +000048 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
49 AU.addRequired(ID);
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000050 }
51};
52
53template <class PassName>
Chris Lattnerf57b8452002-04-27 06:56:12 +000054class PassPrinter<FunctionPass, PassName> : public FunctionPass {
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000055 const AnalysisID ID;
56public:
Chris Lattner50e3f882002-07-22 02:10:07 +000057 PassPrinter(AnalysisID id) : ID(id) {}
Chris Lattner96c466b2002-04-29 14:57:45 +000058
59 const char *getPassName() const { return "Function Pass Printer"; }
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000060
Chris Lattner0b12b5f2002-06-25 16:13:21 +000061 virtual bool runOnFunction(Function &F) {
Chris Lattner50e3f882002-07-22 02:10:07 +000062 std::cout << "Running on function '" << F.getName() << "'\n";
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000063 printPass(getAnalysis<PassName>(ID), std::cout, F);
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000064 return false;
65 }
66
Chris Lattnerf57b8452002-04-27 06:56:12 +000067 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
68 AU.addRequired(ID);
Chris Lattner97e52e42002-04-28 21:27:06 +000069 AU.setPreservesAll();
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000070 }
71};
72
73
Chris Lattnerfbaed2e2002-04-29 18:13:31 +000074struct InstForestHelper : public FunctionPass {
Chris Lattner96c466b2002-04-29 14:57:45 +000075 const char *getPassName() const { return "InstForest Printer"; }
76
Chris Lattner0b12b5f2002-06-25 16:13:21 +000077 void doit(Function &F) {
78 std::cout << InstForest<char>(&F);
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000079 }
Chris Lattner97e52e42002-04-28 21:27:06 +000080
81 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
82 AU.setPreservesAll();
83 }
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000084};
85
Chris Lattnerf57b8452002-04-27 06:56:12 +000086struct IndVars : public FunctionPass {
Chris Lattner96c466b2002-04-29 14:57:45 +000087 const char *getPassName() const { return "IndVars Printer"; }
88
Chris Lattner0b12b5f2002-06-25 16:13:21 +000089 void doit(Function &F) {
Chris Lattner4ec35ab2002-04-28 16:21:53 +000090 LoopInfo &LI = getAnalysis<LoopInfo>();
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000091 for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000092 if (PHINode *PN = dyn_cast<PHINode>(*I)) {
93 InductionVariable IV(PN, &LI);
94 if (IV.InductionType != InductionVariable::Unknown)
Chris Lattner9a740fd2002-07-27 01:08:50 +000095 IV.print(std::cout);
Chris Lattnerfa6db4b2002-01-31 00:46:09 +000096 }
97 }
98
Chris Lattnerf57b8452002-04-27 06:56:12 +000099 void getAnalysisUsage(AnalysisUsage &AU) const {
Chris Lattner4ec35ab2002-04-28 16:21:53 +0000100 AU.addRequired(LoopInfo::ID);
Chris Lattner97e52e42002-04-28 21:27:06 +0000101 AU.setPreservesAll();
Chris Lattnerfa6db4b2002-01-31 00:46:09 +0000102 }
103};
104
Chris Lattnerf57b8452002-04-27 06:56:12 +0000105struct Exprs : public FunctionPass {
Chris Lattner96c466b2002-04-29 14:57:45 +0000106 const char *getPassName() const { return "Expression Printer"; }
107
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000108 static void doit(Function &F) {
109 std::cout << "Classified expressions for: " << F.getName() << "\n";
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000110 for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
Chris Lattnerbc132d62002-03-26 22:43:12 +0000111 std::cout << *I;
Chris Lattnerfa6db4b2002-01-31 00:46:09 +0000112
113 if ((*I)->getType() == Type::VoidTy) continue;
114 analysis::ExprType R = analysis::ClassifyExpression(*I);
115 if (R.Var == *I) continue; // Doesn't tell us anything
116
Chris Lattnerbc132d62002-03-26 22:43:12 +0000117 std::cout << "\t\tExpr =";
Chris Lattnerfa6db4b2002-01-31 00:46:09 +0000118 switch (R.ExprTy) {
119 case analysis::ExprType::ScaledLinear:
Chris Lattnerbc132d62002-03-26 22:43:12 +0000120 WriteAsOperand(std::cout << "(", (Value*)R.Scale) << " ) *";
Chris Lattnerfa6db4b2002-01-31 00:46:09 +0000121 // fall through
122 case analysis::ExprType::Linear:
Chris Lattnerbc132d62002-03-26 22:43:12 +0000123 WriteAsOperand(std::cout << "(", R.Var) << " )";
Chris Lattnerfa6db4b2002-01-31 00:46:09 +0000124 if (R.Offset == 0) break;
Chris Lattnerbc132d62002-03-26 22:43:12 +0000125 else std::cout << " +";
Chris Lattnerfa6db4b2002-01-31 00:46:09 +0000126 // fall through
127 case analysis::ExprType::Constant:
Chris Lattnerbc132d62002-03-26 22:43:12 +0000128 if (R.Offset) WriteAsOperand(std::cout, (Value*)R.Offset);
129 else std::cout << " 0";
Chris Lattnerfa6db4b2002-01-31 00:46:09 +0000130 break;
131 }
Chris Lattnerbc132d62002-03-26 22:43:12 +0000132 std::cout << "\n\n";
Chris Lattnerdf89f6e2001-12-03 17:27:42 +0000133 }
Chris Lattnerfa6db4b2002-01-31 00:46:09 +0000134 }
Chris Lattner97e52e42002-04-28 21:27:06 +0000135 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
136 AU.setPreservesAll();
137 }
Chris Lattnerfa6db4b2002-01-31 00:46:09 +0000138};
Chris Lattner9a740fd2002-07-27 01:08:50 +0000139#endif
Chris Lattner75deac62001-11-26 19:18:11 +0000140
Chris Lattner9a740fd2002-07-27 01:08:50 +0000141struct ModulePassPrinter : public Pass {
142 Pass *PassToPrint;
143 ModulePassPrinter(Pass *PI) : PassToPrint(PI) {}
Chris Lattner75deac62001-11-26 19:18:11 +0000144
Chris Lattner9a740fd2002-07-27 01:08:50 +0000145 virtual bool run(Module &M) {
146 std::cout << "Printing Analysis info for Pass "
147 << PassToPrint->getPassName() << ":\n";
148 PassToPrint->print(std::cout, &M);
149
150 // Get and print pass...
Chris Lattnerfa6db4b2002-01-31 00:46:09 +0000151 return false;
152 }
153};
154
Chris Lattner9a740fd2002-07-27 01:08:50 +0000155struct FunctionPassPrinter : public FunctionPass {
156 const PassInfo *PassToPrint;
157 FunctionPassPrinter(const PassInfo *PI) : PassToPrint(PI) {}
Chris Lattnerfa6db4b2002-01-31 00:46:09 +0000158
Chris Lattner9a740fd2002-07-27 01:08:50 +0000159 virtual bool runOnFunction(Function &F) {
160 std::cout << "Printing Analysis info for function '" << F.getName()
161 << "': Pass " << PassToPrint->getPassName() << ":\n";
162 getAnalysis<Pass>(PassToPrint).print(std::cout, F.getParent());
Chris Lattnerc13aff62001-07-06 16:59:10 +0000163
Chris Lattner9a740fd2002-07-27 01:08:50 +0000164 // Get and print pass...
165 return false;
166 }
Chris Lattnerc13aff62001-07-06 16:59:10 +0000167
Chris Lattner9a740fd2002-07-27 01:08:50 +0000168 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
169 AU.addRequired(PassToPrint);
170 AU.setPreservesAll();
171 }
Chris Lattner8f367bd2001-07-23 02:35:57 +0000172};
173
Chris Lattner9a740fd2002-07-27 01:08:50 +0000174struct BasicBlockPassPrinter : public BasicBlockPass {
175 const PassInfo *PassToPrint;
176 BasicBlockPassPrinter(const PassInfo *PI) : PassToPrint(PI) {}
177
178 virtual bool runOnBasicBlock(BasicBlock &BB) {
179 std::cout << "Printing Analysis info for BasicBlock '" << BB.getName()
180 << "': Pass " << PassToPrint->getPassName() << ":\n";
181 getAnalysis<Pass>(PassToPrint).print(std::cout, BB.getParent()->getParent());
182
183 // Get and print pass...
184 return false;
185 }
186
187 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
188 AU.addRequired(PassToPrint);
189 AU.setPreservesAll();
190 }
191};
192
193
194
195
Chris Lattner98ad7e92002-07-25 16:31:01 +0000196static cl::opt<std::string>
Chris Lattner50e3f882002-07-22 02:10:07 +0000197InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"),
198 cl::value_desc("filename"));
199
200static cl::opt<bool> Quiet("q", cl::desc("Don't print analysis pass names"));
201static cl::alias QuietA("quiet", cl::desc("Alias for -q"),
202 cl::aliasopt(Quiet));
203
Chris Lattner9a740fd2002-07-27 01:08:50 +0000204// The AnalysesList is automatically populated with registered Passes by the
205// PassNameParser.
206//
207static cl::list<const PassInfo*, bool,
208 FilteredPassNameParser<PassInfo::Analysis> >
209AnalysesList(cl::desc("Analyses available:"));
Chris Lattnerfa6db4b2002-01-31 00:46:09 +0000210
Chris Lattnerf3dc2c92001-07-03 15:30:38 +0000211
212int main(int argc, char **argv) {
Chris Lattner8f367bd2001-07-23 02:35:57 +0000213 cl::ParseCommandLineOptions(argc, argv, " llvm analysis printer tool\n");
Chris Lattnerf3dc2c92001-07-03 15:30:38 +0000214
Chris Lattnerbc132d62002-03-26 22:43:12 +0000215 Module *CurMod = 0;
Chris Lattner7d922622002-02-01 05:09:35 +0000216 try {
Chris Lattnerbc132d62002-03-26 22:43:12 +0000217 CurMod = ParseBytecodeFile(InputFilename);
218 if (!CurMod && !(CurMod = ParseAssemblyFile(InputFilename))){
Chris Lattner7d922622002-02-01 05:09:35 +0000219 std::cerr << "Input file didn't read correctly.\n";
220 return 1;
221 }
222 } catch (const ParseException &E) {
Chris Lattner5b077b02002-02-24 23:25:24 +0000223 std::cerr << E.getMessage() << "\n";
Chris Lattnerc13aff62001-07-06 16:59:10 +0000224 return 1;
Chris Lattnerf3dc2c92001-07-03 15:30:38 +0000225 }
226
Chris Lattnerfa6db4b2002-01-31 00:46:09 +0000227 // Create a PassManager to hold and optimize the collection of passes we are
228 // about to build...
229 //
Chris Lattner9a740fd2002-07-27 01:08:50 +0000230 PassManager Passes;
Chris Lattnerfa6db4b2002-01-31 00:46:09 +0000231
Chris Lattner9a740fd2002-07-27 01:08:50 +0000232 // Create a new optimization pass for each one specified on the command line
Chris Lattnerc4199ec2001-09-28 00:07:36 +0000233 for (unsigned i = 0; i < AnalysesList.size(); ++i) {
Chris Lattner9a740fd2002-07-27 01:08:50 +0000234 const PassInfo *Analysis = AnalysesList[i];
235
236 if (Analysis->getNormalCtor()) {
237 Pass *P = Analysis->getNormalCtor()();
238 Passes.add(P);
Chris Lattnerc4199ec2001-09-28 00:07:36 +0000239
Chris Lattner9a740fd2002-07-27 01:08:50 +0000240 if (BasicBlockPass *BBP = dynamic_cast<BasicBlockPass*>(P))
241 Passes.add(new BasicBlockPassPrinter(Analysis));
242 else if (FunctionPass *FP = dynamic_cast<FunctionPass*>(P))
243 Passes.add(new FunctionPassPrinter(Analysis));
244 else
245 Passes.add(new ModulePassPrinter(P));
Chris Lattnerc4199ec2001-09-28 00:07:36 +0000246
Chris Lattner9a740fd2002-07-27 01:08:50 +0000247 } else
248 cerr << "Cannot create pass: " << Analysis->getPassName() << "\n";
249 }
250
251 Passes.run(*CurMod);
Chris Lattnerf3dc2c92001-07-03 15:30:38 +0000252
Chris Lattnerbc132d62002-03-26 22:43:12 +0000253 delete CurMod;
Chris Lattnerf3dc2c92001-07-03 15:30:38 +0000254 return 0;
255}