Start using the new function cloning header
[oota-llvm.git] / lib / Analysis / DataStructure / DataStructureStats.cpp
1 //===- DSGraphStats.cpp - Various statistics for DS Graphs -----*- C++ -*--===//
2 //
3 //===----------------------------------------------------------------------===//
4
5 #include "llvm/Analysis/DataStructure.h"
6 #include "llvm/Analysis/DSGraph.h"
7 #include "llvm/Function.h"
8 #include "llvm/iOther.h"
9 #include "llvm/Pass.h"
10 #include "Support/Statistic.h"
11 #include <vector>
12
13 namespace {
14   Statistic<> TotalNumCallees("totalcallees",
15                 "Total number of callee functions at all indirect call sites");
16   Statistic<> NumIndirectCalls("numindirect",
17                 "Total number of indirect call sites in the program");
18   Statistic<> NumPoolNodes("numpools",
19                   "Number of allocation nodes that could be pool allocated");
20
21   class DSGraphStats: public FunctionPass {
22     void countCallees(const Function& F, const DSGraph& tdGraph);
23
24   public:
25     /// Driver functions to compute the Load/Store Dep. Graph per function.
26     bool runOnFunction(Function& F);
27
28     /// getAnalysisUsage - This modify nothing, and uses the Top-Down Graph.
29     void getAnalysisUsage(AnalysisUsage &AU) const {
30       AU.setPreservesAll();
31       AU.addRequired<TDDataStructures>();
32     }
33
34     /// Debugging support methods
35     void print(std::ostream &O) const { }
36     void dump() const;
37   };
38
39   static RegisterAnalysis<DSGraphStats> Z("dsstats", "DS Graph Statistics");
40 }
41
42 static bool isIndirectCallee(Value *V) {
43   if (isa<Function>(V)) return false;
44
45   if (CastInst *CI = dyn_cast<CastInst>(V))
46     return isIndirectCallee(CI->getOperand(0));
47   return true;
48 }
49
50
51 void DSGraphStats::countCallees(const Function& F,
52                                 const DSGraph& tdGraph)
53 {
54   unsigned numIndirectCalls = 0, totalNumCallees = 0;
55
56   const std::vector<DSCallSite>& callSites = tdGraph.getFunctionCalls();
57   for (unsigned i=0, N = callSites.size(); i < N; ++i)
58     if (isIndirectCallee(callSites[i].getCallInst().getCalledValue()))
59       { // This is an indirect function call
60         std::vector<GlobalValue*> Callees =
61           callSites[i].getCallee().getNode()->getGlobals();
62         if (Callees.size() > 0)
63           {
64             totalNumCallees  += Callees.size();
65             ++numIndirectCalls;
66           }
67 #ifndef NDEBUG
68         else
69           std::cerr << "WARNING: No callee in Function " << F.getName()
70                       << "at call:\n" << callSites[i].getCallInst();
71 #endif
72       }
73
74   TotalNumCallees  += totalNumCallees;
75   NumIndirectCalls += numIndirectCalls;
76
77   if (numIndirectCalls)
78     std::cout << "  In function " << F.getName() << ":  "
79               << (totalNumCallees / (double) numIndirectCalls)
80               << " average callees per indirect call\n";
81 }
82
83
84 bool DSGraphStats::runOnFunction(Function& F)
85 {
86   const DSGraph& tdGraph = getAnalysis<TDDataStructures>().getDSGraph(F);
87   countCallees(F, tdGraph);
88   return true;
89 }
90
91 void DSGraphStats::dump() const
92 {
93   this->print(std::cerr);
94 }