Skip to content

Commit 24a618f

Browse files
[MemProf] Look through alias when applying cloning in ThinLTO backend (#72156)
Mirror the handling in ModuleSummaryAnalysis to look through aliases when handling call instructions in the ThinLTO backend MemProf handling. Fixes #72094
1 parent 5535e48 commit 24a618f

File tree

2 files changed

+82
-4
lines changed

2 files changed

+82
-4
lines changed

llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2984,6 +2984,21 @@ bool MemProfContextDisambiguation::applyImport(Module &M) {
29842984
if (!mayHaveMemprofSummary(CB))
29852985
continue;
29862986

2987+
auto *CalledValue = CB->getCalledOperand();
2988+
auto *CalledFunction = CB->getCalledFunction();
2989+
if (CalledValue && !CalledFunction) {
2990+
CalledValue = CalledValue->stripPointerCasts();
2991+
// Stripping pointer casts can reveal a called function.
2992+
CalledFunction = dyn_cast<Function>(CalledValue);
2993+
}
2994+
// Check if this is an alias to a function. If so, get the
2995+
// called aliasee for the checks below.
2996+
if (auto *GA = dyn_cast<GlobalAlias>(CalledValue)) {
2997+
assert(!CalledFunction &&
2998+
"Expected null called function in callsite for alias");
2999+
CalledFunction = dyn_cast<Function>(GA->getAliaseeObject());
3000+
}
3001+
29873002
CallStack<MDNode, MDNode::op_iterator> CallsiteContext(
29883003
I.getMetadata(LLVMContext::MD_callsite));
29893004
auto *MemProfMD = I.getMetadata(LLVMContext::MD_memprof);
@@ -3115,21 +3130,21 @@ bool MemProfContextDisambiguation::applyImport(Module &M) {
31153130
CloneFuncIfNeeded(/*NumClones=*/StackNode.Clones.size());
31163131

31173132
// Should have skipped indirect calls via mayHaveMemprofSummary.
3118-
assert(CB->getCalledFunction());
3119-
assert(!IsMemProfClone(*CB->getCalledFunction()));
3133+
assert(CalledFunction);
3134+
assert(!IsMemProfClone(*CalledFunction));
31203135

31213136
// Update the calls per the summary info.
31223137
// Save orig name since it gets updated in the first iteration
31233138
// below.
3124-
auto CalleeOrigName = CB->getCalledFunction()->getName();
3139+
auto CalleeOrigName = CalledFunction->getName();
31253140
for (unsigned J = 0; J < StackNode.Clones.size(); J++) {
31263141
// Do nothing if this version calls the original version of its
31273142
// callee.
31283143
if (!StackNode.Clones[J])
31293144
continue;
31303145
auto NewF = M.getOrInsertFunction(
31313146
getMemProfFuncName(CalleeOrigName, StackNode.Clones[J]),
3132-
CB->getCalledFunction()->getFunctionType());
3147+
CalledFunction->getFunctionType());
31333148
CallBase *CBClone;
31343149
// Copy 0 is the original function.
31353150
if (!J)
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
;; Test handling of memprof distributed ThinLTO when the call to update is an alias.
2+
3+
;; Preparation steps to generate the bitcode and perform the thin link.
4+
; RUN: opt -thinlto-bc %s >%t.o
5+
; RUN: llvm-lto2 run %t.o -enable-memprof-context-disambiguation \
6+
; RUN: -supports-hot-cold-new \
7+
; RUN: -thinlto-distributed-indexes \
8+
; RUN: -r=%t.o,main,plx \
9+
; RUN: -r=%t.o,_Znam, \
10+
; RUN: -o %t2.out
11+
12+
;; Run ThinLTO backend
13+
; RUN: opt -passes=memprof-context-disambiguation \
14+
; RUN: -memprof-import-summary=%t.o.thinlto.bc \
15+
; RUN: -pass-remarks=memprof-context-disambiguation \
16+
; RUN: %t.o -S 2>&1 | FileCheck %s --check-prefix=IR
17+
18+
source_filename = "memprof-distrib-alias.ll"
19+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
20+
target triple = "x86_64-unknown-linux-gnu"
21+
22+
define i32 @main() #0 {
23+
entry:
24+
;; The first call to fooAlias does not allocate cold memory. It should call
25+
;; the original function alias, which calls the original allocation decorated
26+
;; with a "notcold" attribute.
27+
; IR: call {{.*}} @_Z8fooAliasv()
28+
%call = call ptr @_Z8fooAliasv(), !callsite !0
29+
;; The second call to fooAlias allocates cold memory. It should call the
30+
;; cloned function which calls a cloned allocation decorated with a "cold"
31+
;; attribute.
32+
; IR: call {{.*}} @_Z3foov.memprof.1()
33+
%call1 = call ptr @_Z8fooAliasv(), !callsite !1
34+
ret i32 0
35+
}
36+
37+
; IR: define internal {{.*}} @_Z3foov()
38+
; IR: call {{.*}} @_Znam(i64 0) #[[NOTCOLD:[0-9]+]]
39+
; IR: define internal {{.*}} @_Z3foov.memprof.1()
40+
; IR: call {{.*}} @_Znam(i64 0) #[[COLD:[0-9]+]]
41+
; IR: attributes #[[NOTCOLD]] = { "memprof"="notcold" }
42+
; IR: attributes #[[COLD]] = { "memprof"="cold" }
43+
44+
declare ptr @_Znam(i64)
45+
46+
@_Z8fooAliasv = internal alias ptr (...), ptr @_Z3foov
47+
48+
define internal ptr @_Z3foov() #0 {
49+
entry:
50+
%call = call ptr @_Znam(i64 0), !memprof !2, !callsite !7
51+
ret ptr null
52+
}
53+
54+
attributes #0 = { noinline optnone }
55+
56+
!0 = !{i64 8632435727821051414}
57+
!1 = !{i64 -3421689549917153178}
58+
!2 = !{!3, !5}
59+
!3 = !{!4, !"notcold"}
60+
!4 = !{i64 9086428284934609951, i64 8632435727821051414}
61+
!5 = !{!6, !"cold"}
62+
!6 = !{i64 9086428284934609951, i64 -3421689549917153178}
63+
!7 = !{i64 9086428284934609951}

0 commit comments

Comments
 (0)