mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 21:29:20 +00:00
Correctly transform dependant arguments, allowing the perimeter bm to work.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2282 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8beec9da6c
commit
3b87167ac4
@ -177,6 +177,23 @@ namespace {
|
||||
// pool entries for the same argument) are kept in depth first order.
|
||||
stable_sort(ArgInfo.begin(), ArgInfo.end());
|
||||
}
|
||||
|
||||
// addCallInfo - For a specified function call CI, figure out which pool
|
||||
// descriptors need to be passed in as arguments, and which arguments need
|
||||
// to be transformed into indices. If Arg != -1, the specified call
|
||||
// argument is passed in as a pointer to a data structure.
|
||||
//
|
||||
void addCallInfo(DataStructure *DS, CallInst *CI, int Arg,
|
||||
DSNode *GraphNode, map<DSNode*, PoolInfo> &PoolDescs);
|
||||
|
||||
// Make sure that all dependant arguments are added to this transformation
|
||||
// info. For example, if we call foo(null, P) and foo treats it's first and
|
||||
// second arguments as belonging to the same data structure, the we MUST add
|
||||
// entries to know that the null needs to be transformed into an index as
|
||||
// well.
|
||||
//
|
||||
void ensureDependantArgumentsIncluded(DataStructure *DS,
|
||||
map<DSNode*, PoolInfo> &PoolDescs);
|
||||
};
|
||||
|
||||
|
||||
@ -332,6 +349,10 @@ bool PoolAllocate::processFunction(Function *F) {
|
||||
|
||||
if (Allocs.empty()) return false; // Nothing to do.
|
||||
|
||||
#ifdef DEBUG_TRANSFORM_PROGRESS
|
||||
cerr << "Transforming Function: " << F->getName() << "\n";
|
||||
#endif
|
||||
|
||||
// Insert instructions into the function we are processing to create all of
|
||||
// the memory pool objects themselves. This also inserts destruction code.
|
||||
// This fills in the PoolDescs map to associate the alloc node with the
|
||||
@ -381,6 +402,8 @@ class NewInstructionCreator : public InstVisitor<NewInstructionCreator> {
|
||||
const ScalarInfo &getScalarRef(const Value *V) {
|
||||
for (unsigned i = 0, e = Scalars.size(); i != e; ++i)
|
||||
if (Scalars[i].Val == V) return Scalars[i];
|
||||
|
||||
cerr << "Could not find scalar " << V << " in scalar map!\n";
|
||||
assert(0 && "Scalar not found in getScalar!");
|
||||
abort();
|
||||
return Scalars[0];
|
||||
@ -740,29 +763,281 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static void addNodeMapping(DSNode *SrcNode, const PointerValSet &PVS,
|
||||
map<DSNode*, PointerValSet> &NodeMapping) {
|
||||
for (unsigned i = 0, e = PVS.size(); i != e; ++i)
|
||||
if (NodeMapping[SrcNode].add(PVS[i])) { // Not in map yet?
|
||||
assert(PVS[i].Index == 0 && "Node indexing not supported yet!");
|
||||
DSNode *DestNode = PVS[i].Node;
|
||||
|
||||
// Loop over all of the outgoing links in the mapped graph
|
||||
for (unsigned l = 0, le = DestNode->getNumOutgoingLinks(); l != le; ++l) {
|
||||
PointerValSet &SrcSet = SrcNode->getOutgoingLink(l);
|
||||
const PointerValSet &DestSet = DestNode->getOutgoingLink(l);
|
||||
|
||||
// Add all of the node mappings now!
|
||||
for (unsigned si = 0, se = SrcSet.size(); si != se; ++si) {
|
||||
assert(SrcSet[si].Index == 0 && "Can't handle node offset!");
|
||||
addNodeMapping(SrcSet[si].Node, DestSet, NodeMapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CalculateNodeMapping - There is a partial isomorphism between the graph
|
||||
// passed in and the graph that is actually used by the function. We need to
|
||||
// figure out what this mapping is so that we can transformFunctionBody the
|
||||
// instructions in the function itself. Note that every node in the graph that
|
||||
// we are interested in must be both in the local graph of the called function,
|
||||
// and in the local graph of the calling function. Because of this, we only
|
||||
// define the mapping for these nodes [conveniently these are the only nodes we
|
||||
// CAN define a mapping for...]
|
||||
//
|
||||
// The roots of the graph that we are transforming is rooted in the arguments
|
||||
// passed into the function from the caller. This is where we start our
|
||||
// mapping calculation.
|
||||
//
|
||||
// The NodeMapping calculated maps from the callers graph to the called graph.
|
||||
//
|
||||
static void CalculateNodeMapping(Function *F, TransformFunctionInfo &TFI,
|
||||
FunctionDSGraph &CallerGraph,
|
||||
FunctionDSGraph &CalledGraph,
|
||||
map<DSNode*, PointerValSet> &NodeMapping) {
|
||||
int LastArgNo = -2;
|
||||
for (unsigned i = 0, e = TFI.ArgInfo.size(); i != e; ++i) {
|
||||
// Figure out what nodes in the called graph the TFI.ArgInfo[i].Node node
|
||||
// corresponds to...
|
||||
//
|
||||
// Only consider first node of sequence. Extra nodes may may be added
|
||||
// to the TFI if the data structure requires more nodes than just the
|
||||
// one the argument points to. We are only interested in the one the
|
||||
// argument points to though.
|
||||
//
|
||||
if (TFI.ArgInfo[i].ArgNo != LastArgNo) {
|
||||
if (TFI.ArgInfo[i].ArgNo == -1) {
|
||||
addNodeMapping(TFI.ArgInfo[i].Node, CalledGraph.getRetNodes(),
|
||||
NodeMapping);
|
||||
} else {
|
||||
// Figure out which node argument # ArgNo points to in the called graph.
|
||||
Value *Arg = F->getArgumentList()[TFI.ArgInfo[i].ArgNo];
|
||||
addNodeMapping(TFI.ArgInfo[i].Node, CalledGraph.getValueMap()[Arg],
|
||||
NodeMapping);
|
||||
}
|
||||
LastArgNo = TFI.ArgInfo[i].ArgNo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void addCallInfo(DataStructure *DS,
|
||||
TransformFunctionInfo &TFI, CallInst *CI, int Arg,
|
||||
DSNode *GraphNode,
|
||||
map<DSNode*, PoolInfo> &PoolDescs) {
|
||||
|
||||
|
||||
// addCallInfo - For a specified function call CI, figure out which pool
|
||||
// descriptors need to be passed in as arguments, and which arguments need to be
|
||||
// transformed into indices. If Arg != -1, the specified call argument is
|
||||
// passed in as a pointer to a data structure.
|
||||
//
|
||||
void TransformFunctionInfo::addCallInfo(DataStructure *DS, CallInst *CI,
|
||||
int Arg, DSNode *GraphNode,
|
||||
map<DSNode*, PoolInfo> &PoolDescs) {
|
||||
assert(CI->getCalledFunction() && "Cannot handle indirect calls yet!");
|
||||
assert(TFI.Func == 0 || TFI.Func == CI->getCalledFunction() &&
|
||||
assert(Func == 0 || Func == CI->getCalledFunction() &&
|
||||
"Function call record should always call the same function!");
|
||||
assert(TFI.Call == 0 || TFI.Call == CI &&
|
||||
assert(Call == 0 || Call == CI &&
|
||||
"Call element already filled in with different value!");
|
||||
TFI.Func = CI->getCalledFunction();
|
||||
TFI.Call = CI;
|
||||
//FunctionDSGraph &CalledGraph = DS->getClosedDSGraph(TFI.Func);
|
||||
Func = CI->getCalledFunction();
|
||||
Call = CI;
|
||||
//FunctionDSGraph &CalledGraph = DS->getClosedDSGraph(Func);
|
||||
|
||||
// For now, add the entire graph that is pointed to by the call argument.
|
||||
// This graph can and should be pruned to only what the function itself will
|
||||
// use, because often this will be a dramatically smaller subset of what we
|
||||
// are providing.
|
||||
//
|
||||
// FIXME: This should use pool links instead of extra arguments!
|
||||
//
|
||||
for (df_iterator<DSNode*> I = df_begin(GraphNode), E = df_end(GraphNode);
|
||||
I != E; ++I)
|
||||
TFI.ArgInfo.push_back(CallArgInfo(Arg, *I, PoolDescs[*I].Handle));
|
||||
ArgInfo.push_back(CallArgInfo(Arg, *I, PoolDescs[*I].Handle));
|
||||
}
|
||||
|
||||
static void markReachableNodes(const PointerValSet &Vals,
|
||||
set<DSNode*> &ReachableNodes) {
|
||||
for (unsigned n = 0, ne = Vals.size(); n != ne; ++n) {
|
||||
DSNode *N = Vals[n].Node;
|
||||
if (ReachableNodes.count(N) == 0) // Haven't already processed node?
|
||||
ReachableNodes.insert(df_begin(N), df_end(N)); // Insert all
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure that all dependant arguments are added to this transformation info.
|
||||
// For example, if we call foo(null, P) and foo treats it's first and second
|
||||
// arguments as belonging to the same data structure, the we MUST add entries to
|
||||
// know that the null needs to be transformed into an index as well.
|
||||
//
|
||||
void TransformFunctionInfo::ensureDependantArgumentsIncluded(DataStructure *DS,
|
||||
map<DSNode*, PoolInfo> &PoolDescs) {
|
||||
// FIXME: This does not work for indirect function calls!!!
|
||||
if (Func == 0) return; // FIXME!
|
||||
|
||||
// Make sure argument entries are sorted.
|
||||
finalizeConstruction();
|
||||
|
||||
// Loop over the function signature, checking to see if there are any pointer
|
||||
// arguments that we do not convert... if there is something we haven't
|
||||
// converted, set done to false.
|
||||
//
|
||||
unsigned PtrNo = 0;
|
||||
bool Done = true;
|
||||
if (isa<PointerType>(Func->getReturnType())) // Make sure we convert retval
|
||||
if (PtrNo < ArgInfo.size() && ArgInfo[PtrNo++].ArgNo == -1) {
|
||||
// We DO transform the ret val... skip all possible entries for retval
|
||||
while (PtrNo < ArgInfo.size() && ArgInfo[PtrNo].ArgNo == -1)
|
||||
PtrNo++;
|
||||
} else {
|
||||
Done = false;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, e = Func->getArgumentList().size(); i != e; ++i) {
|
||||
Argument *Arg = Func->getArgumentList()[i];
|
||||
if (isa<PointerType>(Arg->getType())) {
|
||||
if (PtrNo < ArgInfo.size() && ArgInfo[PtrNo++].ArgNo == (int)i) {
|
||||
// We DO transform this arg... skip all possible entries for argument
|
||||
while (PtrNo < ArgInfo.size() && ArgInfo[PtrNo].ArgNo == (int)i)
|
||||
PtrNo++;
|
||||
} else {
|
||||
Done = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we already have entries for all pointer arguments and retvals, there
|
||||
// certainly is no work to do. Bail out early to avoid building relatively
|
||||
// expensive data structures.
|
||||
//
|
||||
if (Done) return;
|
||||
|
||||
#ifdef DEBUG_TRANSFORM_PROGRESS
|
||||
cerr << "Must ensure dependant arguments for: " << Func->getName() << "\n";
|
||||
#endif
|
||||
|
||||
// Otherwise, we MIGHT have to add the arguments/retval if they are part of
|
||||
// the same datastructure graph as some other argument or retval that we ARE
|
||||
// processing.
|
||||
//
|
||||
// Get the data structure graph for the called function.
|
||||
//
|
||||
FunctionDSGraph &CalledDS = DS->getClosedDSGraph(Func);
|
||||
|
||||
// Build a mapping between the nodes in our current graph and the nodes in the
|
||||
// called function's graph. We build it based on our _incomplete_
|
||||
// transformation information, because it contains all of the info that we
|
||||
// should need.
|
||||
//
|
||||
map<DSNode*, PointerValSet> NodeMapping;
|
||||
CalculateNodeMapping(Func, *this,
|
||||
DS->getClosedDSGraph(Call->getParent()->getParent()),
|
||||
CalledDS, NodeMapping);
|
||||
|
||||
// Build the inverted version of the node mapping, that maps from a node in
|
||||
// the called functions graph to a single node in the caller graph.
|
||||
//
|
||||
map<DSNode*, DSNode*> InverseNodeMap;
|
||||
for (map<DSNode*, PointerValSet>::iterator I = NodeMapping.begin(),
|
||||
E = NodeMapping.end(); I != E; ++I) {
|
||||
PointerValSet &CalledNodes = I->second;
|
||||
for (unsigned i = 0, e = CalledNodes.size(); i != e; ++i)
|
||||
InverseNodeMap[CalledNodes[i].Node] = I->first;
|
||||
}
|
||||
NodeMapping.clear(); // Done with information, free memory
|
||||
|
||||
// Build a set of reachable nodes from the arguments/retval that we ARE
|
||||
// passing in...
|
||||
set<DSNode*> ReachableNodes;
|
||||
|
||||
// Loop through all of the arguments, marking all of the reachable data
|
||||
// structure nodes reachable if they are from this pointer...
|
||||
//
|
||||
for (unsigned i = 0, e = ArgInfo.size(); i != e; ++i) {
|
||||
if (ArgInfo[i].ArgNo == -1) {
|
||||
if (i == 0) // Only process retvals once (performance opt)
|
||||
markReachableNodes(CalledDS.getRetNodes(), ReachableNodes);
|
||||
} else { // If it's an argument value...
|
||||
Argument *Arg = Func->getArgumentList()[ArgInfo[i].ArgNo];
|
||||
if (isa<PointerType>(Arg->getType()))
|
||||
markReachableNodes(CalledDS.getValueMap()[Arg], ReachableNodes);
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we know which nodes are already reachable, see if any of the
|
||||
// arguments that we are not passing values in for can reach one of the
|
||||
// existing nodes...
|
||||
//
|
||||
|
||||
// <FIXME> IN THEORY, we should allow arbitrary paths from the argument to
|
||||
// nodes we know about. The problem is that if we do this, then I don't know
|
||||
// how to get pool pointers for this head list. Since we are completely
|
||||
// deadline driven, I'll just allow direct accesses to the graph. </FIXME>
|
||||
//
|
||||
|
||||
PtrNo = 0;
|
||||
if (isa<PointerType>(Func->getReturnType())) // Make sure we convert retval
|
||||
if (PtrNo < ArgInfo.size() && ArgInfo[PtrNo++].ArgNo == -1) {
|
||||
// We DO transform the ret val... skip all possible entries for retval
|
||||
while (PtrNo < ArgInfo.size() && ArgInfo[PtrNo].ArgNo == -1)
|
||||
PtrNo++;
|
||||
} else {
|
||||
// See what the return value points to...
|
||||
|
||||
// FIXME: This should generalize to any number of nodes, just see if any
|
||||
// are reachable.
|
||||
assert(CalledDS.getRetNodes().size() == 1 &&
|
||||
"Assumes only one node is returned");
|
||||
DSNode *N = CalledDS.getRetNodes()[0].Node;
|
||||
|
||||
// If the return value is not marked as being passed in, but it NEEDS to
|
||||
// be transformed, then make it known now.
|
||||
//
|
||||
if (ReachableNodes.count(N)) {
|
||||
#ifdef DEBUG_TRANSFORM_PROGRESS
|
||||
cerr << "ensure dependant arguments adds return value entry!\n";
|
||||
#endif
|
||||
addCallInfo(DS, Call, -1, InverseNodeMap[N], PoolDescs);
|
||||
|
||||
// Keep sorted!
|
||||
finalizeConstruction();
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0, e = Func->getArgumentList().size(); i != e; ++i) {
|
||||
Argument *Arg = Func->getArgumentList()[i];
|
||||
if (isa<PointerType>(Arg->getType())) {
|
||||
if (PtrNo < ArgInfo.size() && ArgInfo[PtrNo++].ArgNo == (int)i) {
|
||||
// We DO transform this arg... skip all possible entries for argument
|
||||
while (PtrNo < ArgInfo.size() && ArgInfo[PtrNo].ArgNo == (int)i)
|
||||
PtrNo++;
|
||||
} else {
|
||||
// This should generalize to any number of nodes, just see if any are
|
||||
// reachable.
|
||||
assert(CalledDS.getValueMap()[Arg].size() == 1 &&
|
||||
"Only handle case where pointing to one node so far!");
|
||||
|
||||
// If the arg is not marked as being passed in, but it NEEDS to
|
||||
// be transformed, then make it known now.
|
||||
//
|
||||
DSNode *N = CalledDS.getValueMap()[Arg][0].Node;
|
||||
if (ReachableNodes.count(N)) {
|
||||
#ifdef DEBUG_TRANSFORM_PROGRESS
|
||||
cerr << "ensure dependant arguments adds for arg #" << i << "\n";
|
||||
#endif
|
||||
addCallInfo(DS, Call, i, InverseNodeMap[N], PoolDescs);
|
||||
|
||||
// Keep sorted!
|
||||
finalizeConstruction();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -833,7 +1108,7 @@ void PoolAllocate::transformFunctionBody(Function *F, FunctionDSGraph &IPFGraph,
|
||||
// Check to see if the scalar _IS_ a call...
|
||||
if (CallInst *CI = dyn_cast<CallInst>(ScalarVal))
|
||||
// If so, add information about the pool it will be returning...
|
||||
addCallInfo(DS, CallMap[CI], CI, -1, Scalars[i].Pool.Node, PoolDescs);
|
||||
CallMap[CI].addCallInfo(DS, CI, -1, Scalars[i].Pool.Node, PoolDescs);
|
||||
|
||||
// Check to see if the scalar is an operand to a call...
|
||||
for (Value::use_iterator UI = ScalarVal->use_begin(),
|
||||
@ -848,18 +1123,26 @@ void PoolAllocate::transformFunctionBody(Function *F, FunctionDSGraph &IPFGraph,
|
||||
// than once! It will get multiple entries for the first pointer.
|
||||
|
||||
// Add the operand number and pool handle to the call table...
|
||||
addCallInfo(DS, CallMap[CI], CI, OI-CI->op_begin()-1,
|
||||
Scalars[i].Pool.Node, PoolDescs);
|
||||
CallMap[CI].addCallInfo(DS, CI, OI-CI->op_begin()-1,
|
||||
Scalars[i].Pool.Node, PoolDescs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure that all dependant arguments are added as well. For example, if
|
||||
// we call foo(null, P) and foo treats it's first and second arguments as
|
||||
// belonging to the same data structure, the we MUST set up the CallMap to
|
||||
// know that the null needs to be transformed into an index as well.
|
||||
//
|
||||
for (map<CallInst*, TransformFunctionInfo>::iterator I = CallMap.begin();
|
||||
I != CallMap.end(); ++I)
|
||||
I->second.ensureDependantArgumentsIncluded(DS, PoolDescs);
|
||||
|
||||
#ifdef DEBUG_TRANSFORM_PROGRESS
|
||||
// Print out call map...
|
||||
for (map<CallInst*, TransformFunctionInfo>::iterator I = CallMap.begin();
|
||||
I != CallMap.end(); ++I) {
|
||||
cerr << "For call: " << I->first;
|
||||
I->second.finalizeConstruction();
|
||||
cerr << I->second.Func->getName() << " must pass pool pointer for args #";
|
||||
for (unsigned i = 0; i < I->second.ArgInfo.size(); ++i)
|
||||
cerr << I->second.ArgInfo[i].ArgNo << ", ";
|
||||
@ -873,9 +1156,6 @@ void PoolAllocate::transformFunctionBody(Function *F, FunctionDSGraph &IPFGraph,
|
||||
//
|
||||
for (map<CallInst*, TransformFunctionInfo>::iterator I = CallMap.begin(),
|
||||
E = CallMap.end(); I != E; ++I) {
|
||||
// Make sure the entries are sorted.
|
||||
I->second.finalizeConstruction();
|
||||
|
||||
// Transform all of the functions we need, or at least ensure there is a
|
||||
// cached version available.
|
||||
transformFunction(I->second, IPFGraph, PoolDescs);
|
||||
@ -965,7 +1245,6 @@ void PoolAllocate::transformFunctionBody(Function *F, FunctionDSGraph &IPFGraph,
|
||||
Argument *NewArg = new Argument(*TI, Arg->getName());
|
||||
XFormMap[Arg] = NewArg; // Map old arg into new arg...
|
||||
|
||||
|
||||
// Replace the old argument and then delete it...
|
||||
delete F->getArgumentList().replaceWith(I, NewArg);
|
||||
}
|
||||
@ -994,70 +1273,6 @@ void PoolAllocate::transformFunctionBody(Function *F, FunctionDSGraph &IPFGraph,
|
||||
DS->invalidateFunction(F);
|
||||
}
|
||||
|
||||
static void addNodeMapping(DSNode *SrcNode, const PointerValSet &PVS,
|
||||
map<DSNode*, PointerValSet> &NodeMapping) {
|
||||
for (unsigned i = 0, e = PVS.size(); i != e; ++i)
|
||||
if (NodeMapping[SrcNode].add(PVS[i])) { // Not in map yet?
|
||||
assert(PVS[i].Index == 0 && "Node indexing not supported yet!");
|
||||
DSNode *DestNode = PVS[i].Node;
|
||||
|
||||
// Loop over all of the outgoing links in the mapped graph
|
||||
for (unsigned l = 0, le = DestNode->getNumOutgoingLinks(); l != le; ++l) {
|
||||
PointerValSet &SrcSet = SrcNode->getOutgoingLink(l);
|
||||
const PointerValSet &DestSet = DestNode->getOutgoingLink(l);
|
||||
|
||||
// Add all of the node mappings now!
|
||||
for (unsigned si = 0, se = SrcSet.size(); si != se; ++si) {
|
||||
assert(SrcSet[si].Index == 0 && "Can't handle node offset!");
|
||||
addNodeMapping(SrcSet[si].Node, DestSet, NodeMapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CalculateNodeMapping - There is a partial isomorphism between the graph
|
||||
// passed in and the graph that is actually used by the function. We need to
|
||||
// figure out what this mapping is so that we can transformFunctionBody the
|
||||
// instructions in the function itself. Note that every node in the graph that
|
||||
// we are interested in must be both in the local graph of the called function,
|
||||
// and in the local graph of the calling function. Because of this, we only
|
||||
// define the mapping for these nodes [conveniently these are the only nodes we
|
||||
// CAN define a mapping for...]
|
||||
//
|
||||
// The roots of the graph that we are transforming is rooted in the arguments
|
||||
// passed into the function from the caller. This is where we start our
|
||||
// mapping calculation.
|
||||
//
|
||||
// The NodeMapping calculated maps from the callers graph to the called graph.
|
||||
//
|
||||
static void CalculateNodeMapping(Function *F, TransformFunctionInfo &TFI,
|
||||
FunctionDSGraph &CallerGraph,
|
||||
FunctionDSGraph &CalledGraph,
|
||||
map<DSNode*, PointerValSet> &NodeMapping) {
|
||||
int LastArgNo = -2;
|
||||
for (unsigned i = 0, e = TFI.ArgInfo.size(); i != e; ++i) {
|
||||
// Figure out what nodes in the called graph the TFI.ArgInfo[i].Node node
|
||||
// corresponds to...
|
||||
//
|
||||
// Only consider first node of sequence. Extra nodes may may be added
|
||||
// to the TFI if the data structure requires more nodes than just the
|
||||
// one the argument points to. We are only interested in the one the
|
||||
// argument points to though.
|
||||
//
|
||||
if (TFI.ArgInfo[i].ArgNo != LastArgNo) {
|
||||
if (TFI.ArgInfo[i].ArgNo == -1) {
|
||||
addNodeMapping(TFI.ArgInfo[i].Node, CalledGraph.getRetNodes(),
|
||||
NodeMapping);
|
||||
} else {
|
||||
// Figure out which node argument # ArgNo points to in the called graph.
|
||||
Value *Arg = F->getArgumentList()[TFI.ArgInfo[i].ArgNo];
|
||||
addNodeMapping(TFI.ArgInfo[i].Node, CalledGraph.getValueMap()[Arg],
|
||||
NodeMapping);
|
||||
}
|
||||
LastArgNo = TFI.ArgInfo[i].ArgNo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// transformFunction - Transform the specified function the specified way. It
|
||||
@ -1285,6 +1500,12 @@ void PoolAllocate::CreatePools(Function *F, const vector<AllocDSNode*> &Allocs,
|
||||
if (isa<ReturnInst>((*I)->getTerminator()))
|
||||
ReturnNodes.push_back(*I);
|
||||
|
||||
#ifdef DEBUG_CREATE_POOLS
|
||||
cerr << "Allocs that we are pool allocating:\n";
|
||||
for (unsigned i = 0, e = Allocs.size(); i != e; ++i)
|
||||
Allocs[i]->dump();
|
||||
#endif
|
||||
|
||||
map<DSNode*, PATypeHolder> AbsPoolTyMap;
|
||||
|
||||
// First pass over the allocations to process...
|
||||
|
Loading…
Reference in New Issue
Block a user