Make analyze use the Pass repository to populate it's command line argument list
[oota-llvm.git] / tools / analyze / analyze.cpp
1 //===----------------------------------------------------------------------===//
2 // The LLVM analyze utility
3 //
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 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/Module.h"
14 #include "llvm/iPHINode.h"
15 #include "llvm/Type.h"
16 #include "llvm/PassManager.h"
17 #include "llvm/Bytecode/Reader.h"
18 #include "llvm/Assembly/Parser.h"
19 #include "llvm/Assembly/PrintModulePass.h"
20 #include "llvm/Assembly/Writer.h"
21 #include "llvm/Analysis/InstForest.h"
22 #include "llvm/Analysis/Expressions.h"
23 #include "llvm/Analysis/InductionVariable.h"
24 #include "llvm/Support/InstIterator.h"
25 #include "llvm/Support/PassNameParser.h"
26 #include <algorithm>
27
28 using std::ostream;
29
30 #if 0
31
32 template <class PassType, class PassName>
33 class PassPrinter;  // Do not implement
34
35 template <class PassName>
36 class PassPrinter<Pass, PassName> : public Pass {
37   const AnalysisID ID;
38 public:
39   PassPrinter(AnalysisID id) : ID(id) {}
40
41   const char *getPassName() const { return "IP Pass Printer"; }
42   
43   virtual bool run(Module &M) {
44     printPass(getAnalysis<PassName>(ID), std::cout, M);
45     return false;
46   }
47
48   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
49     AU.addRequired(ID);
50   }
51 };
52
53 template <class PassName>
54 class PassPrinter<FunctionPass, PassName> : public FunctionPass {
55   const AnalysisID ID;
56 public:
57   PassPrinter(AnalysisID id) : ID(id) {}
58
59     const char *getPassName() const { return "Function Pass Printer"; }
60   
61   virtual bool runOnFunction(Function &F) {
62     std::cout << "Running on function '" << F.getName() << "'\n";
63     printPass(getAnalysis<PassName>(ID), std::cout, F);
64     return false;
65   }
66
67   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
68     AU.addRequired(ID);
69     AU.setPreservesAll();
70   }
71 };
72
73
74 struct InstForestHelper : public FunctionPass {
75   const char *getPassName() const { return "InstForest Printer"; }
76
77   void doit(Function &F) {
78     std::cout << InstForest<char>(&F);
79   }
80
81   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
82     AU.setPreservesAll();
83   }
84 };
85
86 struct IndVars : public FunctionPass {
87   const char *getPassName() const { return "IndVars Printer"; }
88
89   void doit(Function &F) {
90     LoopInfo &LI = getAnalysis<LoopInfo>();
91     for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
92       if (PHINode *PN = dyn_cast<PHINode>(*I)) {
93         InductionVariable IV(PN, &LI);
94         if (IV.InductionType != InductionVariable::Unknown)
95           IV.print(std::cout);
96       }
97   }
98
99   void getAnalysisUsage(AnalysisUsage &AU) const {
100     AU.addRequired(LoopInfo::ID);
101     AU.setPreservesAll();
102   }
103 };
104
105 struct Exprs : public FunctionPass {
106   const char *getPassName() const { return "Expression Printer"; }
107
108   static void doit(Function &F) {
109     std::cout << "Classified expressions for: " << F.getName() << "\n";
110     for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
111       std::cout << *I;
112       
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       
117       std::cout << "\t\tExpr =";
118       switch (R.ExprTy) {
119       case analysis::ExprType::ScaledLinear:
120         WriteAsOperand(std::cout << "(", (Value*)R.Scale) << " ) *";
121         // fall through
122       case analysis::ExprType::Linear:
123         WriteAsOperand(std::cout << "(", R.Var) << " )";
124         if (R.Offset == 0) break;
125         else std::cout << " +";
126         // fall through
127       case analysis::ExprType::Constant:
128         if (R.Offset) WriteAsOperand(std::cout, (Value*)R.Offset);
129         else std::cout << " 0";
130         break;
131       }
132       std::cout << "\n\n";
133     }
134   }
135   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
136     AU.setPreservesAll();
137   }
138 };
139 #endif
140
141 struct ModulePassPrinter : public Pass {
142   Pass *PassToPrint;
143   ModulePassPrinter(Pass *PI) : PassToPrint(PI) {}
144
145   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...
151     return false;
152   }
153 };
154
155 struct FunctionPassPrinter : public FunctionPass {
156   const PassInfo *PassToPrint;
157   FunctionPassPrinter(const PassInfo *PI) : PassToPrint(PI) {}
158
159   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());
163
164     // Get and print pass...
165     return false;
166   }
167
168   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
169     AU.addRequired(PassToPrint);
170     AU.setPreservesAll();
171   }
172 };
173
174 struct 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
196 static cl::opt<std::string>
197 InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"),
198               cl::value_desc("filename"));
199
200 static cl::opt<bool> Quiet("q", cl::desc("Don't print analysis pass names"));
201 static cl::alias    QuietA("quiet", cl::desc("Alias for -q"),
202                            cl::aliasopt(Quiet));
203
204 // The AnalysesList is automatically populated with registered Passes by the
205 // PassNameParser.
206 //
207 static cl::list<const PassInfo*, bool,
208                 FilteredPassNameParser<PassInfo::Analysis> >
209 AnalysesList(cl::desc("Analyses available:"));
210
211
212 int main(int argc, char **argv) {
213   cl::ParseCommandLineOptions(argc, argv, " llvm analysis printer tool\n");
214
215   Module *CurMod = 0;
216   try {
217     CurMod = ParseBytecodeFile(InputFilename);
218     if (!CurMod && !(CurMod = ParseAssemblyFile(InputFilename))){
219       std::cerr << "Input file didn't read correctly.\n";
220       return 1;
221     }
222   } catch (const ParseException &E) {
223     std::cerr << E.getMessage() << "\n";
224     return 1;
225   }
226
227   // Create a PassManager to hold and optimize the collection of passes we are
228   // about to build...
229   //
230   PassManager Passes;
231
232   // Create a new optimization pass for each one specified on the command line
233   for (unsigned i = 0; i < AnalysesList.size(); ++i) {
234     const PassInfo *Analysis = AnalysesList[i];
235     
236     if (Analysis->getNormalCtor()) {
237       Pass *P = Analysis->getNormalCtor()();
238       Passes.add(P);
239
240       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));
246
247     } else
248       cerr << "Cannot create pass: " << Analysis->getPassName() << "\n";
249   }
250
251   Passes.run(*CurMod);
252
253   delete CurMod;
254   return 0;
255 }