Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0c3cf20

Browse files
[MemProf] Optionally allow transformation of nobuiltin operator new (#158396)
For cases where we can guarantee the application does not override operator new.
1 parent 2610007 commit 0c3cf20

File tree

3 files changed

+70
-35
lines changed

3 files changed

+70
-35
lines changed

llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ class LibCallSimplifier {
189189
Value *optimizeMemSet(CallInst *CI, IRBuilderBase &B);
190190
Value *optimizeRealloc(CallInst *CI, IRBuilderBase &B);
191191
Value *optimizeNew(CallInst *CI, IRBuilderBase &B, LibFunc &Func);
192-
Value *optimizeExistingHotColdNew(CallInst *CI, IRBuilderBase &B);
192+
Value *maybeOptimizeNoBuiltinOperatorNew(CallInst *CI, IRBuilderBase &B);
193193
Value *optimizeWcslen(CallInst *CI, IRBuilderBase &B);
194194
Value *optimizeBCopy(CallInst *CI, IRBuilderBase &B);
195195

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ static cl::opt<bool> OptimizeExistingHotColdNew(
6161
"optimize-existing-hot-cold-new", cl::Hidden, cl::init(false),
6262
cl::desc(
6363
"Enable optimization of existing hot/cold operator new library calls"));
64+
static cl::opt<bool> OptimizeNoBuiltinHotColdNew(
65+
"optimize-nobuiltin-hot-cold-new-new", cl::Hidden, cl::init(false),
66+
cl::desc("Enable transformation of nobuiltin operator new library calls"));
6467

6568
namespace {
6669

@@ -1723,13 +1726,11 @@ Value *LibCallSimplifier::optimizeRealloc(CallInst *CI, IRBuilderBase &B) {
17231726
return nullptr;
17241727
}
17251728

1726-
// Allow existing calls to operator new() that takes a __hot_cold_t parameter to
1727-
// be updated with a compiler-determined hot cold hint value. This is used in
1728-
// cases where the call is marked nobuiltin (because operator new called
1729-
// explicitly) and therefore cannot be replaced with a different callee.
1730-
Value *LibCallSimplifier::optimizeExistingHotColdNew(CallInst *CI,
1731-
IRBuilderBase &B) {
1732-
if (!OptimizeHotColdNew || !OptimizeExistingHotColdNew)
1729+
// Optionally allow optimization of nobuiltin calls to operator new and its
1730+
// variants.
1731+
Value *LibCallSimplifier::maybeOptimizeNoBuiltinOperatorNew(CallInst *CI,
1732+
IRBuilderBase &B) {
1733+
if (!OptimizeHotColdNew)
17331734
return nullptr;
17341735
Function *Callee = CI->getCalledFunction();
17351736
if (!Callee)
@@ -1738,6 +1739,22 @@ Value *LibCallSimplifier::optimizeExistingHotColdNew(CallInst *CI,
17381739
if (!TLI->getLibFunc(*Callee, Func))
17391740
return nullptr;
17401741
switch (Func) {
1742+
case LibFunc_Znwm:
1743+
case LibFunc_ZnwmRKSt9nothrow_t:
1744+
case LibFunc_ZnwmSt11align_val_t:
1745+
case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
1746+
case LibFunc_Znam:
1747+
case LibFunc_ZnamRKSt9nothrow_t:
1748+
case LibFunc_ZnamSt11align_val_t:
1749+
case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
1750+
case LibFunc_size_returning_new:
1751+
case LibFunc_size_returning_new_aligned:
1752+
// By default normal operator new calls (not already passing a hot_cold_t
1753+
// parameter) are not mutated if the call is not marked builtin. Optionally
1754+
// enable that in cases where it is known to be safe.
1755+
if (!OptimizeNoBuiltinHotColdNew)
1756+
return nullptr;
1757+
break;
17411758
case LibFunc_Znwm12__hot_cold_t:
17421759
case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
17431760
case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
@@ -1748,10 +1765,15 @@ Value *LibCallSimplifier::optimizeExistingHotColdNew(CallInst *CI,
17481765
case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
17491766
case LibFunc_size_returning_new_hot_cold:
17501767
case LibFunc_size_returning_new_aligned_hot_cold:
1751-
return optimizeNew(CI, B, Func);
1768+
// If the nobuiltin call already passes a hot_cold_t parameter, allow update
1769+
// of that parameter when enabled.
1770+
if (!OptimizeExistingHotColdNew)
1771+
return nullptr;
1772+
break;
17521773
default:
17531774
return nullptr;
17541775
}
1776+
return optimizeNew(CI, B, Func);
17551777
}
17561778

17571779
// When enabled, replace operator new() calls marked with a hot or cold memprof
@@ -4121,9 +4143,8 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI, IRBuilderBase &Builder) {
41214143
// we can all non-FP calls with the StrictFP attribute to be
41224144
// optimized.
41234145
if (CI->isNoBuiltin()) {
4124-
// If this is an existing call to a hot cold operator new, we can update the
4125-
// hint parameter value, which doesn't change the callee.
4126-
return optimizeExistingHotColdNew(CI, Builder);
4146+
// Optionally update operator new calls.
4147+
return maybeOptimizeNoBuiltinOperatorNew(CI, Builder);
41274148
}
41284149

41294150
LibFunc Func;

llvm/test/Transforms/InstCombine/simplify-libcalls-new.ll

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,18 @@
66
; OFF-LABEL: @new_hot_cold()
77

88
;; First check with the default hint values (254 = -2, 128 = -128, 222 = -34).
9-
; RUN: opt < %s -passes=instcombine -optimize-hot-cold-new -S | FileCheck %s --check-prefix=HOTCOLD -DCOLD=1 -DHOT=-2 -DNOTCOLD=-128 -DAMBIG=-34 -DPREVHINTCOLD=7 -DPREVHINTNOTCOLD=7 -DPREVHINTHOT=7 -DPREVHINTAMBIG=7
9+
; RUN: opt < %s -passes=instcombine -optimize-hot-cold-new -S | FileCheck %s --check-prefixes=HOTCOLD,NOBUILTIN-OFF -DCOLD=1 -DHOT=-2 -DNOTCOLD=-128 -DAMBIG=-34 -DPREVHINTCOLD=7 -DPREVHINTNOTCOLD=7 -DPREVHINTHOT=7 -DPREVHINTAMBIG=7
1010

1111
;; Next check with the non-default cold and hot hint values (200 =-56).
12-
; RUN: opt < %s -passes=instcombine -optimize-hot-cold-new -cold-new-hint-value=5 -hot-new-hint-value=200 -notcold-new-hint-value=99 -ambiguous-new-hint-value=44 -S | FileCheck %s --check-prefix=HOTCOLD -DCOLD=5 -DHOT=-56 -DAMBIG=44 -DNOTCOLD=99 -DPREVHINTCOLD=7 -DPREVHINTNOTCOLD=7 -DPREVHINTHOT=7 -DPREVHINTAMBIG=7
12+
; RUN: opt < %s -passes=instcombine -optimize-hot-cold-new -cold-new-hint-value=5 -hot-new-hint-value=200 -notcold-new-hint-value=99 -ambiguous-new-hint-value=44 -S | FileCheck %s --check-prefixes=HOTCOLD,NOBUILTIN-OFF -DCOLD=5 -DHOT=-56 -DAMBIG=44 -DNOTCOLD=99 -DPREVHINTCOLD=7 -DPREVHINTNOTCOLD=7 -DPREVHINTHOT=7 -DPREVHINTAMBIG=7
13+
14+
;; Next check with the same non-default cold and hot hint values (200 =-56),
15+
;; but with transformation of nobuiltin calls enabled.
16+
; RUN: opt < %s -passes=instcombine -optimize-hot-cold-new -optimize-nobuiltin-hot-cold-new-new -cold-new-hint-value=5 -hot-new-hint-value=200 -notcold-new-hint-value=99 -ambiguous-new-hint-value=44 -S | FileCheck %s --check-prefixes=HOTCOLD,NOBUILTIN-ON -DCOLD=5 -DHOT=-56 -DAMBIG=44 -DNOTCOLD=99 -DPREVHINTCOLD=7 -DPREVHINTNOTCOLD=7 -DPREVHINTHOT=7 -DPREVHINTAMBIG=7
1317

1418
;; Try again with the non-default cold and hot hint values (200 =-56), and this
1519
;; time specify that existing hints should be updated.
16-
; RUN: opt < %s -passes=instcombine -optimize-hot-cold-new -cold-new-hint-value=5 -notcold-new-hint-value=100 -hot-new-hint-value=200 -ambiguous-new-hint-value=44 -optimize-existing-hot-cold-new -S | FileCheck %s --check-prefix=HOTCOLD -DCOLD=5 -DHOT=-56 -DNOTCOLD=100 -DAMBIG=44 -DPREVHINTCOLD=5 -DPREVHINTNOTCOLD=100 -DPREVHINTHOT=-56 -DPREVHINTAMBIG=44
20+
; RUN: opt < %s -passes=instcombine -optimize-hot-cold-new -cold-new-hint-value=5 -notcold-new-hint-value=100 -hot-new-hint-value=200 -ambiguous-new-hint-value=44 -optimize-existing-hot-cold-new -S | FileCheck %s --check-prefixes=HOTCOLD,NOBUILTIN-OFF -DCOLD=5 -DHOT=-56 -DNOTCOLD=100 -DAMBIG=44 -DPREVHINTCOLD=5 -DPREVHINTNOTCOLD=100 -DPREVHINTHOT=-56 -DPREVHINTAMBIG=44
1721

1822
;; Make sure that values not in 0..255 are flagged with an error
1923
; RUN: not opt < %s -passes=instcombine -optimize-hot-cold-new -cold-new-hint-value=256 -S 2>&1 | FileCheck %s --check-prefix=ERROR
@@ -40,8 +44,9 @@ define void @new() {
4044
; HOTCOLD: @_Znwm12__hot_cold_t(i64 10, i8 [[AMBIG]])
4145
%call4 = call ptr @_Znwm(i64 10) #7
4246
call void @dummy(ptr %call4)
43-
;; Attribute cold on a nobuiltin call has no effect.
44-
; HOTCOLD: @_Znwm(i64 10)
47+
;; Attribute cold on a nobuiltin call has no effect, unless optionally enabled.
48+
; NOBUILTIN-OFF: @_Znwm(i64 10)
49+
; NOBUILTIN-ON: @_Znwm12__hot_cold_t(i64 10, i8 [[COLD]])
4550
%call3 = call ptr @_Znwm(i64 10) #6
4651
call void @dummy(ptr %call3)
4752
ret void
@@ -68,8 +73,9 @@ define void @new_align() {
6873
; HOTCOLD: @_ZnwmSt11align_val_t12__hot_cold_t(i64 10, i64 8, i8 [[AMBIG]])
6974
%call4 = call ptr @_ZnwmSt11align_val_t(i64 10, i64 8) #7
7075
call void @dummy(ptr %call4)
71-
;; Attribute cold on a nobuiltin call has no effect.
72-
; HOTCOLD: @_ZnwmSt11align_val_t(i64 10, i64 8)
76+
;; Attribute cold on a nobuiltin call has no effect, unless optionally enabled.
77+
; NOBUILTIN-OFF: @_ZnwmSt11align_val_t(i64 10, i64 8)
78+
; NOBUILTIN-ON: @_ZnwmSt11align_val_t12__hot_cold_t(i64 10, i64 8, i8 [[COLD]])
7379
%call3 = call ptr @_ZnwmSt11align_val_t(i64 10, i64 8) #6
7480
call void @dummy(ptr %call3)
7581
ret void
@@ -97,8 +103,9 @@ define void @new_nothrow() {
97103
; HOTCOLD: @_ZnwmRKSt9nothrow_t12__hot_cold_t(i64 10, ptr nonnull %nt, i8 [[AMBIG]])
98104
%call4 = call ptr @_ZnwmRKSt9nothrow_t(i64 10, ptr %nt) #7
99105
call void @dummy(ptr %call4)
100-
;; Attribute cold on a nobuiltin call has no effect.
101-
; HOTCOLD: @_ZnwmRKSt9nothrow_t(i64 10, ptr nonnull %nt)
106+
;; Attribute cold on a nobuiltin call has no effect, unless optionally enabled.
107+
; NOBUILTIN-OFF: @_ZnwmRKSt9nothrow_t(i64 10, ptr nonnull %nt)
108+
; NOBUILTIN-ON: @_ZnwmRKSt9nothrow_t12__hot_cold_t(i64 10, ptr nonnull %nt, i8 [[COLD]])
102109
%call3 = call ptr @_ZnwmRKSt9nothrow_t(i64 10, ptr %nt) #6
103110
call void @dummy(ptr %call3)
104111
ret void
@@ -127,8 +134,9 @@ define void @new_align_nothrow() {
127134
; HOTCOLD: @_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 10, i64 8, ptr nonnull %nt, i8 [[AMBIG]])
128135
%call4 = call ptr @_ZnwmSt11align_val_tRKSt9nothrow_t(i64 10, i64 8, ptr %nt) #7
129136
call void @dummy(ptr %call4)
130-
;; Attribute cold on a nobuiltin call has no effect.
131-
; HOTCOLD: @_ZnwmSt11align_val_tRKSt9nothrow_t(i64 10, i64 8, ptr nonnull %nt)
137+
;; Attribute cold on a nobuiltin call has no effect, unless optionally enabled.
138+
; NOBUILTIN-OFF: @_ZnwmSt11align_val_tRKSt9nothrow_t(i64 10, i64 8, ptr nonnull %nt)
139+
; NOBUILTIN-ON: @_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 10, i64 8, ptr nonnull %nt, i8 [[COLD]])
132140
%call3 = call ptr @_ZnwmSt11align_val_tRKSt9nothrow_t(i64 10, i64 8, ptr %nt) #6
133141
call void @dummy(ptr %call3)
134142
ret void
@@ -154,8 +162,9 @@ define void @array_new() {
154162
; HOTCOLD: @_Znam12__hot_cold_t(i64 10, i8 [[AMBIG]])
155163
%call4 = call ptr @_Znam(i64 10) #7
156164
call void @dummy(ptr %call4)
157-
;; Attribute cold on a nobuiltin call has no effect.
158-
; HOTCOLD: @_Znam(i64 10)
165+
;; Attribute cold on a nobuiltin call has no effect, unless optionally enabled.
166+
; NOBUILTIN-OFF: @_Znam(i64 10)
167+
; NOBUILTIN-ON: @_Znam12__hot_cold_t(i64 10, i8 [[COLD]])
159168
%call3 = call ptr @_Znam(i64 10) #6
160169
call void @dummy(ptr %call3)
161170
ret void
@@ -182,8 +191,9 @@ define void @array_new_align() {
182191
; HOTCOLD: @_ZnamSt11align_val_t12__hot_cold_t(i64 10, i64 8, i8 [[AMBIG]])
183192
%call4 = call ptr @_ZnamSt11align_val_t(i64 10, i64 8) #7
184193
call void @dummy(ptr %call4)
185-
;; Attribute cold on a nobuiltin call has no effect.
186-
; HOTCOLD: @_ZnamSt11align_val_t(i64 10, i64 8)
194+
;; Attribute cold on a nobuiltin call has no effect, unless optionally enabled.
195+
; NOBUILTIN-OFF: @_ZnamSt11align_val_t(i64 10, i64 8)
196+
; NOBUILTIN-ON: @_ZnamSt11align_val_t12__hot_cold_t(i64 10, i64 8, i8 [[COLD]])
187197
%call3 = call ptr @_ZnamSt11align_val_t(i64 10, i64 8) #6
188198
call void @dummy(ptr %call3)
189199
ret void
@@ -211,8 +221,9 @@ define void @array_new_nothrow() {
211221
; HOTCOLD: @_ZnamRKSt9nothrow_t12__hot_cold_t(i64 10, ptr nonnull %nt, i8 [[AMBIG]])
212222
%call4 = call ptr @_ZnamRKSt9nothrow_t(i64 10, ptr %nt) #7
213223
call void @dummy(ptr %call4)
214-
;; Attribute cold on a nobuiltin call has no effect.
215-
; HOTCOLD: @_ZnamRKSt9nothrow_t(i64 10, ptr nonnull %nt)
224+
;; Attribute cold on a nobuiltin call has no effect, unless optionally enabled.
225+
; NOBUILTIN-OFF: @_ZnamRKSt9nothrow_t(i64 10, ptr nonnull %nt)
226+
; NOBUILTIN-ON: @_ZnamRKSt9nothrow_t12__hot_cold_t(i64 10, ptr nonnull %nt, i8 [[COLD]])
216227
%call3 = call ptr @_ZnamRKSt9nothrow_t(i64 10, ptr %nt) #6
217228
call void @dummy(ptr %call3)
218229
ret void
@@ -241,8 +252,9 @@ define void @array_new_align_nothrow() {
241252
; HOTCOLD: @_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 10, i64 8, ptr nonnull %nt, i8 [[AMBIG]])
242253
%call4 = call ptr @_ZnamSt11align_val_tRKSt9nothrow_t(i64 10, i64 8, ptr %nt) #7
243254
call void @dummy(ptr %call4)
244-
;; Attribute cold on a nobuiltin call has no effect.
245-
; HOTCOLD: @_ZnamSt11align_val_tRKSt9nothrow_t(i64 10, i64 8, ptr nonnull %nt)
255+
;; Attribute cold on a nobuiltin call has no effect, unless optionally enabled.
256+
; NOBUILTIN-OFF: @_ZnamSt11align_val_tRKSt9nothrow_t(i64 10, i64 8, ptr nonnull %nt)
257+
; NOBUILTIN-ON: @_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 10, i64 8, ptr nonnull %nt, i8 [[COLD]])
246258
%call3 = call ptr @_ZnamSt11align_val_tRKSt9nothrow_t(i64 10, i64 8, ptr %nt) #6
247259
call void @dummy(ptr %call3)
248260
ret void
@@ -492,8 +504,9 @@ define void @size_returning_test() {
492504
%call4 = call {ptr, i64} @__size_returning_new(i64 10) #8
493505
%p4 = extractvalue {ptr, i64} %call4, 0
494506
call void @dummy(ptr %p4)
495-
;; Attribute cold on a nobuiltin call has no effect.
496-
; HOTCOLD: @__size_returning_new(i64 10)
507+
;; Attribute cold on a nobuiltin call has no effect, unless optionally enabled.
508+
; NOBUILTIN-OFF: @__size_returning_new(i64 10)
509+
; NOBUILTIN-ON: @__size_returning_new_hot_cold(i64 10, i8 [[COLD]])
497510
%call3 = call {ptr, i64} @__size_returning_new(i64 10) #6
498511
%p3 = extractvalue {ptr, i64} %call3, 0
499512
call void @dummy(ptr %p3)
@@ -524,8 +537,9 @@ define void @size_returning_aligned_test() {
524537
%call4 = call {ptr, i64} @__size_returning_new_aligned(i64 10, i64 8) #8
525538
%p4 = extractvalue {ptr, i64} %call4, 0
526539
call void @dummy(ptr %p4)
527-
;; Attribute cold on a nobuiltin call has no effect.
528-
; HOTCOLD: @__size_returning_new_aligned(i64 10, i64 8)
540+
;; Attribute cold on a nobuiltin call has no effect, unless optionally enabled.
541+
; NOBUILTIN-OFF: @__size_returning_new_aligned(i64 10, i64 8)
542+
; NOBUILTIN-ON: @__size_returning_new_aligned_hot_cold(i64 10, i64 8, i8 [[COLD]])
529543
%call3 = call {ptr, i64} @__size_returning_new_aligned(i64 10, i64 8) #6
530544
%p3 = extractvalue {ptr, i64} %call3, 0
531545
call void @dummy(ptr %p3)

0 commit comments

Comments
 (0)