blob: 674f689a685d4100fe32905869ff3585ac7dbe16 [file] [log] [blame]
Chris Lattner78925492003-09-20 01:20:46 +00001//===- DSGraphStats.cpp - Various statistics for DS Graphs ----------------===//
Vikram S. Adve586aa3c2002-11-13 15:41:00 +00002//
3//===----------------------------------------------------------------------===//
4
5#include "llvm/Analysis/DataStructure.h"
6#include "llvm/Analysis/DSGraph.h"
7#include "llvm/Function.h"
8#include "llvm/iOther.h"
Chris Lattner78925492003-09-20 01:20:46 +00009#include "llvm/iMemory.h"
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000010#include "llvm/Pass.h"
Chris Lattner78925492003-09-20 01:20:46 +000011#include "llvm/Support/InstVisitor.h"
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000012#include "Support/Statistic.h"
13#include <vector>
14
15namespace {
Chris Lattnered806bf2002-11-17 22:17:12 +000016 Statistic<> TotalNumCallees("totalcallees",
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000017 "Total number of callee functions at all indirect call sites");
18 Statistic<> NumIndirectCalls("numindirect",
19 "Total number of indirect call sites in the program");
20 Statistic<> NumPoolNodes("numpools",
21 "Number of allocation nodes that could be pool allocated");
22
Chris Lattner78925492003-09-20 01:20:46 +000023 // Typed/Untyped memory accesses: If DSA can infer that the types the loads
24 // and stores are accessing are correct (ie, the node has not been collapsed),
25 // increment the appropriate counter.
26 Statistic<> NumTypedMemAccesses("numtypedmemaccesses",
27 "Number of loads/stores which are fully typed");
28 Statistic<> NumUntypedMemAccesses("numuntypedmemaccesses",
29 "Number of loads/stores which are untyped");
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000030
Chris Lattner78925492003-09-20 01:20:46 +000031 class DSGraphStats : public FunctionPass, public InstVisitor<DSGraphStats> {
32 void countCallees(const Function &F);
33 const DSGraph *TDGraph;
34
35 DSNode *getNodeForValue(Value *V);
Chris Lattner192cd9c2003-09-20 16:12:57 +000036 bool isNodeForValueCollapsed(Value *V);
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000037 public:
38 /// Driver functions to compute the Load/Store Dep. Graph per function.
39 bool runOnFunction(Function& F);
40
41 /// getAnalysisUsage - This modify nothing, and uses the Top-Down Graph.
42 void getAnalysisUsage(AnalysisUsage &AU) const {
43 AU.setPreservesAll();
44 AU.addRequired<TDDataStructures>();
45 }
46
Chris Lattner78925492003-09-20 01:20:46 +000047 void visitLoad(LoadInst &LI);
48 void visitStore(StoreInst &SI);
49
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000050 /// Debugging support methods
51 void print(std::ostream &O) const { }
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000052 };
53
54 static RegisterAnalysis<DSGraphStats> Z("dsstats", "DS Graph Statistics");
55}
56
Chris Lattnered806bf2002-11-17 22:17:12 +000057static bool isIndirectCallee(Value *V) {
58 if (isa<Function>(V)) return false;
59
60 if (CastInst *CI = dyn_cast<CastInst>(V))
61 return isIndirectCallee(CI->getOperand(0));
62 return true;
63}
64
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000065
Chris Lattner78925492003-09-20 01:20:46 +000066void DSGraphStats::countCallees(const Function& F) {
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000067 unsigned numIndirectCalls = 0, totalNumCallees = 0;
68
Chris Lattner78925492003-09-20 01:20:46 +000069 const std::vector<DSCallSite> &callSites = TDGraph->getFunctionCalls();
70 for (unsigned i = 0, N = callSites.size(); i != N; ++i)
71 if (isIndirectCallee(callSites[i].getCallInst().getCalledValue())) {
72 // This is an indirect function call
73 const std::vector<GlobalValue*> &Callees =
74 callSites[i].getCalleeNode()->getGlobals();
75 if (Callees.size() > 0) {
76 totalNumCallees += Callees.size();
77 ++numIndirectCalls;
78 } else
79 std::cerr << "WARNING: No callee in Function " << F.getName()
80 << "at call:\n" << callSites[i].getCallInst();
81 }
82
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000083 TotalNumCallees += totalNumCallees;
84 NumIndirectCalls += numIndirectCalls;
Chris Lattner78925492003-09-20 01:20:46 +000085
Chris Lattnered806bf2002-11-17 22:17:12 +000086 if (numIndirectCalls)
87 std::cout << " In function " << F.getName() << ": "
88 << (totalNumCallees / (double) numIndirectCalls)
89 << " average callees per indirect call\n";
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000090}
91
Chris Lattner78925492003-09-20 01:20:46 +000092DSNode *DSGraphStats::getNodeForValue(Value *V) {
93 const DSGraph *G = TDGraph;
Chris Lattner192cd9c2003-09-20 16:12:57 +000094 if (isa<GlobalValue>(V) || isa<Constant>(V))
Chris Lattner78925492003-09-20 01:20:46 +000095 G = TDGraph->getGlobalsGraph();
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000096
Chris Lattner192cd9c2003-09-20 16:12:57 +000097 const DSGraph::ScalarMapTy &ScalarMap = G->getScalarMap();
98 DSGraph::ScalarMapTy::const_iterator I = ScalarMap.find(V);
99 if (I != ScalarMap.end())
100 return I->second.getNode();
101 return 0;
102}
103
104bool DSGraphStats::isNodeForValueCollapsed(Value *V) {
105 if (DSNode *N = getNodeForValue(V))
106 return N->isNodeCompletelyFolded();
107 return false;
Vikram S. Adve586aa3c2002-11-13 15:41:00 +0000108}
109
Chris Lattner78925492003-09-20 01:20:46 +0000110void DSGraphStats::visitLoad(LoadInst &LI) {
Chris Lattner192cd9c2003-09-20 16:12:57 +0000111 if (isNodeForValueCollapsed(LI.getOperand(0))) {
Chris Lattner78925492003-09-20 01:20:46 +0000112 NumUntypedMemAccesses++;
113 } else {
114 NumTypedMemAccesses++;
115 }
116}
117
118void DSGraphStats::visitStore(StoreInst &SI) {
Chris Lattner192cd9c2003-09-20 16:12:57 +0000119 if (isNodeForValueCollapsed(SI.getOperand(1))) {
Chris Lattner78925492003-09-20 01:20:46 +0000120 NumUntypedMemAccesses++;
121 } else {
122 NumTypedMemAccesses++;
123 }
124}
125
126
127
128bool DSGraphStats::runOnFunction(Function& F) {
129 TDGraph = &getAnalysis<TDDataStructures>().getDSGraph(F);
130 countCallees(F);
131 visit(F);
132 return true;
Vikram S. Adve586aa3c2002-11-13 15:41:00 +0000133}