diff options
Diffstat (limited to 'lib/Analysis/DataStructure/DataStructureAA.cpp')
| -rw-r--r-- | lib/Analysis/DataStructure/DataStructureAA.cpp | 26 | 
1 files changed, 25 insertions, 1 deletions
| diff --git a/lib/Analysis/DataStructure/DataStructureAA.cpp b/lib/Analysis/DataStructure/DataStructureAA.cpp index 65bdc6e2f2..6f1cb56d86 100644 --- a/lib/Analysis/DataStructure/DataStructureAA.cpp +++ b/lib/Analysis/DataStructure/DataStructureAA.cpp @@ -178,9 +178,33 @@ DSAA::getModRefInfo(CallSite CS, Value *P, unsigned Size) {    AliasAnalysis::ModRefResult Result =AliasAnalysis::getModRefInfo(CS, P, Size);    Function *F = CS.getCalledFunction(); -  if (!F || F->isExternal() || Result == NoModRef) +  if (!F || Result == NoModRef)      return Result; +  if (F->isExternal()) { +    // If we are calling an external function, and if this global doesn't escape +    // the portion of the program we have analyzed, we can draw conclusions +    // based on whether the global escapes the program. +    Function *Caller = CS.getInstruction()->getParent()->getParent(); +    DSGraph *G = &TD->getDSGraph(*Caller); +    DSScalarMap::iterator NI = G->getScalarMap().find(P); +    if (NI == G->getScalarMap().end()) { +      // If it wasn't in the local function graph, check the global graph.  This +      // can occur for globals who are locally reference but hoisted out to the +      // globals graph despite that. +      G = G->getGlobalsGraph(); +      NI = G->getScalarMap().find(P); +      if (NI == G->getScalarMap().end()) +        return Result; +    } + +    // If we found a node and it's complete, it cannot be passed out to the +    // called function. +    if (NI->second.getNode()->isComplete()) +      return NoModRef; +    return Result; +  } +    // 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(); | 
