aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-09-15 05:40:35 +0000
committerChris Lattner <sabre@nondot.org>2009-09-15 05:40:35 +0000
commita51c39cc3265f5d0d5de87b4a3ef9332c83556e1 (patch)
tree66ec9d3d0df0527cbad15e8a2b07a7826b6ea039
parentff1147072a0c9dbe91572bbbbf93031c6451bbae (diff)
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
-rw-r--r--include/llvm/Analysis/CallGraph.h6
-rw-r--r--lib/Analysis/IPA/CallGraph.cpp17
-rw-r--r--lib/Transforms/IPO/ArgumentPromotion.cpp8
3 files changed, 27 insertions, 4 deletions
diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h
index 1d23c695ad..bcb6dee033 100644
--- a/include/llvm/Analysis/CallGraph.h
+++ b/include/llvm/Analysis/CallGraph.h
@@ -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);
+
};
//===----------------------------------------------------------------------===//
diff --git a/lib/Analysis/IPA/CallGraph.cpp b/lib/Analysis/IPA/CallGraph.cpp
index 645916e35e..e2b288d1ba 100644
--- a/lib/Analysis/IPA/CallGraph.cpp
+++ b/lib/Analysis/IPA/CallGraph.cpp
@@ -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)
diff --git a/lib/Transforms/IPO/ArgumentPromotion.cpp b/lib/Transforms/IPO/ArgumentPromotion.cpp
index 3c584c894a..5b91f3d209 100644
--- a/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -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);