aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/CallGraph.cpp
diff options
context:
space:
mode:
authorSergey Dmitriev <serguei.n.dmitriev@intel.com>2020-07-27 06:02:06 -0700
committerSergey Dmitriev <serguei.n.dmitriev@intel.com>2020-07-27 06:02:55 -0700
commitbec77ece14890d2aa40c76eedc6a7a406d84f1fc (patch)
treed507528c4b1e5614c0a1887b067d061970f077cd /llvm/lib/Analysis/CallGraph.cpp
parent005eee8b3ef7f244daf12f574a191079bfc1918b (diff)
downloadllvm-bec77ece14890d2aa40c76eedc6a7a406d84f1fc.zip
llvm-bec77ece14890d2aa40c76eedc6a7a406d84f1fc.tar.gz
llvm-bec77ece14890d2aa40c76eedc6a7a406d84f1fc.tar.bz2
[CallGraph] Preserve call records vector when replacing call edge
Summary: Try not to resize vector of call records in a call graph node when replacing call edge. That would prevent invalidation of iterators stored in the CG SCC pass manager's scc_iterator. Reviewers: jdoerfert Reviewed By: jdoerfert Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D84295
Diffstat (limited to 'llvm/lib/Analysis/CallGraph.cpp')
-rw-r--r--llvm/lib/Analysis/CallGraph.cpp34
1 files changed, 29 insertions, 5 deletions
diff --git a/llvm/lib/Analysis/CallGraph.cpp b/llvm/lib/Analysis/CallGraph.cpp
index 55adb45..19c128b 100644
--- a/llvm/lib/Analysis/CallGraph.cpp
+++ b/llvm/lib/Analysis/CallGraph.cpp
@@ -281,13 +281,37 @@ void CallGraphNode::replaceCallEdge(CallBase &Call, CallBase &NewCall,
I->second = NewNode;
NewNode->AddRef();
- // Refresh callback references.
- forEachCallbackFunction(Call, [=](Function *CB) {
- removeOneAbstractEdgeTo(CG->getOrInsertFunction(CB));
+ // Refresh callback references. Do not resize CalledFunctions if the
+ // number of callbacks is the same for new and old call sites.
+ SmallVector<CallGraphNode *, 4u> OldCBs;
+ SmallVector<CallGraphNode *, 4u> NewCBs;
+ forEachCallbackFunction(Call, [this, &OldCBs](Function *CB) {
+ OldCBs.push_back(CG->getOrInsertFunction(CB));
});
- forEachCallbackFunction(NewCall, [=](Function *CB) {
- addCalledFunction(nullptr, CG->getOrInsertFunction(CB));
+ forEachCallbackFunction(NewCall, [this, &NewCBs](Function *CB) {
+ NewCBs.push_back(CG->getOrInsertFunction(CB));
});
+ if (OldCBs.size() == NewCBs.size()) {
+ for (unsigned N = 0; N < OldCBs.size(); ++N) {
+ CallGraphNode *OldNode = OldCBs[N];
+ CallGraphNode *NewNode = NewCBs[N];
+ for (auto J = CalledFunctions.begin();; ++J) {
+ assert(J != CalledFunctions.end() &&
+ "Cannot find callsite to update!");
+ if (!J->first && J->second == OldNode) {
+ J->second = NewNode;
+ OldNode->DropRef();
+ NewNode->AddRef();
+ break;
+ }
+ }
+ }
+ } else {
+ for (auto *CGN : OldCBs)
+ removeOneAbstractEdgeTo(CGN);
+ for (auto *CGN : NewCBs)
+ addCalledFunction(nullptr, CGN);
+ }
return;
}
}