Skip to content

Commit dde0be9

Browse files
authored
[Metadata] Handle memprof, callsite merging when one is missing. (#132106)
For memprof and callsite metadata we want to pick one deterministically and keep that even if one of them may be missing.
1 parent d7724c8 commit dde0be9

File tree

3 files changed

+117
-9
lines changed

3 files changed

+117
-9
lines changed

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3355,8 +3355,12 @@ static void combineMetadata(Instruction *K, const Instruction *J,
33553355
case LLVMContext::MD_invariant_group:
33563356
// Preserve !invariant.group in K.
33573357
break;
3358+
// Keep empty cases for mmra, memprof, and callsite to prevent them from
3359+
// being removed as unknown metadata. The actual merging is handled
3360+
// separately below.
33583361
case LLVMContext::MD_mmra:
3359-
// Combine MMRAs
3362+
case LLVMContext::MD_memprof:
3363+
case LLVMContext::MD_callsite:
33603364
break;
33613365
case LLVMContext::MD_align:
33623366
if (!AAOnly && (DoesKMove || !K->hasMetadata(LLVMContext::MD_noundef)))
@@ -3369,14 +3373,6 @@ static void combineMetadata(Instruction *K, const Instruction *J,
33693373
K->setMetadata(Kind,
33703374
MDNode::getMostGenericAlignmentOrDereferenceable(JMD, KMD));
33713375
break;
3372-
case LLVMContext::MD_memprof:
3373-
if (!AAOnly)
3374-
K->setMetadata(Kind, MDNode::getMergedMemProfMetadata(KMD, JMD));
3375-
break;
3376-
case LLVMContext::MD_callsite:
3377-
if (!AAOnly)
3378-
K->setMetadata(Kind, MDNode::getMergedCallsiteMetadata(KMD, JMD));
3379-
break;
33803376
case LLVMContext::MD_preserve_access_index:
33813377
// Preserve !preserve.access.index in K.
33823378
break;
@@ -3420,6 +3416,26 @@ static void combineMetadata(Instruction *K, const Instruction *J,
34203416
K->setMetadata(LLVMContext::MD_mmra,
34213417
MMRAMetadata::combine(K->getContext(), JMMRA, KMMRA));
34223418
}
3419+
3420+
// Merge memprof metadata.
3421+
// Handle separately to support cases where only one instruction has the
3422+
// metadata.
3423+
auto *JMemProf = J->getMetadata(LLVMContext::MD_memprof);
3424+
auto *KMemProf = K->getMetadata(LLVMContext::MD_memprof);
3425+
if (!AAOnly && (JMemProf || KMemProf)) {
3426+
K->setMetadata(LLVMContext::MD_memprof,
3427+
MDNode::getMergedMemProfMetadata(KMemProf, JMemProf));
3428+
}
3429+
3430+
// Merge callsite metadata.
3431+
// Handle separately to support cases where only one instruction has the
3432+
// metadata.
3433+
auto *JCallSite = J->getMetadata(LLVMContext::MD_callsite);
3434+
auto *KCallSite = K->getMetadata(LLVMContext::MD_callsite);
3435+
if (!AAOnly && (JCallSite || KCallSite)) {
3436+
K->setMetadata(LLVMContext::MD_callsite,
3437+
MDNode::getMergedCallsiteMetadata(KCallSite, JCallSite));
3438+
}
34233439
}
34243440

34253441
void llvm::combineMetadataForCSE(Instruction *K, const Instruction *J,
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
;; Test to ensure that memprof related metadata is not dropped when
3+
;; instructions are combined. Currently the metadata from the first instruction
4+
;; is kept, which prevents full loss of profile context information.
5+
6+
; RUN: opt < %s -passes=simplifycfg -S | FileCheck %s
7+
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-unknown-linux-gnu"
10+
11+
define dso_local noundef nonnull ptr @_Z9test_leftb(i1 noundef zeroext %b) local_unnamed_addr #0 {
12+
; CHECK-LABEL: define dso_local noundef nonnull ptr @_Z9test_leftb(
13+
; CHECK-SAME: i1 noundef zeroext [[B:%.*]]) local_unnamed_addr {
14+
; CHECK-NEXT: [[ENTRY:.*:]]
15+
; CHECK-NEXT: [[CALL:%.*]] = call noalias noundef nonnull dereferenceable(4) ptr @_Znwm(i64 noundef 4), !memprof [[META0:![0-9]+]], !callsite [[META3:![0-9]+]]
16+
; CHECK-NEXT: ret ptr [[CALL]]
17+
;
18+
entry:
19+
br i1 %b, label %if.then, label %if.else
20+
21+
if.then: ; preds = %entry
22+
%call = call noalias noundef nonnull dereferenceable(4) ptr @_Znwm(i64 noundef 4), !memprof !0, !callsite !3
23+
br label %if.end
24+
25+
if.else: ; preds = %entry
26+
%call1 = call noalias noundef nonnull dereferenceable(4) ptr @_Znwm(i64 noundef 4)
27+
br label %if.end
28+
29+
if.end: ; preds = %if.else, %if.then
30+
%x.0 = phi ptr [ %call, %if.then ], [ %call1, %if.else ]
31+
ret ptr %x.0
32+
}
33+
34+
declare ptr @_Znwm(i64) nounwind readonly
35+
36+
!0 = !{!1}
37+
!1 = !{!2, !"notcold"}
38+
!2 = !{i64 -852997907418798798, i64 -2101080423462424381, i64 5188446645037944434}
39+
!3 = !{i64 -852997907418798798}
40+
41+
;.
42+
; CHECK: [[META0]] = !{[[META1:![0-9]+]]}
43+
; CHECK: [[META1]] = !{[[META2:![0-9]+]], !"notcold"}
44+
; CHECK: [[META2]] = !{i64 -852997907418798798, i64 -2101080423462424381, i64 5188446645037944434}
45+
; CHECK: [[META3]] = !{i64 -852997907418798798}
46+
;.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
;; Test to ensure that memprof related metadata is not dropped when
3+
;; instructions are combined. Currently the metadata from the first instruction
4+
;; is kept, which prevents full loss of profile context information.
5+
6+
; RUN: opt < %s -passes=simplifycfg -S | FileCheck %s
7+
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-unknown-linux-gnu"
10+
11+
define dso_local noundef nonnull ptr @_Z10test_rightb(i1 noundef zeroext %b) local_unnamed_addr #0 {
12+
; CHECK-LABEL: define dso_local noundef nonnull ptr @_Z10test_rightb(
13+
; CHECK-SAME: i1 noundef zeroext [[B:%.*]]) local_unnamed_addr {
14+
; CHECK-NEXT: [[ENTRY:.*:]]
15+
; CHECK-NEXT: [[CALL:%.*]] = call noalias noundef nonnull dereferenceable(4) ptr @_Znwm(i64 noundef 4), !memprof [[META0:![0-9]+]], !callsite [[META3:![0-9]+]]
16+
; CHECK-NEXT: ret ptr [[CALL]]
17+
;
18+
entry:
19+
br i1 %b, label %if.then, label %if.else
20+
21+
if.then: ; preds = %entry
22+
%call = call noalias noundef nonnull dereferenceable(4) ptr @_Znwm(i64 noundef 4)
23+
br label %if.end
24+
25+
if.else: ; preds = %entry
26+
%call1 = call noalias noundef nonnull dereferenceable(4) ptr @_Znwm(i64 noundef 4), !memprof !4, !callsite !7
27+
br label %if.end
28+
29+
if.end: ; preds = %if.else, %if.then
30+
%x.0 = phi ptr [ %call, %if.then ], [ %call1, %if.else ]
31+
ret ptr %x.0
32+
}
33+
34+
declare ptr @_Znwm(i64) nounwind readonly
35+
36+
!4 = !{!5}
37+
!5 = !{!6, !"cold"}
38+
!6 = !{i64 123, i64 -2101080423462424381, i64 5188446645037944434}
39+
!7 = !{i64 123}
40+
41+
;.
42+
; CHECK: [[META0]] = !{[[META1:![0-9]+]]}
43+
; CHECK: [[META1]] = !{[[META2:![0-9]+]], !"cold"}
44+
; CHECK: [[META2]] = !{i64 123, i64 -2101080423462424381, i64 5188446645037944434}
45+
; CHECK: [[META3]] = !{i64 123}
46+
;.

0 commit comments

Comments
 (0)