
Currently, `TargetLoweringObjectFileELF::getSectionForConstant` produce `.<section>.hot` or `.<section>.unlikely` for a constant with non-empty section prefix. This PR changes the implementation add trailing dot when section prefix is not empty, to disambiguate `.hot` as a hotness prefix from `.hot` as a (pure C) variable name. Relevant discussions are in https://github.com/llvm/llvm-project/pull/148985#discussion_r2221141273 and https://github.com/llvm/llvm-project/pull/148985#discussion_r2233382641 and
140 lines
5.4 KiB
LLVM
140 lines
5.4 KiB
LLVM
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"
|
|
target triple = "x86_64-grtev4-linux-gnu"
|
|
|
|
; Tests that constant pool hotness is aggregated across the module. The
|
|
; static-data-splitter processes data from @cold_func first, two functions
|
|
; without profiles secondly, and then @hot_func. Specifically, tests that
|
|
; 1. If a constant is accessed by hot functions, all constant pools for this
|
|
; constant (e.g., from an unprofiled function, or cold function) should have
|
|
; .hot suffix.
|
|
; 2. Similarly if a constant is accessed by both cold function and un-profiled
|
|
; function, constant pools for this constant should not have .unlikely suffix.
|
|
|
|
; RUN: llc -mtriple=x86_64-unknown-linux-gnu -partition-static-data-sections \
|
|
; RUN: -function-sections -data-sections -unique-section-names=false \
|
|
; RUN: %s -o - 2>&1 | FileCheck %s --dump-input=always
|
|
|
|
; RUN: llc -mtriple=x86_64-unknown-linux-gnu -partition-static-data-sections \
|
|
; RUN: -function-sections -data-sections -unique-section-names \
|
|
; RUN: %s -o - 2>&1 | FileCheck %s --dump-input=always
|
|
|
|
; RUN: llc -mtriple=x86_64-unknown-linux-gnu -partition-static-data-sections \
|
|
; RUN: -function-sections=false -data-sections=false \
|
|
; RUN: -unique-section-names=false \
|
|
; RUN: %s -o - 2>&1 | FileCheck %s --dump-input=always
|
|
|
|
;; For function @cold_func
|
|
; CHECK: .section .rodata.cst8.hot.,"aM",@progbits,8
|
|
; CHECK-NEXT: .p2align
|
|
; CHECK-NEXT: .LCPI0_0:
|
|
; CHECK-NEXT: .quad 0x3fe5c28f5c28f5c3 # double 0.68000000000000005
|
|
; CHECK-NEXT: .section .rodata.cst8.unlikely.,"aM",@progbits,8
|
|
; CHECK-NEXT: .p2align
|
|
; CHECK-NEXT: .LCPI0_1:
|
|
; CHECK-NEXT: .quad 0x3eb0000000000000 # double 9.5367431640625E-7
|
|
; CHECK-NEXT: .section .rodata.cst8,"aM",@progbits,8
|
|
; CHECK-NEXT: .p2align
|
|
; CHECK-NEXT: .LCPI0_2:
|
|
; CHECK-NEXT: .quad 0x3fc0000000000000 # double 0.125
|
|
|
|
;; For function @unprofiled_func_double
|
|
; CHECK: .section .rodata.cst8,"aM",@progbits,8
|
|
; CHECK-NEXT: .p2align
|
|
; CHECK-NEXT: .LCPI1_0:
|
|
; CHECK-NEXT: .quad 0x3fc0000000000000 # double 0.125
|
|
|
|
;; For function @unprofiled_func_float
|
|
; CHECK: .section .rodata.cst4,"aM",@progbits,4
|
|
; CHECK-NEXT: .p2align
|
|
; CHECK-NEXT: .LCPI2_0:
|
|
; CHECK-NEXT: .long 0x3e000000 # float 0.125
|
|
|
|
;; For function @hot_func
|
|
; CHECK: .section .rodata.cst8.hot.,"aM",@progbits,8
|
|
; CHECK-NEXT: .p2align
|
|
; CHECK-NEXT: .LCPI3_0:
|
|
; CHECK-NEXT: .quad 0x3fe5c28f5c28f5c3 # double 0.68000000000000005
|
|
; CHECK-NEXT: .section .rodata.cst16.hot.,"aM",@progbits,16
|
|
; CHECK-NEXT: .p2align
|
|
; CHECK-NEXT: .LCPI3_1:
|
|
; CHECK-NEXT: .long 2147483648 # 0x80000000
|
|
; CHECK-NEXT: .long 2147483648 # 0x80000000
|
|
; CHECK-NEXT: .long 2147483648 # 0x80000000
|
|
; CHECK-NEXT: .long 2147483648 # 0x80000000
|
|
; CHECK-NEXT: .LCPI3_2:
|
|
; CHECK-NEXT: .long 2147484090 # 0x800001ba
|
|
; CHECK-NEXT: .long 2147483748 # 0x80000064
|
|
; CHECK-NEXT: .long 2147483648 # 0x80000000
|
|
; CHECK-NEXT: .long 2147483648 # 0x80000000
|
|
|
|
; CHECK: .section .rodata.cst32,"aM",@progbits,32
|
|
; CHECK-NEXT: .globl val
|
|
|
|
define double @cold_func(double %x) !prof !16 {
|
|
%2 = tail call i32 (...) @func_taking_arbitrary_param(double 6.800000e-01)
|
|
%y = fmul double %x, 0x3EB0000000000000
|
|
%z = fmul double %y, 0x3fc0000000000000
|
|
ret double %z
|
|
}
|
|
|
|
define double @unprofiled_func_double(double %x) {
|
|
%z = fmul double %x, 0x3fc0000000000000
|
|
ret double %z
|
|
}
|
|
|
|
define float @unprofiled_func_float(float %x) {
|
|
%z = fmul float %x, 0x3fc0000000000000
|
|
ret float %z
|
|
}
|
|
|
|
define <4 x i1> @hot_func(i32 %0, <4 x i32> %a) !prof !17 {
|
|
%2 = tail call i32 (...) @func_taking_arbitrary_param(double 6.800000e-01)
|
|
%b = icmp ule <4 x i32> %a, <i32 442, i32 100, i32 0, i32 0>
|
|
ret <4 x i1> %b
|
|
}
|
|
|
|
@val = unnamed_addr constant i256 1
|
|
|
|
define i32 @main(i32 %0, ptr %1) !prof !16 {
|
|
br label %7
|
|
|
|
5: ; preds = %7
|
|
%x = call double @double_func()
|
|
call void @cold_func(double %x)
|
|
ret i32 0
|
|
|
|
7: ; preds = %7, %2
|
|
%8 = phi i32 [ 0, %2 ], [ %10, %7 ]
|
|
%seed_val = load i256, ptr @val
|
|
%9 = call i32 @seed(i256 %seed_val)
|
|
call void @hot_func(i32 %9)
|
|
%10 = add i32 %8, 1
|
|
%11 = icmp eq i32 %10, 100000
|
|
br i1 %11, label %5, label %7, !prof !18
|
|
}
|
|
|
|
declare i32 @seed(i256)
|
|
declare double @double_func()
|
|
declare i32 @func_taking_arbitrary_param(...)
|
|
|
|
!llvm.module.flags = !{!1}
|
|
|
|
!1 = !{i32 1, !"ProfileSummary", !2}
|
|
!2 = !{!3, !4, !5, !6, !7, !8, !9, !10, !11, !12}
|
|
!3 = !{!"ProfileFormat", !"InstrProf"}
|
|
!4 = !{!"TotalCount", i64 1460617}
|
|
!5 = !{!"MaxCount", i64 849536}
|
|
!6 = !{!"MaxInternalCount", i64 32769}
|
|
!7 = !{!"MaxFunctionCount", i64 849536}
|
|
!8 = !{!"NumCounts", i64 23784}
|
|
!9 = !{!"NumFunctions", i64 3301}
|
|
!10 = !{!"IsPartialProfile", i64 0}
|
|
!11 = !{!"PartialProfileRatio", double 0.000000e+00}
|
|
!12 = !{!"DetailedSummary", !13}
|
|
!13 = !{!14, !15}
|
|
!14 = !{i32 990000, i64 166, i32 73}
|
|
!15 = !{i32 999999, i64 1, i32 1463}
|
|
!16 = !{!"function_entry_count", i64 1}
|
|
!17 = !{!"function_entry_count", i64 100000}
|
|
!18 = !{!"branch_weights", i32 1, i32 99999}
|