Skip to content

Commit e4d7b89

Browse files
[MemProf] Propagate function call assignments to newly cloned nodes (#159907)
There are a couple of places during function cloning where we may create new callsite clone nodes. One of those places was correctly propagating the assignment to which function clone it should call, and one was not. Refactor this handling into a helper and use in both places so the newly created callsite clones actually call the assigned callee function clones.
1 parent db2a5a9 commit e4d7b89

File tree

2 files changed

+85
-12
lines changed

2 files changed

+85
-12
lines changed

llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4602,6 +4602,25 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
46024602
}
46034603
};
46044604

4605+
// Invokes moveEdgeToNewCalleeClone which creates a new clone, and then
4606+
// performs the necessary fixups (removing none type edges, and
4607+
// importantly, propagating any function call assignment of the original
4608+
// node to the new clone).
4609+
auto MoveEdgeToNewCalleeCloneAndSetUp =
4610+
[&](const std::shared_ptr<ContextEdge> &Edge) {
4611+
ContextNode *OrigCallee = Edge->Callee;
4612+
ContextNode *NewClone = moveEdgeToNewCalleeClone(Edge);
4613+
removeNoneTypeCalleeEdges(NewClone);
4614+
assert(NewClone->AllocTypes != (uint8_t)AllocationType::None);
4615+
// If the original Callee was already assigned to call a specific
4616+
// function version, make sure its new clone is assigned to call
4617+
// that same function clone.
4618+
if (CallsiteToCalleeFuncCloneMap.count(OrigCallee))
4619+
RecordCalleeFuncOfCallsite(
4620+
NewClone, CallsiteToCalleeFuncCloneMap[OrigCallee]);
4621+
return NewClone;
4622+
};
4623+
46054624
// Keep track of the clones of callsite Node that need to be assigned to
46064625
// function clones. This list may be expanded in the loop body below if we
46074626
// find additional cloning is required.
@@ -4758,18 +4777,11 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
47584777
// we tried.
47594778
if (Callee == CalleeEdge->Caller)
47604779
continue;
4761-
ContextNode *NewClone = moveEdgeToNewCalleeClone(CalleeEdge);
4762-
removeNoneTypeCalleeEdges(NewClone);
4780+
ContextNode *NewClone =
4781+
MoveEdgeToNewCalleeCloneAndSetUp(CalleeEdge);
47634782
// Moving the edge may have resulted in some none type
47644783
// callee edges on the original Callee.
47654784
removeNoneTypeCalleeEdges(Callee);
4766-
assert(NewClone->AllocTypes != (uint8_t)AllocationType::None);
4767-
// If the Callee node was already assigned to call a specific
4768-
// function version, make sure its new clone is assigned to call
4769-
// that same function clone.
4770-
if (CallsiteToCalleeFuncCloneMap.count(Callee))
4771-
RecordCalleeFuncOfCallsite(
4772-
NewClone, CallsiteToCalleeFuncCloneMap[Callee]);
47734785
// Update NewClone with the new Call clone of this callsite's Call
47744786
// created for the new function clone created earlier.
47754787
// Recall that we have already ensured when building the graph
@@ -4893,13 +4905,11 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
48934905
removeNoneTypeCalleeEdges(NewClone);
48944906
} else {
48954907
// Create a new callsite clone.
4896-
ContextNode *NewClone = moveEdgeToNewCalleeClone(Edge);
4897-
removeNoneTypeCalleeEdges(NewClone);
4908+
ContextNode *NewClone = MoveEdgeToNewCalleeCloneAndSetUp(Edge);
48984909
FuncCloneToNewCallsiteCloneMap[FuncCloneCalledByCaller] =
48994910
NewClone;
49004911
// Add to list of clones and process later.
49014912
ClonesWorklist.push_back(NewClone);
4902-
assert(NewClone->AllocTypes != (uint8_t)AllocationType::None);
49034913
}
49044914
// Moving the caller edge may have resulted in some none type
49054915
// callee edges.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
;; Test to ensure assignments of calls to their callee function clones are
2+
;; propagated when we create new callsite clones during function assignment.
3+
;
4+
; RUN: opt -passes=memprof-context-disambiguation -supports-hot-cold-new %s -S | FileCheck %s
5+
6+
; ModuleID = 'funcassigncloning3.ll'
7+
source_filename = "funcassigncloning3.ll"
8+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
9+
target triple = "x86_64-grtev4-linux-gnu"
10+
11+
define void @A() {
12+
call void @_Znwm(), !memprof !0, !callsite !9
13+
ret void
14+
}
15+
16+
define void @B() {
17+
call void @A(), !callsite !10
18+
ret void
19+
}
20+
21+
define void @C() {
22+
call void @E(), !callsite !11
23+
ret void
24+
}
25+
26+
define void @D() {
27+
call void @E(), !callsite !12
28+
ret void
29+
}
30+
31+
; Function Attrs: cold
32+
define void @E() {
33+
call void @B(), !callsite !13
34+
call void @A(), !callsite !14
35+
ret void
36+
}
37+
38+
;; Clone E.memprof.2 is eventually created to satisfy the necessary combination
39+
;; of caller edges, which causes creation of a new clone of callsite for the
40+
;; call to A. Earlier this was assigned to call A.memprof.1 and we need to
41+
;; ensure that assignment is propagated.
42+
43+
; CHECK: define void @E.memprof.2()
44+
; CHECK-NEXT: call void @B()
45+
; CHECK-NEXT: call void @A.memprof.1()
46+
47+
declare void @_Znwm()
48+
49+
!0 = !{!1, !3, !5, !7}
50+
!1 = !{!2, !"cold"}
51+
!2 = !{i64 761518489666860826, i64 -1420336805534834351, i64 -2943078617660248973, i64 3500755695426091485, i64 4378935957859808257, i64 4501820981166842392, i64 -6517003774656365154, i64 -3601339536116888955, i64 1856492280661618760, i64 5795517037440084991, i64 3898931366823636439}
52+
!3 = !{!4, !"notcold"}
53+
!4 = !{i64 761518489666860826, i64 -1420336805534834351, i64 -2943078617660248973, i64 3500755695426091485, i64 4378935957859808257, i64 4501820981166842392, i64 -6517003774656365154, i64 -3601339536116888955, i64 1856492280661618760, i64 5795517037440084991, i64 8489804099578214685}
54+
!5 = !{!6, !"notcold"}
55+
!6 = !{i64 761518489666860826, i64 -1420336805534834351, i64 -2943078617660248973, i64 3500755695426091485, i64 4378935957859808257, i64 4501820981166842392, i64 -3569839323322692552, i64 -4068062742094437340, i64 3898931366823636439}
56+
!7 = !{!8, !"cold"}
57+
!8 = !{i64 761518489666860826, i64 -1420336805534834351, i64 -2943078617660248973, i64 3500755695426091485, i64 4378935957859808257, i64 4501820981166842392, i64 -3569839323322692552, i64 -4068062742094437340, i64 8158446606478904094}
58+
!9 = !{i64 761518489666860826, i64 -1420336805534834351, i64 -2943078617660248973, i64 3500755695426091485, i64 4378935957859808257, i64 4501820981166842392}
59+
!10 = !{i64 -3569839323322692552}
60+
!11 = !{i64 3898931366823636439}
61+
!12 = !{i64 8158446606478904094}
62+
!13 = !{i64 -4068062742094437340}
63+
!14 = !{i64 -6517003774656365154, i64 -3601339536116888955, i64 1856492280661618760, i64 5795517037440084991}

0 commit comments

Comments
 (0)