-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[MemProf] Optionally update hints on existing hot/cold new calls #91047
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MemProf] Optionally update hints on existing hot/cold new calls #91047
Conversation
If directed by an option, update hints on calls to new that already provide a hot/cold hint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
switch (Func) { | ||
case LibFunc_Znwm12__hot_cold_t: | ||
if (OptimizeExistingHotColdNew) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be useful to count how many times an existing call had a hint value which differs in nature?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would require analyzing the value passed to the existing hot/cold new, and it may not be available in the function scope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true, I assumed that we would be able to inspect the operand as a constant value. Feel free to ignore the comment if that is not the case.
// For calls that already pass a hot/cold hint, only update the hint if | ||
// directed by OptimizeExistingHotColdNew. For other calls to new, add a hint | ||
// if cold or hot, and leave as-is for default handling if "notcold" aka warm. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If an existing hinted allocation is to be marked with a notcold hint, there should be a slight performance advantage to delegate to an unhinted variant rather than passing in the new hinted value. It's not a very important use case right now but perhaps worth noting in the comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there should be a slight performance advantage to delegate to an unhinted variant rather than passing in the new hinted value
I might be missing something, but why would that be? Afaik tcmalloc should treat something with the default notcold hint value the same as anything else that isn't cold hinted. Or are you just talking about the need for the allocator to check the hint value being passed in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'm referring to the latter. There is an additional load (of a parameter value), a check and a branch which can be avoided if we replace it with the unhinted variant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comment
@llvm/pr-subscribers-llvm-transforms Author: Teresa Johnson (teresajohnson) ChangesIf directed by an option, update hints on calls to new that already Full diff: https://github.com/llvm/llvm-project/pull/91047.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 2e68a9c01898c..174cc7a3c778d 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -52,6 +52,10 @@ static cl::opt<bool>
static cl::opt<bool>
OptimizeHotColdNew("optimize-hot-cold-new", cl::Hidden, cl::init(false),
cl::desc("Enable hot/cold operator new library calls"));
+static cl::opt<bool> OptimizeExistingHotColdNew(
+ "optimize-existing-hot-cold-new", cl::Hidden, cl::init(false),
+ cl::desc(
+ "Enable optimization of existing hot/cold operator new library calls"));
namespace {
@@ -81,6 +85,10 @@ struct HotColdHintParser : public cl::parser<unsigned> {
static cl::opt<unsigned, false, HotColdHintParser> ColdNewHintValue(
"cold-new-hint-value", cl::Hidden, cl::init(1),
cl::desc("Value to pass to hot/cold operator new for cold allocation"));
+static cl::opt<unsigned, false, HotColdHintParser>
+ NotColdNewHintValue("notcold-new-hint-value", cl::Hidden, cl::init(128),
+ cl::desc("Value to pass to hot/cold operator new for "
+ "notcold (warm) allocation"));
static cl::opt<unsigned, false, HotColdHintParser> HotNewHintValue(
"hot-new-hint-value", cl::Hidden, cl::init(254),
cl::desc("Value to pass to hot/cold operator new for hot allocation"));
@@ -1722,45 +1730,122 @@ Value *LibCallSimplifier::optimizeNew(CallInst *CI, IRBuilderBase &B,
uint8_t HotCold;
if (CI->getAttributes().getFnAttr("memprof").getValueAsString() == "cold")
HotCold = ColdNewHintValue;
+ else if (CI->getAttributes().getFnAttr("memprof").getValueAsString() ==
+ "notcold")
+ HotCold = NotColdNewHintValue;
else if (CI->getAttributes().getFnAttr("memprof").getValueAsString() == "hot")
HotCold = HotNewHintValue;
else
return nullptr;
+ // For calls that already pass a hot/cold hint, only update the hint if
+ // directed by OptimizeExistingHotColdNew. For other calls to new, add a hint
+ // if cold or hot, and leave as-is for default handling if "notcold" aka warm.
+ // Note that in cases where we decide it is "notcold", it might be slightly
+ // better to replace the hinted call with a non hinted call, to avoid the
+ // extra paramter and the if condition check of the hint value in the
+ // allocator. This can be considered in the future.
switch (Func) {
+ case LibFunc_Znwm12__hot_cold_t:
+ if (OptimizeExistingHotColdNew)
+ return emitHotColdNew(CI->getArgOperand(0), B, TLI,
+ LibFunc_Znwm12__hot_cold_t, HotCold);
+ break;
case LibFunc_Znwm:
- return emitHotColdNew(CI->getArgOperand(0), B, TLI,
- LibFunc_Znwm12__hot_cold_t, HotCold);
+ if (HotCold != NotColdNewHintValue)
+ return emitHotColdNew(CI->getArgOperand(0), B, TLI,
+ LibFunc_Znwm12__hot_cold_t, HotCold);
+ break;
+ case LibFunc_Znam12__hot_cold_t:
+ if (OptimizeExistingHotColdNew)
+ return emitHotColdNew(CI->getArgOperand(0), B, TLI,
+ LibFunc_Znam12__hot_cold_t, HotCold);
+ break;
case LibFunc_Znam:
- return emitHotColdNew(CI->getArgOperand(0), B, TLI,
- LibFunc_Znam12__hot_cold_t, HotCold);
+ if (HotCold != NotColdNewHintValue)
+ return emitHotColdNew(CI->getArgOperand(0), B, TLI,
+ LibFunc_Znam12__hot_cold_t, HotCold);
+ break;
+ case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
+ if (OptimizeExistingHotColdNew)
+ return emitHotColdNewNoThrow(
+ CI->getArgOperand(0), CI->getArgOperand(1), B, TLI,
+ LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t, HotCold);
+ break;
case LibFunc_ZnwmRKSt9nothrow_t:
- return emitHotColdNewNoThrow(CI->getArgOperand(0), CI->getArgOperand(1), B,
- TLI, LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t,
- HotCold);
+ if (HotCold != NotColdNewHintValue)
+ return emitHotColdNewNoThrow(
+ CI->getArgOperand(0), CI->getArgOperand(1), B, TLI,
+ LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t, HotCold);
+ break;
+ case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
+ if (OptimizeExistingHotColdNew)
+ return emitHotColdNewNoThrow(
+ CI->getArgOperand(0), CI->getArgOperand(1), B, TLI,
+ LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t, HotCold);
+ break;
case LibFunc_ZnamRKSt9nothrow_t:
- return emitHotColdNewNoThrow(CI->getArgOperand(0), CI->getArgOperand(1), B,
- TLI, LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t,
- HotCold);
+ if (HotCold != NotColdNewHintValue)
+ return emitHotColdNewNoThrow(
+ CI->getArgOperand(0), CI->getArgOperand(1), B, TLI,
+ LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t, HotCold);
+ break;
+ case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
+ if (OptimizeExistingHotColdNew)
+ return emitHotColdNewAligned(
+ CI->getArgOperand(0), CI->getArgOperand(1), B, TLI,
+ LibFunc_ZnwmSt11align_val_t12__hot_cold_t, HotCold);
+ break;
case LibFunc_ZnwmSt11align_val_t:
- return emitHotColdNewAligned(CI->getArgOperand(0), CI->getArgOperand(1), B,
- TLI, LibFunc_ZnwmSt11align_val_t12__hot_cold_t,
- HotCold);
+ if (HotCold != NotColdNewHintValue)
+ return emitHotColdNewAligned(
+ CI->getArgOperand(0), CI->getArgOperand(1), B, TLI,
+ LibFunc_ZnwmSt11align_val_t12__hot_cold_t, HotCold);
+ break;
+ case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
+ if (OptimizeExistingHotColdNew)
+ return emitHotColdNewAligned(
+ CI->getArgOperand(0), CI->getArgOperand(1), B, TLI,
+ LibFunc_ZnamSt11align_val_t12__hot_cold_t, HotCold);
+ break;
case LibFunc_ZnamSt11align_val_t:
- return emitHotColdNewAligned(CI->getArgOperand(0), CI->getArgOperand(1), B,
- TLI, LibFunc_ZnamSt11align_val_t12__hot_cold_t,
- HotCold);
+ if (HotCold != NotColdNewHintValue)
+ return emitHotColdNewAligned(
+ CI->getArgOperand(0), CI->getArgOperand(1), B, TLI,
+ LibFunc_ZnamSt11align_val_t12__hot_cold_t, HotCold);
+ break;
+ case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
+ if (OptimizeExistingHotColdNew)
+ return emitHotColdNewAlignedNoThrow(
+ CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2), B,
+ TLI, LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
+ HotCold);
+ break;
case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
- return emitHotColdNewAlignedNoThrow(
- CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2), B,
- TLI, LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t, HotCold);
+ if (HotCold != NotColdNewHintValue)
+ return emitHotColdNewAlignedNoThrow(
+ CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2), B,
+ TLI, LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
+ HotCold);
+ break;
+ case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
+ if (OptimizeExistingHotColdNew)
+ return emitHotColdNewAlignedNoThrow(
+ CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2), B,
+ TLI, LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
+ HotCold);
+ break;
case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
- return emitHotColdNewAlignedNoThrow(
- CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2), B,
- TLI, LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t, HotCold);
+ if (HotCold != NotColdNewHintValue)
+ return emitHotColdNewAlignedNoThrow(
+ CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2), B,
+ TLI, LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t,
+ HotCold);
+ break;
default:
return nullptr;
}
+ return nullptr;
}
//===----------------------------------------------------------------------===//
@@ -3675,6 +3760,14 @@ Value *LibCallSimplifier::optimizeStringMemoryLibCall(CallInst *CI,
case LibFunc_ZnamRKSt9nothrow_t:
case LibFunc_ZnamSt11align_val_t:
case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
+ case LibFunc_Znwm12__hot_cold_t:
+ case LibFunc_ZnwmRKSt9nothrow_t12__hot_cold_t:
+ case LibFunc_ZnwmSt11align_val_t12__hot_cold_t:
+ case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
+ case LibFunc_Znam12__hot_cold_t:
+ case LibFunc_ZnamRKSt9nothrow_t12__hot_cold_t:
+ case LibFunc_ZnamSt11align_val_t12__hot_cold_t:
+ case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t:
return optimizeNew(CI, Builder, Func);
default:
break;
diff --git a/llvm/test/Transforms/InstCombine/simplify-libcalls-new.ll b/llvm/test/Transforms/InstCombine/simplify-libcalls-new.ll
index 51debdf6643ec..ecfafbc69797b 100644
--- a/llvm/test/Transforms/InstCombine/simplify-libcalls-new.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-libcalls-new.ll
@@ -1,13 +1,19 @@
;; Test behavior of -optimize-hot-cold-new and related options.
;; Check that we don't get hot/cold new calls without enabling it explicitly.
-; RUN: opt < %s -passes=instcombine -S | FileCheck %s --implicit-check-not=hot_cold_t
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s --check-prefix=OFF
+; OFF-NOT: hot_cold_t
+; OFF-LABEL: @new_hot_cold()
;; First check with the default cold and hot hint values (255 = -2).
-; RUN: opt < %s -passes=instcombine -optimize-hot-cold-new -S | FileCheck %s --check-prefix=HOTCOLD -DCOLD=1 -DHOT=-2
+; RUN: opt < %s -passes=instcombine -optimize-hot-cold-new -S | FileCheck %s --check-prefix=HOTCOLD -DCOLD=1 -DHOT=-2 -DPREVHINTCOLD=7 -DPREVHINTNOTCOLD=7 -DPREVHINTHOT=7
;; Next check with the non-default cold and hot hint values (200 =-56).
-; RUN: opt < %s -passes=instcombine -optimize-hot-cold-new -cold-new-hint-value=5 -hot-new-hint-value=200 -S | FileCheck %s --check-prefix=HOTCOLD -DCOLD=5 -DHOT=-56
+; RUN: opt < %s -passes=instcombine -optimize-hot-cold-new -cold-new-hint-value=5 -hot-new-hint-value=200 -S | FileCheck %s --check-prefix=HOTCOLD -DCOLD=5 -DHOT=-56 -DPREVHINTCOLD=7 -DPREVHINTNOTCOLD=7 -DPREVHINTHOT=7
+
+;; Try again with the non-default cold and hot hint values (200 =-56), and this
+;; time specify that existing hints should be updated.
+; RUN: opt < %s -passes=instcombine -optimize-hot-cold-new -cold-new-hint-value=5 -notcold-new-hint-value=100 -hot-new-hint-value=200 -optimize-existing-hot-cold-new -S | FileCheck %s --check-prefix=HOTCOLD -DCOLD=5 -DHOT=-56 -DPREVHINTCOLD=5 -DPREVHINTNOTCOLD=100 -DPREVHINTHOT=-56
;; Make sure that values not in 0..255 are flagged with an error
; RUN: not opt < %s -passes=instcombine -optimize-hot-cold-new -cold-new-hint-value=256 -S 2>&1 | FileCheck %s --check-prefix=ERROR
@@ -178,6 +184,162 @@ define void @array_new_align_nothrow() {
ret void
}
+;; Check that operator new(unsigned long, __hot_cold_t)
+;; optionally has its hint updated.
+; HOTCOLD-LABEL: @new_hot_cold()
+define void @new_hot_cold() {
+ ;; Attribute cold converted to __hot_cold_t cold value.
+ ; HOTCOLD: @_Znwm12__hot_cold_t(i64 10, i8 [[PREVHINTCOLD]])
+ %call = call ptr @_Znwm12__hot_cold_t(i64 10, i8 7) #0
+ call void @dummy(ptr %call)
+ ;; Attribute notcold converted to __hot_cold_t notcold value.
+ ; HOTCOLD: @_Znwm12__hot_cold_t(i64 10, i8 [[PREVHINTNOTCOLD]])
+ %call1 = call ptr @_Znwm12__hot_cold_t(i64 10, i8 7) #1
+ call void @dummy(ptr %call1)
+ ;; Attribute hot converted to __hot_cold_t hot value.
+ ; HOTCOLD: @_Znwm12__hot_cold_t(i64 10, i8 [[PREVHINTHOT]])
+ %call2 = call ptr @_Znwm12__hot_cold_t(i64 10, i8 7) #2
+ call void @dummy(ptr %call2)
+ ret void
+}
+
+;; Check that operator new(unsigned long, std::align_val_t, __hot_cold_t)
+;; optionally has its hint updated.
+; HOTCOLD-LABEL: @new_align_hot_cold()
+define void @new_align_hot_cold() {
+ ;; Attribute cold converted to __hot_cold_t cold value.
+ ; HOTCOLD: @_ZnwmSt11align_val_t12__hot_cold_t(i64 10, i64 8, i8 [[PREVHINTCOLD]])
+ %call = call ptr @_ZnwmSt11align_val_t12__hot_cold_t(i64 10, i64 8, i8 7) #0
+ call void @dummy(ptr %call)
+ ;; Attribute notcold converted to __hot_cold_t notcold value.
+ ; HOTCOLD: @_ZnwmSt11align_val_t12__hot_cold_t(i64 10, i64 8, i8 [[PREVHINTNOTCOLD]])
+ %call1 = call ptr @_ZnwmSt11align_val_t12__hot_cold_t(i64 10, i64 8, i8 7) #1
+ call void @dummy(ptr %call1)
+ ;; Attribute hot converted to __hot_cold_t hot value.
+ ; HOTCOLD: @_ZnwmSt11align_val_t12__hot_cold_t(i64 10, i64 8, i8 [[PREVHINTHOT]])
+ %call2 = call ptr @_ZnwmSt11align_val_t12__hot_cold_t(i64 10, i64 8, i8 7) #2
+ call void @dummy(ptr %call2)
+ ret void
+}
+
+;; Check that operator new(unsigned long, const std::nothrow_t&, __hot_cold_t)
+;; optionally has its hint updated.
+; HOTCOLD-LABEL: @new_nothrow_hot_cold()
+define void @new_nothrow_hot_cold() {
+ %nt = alloca i8
+ ;; Attribute cold converted to __hot_cold_t cold value.
+ ; HOTCOLD: @_ZnwmRKSt9nothrow_t12__hot_cold_t(i64 10, ptr nonnull %nt, i8 [[PREVHINTCOLD]])
+ %call = call ptr @_ZnwmRKSt9nothrow_t12__hot_cold_t(i64 10, ptr %nt, i8 7) #0
+ call void @dummy(ptr %call)
+ ;; Attribute notcold converted to __hot_cold_t notcold value.
+ ; HOTCOLD: @_ZnwmRKSt9nothrow_t12__hot_cold_t(i64 10, ptr nonnull %nt, i8 [[PREVHINTNOTCOLD]])
+ %call1 = call ptr @_ZnwmRKSt9nothrow_t12__hot_cold_t(i64 10, ptr %nt, i8 7) #1
+ call void @dummy(ptr %call1)
+ ;; Attribute hot converted to __hot_cold_t hot value.
+ ; HOTCOLD: @_ZnwmRKSt9nothrow_t12__hot_cold_t(i64 10, ptr nonnull %nt, i8 [[PREVHINTHOT]])
+ %call2 = call ptr @_ZnwmRKSt9nothrow_t12__hot_cold_t(i64 10, ptr %nt, i8 7) #2
+ call void @dummy(ptr %call2)
+ ret void
+}
+
+;; Check that operator new(unsigned long, std::align_val_t, const std::nothrow_t&, __hot_cold_t)
+;; optionally has its hint updated.
+; HOTCOLD-LABEL: @new_align_nothrow_hot_cold()
+define void @new_align_nothrow_hot_cold() {
+ %nt = alloca i8
+ ;; Attribute cold converted to __hot_cold_t cold value.
+ ; HOTCOLD: @_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 10, i64 8, ptr nonnull %nt, i8 [[PREVHINTCOLD]])
+ %call = call ptr @_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 10, i64 8, ptr %nt, i8 7) #0
+ call void @dummy(ptr %call)
+ ;; Attribute notcold converted to __hot_cold_t notcold value.
+ ; HOTCOLD: @_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 10, i64 8, ptr nonnull %nt, i8 [[PREVHINTNOTCOLD]])
+ %call1 = call ptr @_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 10, i64 8, ptr %nt, i8 7) #1
+ call void @dummy(ptr %call1)
+ ;; Attribute hot converted to __hot_cold_t hot value.
+ ; HOTCOLD: @_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 10, i64 8, ptr nonnull %nt, i8 [[PREVHINTHOT]])
+ %call2 = call ptr @_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 10, i64 8, ptr %nt, i8 7) #2
+ call void @dummy(ptr %call2)
+ ret void
+}
+
+;; Check that operator new[](unsigned long, __hot_cold_t)
+;; optionally has its hint updated.
+; HOTCOLD-LABEL: @array_new_hot_cold()
+define void @array_new_hot_cold() {
+ ;; Attribute cold converted to __hot_cold_t cold value.
+ ; HOTCOLD: @_Znam12__hot_cold_t(i64 10, i8 [[PREVHINTCOLD]])
+ %call = call ptr @_Znam12__hot_cold_t(i64 10, i8 7) #0
+ call void @dummy(ptr %call)
+ ;; Attribute notcold converted to __hot_cold_t notcold value.
+ ; HOTCOLD: @_Znam12__hot_cold_t(i64 10, i8 [[PREVHINTNOTCOLD]])
+ %call1 = call ptr @_Znam12__hot_cold_t(i64 10, i8 7) #1
+ call void @dummy(ptr %call1)
+ ;; Attribute hot converted to __hot_cold_t hot value.
+ ; HOTCOLD: @_Znam12__hot_cold_t(i64 10, i8 [[PREVHINTHOT]])
+ %call2 = call ptr @_Znam12__hot_cold_t(i64 10, i8 7) #2
+ call void @dummy(ptr %call2)
+ ret void
+}
+
+;; Check that operator new[](unsigned long, std::align_val_t, __hot_cold_t)
+;; optionally has its hint updated.
+; HOTCOLD-LABEL: @array_new_align_hot_cold()
+define void @array_new_align_hot_cold() {
+ ;; Attribute cold converted to __hot_cold_t cold value.
+ ; HOTCOLD: @_ZnamSt11align_val_t12__hot_cold_t(i64 10, i64 8, i8 [[PREVHINTCOLD]])
+ %call = call ptr @_ZnamSt11align_val_t12__hot_cold_t(i64 10, i64 8, i8 7) #0
+ call void @dummy(ptr %call)
+ ;; Attribute notcold converted to __hot_cold_t notcold value.
+ ; HOTCOLD: @_ZnamSt11align_val_t12__hot_cold_t(i64 10, i64 8, i8 [[PREVHINTNOTCOLD]])
+ %call1 = call ptr @_ZnamSt11align_val_t12__hot_cold_t(i64 10, i64 8, i8 7) #1
+ call void @dummy(ptr %call1)
+ ;; Attribute hot converted to __hot_cold_t hot value.
+ ; HOTCOLD: @_ZnamSt11align_val_t12__hot_cold_t(i64 10, i64 8, i8 [[PREVHINTHOT]])
+ %call2 = call ptr @_ZnamSt11align_val_t12__hot_cold_t(i64 10, i64 8, i8 7) #2
+ call void @dummy(ptr %call2)
+ ret void
+}
+
+;; Check that operator new[](unsigned long, const std::nothrow_t&, __hot_cold_t)
+;; optionally has its hint updated.
+; HOTCOLD-LABEL: @array_new_nothrow_hot_cold()
+define void @array_new_nothrow_hot_cold() {
+ %nt = alloca i8
+ ;; Attribute cold converted to __hot_cold_t cold value.
+ ; HOTCOLD: @_ZnamRKSt9nothrow_t12__hot_cold_t(i64 10, ptr nonnull %nt, i8 [[PREVHINTCOLD]])
+ %call = call ptr @_ZnamRKSt9nothrow_t12__hot_cold_t(i64 10, ptr %nt, i8 7) #0
+ call void @dummy(ptr %call)
+ ;; Attribute notcold converted to __hot_cold_t notcold value.
+ ; HOTCOLD: @_ZnamRKSt9nothrow_t12__hot_cold_t(i64 10, ptr nonnull %nt, i8 [[PREVHINTNOTCOLD]])
+ %call1 = call ptr @_ZnamRKSt9nothrow_t12__hot_cold_t(i64 10, ptr %nt, i8 7) #1
+ call void @dummy(ptr %call1)
+ ;; Attribute hot converted to __hot_cold_t hot value.
+ ; HOTCOLD: @_ZnamRKSt9nothrow_t12__hot_cold_t(i64 10, ptr nonnull %nt, i8 [[PREVHINTHOT]])
+ %call2 = call ptr @_ZnamRKSt9nothrow_t12__hot_cold_t(i64 10, ptr %nt, i8 7) #2
+ call void @dummy(ptr %call2)
+ ret void
+}
+
+;; Check that operator new[](unsigned long, std::align_val_t, const std::nothrow_t&, __hot_cold_t)
+;; optionally has its hint updated.
+; HOTCOLD-LABEL: @array_new_align_nothrow_hot_cold()
+define void @array_new_align_nothrow_hot_cold() {
+ %nt = alloca i8
+ ;; Attribute cold converted to __hot_cold_t cold value.
+ ; HOTCOLD: @_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 10, i64 8, ptr nonnull %nt, i8 [[PREVHINTCOLD]])
+ %call = call ptr @_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 10, i64 8, ptr %nt, i8 7) #0
+ call void @dummy(ptr %call)
+ ;; Attribute notcold converted to __hot_cold_t notcold value.
+ ; HOTCOLD: @_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 10, i64 8, ptr nonnull %nt, i8 [[PREVHINTNOTCOLD]])
+ %call1 = call ptr @_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 10, i64 8, ptr %nt, i8 7) #1
+ call void @dummy(ptr %call1)
+ ;; Attribute hot converted to __hot_cold_t hot value.
+ ; HOTCOLD: @_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 10, i64 8, ptr nonnull %nt, i8 [[PREVHINTHOT]])
+ %call2 = call ptr @_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64 10, i64 8, ptr %nt, i8 7) #2
+ call void @dummy(ptr %call2)
+ ret void
+}
+
;; So that instcombine doesn't optimize out the call.
declare void @dummy(ptr)
@@ -189,6 +351,14 @@ declare ptr @_Znam(i64)
declare ptr @_ZnamSt11align_val_t(i64, i64)
declare ptr @_ZnamRKSt9nothrow_t(i64, ptr)
declare ptr @_ZnamSt11align_val_tRKSt9nothrow_t(i64, i64, ptr)
+declare ptr @_Znwm12__hot_cold_t(i64, i8)
+declare ptr @_ZnwmSt11align_val_t12__hot_cold_t(i64, i64, i8)
+declare ptr @_ZnwmRKSt9nothrow_t12__hot_cold_t(i64, ptr, i8)
+declare ptr @_ZnwmSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64, i64, ptr, i8)
+declare ptr @_Znam12__hot_cold_t(i64, i8)
+declare ptr @_ZnamSt11align_val_t12__hot_cold_t(i64, i64, i8)
+declare ptr @_ZnamRKSt9nothrow_t12__hot_cold_t(i64, ptr, i8)
+declare ptr @_ZnamSt11align_val_tRKSt9nothrow_t12__hot_cold_t(i64, i64, ptr, i8)
attributes #0 = { builtin allocsize(0) "memprof"="cold" }
attributes #1 = { builtin allocsize(0) "memprof"="notcold" }
|
If directed by an option, update hints on calls to new that already
provide a hot/cold hint.