Gives the count for various instructions.
[oota-llvm.git] / lib / Analysis / InstCount.cpp
1 //===-- InstCount.cpp - Collects the count of all instructions ------------===//
2 //
3 // This pass collects the count of all instructions and reports them 
4 //
5 //
6 //===----------------------------------------------------------------------===//
7
8 #include "llvm/Pass.h"
9 #include "llvm/Module.h"
10 #include "llvm/iMemory.h"
11 #include "llvm/iTerminators.h"
12 #include "llvm/iPHINode.h"
13 #include "llvm/iOther.h"
14 #include "llvm/iOperators.h"
15 #include "llvm/Support/InstVisitor.h"
16 #include "llvm/Support/InstIterator.h"
17 #include "llvm/Support/InstIterator.h"
18 #include "Support/Statistic.h"
19 #include <algorithm>
20
21 namespace {
22   static Statistic<> NumReturnInst("instcount","Number of ReturnInsts");
23   static Statistic<> NumBranchInst("instcount", "Number of BranchInsts");
24   static Statistic<> NumPHINode("instcount", "Number of PHINodes");
25   static Statistic<> NumCastInst("instcount", "Number of CastInsts");
26   static Statistic<> NumCallInst("instcount", "Number of CallInsts");
27   static Statistic<> NumMallocInst("instcount", "Number of MallocInsts");
28   static Statistic<> NumAllocaInst("instcount", "Number of AllocaInsts");
29   static Statistic<> NumFreeInst("instcount", "Number of FreeInsts");
30   static Statistic<> NumLoadInst("instcount", "Number of LoadInsts");
31   static Statistic<> NumStoreInst("instcount", "Number of StoreInsts");
32   static Statistic<> NumGetElementPtrInst("instcount",
33                                           "Number of GetElementPtrInsts");
34                                                      
35   static Statistic<> NumSwitchInst("instcount", "Number of SwitchInsts");
36   static Statistic<> NumInvokeInst("instcount", "Number of InvokeInsts");
37   static Statistic<> NumBinaryOperator("instcount",
38                                        "Total Number of BinaryOperators");
39                                                           
40   static Statistic<> NumShiftInst("instcount", " Total Number of ShiftInsts");
41   static Statistic<> NumShlInst("instcount", "Number of Left ShiftInsts");
42                                                            
43   static Statistic<> NumShrInst("instcount", "Number of Right ShiftInsts");
44                                                                 
45
46   static Statistic<> NumAddInst("instcount", "Number of AddInsts");
47   static Statistic<> NumSubInst("instcount", "Number of SubInsts");
48   static Statistic<> NumMulInst("instcount", "Number of MulInsts");
49   static Statistic<> NumDivInst("instcount", "Number of DivInsts");
50   static Statistic<> NumRemInst("instcount", "Number of RemInsts");
51   static Statistic<> NumAndInst("instcount", "Number of AndInsts");
52   static Statistic<> NumOrInst("instcount", "Number of OrInsts");
53   static Statistic<> NumXorInst("instcount", "Number of XorInsts");
54   static Statistic<> NumSetCondInst("instcount", "Total Number of SetCondInsts");
55   static Statistic<> NumSetEQInst("instcount", "Number of SetEQInsts");
56   static Statistic<> NumSetNEInst("instcount", "Number of SetNEInsts");
57   static Statistic<> NumSetLEInst("instcount", "Number of SetLEInsts");
58   static Statistic<> NumSetGEInst("instcount", "Number of SetGEInsts");
59   static Statistic<> NumSetLTInst("instcount", "Number of SetLTInsts");
60   static Statistic<> NumSetGTInst("instcount", "Number of SetGTInsts");
61   
62   class InstCount : public Pass, public InstVisitor<InstCount> {
63   private:
64         friend class InstVisitor<InstCount>;
65
66
67     void visitBinaryOperator(BinaryOperator &I);
68     void visitShiftInst(ShiftInst &I);
69     void visitSetCondInst(SetCondInst &I);
70     
71     inline void visitSwitchInst(SwitchInst &I) { NumSwitchInst++; }
72     inline void visitInvokeInst(InvokeInst &I) { NumInvokeInst++; }
73     inline void visitReturnInst(ReturnInst &I) { NumReturnInst++; }
74     inline void visitBranchInst(BranchInst &I) { NumBranchInst++; }
75     inline void visitPHINode(PHINode &I) { NumPHINode++; }
76     inline void visitCastInst (CastInst &I) { NumCastInst++; }
77     inline void visitCallInst (CallInst &I) { NumCastInst++; }
78     inline void visitMallocInst(MallocInst &I) { NumMallocInst++; }
79     inline void visitAllocaInst(AllocaInst &I) { NumAllocaInst++; }
80     inline void visitFreeInst  (FreeInst   &I) { NumFreeInst++; }
81     inline void visitLoadInst  (LoadInst   &I) { NumLoadInst++; }
82     inline void visitStoreInst (StoreInst  &I) { NumStoreInst++; }
83     inline void visitGetElementPtrInst(GetElementPtrInst &I) {
84       NumGetElementPtrInst++; }
85
86     inline void visitInstruction(Instruction &I) {
87       std::cerr << "Instruction Count does not know about " << I;
88       abort();
89     }
90   public:
91     virtual bool run(Module &M);
92
93     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
94       AU.setPreservesAll();
95     }
96   };
97
98   RegisterOpt<InstCount> X("instcount",
99                            "Counts the various types of Instructions");
100                                                             
101 }
102
103 // createInstCountPass - The public interface to this file...
104 Pass *createInstCountPass() { return new InstCount(); }
105
106
107 // InstCount::run - This is the main Analysis entry point for a
108 // function.
109 //
110 bool InstCount::run(Module &M) {
111     /* Initialization */
112   NumReturnInst = 0;
113   NumBranchInst = 0;
114   NumPHINode = 0;
115   NumCastInst = 0;
116   NumCallInst = 0;
117   NumMallocInst = 0;
118   NumAllocaInst = 0;
119   NumFreeInst = 0;
120   NumLoadInst = 0;
121   NumStoreInst = 0;
122   NumGetElementPtrInst = 0;
123   NumSwitchInst = 0;
124   NumInvokeInst = 0;
125   NumBinaryOperator = 0;
126   NumShiftInst = 0;
127   NumShlInst = 0;
128   NumShrInst = 0;
129   NumAddInst = 0;
130   NumSubInst = 0;
131   NumMulInst = 0;
132   NumDivInst = 0;
133   NumRemInst = 0;
134   NumAndInst = 0;
135   NumOrInst = 0;
136   NumXorInst = 0;
137   NumSetCondInst = 0;
138   NumSetEQInst = 0;
139   NumSetNEInst = 0;
140   NumSetLEInst = 0;
141   NumSetGEInst = 0;
142   NumSetLTInst = 0;
143   NumSetGTInst = 0;
144
145   for (Module::iterator mI = M.begin(), mE = M.end(); mI != mE; ++mI)
146     for (inst_iterator I = inst_begin(*mI), E = inst_end(*mI); I != E; ++I)
147       visit(*I);
148   return false;
149 }
150
151
152
153 void InstCount::visitBinaryOperator(BinaryOperator &I) {
154   NumBinaryOperator++;
155   switch (I.getOpcode()) {
156   case Instruction::Add: NumAddInst++; break;
157   case Instruction::Sub: NumSubInst++; break;
158   case Instruction::Mul: NumMulInst++; break;
159   case Instruction::Div: NumDivInst++; break;
160   case Instruction::Rem: NumRemInst++; break;
161   case Instruction::And: NumAndInst++; break;
162   case Instruction::Or: NumOrInst++; break;
163   case Instruction::Xor: NumXorInst++; break;
164   default : std::cerr<< " Wrong binary operator \n";
165   }
166 }
167
168 void InstCount::visitSetCondInst(SetCondInst &I) {
169   NumBinaryOperator++;
170   NumSetCondInst++;
171   switch (I.getOpcode()) {
172   case Instruction::SetEQ: NumSetEQInst++; break;
173   case Instruction::SetNE: NumSetNEInst++; break;
174   case Instruction::SetLE: NumSetLEInst++; break;
175   case Instruction::SetGE: NumSetGEInst++; break;
176   case Instruction::SetLT: NumSetLTInst++; break;
177   case Instruction::SetGT: NumSetGTInst++; break;
178   default : std::cerr<< " Wrong SetCond Inst \n";
179   }
180 }
181
182 void InstCount::visitShiftInst(ShiftInst &I) { 
183   NumShiftInst++;
184   switch (I.getOpcode()) {
185   case Instruction::Shl: NumShlInst++; break;
186   case Instruction::Shr: NumShrInst++; break;
187   default : std::cerr<< " Wrong ShiftInst \n";
188   }
189 }