diff options
Diffstat (limited to 'lib/Analysis/DataStructure')
-rw-r--r-- | lib/Analysis/DataStructure/BottomUpClosure.cpp | 48 | ||||
-rw-r--r-- | lib/Analysis/DataStructure/DataStructure.cpp | 52 | ||||
-rw-r--r-- | lib/Analysis/DataStructure/TopDownClosure.cpp | 60 |
3 files changed, 86 insertions, 74 deletions
diff --git a/lib/Analysis/DataStructure/BottomUpClosure.cpp b/lib/Analysis/DataStructure/BottomUpClosure.cpp index 02a9e64408..cbe53ce68e 100644 --- a/lib/Analysis/DataStructure/BottomUpClosure.cpp +++ b/lib/Analysis/DataStructure/BottomUpClosure.cpp @@ -46,29 +46,6 @@ bool BUDataStructures::run(Module &M) { return false; } -// ResolveArguments - Resolve the formal and actual arguments for a function -// call. -// -static void ResolveArguments(DSCallSite &Call, Function &F, - map<Value*, DSNodeHandle> &ScalarMap) { - // Resolve all of the function arguments... - Function::aiterator AI = F.abegin(); - for (unsigned i = 0, e = Call.getNumPtrArgs(); i != e; ++i, ++AI) { - // Advance the argument iterator to the first pointer argument... - while (!isPointerType(AI->getType())) { - ++AI; -#ifndef NDEBUG - if (AI == F.aend()) - std::cerr << "Bad call to Function: " << F.getName() << "\n"; -#endif - assert(AI != F.aend() && "# Args provided is not # Args required!"); - } - - // Add the link from the argument scalar to the provided value - ScalarMap[AI].mergeWith(Call.getPtrArg(i)); - } -} - DSGraph &BUDataStructures::calculateGraph(Function &F) { // Make sure this graph has not already been calculated, or that we don't get // into an infinite loop with mutually recursive functions. @@ -115,11 +92,8 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) { // actual arguments... DEBUG(std::cerr << "\t[BU] Self Inlining: " << F.getName() << "\n"); - // Handle the return value if present... - Graph->getRetNode().mergeWith(Call.getRetVal()); - - // Resolve the arguments in the call to the actual values... - ResolveArguments(Call, F, Graph->getScalarMap()); + // Handle self recursion by resolving the arguments and return value + Graph->mergeInGraph(Call, *Graph, true); // Erase the entry in the callees vector Callees.erase(Callees.begin()+c--); @@ -145,22 +119,8 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) { CallSitesForFunc.back().setResolvingCaller(&F); CallSitesForFunc.back().setCallee(0); - // Clone the callee's graph into the current graph, keeping - // track of where scalars in the old graph _used_ to point, - // and of the new nodes matching nodes of the old graph. - map<Value*, DSNodeHandle> OldValMap; - map<const DSNode*, DSNode*> OldNodeMap; - - // The clone call may invalidate any of the vectors in the data - // structure graph. Strip locals and don't copy the list of callers - DSNodeHandle RetVal = Graph->cloneInto(GI, OldValMap, OldNodeMap, - /*StripAllocas*/ true); - - // Resolve the arguments in the call to the actual values... - ResolveArguments(Call, FI, OldValMap); - - // Handle the return value if present... - RetVal.mergeWith(Call.getRetVal()); + // Handle self recursion by resolving the arguments and return value + Graph->mergeInGraph(Call, GI, true); // Erase the entry in the Callees vector Callees.erase(Callees.begin()+c--); diff --git a/lib/Analysis/DataStructure/DataStructure.cpp b/lib/Analysis/DataStructure/DataStructure.cpp index ff2a4b8e0a..41cd7185ec 100644 --- a/lib/Analysis/DataStructure/DataStructure.cpp +++ b/lib/Analysis/DataStructure/DataStructure.cpp @@ -90,6 +90,7 @@ void DSNode::foldNodeCompletely() { Links[0].mergeWith(Links[i]); Links.resize(1); } + /// isNodeCompletelyFolded - Return true if this node has been completely /// folded down to something that can never be expanded, effectively losing /// all of the field sensitivity that may be present in the node. @@ -573,6 +574,57 @@ DSNodeHandle DSGraph::cloneInto(const DSGraph &G, return DSNodeHandle(OldNodeMap[G.RetNode.getNode()], G.RetNode.getOffset()); } +/// mergeInGraph - The method is used for merging graphs together. If the +/// argument graph is not *this, it makes a clone of the specified graph, then +/// merges the nodes specified in the call site with the formal arguments in the +/// graph. +/// +void DSGraph::mergeInGraph(DSCallSite &CS, const DSGraph &Graph, + bool StripAllocas) { + std::map<Value*, DSNodeHandle> OldValMap; + DSNodeHandle RetVal; + std::map<Value*, DSNodeHandle> *ScalarMap = &OldValMap; + + // If this is not a recursive call, clone the graph into this graph... + if (&Graph != this) { + // Clone the callee's graph into the current graph, keeping + // track of where scalars in the old graph _used_ to point, + // and of the new nodes matching nodes of the old graph. + std::map<const DSNode*, DSNode*> OldNodeMap; + + // The clone call may invalidate any of the vectors in the data + // structure graph. Strip locals and don't copy the list of callers + RetVal = cloneInto(Graph, OldValMap, OldNodeMap, StripAllocas); + ScalarMap = &OldValMap; + } else { + RetVal = getRetNode(); + ScalarMap = &getScalarMap(); + } + + // Merge the return value with the return value of the context... + RetVal.mergeWith(CS.getRetVal()); + + // Resolve all of the function arguments... + Function &F = Graph.getFunction(); + Function::aiterator AI = F.abegin(); + for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i, ++AI) { + // Advance the argument iterator to the first pointer argument... + while (!isPointerType(AI->getType())) { + ++AI; +#ifndef NDEBUG + if (AI == F.aend()) + std::cerr << "Bad call to Function: " << F.getName() << "\n"; +#endif + assert(AI != F.aend() && "# Args provided is not # Args required!"); + } + + // Add the link from the argument scalar to the provided value + DSNodeHandle &NH = (*ScalarMap)[AI]; + assert(NH.getNode() && "Pointer argument without scalarmap entry?"); + NH.mergeWith(CS.getPtrArg(i)); + } +} + #if 0 // cloneGlobalInto - Clone the given global node and all its target links // (and all their llinks, recursively). diff --git a/lib/Analysis/DataStructure/TopDownClosure.cpp b/lib/Analysis/DataStructure/TopDownClosure.cpp index 69422caa8f..817e734a9c 100644 --- a/lib/Analysis/DataStructure/TopDownClosure.cpp +++ b/lib/Analysis/DataStructure/TopDownClosure.cpp @@ -149,36 +149,36 @@ DSGraph &TDDataStructures::calculateGraph(Function &F) { DEBUG(std::cerr << "\t [TD] Inlining caller #" << c << " '" << Caller.getName() << "' into callee: " << F.getName() << "\n"); - if (&Caller == &F) { - // Self-recursive call: this can happen after a cycle of calls is inlined. - ResolveCallSite(*Graph, CallSite); - } else { - - // Recursively compute the graph for the Caller. It should be fully - // resolved except if there is mutual recursion... - // - DSGraph &CG = calculateGraph(Caller); // Graph to inline - - DEBUG(std::cerr << "\t\t[TD] Got graph for " << Caller.getName() - << " in: " << F.getName() << "\n"); - - // These two maps keep track of where scalars in the old graph _used_ - // to point to, and of new nodes matching nodes of the old graph. - std::map<Value*, DSNodeHandle> OldValMap; - std::map<const DSNode*, DSNode*> OldNodeMap; - - // Translate call site from having links into the BU graph - DSCallSite CallSiteInCG(CallSite, BUMaps[&Caller]); - - // Clone the Caller's graph into the current graph, keeping - // track of where scalars in the old graph _used_ to point... - // Do this here because it only needs to happens once for each Caller! - // Strip scalars but not allocas since they are alive in callee. - // - DSNodeHandle RetVal = Graph->cloneInto(CG, OldValMap, OldNodeMap, - /*StripAllocas*/ false); - ResolveCallSite(*Graph, DSCallSite(CallSiteInCG, OldNodeMap)); - } + // Self recursion is not tracked in BU pass... + assert(&Caller != &F && "This cannot happen!\n"); + + // Recursively compute the graph for the Caller. It should be fully + // resolved except if there is mutual recursion... + // + DSGraph &CG = calculateGraph(Caller); // Graph to inline + + DEBUG(std::cerr << "\t\t[TD] Got graph for " << Caller.getName() + << " in: " << F.getName() << "\n"); + + // Translate call site from having links into the BU graph + DSCallSite CallSiteInCG(CallSite, BUMaps[&Caller]); + + // These two maps keep track of where scalars in the old graph _used_ + // to point to, and of new nodes matching nodes of the old graph. + std::map<Value*, DSNodeHandle> OldValMap; + std::map<const DSNode*, DSNode*> OldNodeMap; + + // FIXME: Eventually use DSGraph::mergeInGraph here... + // Graph->mergeInGraph(CallSiteInCG, CG, false); + + // Clone the Caller's graph into the current graph, keeping + // track of where scalars in the old graph _used_ to point... + // Do this here because it only needs to happens once for each Caller! + // Strip scalars but not allocas since they are alive in callee. + // + DSNodeHandle RetVal = Graph->cloneInto(CG, OldValMap, OldNodeMap, + /*StripAllocas*/ false); + ResolveCallSite(*Graph, DSCallSite(CallSiteInCG, OldNodeMap)); } // Recompute the Incomplete markers and eliminate unreachable nodes. |