blob: 887eb7f550a0339de12faac9034fc4030d6fbea9 [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);
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000036 public:
37 /// Driver functions to compute the Load/Store Dep. Graph per function.
38 bool runOnFunction(Function& F);
39
40 /// getAnalysisUsage - This modify nothing, and uses the Top-Down Graph.
41 void getAnalysisUsage(AnalysisUsage &AU) const {
42 AU.setPreservesAll();
43 AU.addRequired<TDDataStructures>();
44 }
45
Chris Lattner78925492003-09-20 01:20:46 +000046 void visitLoad(LoadInst &LI);
47 void visitStore(StoreInst &SI);
48
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000049 /// Debugging support methods
50 void print(std::ostream &O) const { }
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000051 };
52
53 static RegisterAnalysis<DSGraphStats> Z("dsstats", "DS Graph Statistics");
54}
55
Chris Lattnered806bf2002-11-17 22:17:12 +000056static bool isIndirectCallee(Value *V) {
57 if (isa<Function>(V)) return false;
58
59 if (CastInst *CI = dyn_cast<CastInst>(V))
60 return isIndirectCallee(CI->getOperand(0));
61 return true;
62}
63
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000064
Chris Lattner78925492003-09-20 01:20:46 +000065void DSGraphStats::countCallees(const Function& F) {
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000066 unsigned numIndirectCalls = 0, totalNumCallees = 0;
67
Chris Lattner78925492003-09-20 01:20:46 +000068 const std::vector<DSCallSite> &callSites = TDGraph->getFunctionCalls();
69 for (unsigned i = 0, N = callSites.size(); i != N; ++i)
70 if (isIndirectCallee(callSites[i].getCallInst().getCalledValue())) {
71 // This is an indirect function call
72 const std::vector<GlobalValue*> &Callees =
73 callSites[i].getCalleeNode()->getGlobals();
74 if (Callees.size() > 0) {
75 totalNumCallees += Callees.size();
76 ++numIndirectCalls;
77 } else
78 std::cerr << "WARNING: No callee in Function " << F.getName()
79 << "at call:\n" << callSites[i].getCallInst();
80 }
81
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000082 TotalNumCallees += totalNumCallees;
83 NumIndirectCalls += numIndirectCalls;
Chris Lattner78925492003-09-20 01:20:46 +000084
Chris Lattnered806bf2002-11-17 22:17:12 +000085 if (numIndirectCalls)
86 std::cout << " In function " << F.getName() << ": "
87 << (totalNumCallees / (double) numIndirectCalls)
88 << " average callees per indirect call\n";
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000089}
90
Chris Lattner78925492003-09-20 01:20:46 +000091DSNode *DSGraphStats::getNodeForValue(Value *V) {
92 const DSGraph *G = TDGraph;
93 if (isa<GlobalValue>(V))
94 G = TDGraph->getGlobalsGraph();
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000095
Chris Lattner78925492003-09-20 01:20:46 +000096 return G->getNodeForValue(V).getNode();
Vikram S. Adve586aa3c2002-11-13 15:41:00 +000097}
98
Chris Lattner78925492003-09-20 01:20:46 +000099void DSGraphStats::visitLoad(LoadInst &LI) {
100 if (getNodeForValue(LI.getOperand(0))->isNodeCompletelyFolded()) {
101 NumUntypedMemAccesses++;
102 } else {
103 NumTypedMemAccesses++;
104 }
105}
106
107void DSGraphStats::visitStore(StoreInst &SI) {
108 if (getNodeForValue(SI.getOperand(1))->isNodeCompletelyFolded()) {
109 NumUntypedMemAccesses++;
110 } else {
111 NumTypedMemAccesses++;
112 }
113}
114
115
116
117bool DSGraphStats::runOnFunction(Function& F) {
118 TDGraph = &getAnalysis<TDDataStructures>().getDSGraph(F);
119 countCallees(F);
120 visit(F);
121 return true;
Vikram S. Adve586aa3c2002-11-13 15:41:00 +0000122}