add a new CallGraphNode::replaceCallEdge method and use it from

argpromote to avoid invalidating an iterator.  This fixes PR4977.
All clang tests now pass with expensive checking (on my system 
at least).


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81843 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2009-09-15 05:40:35 +00:00
parent ff1147072a
commit a51c39cc32
3 changed files with 27 additions and 4 deletions

View File

@ -270,6 +270,12 @@ public:
/// removeOneAbstractEdgeTo - Remove one edge associated with a null callsite
/// from this node to the specified callee function.
void removeOneAbstractEdgeTo(CallGraphNode *Callee);
/// replaceCallEdge - This method replaces the edge in the node for the
/// specified call site with a new one. Note that this method takes linear
/// time, so it should be used sparingly.
void replaceCallEdge(CallSite CS, CallSite NewCS, CallGraphNode *NewNode);
};
//===----------------------------------------------------------------------===//

View File

@ -279,5 +279,22 @@ void CallGraphNode::removeOneAbstractEdgeTo(CallGraphNode *Callee) {
}
}
/// replaceCallEdge - This method replaces the edge in the node for the
/// specified call site with a new one. Note that this method takes linear
/// time, so it should be used sparingly.
void CallGraphNode::replaceCallEdge(CallSite CS,
CallSite NewCS, CallGraphNode *NewNode){
for (CalledFunctionsVector::iterator I = CalledFunctions.begin(); ; ++I) {
assert(I != CalledFunctions.end() && "Cannot find callsite to remove!");
if (I->first == CS.getInstruction()) {
I->second->DropRef();
I->first = NewCS.getInstruction();
I->second = NewNode;
NewNode->AddRef();
return;
}
}
}
// Enuse that users of CallGraph.h also link with this file
DEFINING_FILE_FOR(CallGraph)

View File

@ -589,7 +589,7 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F,
// Construct the new function type using the new arguments.
FunctionType *NFTy = FunctionType::get(RetTy, Params, FTy->isVarArg());
// Create the new function body and insert it into the module...
// Create the new function body and insert it into the module.
Function *NF = Function::Create(NFTy, F->getLinkage(), F->getName());
NF->copyAttributesFrom(F);
@ -599,7 +599,8 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F,
// Recompute the parameter attributes list based on the new arguments for
// the function.
NF->setAttributes(AttrListPtr::get(AttributesVec.begin(), AttributesVec.end()));
NF->setAttributes(AttrListPtr::get(AttributesVec.begin(),
AttributesVec.end()));
AttributesVec.clear();
F->getParent()->getFunctionList().insert(F, NF);
@ -729,8 +730,7 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F,
// Update the callgraph to know that the callsite has been transformed.
CallGraphNode *CalleeNode = CG[Call->getParent()->getParent()];
CalleeNode->removeCallEdgeFor(Call);
CalleeNode->addCalledFunction(New, NF_CGN);
CalleeNode->replaceCallEdge(Call, New, NF_CGN);
if (!Call->use_empty()) {
Call->replaceAllUsesWith(New);