aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Analysis/CallGraph.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-06-13 19:31:46 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-06-13 19:37:19 +0000
commite8d8bef961a50d4dc22501cde4fb9fb0be1b2532 (patch)
tree94f04805f47bb7c59ae29690d8952b6074fff602 /contrib/llvm-project/llvm/lib/Analysis/CallGraph.cpp
parentbb130ff39747b94592cb26d71b7cb097b9a4ea6b (diff)
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Analysis/CallGraph.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Analysis/CallGraph.cpp48
1 files changed, 29 insertions, 19 deletions
diff --git a/contrib/llvm-project/llvm/lib/Analysis/CallGraph.cpp b/contrib/llvm-project/llvm/lib/Analysis/CallGraph.cpp
index 55adb454b733..9b212e564a46 100644
--- a/contrib/llvm-project/llvm/lib/Analysis/CallGraph.cpp
+++ b/contrib/llvm-project/llvm/lib/Analysis/CallGraph.cpp
@@ -167,20 +167,6 @@ Function *CallGraph::removeFunctionFromModule(CallGraphNode *CGN) {
return F;
}
-/// spliceFunction - Replace the function represented by this node by another.
-/// This does not rescan the body of the function, so it is suitable when
-/// splicing the body of the old function to the new while also updating all
-/// callers from old to new.
-void CallGraph::spliceFunction(const Function *From, const Function *To) {
- assert(FunctionMap.count(From) && "No CallGraphNode for function!");
- assert(!FunctionMap.count(To) &&
- "Pointing CallGraphNode at a function that already exists");
- FunctionMapTy::iterator I = FunctionMap.find(From);
- I->second->F = const_cast<Function*>(To);
- FunctionMap[To] = std::move(I->second);
- FunctionMap.erase(I);
-}
-
// getOrInsertFunction - This method is identical to calling operator[], but
// it will insert a new CallGraphNode for the specified function if one does
// not already exist.
@@ -281,13 +267,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;
}
}