blob: c2ca7ea37c3c11a098714ebb2e53bff939bba1f3 [file] [log] [blame]
Vikram S. Adve586aa3c2002-11-13 15:41:00 +00001//===- 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
13namespace {
Chris Lattnered806bf2002-11-17 22:17:12 +000014 Statistic<> TotalNumCallees("totalcallees",
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000015 "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
Chris Lattnered806bf2002-11-17 22:17:12 +000042static 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
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000050
Chris Lattner923fc052003-02-05 21:59:58 +000051void DSGraphStats::countCallees(const Function& F, const DSGraph& tdGraph) {
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000052 unsigned numIndirectCalls = 0, totalNumCallees = 0;
53
54 const std::vector<DSCallSite>& callSites = tdGraph.getFunctionCalls();
55 for (unsigned i=0, N = callSites.size(); i < N; ++i)
Chris Lattnered806bf2002-11-17 22:17:12 +000056 if (isIndirectCallee(callSites[i].getCallInst().getCalledValue()))
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000057 { // This is an indirect function call
58 std::vector<GlobalValue*> Callees =
Chris Lattner923fc052003-02-05 21:59:58 +000059 callSites[i].getCalleeNode()->getGlobals();
60 if (Callees.size() > 0) {
61 totalNumCallees += Callees.size();
62 ++numIndirectCalls;
63 }
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000064#ifndef NDEBUG
65 else
66 std::cerr << "WARNING: No callee in Function " << F.getName()
67 << "at call:\n" << callSites[i].getCallInst();
68#endif
69 }
70
71 TotalNumCallees += totalNumCallees;
72 NumIndirectCalls += numIndirectCalls;
73
Chris Lattnered806bf2002-11-17 22:17:12 +000074 if (numIndirectCalls)
75 std::cout << " In function " << F.getName() << ": "
76 << (totalNumCallees / (double) numIndirectCalls)
77 << " average callees per indirect call\n";
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000078}
79
80
Chris Lattner923fc052003-02-05 21:59:58 +000081bool DSGraphStats::runOnFunction(Function& F) {
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000082 const DSGraph& tdGraph = getAnalysis<TDDataStructures>().getDSGraph(F);
83 countCallees(F, tdGraph);
84 return true;
85}
86
87void DSGraphStats::dump() const
88{
89 this->print(std::cerr);
90}