[llvm-commits] [poolalloc] r98921 - in /poolalloc/trunk: include/dsa/DSCallGraph.h lib/DSA/BottomUpClosure.cpp lib/DSA/DSCallGraph.cpp lib/DSA/DSGraph.cpp lib/DSA/Local.cpp
Andrew Lenharth
andrewl at lenharth.org
Thu Mar 18 19:58:30 PDT 2010
Author: alenhar2
Date: Thu Mar 18 21:58:30 2010
New Revision: 98921
URL: http://llvm.org/viewvc/llvm-project?rev=98921&view=rev
Log:
remove callnodes condition implemented for partial-knowledge inlining. Also add some stats to see if the results are believable
Modified:
poolalloc/trunk/include/dsa/DSCallGraph.h
poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
poolalloc/trunk/lib/DSA/DSCallGraph.cpp
poolalloc/trunk/lib/DSA/DSGraph.cpp
poolalloc/trunk/lib/DSA/Local.cpp
Modified: poolalloc/trunk/include/dsa/DSCallGraph.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSCallGraph.h?rev=98921&r1=98920&r2=98921&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSCallGraph.h (original)
+++ poolalloc/trunk/include/dsa/DSCallGraph.h Thu Mar 18 21:58:30 2010
@@ -68,7 +68,9 @@
typedef llvm::EquivalenceClasses<const llvm::Function*>::member_iterator scc_iterator;
void insert(llvm::CallSite CS, const llvm::Function* F);
-
+
+ void insureEntry(const llvm::Function* F);
+
template<class Iterator>
void insert(llvm::CallSite CS, Iterator _begin, Iterator _end) {
for (; _begin != _end; ++_begin)
@@ -153,6 +155,10 @@
return sum;
}
+ unsigned flat_size() const {
+ return SimpleCallees.size();
+ }
+
void buildSCCs();
void buildRoots();
Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=98921&r1=98920&r2=98921&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Thu Mar 18 21:58:30 2010
@@ -29,6 +29,9 @@
STATISTIC (NumInlines, "Number of graphs inlined");
STATISTIC (NumCallEdges, "Number of 'actual' call edges");
STATISTIC (NumSCCMerges, "Number of SCC merges");
+ STATISTIC (NumIndResolved, "Number of resolved IndCalls");
+ STATISTIC (NumIndUnresolved, "Number of unresolved IndCalls");
+ STATISTIC (NumEmptyCalls, "Number of calls we know nothing about");
RegisterPass<BUDataStructures>
X("dsa-bu", "Bottom-up Data Structure Analysis");
@@ -269,6 +272,9 @@
}
}
+
+//Inline all graphs in the callgraph, remove callsites that are completely dealt
+//with
void BUDataStructures::calculateGraph(DSGraph* Graph) {
DEBUG(Graph->AssertGraphOK(); Graph->getGlobalsGraph()->AssertGraphOK());
@@ -297,14 +303,11 @@
std::list<DSCallSite> &AuxCallsList = Graph->getAuxFunctionCalls();
TempFCs.swap(AuxCallsList);
- std::vector<const Function*> CalledFuncs;
while (!TempFCs.empty()) {
DEBUG(Graph->AssertGraphOK(); Graph->getGlobalsGraph()->AssertGraphOK());
DSCallSite &CS = *TempFCs.begin();
- CalledFuncs.clear();
-
// Fast path for noop calls. Note that we don't care about merging globals
// in the callee with nodes in the caller here.
if (CS.getRetVal().isNull() && CS.getNumPtrArgs() == 0) {
@@ -312,21 +315,51 @@
continue;
}
- std::copy(callgraph.callee_begin(CS.getCallSite()),
- callgraph.callee_end(CS.getCallSite()),
- std::back_inserter(CalledFuncs));
-
- std::vector<const Function*>::iterator ErasePoint =
- std::remove_if(CalledFuncs.begin(), CalledFuncs.end(),
- std::mem_fun(&Function::isDeclaration));
- CalledFuncs.erase(ErasePoint, CalledFuncs.end());
+ std::vector<const Function*> CalledFuncs;
+ //Get the callees from the callgraph
+ {
+ std::copy(callgraph.callee_begin(CS.getCallSite()),
+ callgraph.callee_end(CS.getCallSite()),
+ std::back_inserter(CalledFuncs));
+
+ std::vector<const Function*>::iterator ErasePoint =
+ std::remove_if(CalledFuncs.begin(), CalledFuncs.end(),
+ std::mem_fun(&Function::isDeclaration));
+ CalledFuncs.erase(ErasePoint, CalledFuncs.end());
+ }
if (CalledFuncs.empty()) {
+ ++NumEmptyCalls;
// Remember that we could not resolve this yet!
AuxCallsList.splice(AuxCallsList.end(), TempFCs, TempFCs.begin());
continue;
}
+ //Direct calls are always inlined and removed from AuxCalls
+ //Indirect calls are removed if the callnode is complete and the callnode's
+ //functions set is a subset of the Calls from the callgraph
+ //We only inline from the callgraph (which is immutable during this phase
+ //of bu) so as to not introduce SCCs and still be able to inline
+ //aggressively
+ bool eraseCS = true;
+ if (CS.isIndirectCall()) {
+ eraseCS = false;
+ if (CS.getCalleeNode()->isCompleteNode()) {
+ std::vector<const Function*> NodeCallees;
+ CS.getCalleeNode()->addFullFunctionList(NodeCallees);
+ std::vector<const Function*>::iterator ErasePoint =
+ std::remove_if(NodeCallees.begin(), NodeCallees.end(),
+ std::mem_fun(&Function::isDeclaration));
+ NodeCallees.erase(ErasePoint, NodeCallees.end());
+ std::sort(CalledFuncs.begin(), CalledFuncs.end());
+ std::sort(NodeCallees.begin(), NodeCallees.end());
+ eraseCS = std::includes(CalledFuncs.begin(), CalledFuncs.end(),
+ NodeCallees.begin(), NodeCallees.end());
+ }
+ if (eraseCS) ++NumIndResolved;
+ else ++NumIndUnresolved;
+ }
+
DSGraph *GI;
for (unsigned x = 0; x < CalledFuncs.size(); ++x) {
@@ -345,7 +378,10 @@
++NumInlines;
DEBUG(Graph->AssertGraphOK(););
}
- TempFCs.erase(TempFCs.begin());
+ if (eraseCS)
+ TempFCs.erase(TempFCs.begin());
+ else
+ AuxCallsList.splice(AuxCallsList.end(), TempFCs, TempFCs.begin());
}
// Recompute the Incomplete markers
Modified: poolalloc/trunk/lib/DSA/DSCallGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DSCallGraph.cpp?rev=98921&r1=98920&r2=98921&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DSCallGraph.cpp (original)
+++ poolalloc/trunk/lib/DSA/DSCallGraph.cpp Thu Mar 18 21:58:30 2010
@@ -54,16 +54,14 @@
// The edges out of the current node are the call site targets...
for (flat_iterator ii = flat_callee_begin(F),
ee = flat_callee_end(F); ii != ee; ++ii) {
- if (!(*ii)->isDeclaration()) {
- unsigned M = Min;
- // Have we visited the destination function yet?
- TFMap::iterator It = ValMap.find(*ii);
- if (It == ValMap.end()) // No, visit it now.
- M = tarjan_rec(*ii, Stack, NextID, ValMap);
- else if (std::find(Stack.begin(), Stack.end(), *ii) != Stack.end())
- M = It->second;
- if (M < Min) Min = M;
- }
+ unsigned M = Min;
+ // Have we visited the destination function yet?
+ TFMap::iterator It = ValMap.find(*ii);
+ if (It == ValMap.end()) // No, visit it now.
+ M = tarjan_rec(*ii, Stack, NextID, ValMap);
+ else if (std::find(Stack.begin(), Stack.end(), *ii) != Stack.end())
+ M = It->second;
+ if (M < Min) Min = M;
}
assert(ValMap[F] == MyID && "SCC construction assumption wrong!");
@@ -209,11 +207,15 @@
//Filter all call edges. We only want pointer edges.
void DSCallGraph::insert(llvm::CallSite CS, const llvm::Function* F) {
+ //Create an empty set for the callee, hence all called functions get to be
+ // in the call graph also. This simplifies SCC formation
+ SimpleCallees[CS.getInstruction()->getParent()->getParent()];
if (F) {
ActualCallees[CS].insert(F);
SimpleCallees[CS.getInstruction()->getParent()->getParent()].insert(F);
- //Create an empty set for the callee, hence all called functions get to be
- // in the call graph also. This simplifies SCC formation
- SimpleCallees[F];
}
}
+
+void DSCallGraph::insureEntry(const llvm::Function* F) {
+ SimpleCallees[F];
+}
Modified: poolalloc/trunk/lib/DSA/DSGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DSGraph.cpp?rev=98921&r1=98920&r2=98921&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DSGraph.cpp (original)
+++ poolalloc/trunk/lib/DSA/DSGraph.cpp Thu Mar 18 21:58:30 2010
@@ -1267,6 +1267,8 @@
CallSite CS = ii->getCallSite();
std::vector<const Function*> MaybeTargets;
ii->getCalleeNode()->addFullFunctionList(MaybeTargets);
+ //Assure have a record for this callsite
+ DCG.insert(CS, 0);
for (std::vector<const Function*>::iterator Fi = MaybeTargets.begin(),
Fe = MaybeTargets.end(); Fi != Fe; ++Fi)
if (functionIsCallable(CS, *Fi))
Modified: poolalloc/trunk/lib/DSA/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Local.cpp?rev=98921&r1=98920&r2=98921&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Local.cpp (original)
+++ poolalloc/trunk/lib/DSA/Local.cpp Thu Mar 18 21:58:30 2010
@@ -12,6 +12,7 @@
//
//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "dsa-local"
#include "dsa/DataStructure.h"
#include "dsa/DSGraph.h"
#include "llvm/Constants.h"
@@ -38,11 +39,19 @@
using namespace llvm;
-static RegisterPass<LocalDataStructures>
+namespace {
+STATISTIC(NumDirectCall, "Number of direct calls added");
+STATISTIC(NumIndirectCall, "Number of indirect calls added");
+STATISTIC(NumAsmCall, "Number of asm calls collapsed/seen");
+STATISTIC(NumBoringCall, "Number of pointer-free direct calls ignored");
+STATISTIC(NumIntrinsicCall, "Number of intrinsics called");
+
+RegisterPass<LocalDataStructures>
X("dsa-local", "Local Data Structure Analysis");
-static cl::opt<std::string> hasMagicSections("dsa-magic-sections",
- cl::desc("File with section to global mapping")); //, cl::ReallyHidden);
+cl::opt<std::string> hasMagicSections("dsa-magic-sections",
+ cl::desc("File with section to global mapping")); //, cl::ReallyHidden);
+}
namespace {
//===--------------------------------------------------------------------===//
@@ -597,6 +606,7 @@
/// returns true if the intrinsic is handled
bool GraphBuilder::visitIntrinsic(CallSite CS, Function *F) {
+ ++NumIntrinsicCall;
switch (F->getIntrinsicID()) {
case Intrinsic::vastart: {
// Mark the memory written by the vastart intrinsic as incomplete
@@ -751,6 +761,7 @@
//Can't do much about inline asm (yet!)
if (isa<InlineAsm>(CS.getCalledValue())) {
+ ++NumAsmCall;
DSNodeHandle RetVal;
Instruction *I = CS.getInstruction();
if (isa<PointerType > (I->getType()))
@@ -766,15 +777,10 @@
}
//uninteresting direct call
- if (CS.getCalledFunction() && !DSCallGraph::hasPointers(CS))
+ if (CS.getCalledFunction() && !DSCallGraph::hasPointers(CS)) {
+ ++NumBoringCall;
return;
-
-
-// if (InlineAsm* IASM = dyn_cast<InlineAsm>(CS.getCalledValue())) {
-// if (IASM->hasSideEffects())
-// errs() << ASM w/ Side Effects\n";
-// return;
-// }
+ }
// Set up the return value...
DSNodeHandle RetVal;
@@ -806,11 +812,13 @@
// Add a new function call entry...
if (CalleeNode) {
+ ++NumIndirectCall;
G.getFunctionCalls().push_back(DSCallSite(CS, RetVal, CalleeNode, Args));
-// DS->callee_site(CS.getInstruction());
- }else
+ } else {
+ ++NumDirectCall;
G.getFunctionCalls().push_back(DSCallSite(CS, RetVal, cast<Function>(Callee),
Args));
+ }
}
// visitInstruction - For all other instruction types, if we have any arguments
@@ -970,11 +978,10 @@
G->getAuxFunctionCalls() = G->getFunctionCalls();
setDSGraph(*I, G);
propagateUnknownFlag(G);
+ callgraph.insureEntry(I);
G->buildCallGraph(callgraph);
}
-
-
GlobalsGraph->removeTriviallyDeadNodes();
GlobalsGraph->markIncompleteNodes(DSGraph::MarkFormalArgs);
More information about the llvm-commits
mailing list