Rewrite DSAA::getModRefInfo to compute the mapping between caller and callee

to determine mod/ref behavior, instead of creating a *copy* of the caller
graph and inlining the callee graph into the copy.

This speeds up aa-eval on Ptrdist/yacr2 from 109.13s to 3.98s, and gives
identical results.  The speedup is similar on other programs.

llvm-svn: 20669
This commit is contained in:
Chris Lattner 2005-03-18 00:21:03 +00:00
parent b8d85c1a74
commit 3f181d7880
1 changed files with 46 additions and 23 deletions

View File

@ -125,15 +125,14 @@ AliasAnalysis::AliasResult DSAA::alias(const Value *V1, unsigned V1Size,
const DSGraph::ScalarMapTy &GSM = G.getScalarMap();
DSGraph::ScalarMapTy::const_iterator I = GSM.find((Value*)V1);
if (I == GSM.end()) return NoAlias;
assert(I->second.getNode() && "Scalar map points to null node?");
DSGraph::ScalarMapTy::const_iterator J = GSM.find((Value*)V2);
if (J == GSM.end()) return NoAlias;
assert(J->second.getNode() && "Scalar map points to null node?");
DSNode *N1 = I->second.getNode(), *N2 = J->second.getNode();
unsigned O1 = I->second.getOffset(), O2 = J->second.getOffset();
if (N1 == 0 || N2 == 0)
return MayAlias; // Can't tell whether anything aliases null.
// We can only make a judgment of one of the nodes is complete...
if (N1->isComplete() || N2->isComplete()) {
@ -181,32 +180,56 @@ DSAA::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
if (!F || F->isExternal() || Result == NoModRef)
return Result;
// Clone the function TD graph, clearing off Mod/Ref flags
const Function *csParent = CS.getInstruction()->getParent()->getParent();
DSGraph TDGraph(TD->getDSGraph(*csParent));
TDGraph.maskNodeTypes(~(DSNode::Modified|DSNode::Read));
// Insert the callee's BU graph into the TD graph
const DSGraph &BUGraph = BU->getDSGraph(*F);
TDGraph.mergeInGraph(TDGraph.getDSCallSiteForCallSite(CS),
*F, BUGraph, 0);
// Get the graphs for the callee and caller. Note that we want the BU graph
// for the callee because we don't want all caller's effects incorporated!
const Function *Caller = CS.getInstruction()->getParent()->getParent();
DSGraph &CallerTDGraph = TD->getDSGraph(*Caller);
DSGraph &CalleeBUGraph = BU->getDSGraph(*F);
// Report the flags that have been added
const DSNodeHandle &DSH = TDGraph.getNodeForValue(P);
if (const DSNode *N = DSH.getNode()) {
if (!N->isModified()) // We proved it was not modified.
Result = ModRefResult(Result & ~Mod);
if (!N->isRead()) // We proved it was not read.
Result = ModRefResult(Result & ~Ref);
} else {
// Figure out which node in the TD graph this pointer corresponds to.
DSScalarMap &CallerSM = CallerTDGraph.getScalarMap();
DSScalarMap::iterator NI = CallerSM.find(P);
if (NI == CallerSM.end()) {
if (isa<ConstantPointerNull>(P))
Result = NoModRef;
else
Result = NoModRef; // null is never modified :)
else {
assert(isa<GlobalVariable>(P) &&
cast<GlobalVariable>(P)->getType()->getElementType()->isFirstClassType() &&
"This isn't a global that DSA inconsiderately dropped "
"from the graph?");
}
return Result;
}
const DSNode *N = NI->second.getNode();
assert(N && "Null pointer in scalar map??");
// Compute the mapping from nodes in the callee graph to the nodes in the
// caller graph for this call site.
DSGraph::NodeMapTy CalleeCallerMap;
DSCallSite DSCS = CallerTDGraph.getDSCallSiteForCallSite(CS);
CallerTDGraph.computeCalleeCallerMapping(DSCS, *F, CalleeBUGraph,
CalleeCallerMap);
// Loop over all of the nodes in the callee that correspond to "N", keeping
// track of aggregate mod/ref info.
bool NeverReads = true, NeverWrites = true;
for (DSGraph::NodeMapTy::iterator I = CalleeCallerMap.begin(),
E = CalleeCallerMap.end(); I != E; ++I)
if (I->second.getNode() == N) {
if (I->first->isModified())
NeverWrites = false;
if (I->first->isRead())
NeverReads = false;
if (NeverReads == false && NeverWrites == false)
return Result;
}
if (NeverWrites) // We proved it was not modified.
Result = ModRefResult(Result & ~Mod);
if (NeverReads) // We proved it was not read.
Result = ModRefResult(Result & ~Ref);
return Result;
}