2004-07-07 06:32:21 +00:00
|
|
|
//===- DataStructureStats.cpp - Various statistics for DS Graphs ----------===//
|
2005-04-21 21:13:18 +00:00
|
|
|
//
|
2003-10-20 19:43:21 +00:00
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file was developed by the LLVM research group and is distributed under
|
|
|
|
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
2005-04-21 21:13:18 +00:00
|
|
|
//
|
2003-10-20 19:43:21 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
2002-11-13 15:41:00 +00:00
|
|
|
//
|
2004-07-07 06:32:21 +00:00
|
|
|
// This file defines a little pass that prints out statistics for DS Graphs.
|
|
|
|
//
|
2002-11-13 15:41:00 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2004-07-07 06:32:21 +00:00
|
|
|
#include "llvm/Analysis/DataStructure/DataStructure.h"
|
|
|
|
#include "llvm/Analysis/DataStructure/DSGraph.h"
|
2002-11-13 15:41:00 +00:00
|
|
|
#include "llvm/Function.h"
|
2004-07-29 17:05:13 +00:00
|
|
|
#include "llvm/Instructions.h"
|
2002-11-13 15:41:00 +00:00
|
|
|
#include "llvm/Pass.h"
|
2003-09-20 01:20:46 +00:00
|
|
|
#include "llvm/Support/InstVisitor.h"
|
2006-11-28 23:33:06 +00:00
|
|
|
#include "llvm/Support/Streams.h"
|
2004-09-01 22:55:40 +00:00
|
|
|
#include "llvm/ADT/Statistic.h"
|
2006-11-28 23:33:06 +00:00
|
|
|
#include <ostream>
|
2003-11-12 23:11:14 +00:00
|
|
|
using namespace llvm;
|
2003-11-11 22:41:34 +00:00
|
|
|
|
2002-11-13 15:41:00 +00:00
|
|
|
namespace {
|
2002-11-17 22:17:12 +00:00
|
|
|
Statistic<> TotalNumCallees("totalcallees",
|
2002-11-13 15:41:00 +00:00
|
|
|
"Total number of callee functions at all indirect call sites");
|
|
|
|
Statistic<> NumIndirectCalls("numindirect",
|
|
|
|
"Total number of indirect call sites in the program");
|
|
|
|
Statistic<> NumPoolNodes("numpools",
|
|
|
|
"Number of allocation nodes that could be pool allocated");
|
|
|
|
|
2003-09-20 01:20:46 +00:00
|
|
|
// Typed/Untyped memory accesses: If DSA can infer that the types the loads
|
|
|
|
// and stores are accessing are correct (ie, the node has not been collapsed),
|
|
|
|
// increment the appropriate counter.
|
|
|
|
Statistic<> NumTypedMemAccesses("numtypedmemaccesses",
|
|
|
|
"Number of loads/stores which are fully typed");
|
|
|
|
Statistic<> NumUntypedMemAccesses("numuntypedmemaccesses",
|
|
|
|
"Number of loads/stores which are untyped");
|
2002-11-13 15:41:00 +00:00
|
|
|
|
2003-09-20 01:20:46 +00:00
|
|
|
class DSGraphStats : public FunctionPass, public InstVisitor<DSGraphStats> {
|
|
|
|
void countCallees(const Function &F);
|
|
|
|
const DSGraph *TDGraph;
|
|
|
|
|
|
|
|
DSNode *getNodeForValue(Value *V);
|
2003-09-20 16:12:57 +00:00
|
|
|
bool isNodeForValueCollapsed(Value *V);
|
2002-11-13 15:41:00 +00:00
|
|
|
public:
|
|
|
|
/// Driver functions to compute the Load/Store Dep. Graph per function.
|
|
|
|
bool runOnFunction(Function& F);
|
|
|
|
|
|
|
|
/// getAnalysisUsage - This modify nothing, and uses the Top-Down Graph.
|
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const {
|
|
|
|
AU.setPreservesAll();
|
|
|
|
AU.addRequired<TDDataStructures>();
|
|
|
|
}
|
|
|
|
|
2003-09-20 01:20:46 +00:00
|
|
|
void visitLoad(LoadInst &LI);
|
|
|
|
void visitStore(StoreInst &SI);
|
|
|
|
|
2002-11-13 15:41:00 +00:00
|
|
|
/// Debugging support methods
|
2004-12-07 04:03:45 +00:00
|
|
|
void print(std::ostream &O, const Module* = 0) const { }
|
2002-11-13 15:41:00 +00:00
|
|
|
};
|
|
|
|
|
2006-08-27 22:30:17 +00:00
|
|
|
static RegisterPass<DSGraphStats> Z("dsstats", "DS Graph Statistics");
|
2002-11-13 15:41:00 +00:00
|
|
|
}
|
|
|
|
|
2005-10-24 00:38:38 +00:00
|
|
|
FunctionPass *llvm::createDataStructureStatsPass() {
|
|
|
|
return new DSGraphStats();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-11-17 22:17:12 +00:00
|
|
|
static bool isIndirectCallee(Value *V) {
|
|
|
|
if (isa<Function>(V)) return false;
|
|
|
|
|
|
|
|
if (CastInst *CI = dyn_cast<CastInst>(V))
|
|
|
|
return isIndirectCallee(CI->getOperand(0));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2002-11-13 15:41:00 +00:00
|
|
|
|
2003-09-20 01:20:46 +00:00
|
|
|
void DSGraphStats::countCallees(const Function& F) {
|
2002-11-13 15:41:00 +00:00
|
|
|
unsigned numIndirectCalls = 0, totalNumCallees = 0;
|
|
|
|
|
2005-01-30 23:51:02 +00:00
|
|
|
for (DSGraph::fc_iterator I = TDGraph->fc_begin(), E = TDGraph->fc_end();
|
2005-04-21 21:13:18 +00:00
|
|
|
I != E; ++I)
|
2005-01-30 23:51:02 +00:00
|
|
|
if (isIndirectCallee(I->getCallSite().getCalledValue())) {
|
2003-09-20 01:20:46 +00:00
|
|
|
// This is an indirect function call
|
2005-03-20 02:40:27 +00:00
|
|
|
std::vector<Function*> Callees;
|
|
|
|
I->getCalleeNode()->addFullFunctionList(Callees);
|
|
|
|
|
2003-09-20 01:20:46 +00:00
|
|
|
if (Callees.size() > 0) {
|
|
|
|
totalNumCallees += Callees.size();
|
|
|
|
++numIndirectCalls;
|
|
|
|
} else
|
2006-11-28 23:33:06 +00:00
|
|
|
llvm_cerr << "WARNING: No callee in Function '" << F.getName()
|
2003-09-20 16:34:13 +00:00
|
|
|
<< "' at call: \n"
|
2005-01-30 23:51:02 +00:00
|
|
|
<< *I->getCallSite().getInstruction();
|
2003-09-20 01:20:46 +00:00
|
|
|
}
|
2005-04-21 21:13:18 +00:00
|
|
|
|
2002-11-13 15:41:00 +00:00
|
|
|
TotalNumCallees += totalNumCallees;
|
|
|
|
NumIndirectCalls += numIndirectCalls;
|
2005-04-21 21:13:18 +00:00
|
|
|
|
2002-11-17 22:17:12 +00:00
|
|
|
if (numIndirectCalls)
|
2006-11-28 23:33:06 +00:00
|
|
|
llvm_cout << " In function " << F.getName() << ": "
|
2002-11-17 22:17:12 +00:00
|
|
|
<< (totalNumCallees / (double) numIndirectCalls)
|
|
|
|
<< " average callees per indirect call\n";
|
2002-11-13 15:41:00 +00:00
|
|
|
}
|
|
|
|
|
2003-09-20 01:20:46 +00:00
|
|
|
DSNode *DSGraphStats::getNodeForValue(Value *V) {
|
|
|
|
const DSGraph *G = TDGraph;
|
2004-07-18 00:18:30 +00:00
|
|
|
if (isa<Constant>(V))
|
2003-09-20 01:20:46 +00:00
|
|
|
G = TDGraph->getGlobalsGraph();
|
2002-11-13 15:41:00 +00:00
|
|
|
|
2003-09-20 16:12:57 +00:00
|
|
|
const DSGraph::ScalarMapTy &ScalarMap = G->getScalarMap();
|
|
|
|
DSGraph::ScalarMapTy::const_iterator I = ScalarMap.find(V);
|
|
|
|
if (I != ScalarMap.end())
|
|
|
|
return I->second.getNode();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DSGraphStats::isNodeForValueCollapsed(Value *V) {
|
|
|
|
if (DSNode *N = getNodeForValue(V))
|
2003-09-20 21:48:01 +00:00
|
|
|
return N->isNodeCompletelyFolded() || N->isIncomplete();
|
2003-09-20 16:12:57 +00:00
|
|
|
return false;
|
2002-11-13 15:41:00 +00:00
|
|
|
}
|
|
|
|
|
2003-09-20 01:20:46 +00:00
|
|
|
void DSGraphStats::visitLoad(LoadInst &LI) {
|
2003-09-20 16:12:57 +00:00
|
|
|
if (isNodeForValueCollapsed(LI.getOperand(0))) {
|
2003-09-20 01:20:46 +00:00
|
|
|
NumUntypedMemAccesses++;
|
|
|
|
} else {
|
|
|
|
NumTypedMemAccesses++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DSGraphStats::visitStore(StoreInst &SI) {
|
2003-09-20 16:12:57 +00:00
|
|
|
if (isNodeForValueCollapsed(SI.getOperand(1))) {
|
2003-09-20 01:20:46 +00:00
|
|
|
NumUntypedMemAccesses++;
|
|
|
|
} else {
|
|
|
|
NumTypedMemAccesses++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool DSGraphStats::runOnFunction(Function& F) {
|
|
|
|
TDGraph = &getAnalysis<TDDataStructures>().getDSGraph(F);
|
|
|
|
countCallees(F);
|
|
|
|
visit(F);
|
|
|
|
return true;
|
2002-11-13 15:41:00 +00:00
|
|
|
}
|