1 //===- DSGraphStats.cpp - Various statistics for DS Graphs ----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 //===----------------------------------------------------------------------===//
12 #include "llvm/Analysis/DataStructure.h"
13 #include "llvm/Analysis/DSGraph.h"
14 #include "llvm/Function.h"
15 #include "llvm/iOther.h"
16 #include "llvm/iMemory.h"
17 #include "llvm/Pass.h"
18 #include "llvm/Support/InstVisitor.h"
19 #include "Support/Statistic.h"
24 Statistic<> TotalNumCallees("totalcallees",
25 "Total number of callee functions at all indirect call sites");
26 Statistic<> NumIndirectCalls("numindirect",
27 "Total number of indirect call sites in the program");
28 Statistic<> NumPoolNodes("numpools",
29 "Number of allocation nodes that could be pool allocated");
31 // Typed/Untyped memory accesses: If DSA can infer that the types the loads
32 // and stores are accessing are correct (ie, the node has not been collapsed),
33 // increment the appropriate counter.
34 Statistic<> NumTypedMemAccesses("numtypedmemaccesses",
35 "Number of loads/stores which are fully typed");
36 Statistic<> NumUntypedMemAccesses("numuntypedmemaccesses",
37 "Number of loads/stores which are untyped");
39 class DSGraphStats : public FunctionPass, public InstVisitor<DSGraphStats> {
40 void countCallees(const Function &F);
41 const DSGraph *TDGraph;
43 DSNode *getNodeForValue(Value *V);
44 bool isNodeForValueCollapsed(Value *V);
46 /// Driver functions to compute the Load/Store Dep. Graph per function.
47 bool runOnFunction(Function& F);
49 /// getAnalysisUsage - This modify nothing, and uses the Top-Down Graph.
50 void getAnalysisUsage(AnalysisUsage &AU) const {
52 AU.addRequired<TDDataStructures>();
55 void visitLoad(LoadInst &LI);
56 void visitStore(StoreInst &SI);
58 /// Debugging support methods
59 void print(std::ostream &O) const { }
62 static RegisterAnalysis<DSGraphStats> Z("dsstats", "DS Graph Statistics");
65 static bool isIndirectCallee(Value *V) {
66 if (isa<Function>(V)) return false;
68 if (CastInst *CI = dyn_cast<CastInst>(V))
69 return isIndirectCallee(CI->getOperand(0));
74 void DSGraphStats::countCallees(const Function& F) {
75 unsigned numIndirectCalls = 0, totalNumCallees = 0;
77 const std::vector<DSCallSite> &callSites = TDGraph->getFunctionCalls();
78 for (unsigned i = 0, N = callSites.size(); i != N; ++i)
79 if (isIndirectCallee(callSites[i].getCallSite().getCalledValue())) {
80 // This is an indirect function call
81 const std::vector<GlobalValue*> &Callees =
82 callSites[i].getCalleeNode()->getGlobals();
83 if (Callees.size() > 0) {
84 totalNumCallees += Callees.size();
87 std::cerr << "WARNING: No callee in Function '" << F.getName()
89 << *callSites[i].getCallSite().getInstruction();
92 TotalNumCallees += totalNumCallees;
93 NumIndirectCalls += numIndirectCalls;
96 std::cout << " In function " << F.getName() << ": "
97 << (totalNumCallees / (double) numIndirectCalls)
98 << " average callees per indirect call\n";
101 DSNode *DSGraphStats::getNodeForValue(Value *V) {
102 const DSGraph *G = TDGraph;
103 if (isa<GlobalValue>(V) || isa<Constant>(V))
104 G = TDGraph->getGlobalsGraph();
106 const DSGraph::ScalarMapTy &ScalarMap = G->getScalarMap();
107 DSGraph::ScalarMapTy::const_iterator I = ScalarMap.find(V);
108 if (I != ScalarMap.end())
109 return I->second.getNode();
113 bool DSGraphStats::isNodeForValueCollapsed(Value *V) {
114 if (DSNode *N = getNodeForValue(V))
115 return N->isNodeCompletelyFolded() || N->isIncomplete();
119 void DSGraphStats::visitLoad(LoadInst &LI) {
120 if (isNodeForValueCollapsed(LI.getOperand(0))) {
121 NumUntypedMemAccesses++;
123 NumTypedMemAccesses++;
127 void DSGraphStats::visitStore(StoreInst &SI) {
128 if (isNodeForValueCollapsed(SI.getOperand(1))) {
129 NumUntypedMemAccesses++;
131 NumTypedMemAccesses++;
137 bool DSGraphStats::runOnFunction(Function& F) {
138 TDGraph = &getAnalysis<TDDataStructures>().getDSGraph(F);