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