[llvm] [MemProf] Merge callee clones as needed before assigning functions (PR #135702)
Teresa Johnson via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 18 08:45:09 PDT 2025
================
@@ -4016,6 +4040,306 @@ IndexCallsiteContextGraph::cloneFunctionForCallsite(
return {Func.func(), CloneNo};
}
+// We perform cloning for each allocation node separately. However, this
+// sometimes results in a situation where the same node calls multiple
+// clones of the same callee, created for different allocations. This
+// causes issues when assigning functions to these clones, as each node can
+// in reality only call a single callee clone.
+//
+// To address this, before assigning functions, merge callee clone nodes as
+// needed using a post order traversal from the allocations. We attempt to
+// use existing clones as the merge node when legal, and to share them
+// among callers with the same properties (callers calling the same set of
+// callee clone nodes for the same allocations).
+//
+// Without this fix, in some cases incorrect function assignment will lead
+// to calling the wrong allocation clone.
+template <typename DerivedCCG, typename FuncTy, typename CallTy>
+void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::mergeClones() {
+ if (!MergeClones)
+ return;
+
+ // Generate a map from context id to the associated allocation node for use
+ // when merging clones.
+ DenseMap<uint32_t, ContextNode *> ContextIdToAllocationNode;
+ for (auto &Entry : AllocationCallToContextNodeMap) {
+ auto *Node = Entry.second;
+ for (auto Id : Node->getContextIds())
+ ContextIdToAllocationNode[Id] = Node->getOrigNode();
+ for (auto *Clone : Node->Clones) {
+ for (auto Id : Clone->getContextIds())
+ ContextIdToAllocationNode[Id] = Clone->getOrigNode();
+ }
+ }
+
+ // Post order traversal starting from allocations to ensure each callsite
+ // calls a single clone of its callee. Callee nodes that are clones of each
+ // other are merged (via new merge nodes if needed) to achieve this.
+ DenseSet<const ContextNode *> Visited;
+ for (auto &Entry : AllocationCallToContextNodeMap) {
+ auto *Node = Entry.second;
+
+ mergeClones(Node, Visited, ContextIdToAllocationNode);
+
+ // Make a copy so the recursive post order traversal that may create new
+ // clones doesn't mess up iteration.
+ auto Clones = Node->Clones;
----------------
teresajohnson wrote:
As discussed offline, added clarifying comment about recursion. Please let me know if you had something else in mind.
https://github.com/llvm/llvm-project/pull/135702
More information about the llvm-commits
mailing list