mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Revamp DSGraphs so that they can support multiple functions in the same
DSGraph at one time llvm-svn: 6994
This commit is contained in:
parent
2ce6424601
commit
203826c2e1
@ -342,7 +342,7 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
|
||||
DEBUG(std::cerr << " Self Inlining: " << F.getName() << "\n");
|
||||
|
||||
// Handle self recursion by resolving the arguments and return value
|
||||
Graph.mergeInGraph(CS, Graph, 0);
|
||||
Graph.mergeInGraph(CS, F, Graph, 0);
|
||||
|
||||
} else {
|
||||
// Get the data structure graph for the called function.
|
||||
@ -360,7 +360,7 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
|
||||
#endif
|
||||
|
||||
// Handle self recursion by resolving the arguments and return value
|
||||
Graph.mergeInGraph(CS, GI,
|
||||
Graph.mergeInGraph(CS, *Callee, GI,
|
||||
DSGraph::KeepModRefBits |
|
||||
DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes);
|
||||
|
||||
@ -423,28 +423,28 @@ DSGraph &BUDataStructures::inlineNonSCCGraphs(Function &F,
|
||||
LastCallSiteIdx = I.getCallSiteIdx();
|
||||
|
||||
// Resolve the current call...
|
||||
Function *Callee = *I;
|
||||
Function &Callee = **I;
|
||||
DSCallSite &CS = I.getCallSite();
|
||||
|
||||
if (Callee->isExternal()) {
|
||||
if (Callee.isExternal()) {
|
||||
// Ignore this case, simple varargs functions we cannot stub out!
|
||||
} else if (SCCFunctions.count(Callee)) {
|
||||
} else if (SCCFunctions.count(&Callee)) {
|
||||
// Calling a function in the SCC, ignore it for now!
|
||||
DEBUG(std::cerr << " SCC CallSite for: " << Callee->getName() << "\n");
|
||||
DEBUG(std::cerr << " SCC CallSite for: " << Callee.getName() << "\n");
|
||||
AuxCallsList.push_back(CS);
|
||||
} else {
|
||||
// Get the data structure graph for the called function.
|
||||
//
|
||||
DSGraph &GI = getDSGraph(*Callee); // Graph to inline
|
||||
DSGraph &GI = getDSGraph(Callee); // Graph to inline
|
||||
|
||||
DEBUG(std::cerr << " Inlining graph for " << Callee->getName()
|
||||
DEBUG(std::cerr << " Inlining graph for " << Callee.getName()
|
||||
<< "[" << GI.getGraphSize() << "+"
|
||||
<< GI.getAuxFunctionCalls().size() << "] into: " << F.getName()
|
||||
<< "[" << Graph.getGraphSize() << "+"
|
||||
<< Graph.getAuxFunctionCalls().size() << "]\n");
|
||||
|
||||
// Handle self recursion by resolving the arguments and return value
|
||||
Graph.mergeInGraph(CS, GI,
|
||||
Graph.mergeInGraph(CS, Callee, GI,
|
||||
DSGraph::KeepModRefBits | DSGraph::StripAllocaBit |
|
||||
DSGraph::DontCloneCallNodes);
|
||||
}
|
||||
@ -514,7 +514,7 @@ DSGraph &BUDataStructures::calculateSCCGraph(Function &F,
|
||||
DEBUG(std::cerr << " Self Inlining: " << F.getName() << "\n");
|
||||
|
||||
// Handle self recursion by resolving the arguments and return value
|
||||
Graph.mergeInGraph(CS, Graph, 0);
|
||||
Graph.mergeInGraph(CS, *Callee, Graph, 0);
|
||||
} else if (SCCCallSiteMap.count(Callee)) {
|
||||
// We have already seen a call site in the SCC for this function, just
|
||||
// merge the two call sites together and we are done.
|
||||
@ -530,7 +530,7 @@ DSGraph &BUDataStructures::calculateSCCGraph(Function &F,
|
||||
<< Graph.getAuxFunctionCalls().size() << "]\n");
|
||||
|
||||
// Handle self recursion by resolving the arguments and return value
|
||||
Graph.mergeInGraph(CS, GI,
|
||||
Graph.mergeInGraph(CS, *Callee, GI,
|
||||
DSGraph::KeepModRefBits | DSGraph::StripAllocaBit |
|
||||
DSGraph::DontCloneCallNodes);
|
||||
|
||||
|
@ -703,24 +703,23 @@ Function &DSCallSite::getCaller() const {
|
||||
// DSGraph Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
DSGraph::DSGraph(const DSGraph &G) : Func(G.Func), GlobalsGraph(0) {
|
||||
DSGraph::DSGraph(const DSGraph &G) : GlobalsGraph(0) {
|
||||
PrintAuxCalls = false;
|
||||
hash_map<const DSNode*, DSNodeHandle> NodeMap;
|
||||
RetNode = cloneInto(G, ScalarMap, NodeMap);
|
||||
NodeMapTy NodeMap;
|
||||
cloneInto(G, ScalarMap, ReturnNodes, NodeMap);
|
||||
}
|
||||
|
||||
DSGraph::DSGraph(const DSGraph &G,
|
||||
hash_map<const DSNode*, DSNodeHandle> &NodeMap)
|
||||
: Func(G.Func), GlobalsGraph(0) {
|
||||
DSGraph::DSGraph(const DSGraph &G, NodeMapTy &NodeMap)
|
||||
: GlobalsGraph(0) {
|
||||
PrintAuxCalls = false;
|
||||
RetNode = cloneInto(G, ScalarMap, NodeMap);
|
||||
cloneInto(G, ScalarMap, ReturnNodes, NodeMap);
|
||||
}
|
||||
|
||||
DSGraph::~DSGraph() {
|
||||
FunctionCalls.clear();
|
||||
AuxFunctionCalls.clear();
|
||||
ScalarMap.clear();
|
||||
RetNode.setNode(0);
|
||||
ReturnNodes.clear();
|
||||
|
||||
// Drop all intra-node references, so that assertions don't fail...
|
||||
std::for_each(Nodes.begin(), Nodes.end(),
|
||||
@ -746,16 +745,15 @@ void DSNode::remapLinks(hash_map<const DSNode*, DSNodeHandle> &OldNodeMap) {
|
||||
}
|
||||
|
||||
|
||||
// cloneInto - Clone the specified DSGraph into the current graph, returning the
|
||||
// Return node of the graph. The translated ScalarMap for the old function is
|
||||
// filled into the OldValMap member. If StripAllocas is set to true, Alloca
|
||||
// markers are removed from the graph, as the graph is being cloned into a
|
||||
// calling function's graph.
|
||||
//
|
||||
DSNodeHandle DSGraph::cloneInto(const DSGraph &G,
|
||||
hash_map<Value*, DSNodeHandle> &OldValMap,
|
||||
hash_map<const DSNode*, DSNodeHandle> &OldNodeMap,
|
||||
unsigned CloneFlags) {
|
||||
/// cloneInto - Clone the specified DSGraph into the current graph. The
|
||||
/// translated ScalarMap for the old function is filled into the OldValMap
|
||||
/// member, and the translated ReturnNodes map is returned into ReturnNodes.
|
||||
///
|
||||
/// The CloneFlags member controls various aspects of the cloning process.
|
||||
///
|
||||
void DSGraph::cloneInto(const DSGraph &G, ScalarMapTy &OldValMap,
|
||||
ReturnNodesTy &OldReturnNodes, NodeMapTy &OldNodeMap,
|
||||
unsigned CloneFlags) {
|
||||
assert(OldNodeMap.empty() && "Returned OldNodeMap should be empty!");
|
||||
assert(&G != this && "Cannot clone graph into itself!");
|
||||
|
||||
@ -816,10 +814,15 @@ DSNodeHandle DSGraph::cloneInto(const DSGraph &G,
|
||||
AuxFunctionCalls.push_back(DSCallSite(G.AuxFunctionCalls[i], OldNodeMap));
|
||||
}
|
||||
|
||||
// Return the returned node pointer...
|
||||
DSNodeHandle &MappedRet = OldNodeMap[G.RetNode.getNode()];
|
||||
return DSNodeHandle(MappedRet.getNode(),
|
||||
MappedRet.getOffset()+G.RetNode.getOffset());
|
||||
// Map the return node pointers over...
|
||||
for (ReturnNodesTy::const_iterator I = G.getReturnNodes().begin(),
|
||||
E = G.getReturnNodes().end(); I != E; ++I) {
|
||||
const DSNodeHandle &Ret = I->second;
|
||||
DSNodeHandle &MappedRet = OldNodeMap[Ret.getNode()];
|
||||
OldReturnNodes.insert(std::make_pair(I->first,
|
||||
DSNodeHandle(MappedRet.getNode(),
|
||||
MappedRet.getOffset()+Ret.getOffset())));
|
||||
}
|
||||
}
|
||||
|
||||
/// mergeInGraph - The method is used for merging graphs together. If the
|
||||
@ -827,25 +830,27 @@ DSNodeHandle DSGraph::cloneInto(const DSGraph &G,
|
||||
/// merges the nodes specified in the call site with the formal arguments in the
|
||||
/// graph.
|
||||
///
|
||||
void DSGraph::mergeInGraph(DSCallSite &CS, const DSGraph &Graph,
|
||||
void DSGraph::mergeInGraph(DSCallSite &CS, Function &F, const DSGraph &Graph,
|
||||
unsigned CloneFlags) {
|
||||
hash_map<Value*, DSNodeHandle> OldValMap;
|
||||
ScalarMapTy OldValMap;
|
||||
ScalarMapTy *ScalarMap = &OldValMap;
|
||||
DSNodeHandle RetVal;
|
||||
hash_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.
|
||||
hash_map<const DSNode*, DSNodeHandle> OldNodeMap;
|
||||
NodeMapTy 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, CloneFlags);
|
||||
ReturnNodesTy OldRetNodes;
|
||||
cloneInto(Graph, OldValMap, OldRetNodes, OldNodeMap, CloneFlags);
|
||||
RetVal = OldRetNodes[&F];
|
||||
ScalarMap = &OldValMap;
|
||||
} else {
|
||||
RetVal = getRetNode();
|
||||
RetVal = getReturnNodeFor(F);
|
||||
ScalarMap = &getScalarMap();
|
||||
}
|
||||
|
||||
@ -853,7 +858,6 @@ void DSGraph::mergeInGraph(DSCallSite &CS, const DSGraph &Graph,
|
||||
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) {
|
||||
@ -916,10 +920,16 @@ static void markIncomplete(DSCallSite &Call) {
|
||||
//
|
||||
void DSGraph::markIncompleteNodes(unsigned Flags) {
|
||||
// Mark any incoming arguments as incomplete...
|
||||
if ((Flags & DSGraph::MarkFormalArgs) && Func && Func->getName() != "main")
|
||||
for (Function::aiterator I = Func->abegin(), E = Func->aend(); I != E; ++I)
|
||||
if (isPointerType(I->getType()) && ScalarMap.find(I) != ScalarMap.end())
|
||||
markIncompleteNode(ScalarMap[I].getNode());
|
||||
if (Flags & DSGraph::MarkFormalArgs)
|
||||
for (ReturnNodesTy::iterator FI = ReturnNodes.begin(), E =ReturnNodes.end();
|
||||
FI != E; ++FI) {
|
||||
Function &F = *FI->first;
|
||||
if (F.getName() != "main")
|
||||
for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
|
||||
if (isPointerType(I->getType()) &&
|
||||
ScalarMap.find(I) != ScalarMap.end())
|
||||
markIncompleteNode(ScalarMap[I].getNode());
|
||||
}
|
||||
|
||||
// Mark stuff passed into functions calls as being incomplete...
|
||||
if (!shouldPrintAuxCalls())
|
||||
@ -954,8 +964,7 @@ static inline bool nodeContainsExternalFunction(const DSNode *N) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static void removeIdenticalCalls(std::vector<DSCallSite> &Calls,
|
||||
const std::string &where) {
|
||||
static void removeIdenticalCalls(std::vector<DSCallSite> &Calls) {
|
||||
// Remove trivially identical function calls
|
||||
unsigned NumFns = Calls.size();
|
||||
std::sort(Calls.begin(), Calls.end()); // Sort by callee as primary key!
|
||||
@ -1034,8 +1043,7 @@ static void removeIdenticalCalls(std::vector<DSCallSite> &Calls,
|
||||
NumCallNodesMerged += NumFns-Calls.size();
|
||||
|
||||
DEBUG(if (NumFns != Calls.size())
|
||||
std::cerr << "Merged " << (NumFns-Calls.size())
|
||||
<< " call nodes in " << where << "\n";);
|
||||
std::cerr << "Merged " << (NumFns-Calls.size()) << " call nodes.\n";);
|
||||
}
|
||||
|
||||
|
||||
@ -1045,8 +1053,8 @@ static void removeIdenticalCalls(std::vector<DSCallSite> &Calls,
|
||||
// we don't have to perform any non-trivial analysis here.
|
||||
//
|
||||
void DSGraph::removeTriviallyDeadNodes() {
|
||||
removeIdenticalCalls(FunctionCalls, Func ? Func->getName() : "");
|
||||
removeIdenticalCalls(AuxFunctionCalls, Func ? Func->getName() : "");
|
||||
removeIdenticalCalls(FunctionCalls);
|
||||
removeIdenticalCalls(AuxFunctionCalls);
|
||||
|
||||
for (unsigned i = 0; i != Nodes.size(); ++i) {
|
||||
DSNode *Node = Nodes[i];
|
||||
@ -1195,7 +1203,9 @@ void DSGraph::removeDeadNodes(unsigned Flags) {
|
||||
}
|
||||
|
||||
// The return value is alive as well...
|
||||
RetNode.getNode()->markReachableNodes(Alive);
|
||||
for (ReturnNodesTy::iterator I = ReturnNodes.begin(), E = ReturnNodes.end();
|
||||
I != E; ++I)
|
||||
I->second.getNode()->markReachableNodes(Alive);
|
||||
|
||||
// Mark any nodes reachable by primary calls as alive...
|
||||
for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i)
|
||||
|
@ -62,25 +62,26 @@ namespace {
|
||||
/// graph by performing a single pass over the function in question.
|
||||
///
|
||||
class GraphBuilder : InstVisitor<GraphBuilder> {
|
||||
Function &F;
|
||||
DSGraph &G;
|
||||
std::vector<DSNode*> &Nodes;
|
||||
DSNodeHandle &RetNode; // Node that gets returned...
|
||||
hash_map<Value*, DSNodeHandle> &ScalarMap;
|
||||
DSGraph::ScalarMapTy &ScalarMap;
|
||||
std::vector<DSCallSite> &FunctionCalls;
|
||||
|
||||
public:
|
||||
GraphBuilder(DSGraph &g, std::vector<DSNode*> &nodes, DSNodeHandle &retNode,
|
||||
hash_map<Value*, DSNodeHandle> &SM,
|
||||
GraphBuilder(Function &f, DSGraph &g, std::vector<DSNode*> &nodes,
|
||||
DSNodeHandle &retNode, DSGraph::ScalarMapTy &SM,
|
||||
std::vector<DSCallSite> &fc)
|
||||
: G(g), Nodes(nodes), RetNode(retNode), ScalarMap(SM), FunctionCalls(fc) {
|
||||
: F(f), G(g), Nodes(nodes), RetNode(retNode), ScalarMap(SM),
|
||||
FunctionCalls(fc) {
|
||||
|
||||
// Create scalar nodes for all pointer arguments...
|
||||
for (Function::aiterator I = G.getFunction().abegin(),
|
||||
E = G.getFunction().aend(); I != E; ++I)
|
||||
for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I)
|
||||
if (isPointerType(I->getType()))
|
||||
getValueDest(*I);
|
||||
|
||||
visit(G.getFunction()); // Single pass over the function
|
||||
visit(F); // Single pass over the function
|
||||
}
|
||||
|
||||
private:
|
||||
@ -139,10 +140,10 @@ namespace {
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DSGraph constructor - Simply use the GraphBuilder to construct the local
|
||||
// graph.
|
||||
DSGraph::DSGraph(Function &F, DSGraph *GG) : Func(&F), GlobalsGraph(GG) {
|
||||
DSGraph::DSGraph(Function &F, DSGraph *GG) : GlobalsGraph(GG) {
|
||||
PrintAuxCalls = false;
|
||||
// Use the graph builder to construct the local version of the graph
|
||||
GraphBuilder B(*this, Nodes, RetNode, ScalarMap, FunctionCalls);
|
||||
GraphBuilder B(F, *this, Nodes, ReturnNodes[&F], ScalarMap, FunctionCalls);
|
||||
#ifndef NDEBUG
|
||||
Timer::addPeakMemoryMeasurement();
|
||||
#endif
|
||||
|
@ -29,7 +29,10 @@ void DSNode::dump() const { print(std::cerr, 0); }
|
||||
|
||||
static std::string getCaption(const DSNode *N, const DSGraph *G) {
|
||||
std::stringstream OS;
|
||||
Module *M = G && G->hasFunction() ? G->getFunction().getParent() : 0;
|
||||
Module *M = 0;
|
||||
// Get the module from ONE of the functions in the graph it is available.
|
||||
if (G && !G->getReturnNodes().empty())
|
||||
M = G->getReturnNodes().begin()->first->getParent();
|
||||
|
||||
if (N->isNodeCompletelyFolded())
|
||||
OS << "FOLDED";
|
||||
@ -64,10 +67,16 @@ static std::string getCaption(const DSNode *N, const DSGraph *G) {
|
||||
template<>
|
||||
struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
|
||||
static std::string getGraphName(const DSGraph *G) {
|
||||
if (G->hasFunction())
|
||||
return "Function " + G->getFunction().getName();
|
||||
else
|
||||
return "Global graph";
|
||||
switch (G->getReturnNodes().size()) {
|
||||
case 0: return "Global graph";
|
||||
case 1: return "Function " + G->getReturnNodes().begin()->first->getName();
|
||||
default:
|
||||
std::string Return = "Functions: ";
|
||||
for (DSGraph::ReturnNodesTy::const_iterator I=G->getReturnNodes().begin();
|
||||
I != G->getReturnNodes().end(); ++I)
|
||||
Return += I->first->getName() + " ";
|
||||
return Return;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *getGraphProperties(const DSGraph *G) {
|
||||
@ -88,12 +97,13 @@ struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
|
||||
///
|
||||
static void addCustomGraphFeatures(const DSGraph *G,
|
||||
GraphWriter<const DSGraph*> &GW) {
|
||||
Module *CurMod = G->hasFunction() ? G->getFunction().getParent() : 0;
|
||||
Module *CurMod = 0;
|
||||
if (!G->getReturnNodes().empty())
|
||||
CurMod = G->getReturnNodes().begin()->first->getParent();
|
||||
|
||||
// Add scalar nodes to the graph...
|
||||
const hash_map<Value*, DSNodeHandle> &VM = G->getScalarMap();
|
||||
for (hash_map<Value*, DSNodeHandle>::const_iterator I = VM.begin();
|
||||
I != VM.end(); ++I)
|
||||
const DSGraph::ScalarMapTy &VM = G->getScalarMap();
|
||||
for (DSGraph::ScalarMapTy::const_iterator I = VM.begin(); I != VM.end();++I)
|
||||
if (!isa<GlobalValue>(I->first)) {
|
||||
std::stringstream OS;
|
||||
WriteAsOperand(OS, I->first, false, true, CurMod);
|
||||
@ -108,16 +118,24 @@ struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
|
||||
|
||||
|
||||
// Output the returned value pointer...
|
||||
if (G->getRetNode().getNode() != 0) {
|
||||
// Output the return node...
|
||||
GW.emitSimpleNode((void*)1, "plaintext=circle", "returning");
|
||||
const DSGraph::ReturnNodesTy &RetNodes = G->getReturnNodes();
|
||||
for (DSGraph::ReturnNodesTy::const_iterator I = RetNodes.begin(),
|
||||
E = RetNodes.end(); I != E; ++I)
|
||||
if (I->second.getNode()) {
|
||||
std::string Label;
|
||||
if (RetNodes.size() == 1)
|
||||
Label = "returning";
|
||||
else
|
||||
Label = I->first->getName() + " ret node";
|
||||
// Output the return node...
|
||||
GW.emitSimpleNode((void*)1, "plaintext=circle", Label);
|
||||
|
||||
// Add edge from return node to real destination
|
||||
int RetEdgeDest = G->getRetNode().getOffset() >> DS::PointerShift;;
|
||||
if (RetEdgeDest == 0) RetEdgeDest = -1;
|
||||
GW.emitEdge((void*)1, -1, G->getRetNode().getNode(),
|
||||
RetEdgeDest, "arrowtail=tee,color=gray63");
|
||||
}
|
||||
// Add edge from return node to real destination
|
||||
int RetEdgeDest = I->second.getOffset() >> DS::PointerShift;;
|
||||
if (RetEdgeDest == 0) RetEdgeDest = -1;
|
||||
GW.emitEdge((void*)1, -1, I->second.getNode(),
|
||||
RetEdgeDest, "arrowtail=tee,color=gray63");
|
||||
}
|
||||
|
||||
// Output all of the call nodes...
|
||||
const std::vector<DSCallSite> &FCs =
|
||||
|
@ -111,7 +111,7 @@ bool Steens::run(Module &M) {
|
||||
// RetValMap - Keep track of the return values for all functions that return
|
||||
// valid pointers.
|
||||
//
|
||||
hash_map<Function*, DSNodeHandle> RetValMap;
|
||||
DSGraph::ReturnNodesTy RetValMap;
|
||||
|
||||
// Loop over the rest of the module, merging graphs for non-external functions
|
||||
// into this graph.
|
||||
@ -119,22 +119,16 @@ bool Steens::run(Module &M) {
|
||||
unsigned Count = 0;
|
||||
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
|
||||
if (!I->isExternal()) {
|
||||
hash_map<Value*, DSNodeHandle> ValMap;
|
||||
DSGraph::ScalarMapTy ValMap;
|
||||
{ // Scope to free NodeMap memory ASAP
|
||||
hash_map<const DSNode*, DSNodeHandle> NodeMap;
|
||||
DSGraph::NodeMapTy NodeMap;
|
||||
const DSGraph &FDSG = LDS.getDSGraph(*I);
|
||||
DSNodeHandle RetNode = ResultGraph->cloneInto(FDSG, ValMap, NodeMap);
|
||||
|
||||
// Keep track of the return node of the function's graph if it returns a
|
||||
// value...
|
||||
//
|
||||
if (RetNode.getNode())
|
||||
RetValMap[I] = RetNode;
|
||||
ResultGraph->cloneInto(FDSG, ValMap, RetValMap, NodeMap);
|
||||
}
|
||||
|
||||
// Incorporate the inlined Function's ScalarMap into the global
|
||||
// ScalarMap...
|
||||
hash_map<Value*, DSNodeHandle> &GVM = ResultGraph->getScalarMap();
|
||||
DSGraph::ScalarMapTy &GVM = ResultGraph->getScalarMap();
|
||||
for (hash_map<Value*, DSNodeHandle>::iterator I = ValMap.begin(),
|
||||
E = ValMap.end(); I != E; ++I)
|
||||
GVM[I->first].mergeWith(I->second);
|
||||
|
@ -57,6 +57,7 @@ void TDDataStructures::releaseMyMemory() {
|
||||
GlobalsGraph = 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/// ResolveCallSite - This method is used to link the actual arguments together
|
||||
/// with the formal arguments for a function call in the top-down closure. This
|
||||
/// method assumes that the call site arguments have been mapped into nodes
|
||||
@ -82,6 +83,7 @@ void TDDataStructures::ResolveCallSite(DSGraph &Graph,
|
||||
if (CallSite.getRetVal().getNode() && Graph.getRetNode().getNode())
|
||||
Graph.getRetNode().mergeWith(CallSite.getRetVal());
|
||||
}
|
||||
#endif
|
||||
|
||||
DSGraph &TDDataStructures::getOrCreateDSGraph(Function &F) {
|
||||
DSGraph *&G = DSInfo[&F];
|
||||
@ -169,13 +171,15 @@ void TDDataStructures::calculateGraph(Function &F) {
|
||||
<< "'\n");
|
||||
|
||||
// Clone our current graph into the callee...
|
||||
hash_map<Value*, DSNodeHandle> OldValMap;
|
||||
hash_map<const DSNode*, DSNodeHandle> OldNodeMap;
|
||||
CG.cloneInto(Graph, OldValMap, OldNodeMap,
|
||||
DSGraph::ScalarMapTy OldValMap;
|
||||
DSGraph::NodeMapTy OldNodeMap;
|
||||
DSGraph::ReturnNodesTy ReturnNodes;
|
||||
CG.cloneInto(Graph, OldValMap, ReturnNodes, OldNodeMap,
|
||||
DSGraph::StripModRefBits |
|
||||
DSGraph::KeepAllocaBit | DSGraph::DontCloneCallNodes |
|
||||
DSGraph::DontCloneAuxCallNodes);
|
||||
OldValMap.clear(); // We don't care about the ValMap
|
||||
ReturnNodes.clear(); // We don't care about return values either
|
||||
|
||||
// Loop over all of the invocation sites of the callee, resolving
|
||||
// arguments to our graph. This loop may iterate multiple times if the
|
||||
@ -187,7 +191,7 @@ void TDDataStructures::calculateGraph(Function &F) {
|
||||
DSCallSite NewCS(*I->second, OldNodeMap);
|
||||
|
||||
// Resolve the return values...
|
||||
NewCS.getRetVal().mergeWith(CG.getRetNode());
|
||||
NewCS.getRetVal().mergeWith(CG.getReturnNodeFor(Callee));
|
||||
|
||||
// Resolve all of the arguments...
|
||||
Function::aiterator AI = Callee.abegin();
|
||||
|
Loading…
Reference in New Issue
Block a user