Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion llvm/lib/Analysis/StaticDataProfileInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
#include "llvm/ProfileData/InstrProf.h"

using namespace llvm;

cl::opt<bool> PreserveHotDataSectionPrefix(
"preserve-hot-data-section-prefix", cl::Hidden, cl::init(true),
cl::desc("If true, hot data section prefixes are preserved"));

void StaticDataProfileInfo::addConstantProfileCount(
const Constant *C, std::optional<uint64_t> Count) {
if (!Count) {
Expand Down Expand Up @@ -36,7 +41,7 @@ StringRef StaticDataProfileInfo::getConstantSectionPrefix(
// The accummulated counter shows the constant is hot. Return 'hot' whether
// this variable is seen by unprofiled functions or not.
if (PSI->isHotCount(*Count))
return "hot";
return PreserveHotDataSectionPrefix ? "hot" : "";
// The constant is not hot, and seen by unprofiled functions. We don't want to
// assign it to unlikely sections, even if the counter says 'cold'. So return
// an empty prefix before checking whether the counter is cold.
Expand Down
43 changes: 31 additions & 12 deletions llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@
using namespace llvm;
using namespace dwarf;

extern cl::opt<bool> PreserveHotDataSectionPrefix;

static cl::opt<bool> JumpTableInFunctionSection(
"jumptable-in-function-section", cl::Hidden, cl::init(false),
cl::desc("Putting Jump Table in function section"));
Expand Down Expand Up @@ -655,26 +657,43 @@ getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind,
}

bool HasPrefix = false;
SmallString<32> SectionPrefix;
if (const auto *F = dyn_cast<Function>(GO)) {
// Jump table hotness takes precedence over its enclosing function's hotness
// if it's known. The function's section prefix is used if jump table entry
// hotness is unknown.
if (JTE && JTE->Hotness != MachineFunctionDataHotness::Unknown) {
if (JTE->Hotness == MachineFunctionDataHotness::Hot) {
raw_svector_ostream(Name) << ".hot";
} else {
assert(JTE->Hotness == MachineFunctionDataHotness::Cold &&
"Hotness must be cold");
raw_svector_ostream(Name) << ".unlikely";
switch (JTE->Hotness) {
case MachineFunctionDataHotness::Cold:
raw_svector_ostream(SectionPrefix) << ".unlikely";
break;
case MachineFunctionDataHotness::Hot: {
if (PreserveHotDataSectionPrefix)
raw_svector_ostream(SectionPrefix) << ".hot";
break;
}
HasPrefix = true;
} else if (std::optional<StringRef> Prefix = F->getSectionPrefix()) {
raw_svector_ostream(Name) << '.' << *Prefix;
HasPrefix = true;
}
default:
llvm_unreachable("Unknown jump table hotness");
break;
}
} else if (std::optional<StringRef> Prefix = F->getSectionPrefix())
raw_svector_ostream(SectionPrefix) << "." << *Prefix;
} else if (const auto *GV = dyn_cast<GlobalVariable>(GO)) {
if (std::optional<StringRef> Prefix = GV->getSectionPrefix()) {
raw_svector_ostream(Name) << '.' << *Prefix;
raw_svector_ostream(SectionPrefix) << "." << *Prefix;
}
}

if (!SectionPrefix.empty()) {
bool AddSectionPrefix = true;
if (Kind.isReadOnly() || Kind.isReadOnlyWithRel() || Kind.isData() ||
Kind.isBSS()) {
AddSectionPrefix =
!SectionPrefix.starts_with(".hot") || PreserveHotDataSectionPrefix;
}

if (AddSectionPrefix) {
Name += SectionPrefix;
HasPrefix = true;
}
}
Expand Down
175 changes: 110 additions & 65 deletions llvm/test/CodeGen/AArch64/constant-pool-partition.ll
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
; RUN: llc -mtriple=aarch64 -partition-static-data-sections \
; RUN: -function-sections -unique-section-names=false \
; RUN: %s -o - 2>&1 | FileCheck %s --dump-input=always
; RUN: %s -o - 2>&1 | FileCheck %s --check-prefixes=HOT,COMM --dump-input=always

; RUN: llc -mtriple=aarch64 -partition-static-data-sections \
; RUN: -function-sections -unique-section-names=false \
; RUN: -preserve-hot-data-section-prefix=false \
; RUN: %s -o - 2>&1 | FileCheck %s --check-prefixes=NOHOT,COMM --dump-input=always

; Repeat the RUN commands above for big-endian systems.
; RUN: llc -mtriple=aarch64_be -partition-static-data-sections \
; RUN: -function-sections -unique-section-names=false \
; RUN: %s -o - 2>&1 | FileCheck %s --check-prefixes=HOT,COMM --dump-input=always

; Repeat the RUN command above for big-endian systems.
; RUN: llc -mtriple=aarch64_be -partition-static-data-sections \
; RUN: -function-sections -unique-section-names=false \
; RUN: %s -o - 2>&1 | FileCheck %s --dump-input=always
; RUN: -preserve-hot-data-section-prefix=false \
; RUN: %s -o - 2>&1 | FileCheck %s --check-prefixes=NOHOT,COMM --dump-input=always

; Tests that constant pool hotness is aggregated across the module. The
; static-data-splitter processes data from cold_func first, unprofiled_func
Expand All @@ -19,77 +29,112 @@
; function, constant pools for this constant should not have `.unlikely` suffix.

;; Constant pools for function @cold_func.
; CHECK: .section .rodata.cst8.hot.,"aM",@progbits,8
; CHECK-NEXT: .p2align
; CHECK-NEXT: .LCPI0_0:
; CHECK-NEXT: .xword 0x3fe5c28f5c28f5c3 // double 0.68000000000000005
; CHECK-NEXT: .section .rodata.cst8.unlikely.,"aM",@progbits,8
; CHECK-NEXT: .p2align
; CHECK-NEXT: .LCPI0_1:
; CHECK-NEXT: .xword 0x3fe5eb851eb851ec // double 0.68500000000000005
; CHECK-NEXT: .section .rodata.cst8,"aM",@progbits,8
; CHECK-NEXT: .p2align
; CHECK-NEXT: .LCPI0_2:
; CHECK-NEXT: .byte 0 // 0x0
; CHECK-NEXT: .byte 4 // 0x4
; CHECK-NEXT: .byte 8 // 0x8
; CHECK-NEXT: .byte 12 // 0xc
; CHECK-NEXT: .byte 255 // 0xff
; CHECK-NEXT: .byte 255 // 0xff
; CHECK-NEXT: .byte 255 // 0xff
; CHECK-NEXT: .byte 255 // 0xff
; HOT: .section .rodata.cst8.hot.,"aM",@progbits,8
; HOT-NEXT: .p2align
; HOT-NEXT: .LCPI0_0:
; HOT-NEXT: .xword 0x3fe5c28f5c28f5c3 // double 0.68000000000000005
; HOT-NEXT: .section .rodata.cst8.unlikely.,"aM",@progbits,8
; HOT-NEXT: .p2align
; HOT-NEXT: .LCPI0_1:
; HOT-NEXT: .xword 0x3fe5eb851eb851ec // double 0.68500000000000005
; HOT-NEXT: .section .rodata.cst8,"aM",@progbits,8
; HOT-NEXT: .p2align
; HOT-NEXT: .LCPI0_2:
; HOT-NEXT: .byte 0 // 0x0
; HOT-NEXT: .byte 4 // 0x4
; HOT-NEXT: .byte 8 // 0x8
; HOT-NEXT: .byte 12 // 0xc
; HOT-NEXT: .byte 255 // 0xff
; HOT-NEXT: .byte 255 // 0xff
; HOT-NEXT: .byte 255 // 0xff
; HOT-NEXT: .byte 255 // 0xff

;; Constant pools for function @cold_func.
; NOHOT: .section .rodata.cst8,"aM",@progbits,8
; NOHOT-NEXT: .p2align
; NOHOT-NEXT: .LCPI0_0:
; NOHOT-NEXT: .xword 0x3fe5c28f5c28f5c3 // double 0.68000000000000005
; NOHOT-NEXT: .LCPI0_2:
; NOHOT-NEXT: .byte 0 // 0x0
; NOHOT-NEXT: .byte 4 // 0x4
; NOHOT-NEXT: .byte 8 // 0x8
; NOHOT-NEXT: .byte 12 // 0xc
; NOHOT-NEXT: .byte 255 // 0xff
; NOHOT-NEXT: .byte 255 // 0xff
; NOHOT-NEXT: .byte 255 // 0xff
; NOHOT-NEXT: .byte 255 // 0xff
; NOHOT-NEXT: .section .rodata.cst8.unlikely.,"aM",@progbits,8
; NOHOT-NEXT: .p2align
; NOHOT-NEXT: .LCPI0_1:
; NOHOT-NEXT: .xword 0x3fe5eb851eb851ec // double 0.68500000000000005

;; Constant pools for function @unprofiled_func
; CHECK: .section .rodata.cst8,"aM",@progbits,8
; CHECK-NEXT: .p2align
; CHECK-NEXT: .LCPI1_0:
; CHECK-NEXT: .byte 0 // 0x0
; CHECK-NEXT: .byte 4 // 0x4
; CHECK-NEXT: .byte 8 // 0x8
; CHECK-NEXT: .byte 12 // 0xc
; CHECK-NEXT: .byte 255 // 0xff
; CHECK-NEXT: .byte 255 // 0xff
; CHECK-NEXT: .byte 255 // 0xff
; CHECK-NEXT: .byte 255 // 0xff
; CHECK-NEXT: .section .rodata.cst16,"aM",@progbits,16
; CHECK-NEXT: .p2align
; CHECK-NEXT: .LCPI1_1:
; CHECK-NEXT: .word 2 // 0x2
; CHECK-NEXT: .word 3 // 0x3
; CHECK-NEXT: .word 5 // 0x5
; CHECK-NEXT: .word 7 // 0x7
; CHECK-NEXT: .section .rodata.cst16.hot.,"aM",@progbits,16
; CHECK-NEXT: .p2align
; CHECK-NEXT: .LCPI1_2:
; CHECK-NEXT: .word 442 // 0x1ba
; CHECK-NEXT: .word 100 // 0x64
; CHECK-NEXT: .word 0 // 0x0
; CHECK-NEXT: .word 0 // 0x0
; COMM: .section .rodata.cst8,"aM",@progbits,8
; COMM-NEXT: .p2align
; COMM-NEXT: .LCPI1_0:
; COMM-NEXT: .byte 0 // 0x0
; COMM-NEXT: .byte 4 // 0x4
; COMM-NEXT: .byte 8 // 0x8
; COMM-NEXT: .byte 12 // 0xc
; COMM-NEXT: .byte 255 // 0xff
; COMM-NEXT: .byte 255 // 0xff
; COMM-NEXT: .byte 255 // 0xff
; COMM-NEXT: .byte 255 // 0xff

; HOT-NEXT: .section .rodata.cst16,"aM",@progbits,16
; HOT-NEXT: .p2align
; HOT-NEXT: .LCPI1_1:
; HOT-NEXT: .word 2 // 0x2
; HOT-NEXT: .word 3 // 0x3
; HOT-NEXT: .word 5 // 0x5
; HOT-NEXT: .word 7 // 0x7
; HOT-NEXT: .section .rodata.cst16.hot.,"aM",@progbits,16
; HOT-NEXT: .p2align
; HOT-NEXT: .LCPI1_2:
; HOT-NEXT: .word 442 // 0x1ba
; HOT-NEXT: .word 100 // 0x64
; HOT-NEXT: .word 0 // 0x0
; HOT-NEXT: .word 0 // 0x0

; NOHOT: .section .rodata.cst16,"aM",@progbits,16
; NOHOT-NEXT: .p2align
; NOHOT-NEXT: .LCPI1_1:
; NOHOT-NEXT: .word 2 // 0x2
; NOHOT-NEXT: .word 3 // 0x3
; NOHOT-NEXT: .word 5 // 0x5
; NOHOT-NEXT: .word 7 // 0x7
; NOHOT-NEXT: .LCPI1_2:
; NOHOT-NEXT: .word 442 // 0x1ba
; NOHOT-NEXT: .word 100 // 0x64
; NOHOT-NEXT: .word 0 // 0x0
; NOHOT-NEXT: .word 0 // 0x0

;; Constant pools for function @hot_func
; CHECK: .section .rodata.cst8.hot.,"aM",@progbits,8
; CHECK-NEXT: .p2align
; CHECK-NEXT: .LCPI2_0:
; CHECK-NEXT: .xword 0x3fe5c28f5c28f5c3 // double 0.68000000000000005
; CHECK-NEXT: .section .rodata.cst16.hot.,"aM",@progbits,16
; CHECK-NEXT: .p2align
; CHECK-NEXT: .LCPI2_1:
; CHECK-NEXT: .word 0 // 0x0
; CHECK-NEXT: .word 100 // 0x64
; CHECK-NEXT: .word 0 // 0x0
; CHECK-NEXT: .word 442 // 0x1ba
; CHECK-NEXT: .LCPI2_2:
; CHECK-NEXT: .word 442 // 0x1ba
; CHECK-NEXT: .word 100 // 0x64
; CHECK-NEXT: .word 0 // 0x0
; CHECK-NEXT: .word 0 // 0x0
; HOT: .section .rodata.cst8.hot.,"aM",@progbits,8
; NOHOT: .section .rodata.cst8,"aM",@progbits,8
; COMM: .p2align
; COMM-NEXT: .LCPI2_0:
; COMM-NEXT: .xword 0x3fe5c28f5c28f5c3 // double 0.68000000000000005
; NOHOT: .section .rodata.cst16,"aM",@progbits,16
; HOT-NEXT: .section .rodata.cst16.hot.,"aM",@progbits,16
; COMM: .p2align
; COMM-NEXT: .LCPI2_1:
; COMM-NEXT: .word 0 // 0x0
; COMM-NEXT: .word 100 // 0x64
; COMM-NEXT: .word 0 // 0x0
; COMM-NEXT: .word 442 // 0x1ba
; COMM-NEXT: .LCPI2_2:
; COMM-NEXT: .word 442 // 0x1ba
; COMM-NEXT: .word 100 // 0x64
; COMM-NEXT: .word 0 // 0x0
; COMM-NEXT: .word 0 // 0x0

;; For global variable @val
;; The section name remains `.rodata.cst32` without hotness prefix because
;; the variable has external linkage and not analyzed. Compiler need symbolized
;; data access profiles to annotate such global variables' hotness.
; CHECK: .section .rodata.cst32,"aM",@progbits,32
; CHECK-NEXT: .globl val
; COMM: .section .rodata.cst32,"aM",@progbits,32
; COMM-NEXT: .globl val

define i32 @cold_func(double %x, <16 x i8> %a, <16 x i8> %b) !prof !16 {
%2 = tail call i32 (...) @func_taking_arbitrary_param(double 6.800000e-01)
Expand Down
34 changes: 25 additions & 9 deletions llvm/test/CodeGen/AArch64/jump-table-partition.ll
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,24 @@
; The static-data-splitter pass doesn't run.
; RUN: llc -mtriple=aarch64-unknown-linux-gnu -function-sections=true \
; RUN: -aarch64-enable-atomic-cfg-tidy=false -aarch64-min-jump-table-entries=2 \
; RUN: -unique-section-names=true %s -o - 2>&1 | FileCheck %s --check-prefixes=DEFAULT
; RUN: -unique-section-names=true %s -o - 2>&1 | FileCheck %s --check-prefixes=DEFAULT,COMM

; Repeat the command with -preserve-hot-data-section-prefix=false
; RUN: llc -mtriple=aarch64-unknown-linux-gnu -function-sections=true \
; RUN: -aarch64-enable-atomic-cfg-tidy=false -aarch64-min-jump-table-entries=2 \
; RUN: -preserve-hot-data-section-prefix=false \
; RUN: -unique-section-names=true %s -o - 2>&1 | FileCheck %s --check-prefixes=DEFNOHOT,COMM

; DEFAULT: .section .rodata.hot.foo,"a",@progbits
; DEFAULT: .LJTI0_0:
; DEFAULT: .LJTI0_1:
; DEFAULT: .LJTI0_2:
; DEFAULT: .LJTI0_3:
; DEFAULT: .section .rodata.func_without_profile,"a",@progbits
; DEFAULT: .LJTI1_0:
; DEFAULT: .section .rodata.bar_prefix.bar,"a",@progbits
; DEFAULT: .LJTI2_0
; DEFNOHOT: .section .rodata.foo,"a",@progbits
; COMM: .LJTI0_0:
; COMM: .LJTI0_1:
; COMM: .LJTI0_2:
; COMM: .LJTI0_3:
; COMM: .section .rodata.func_without_profile,"a",@progbits
; COMM: .LJTI1_0:
; COMM: .section .rodata.bar_prefix.bar,"a",@progbits
; COMM: .LJTI2_0

; Test that section names are uniqufied by numbers but not function names with
; {-function-sections, -unique-section-names=false}. Specifically, @foo jump
Expand All @@ -40,6 +47,14 @@
; RUN: -aarch64-enable-atomic-cfg-tidy=false -aarch64-min-jump-table-entries=2 \
; RUN: %s -o - 2>&1 | FileCheck %s --check-prefixes=FUNCLESS,JT

;; Repeat the commands above with -preserve-hot-data-section-prefix=false
; RUN: llc -mtriple=aarch64-unknown-linux-gnu -partition-static-data-sections \
; RUN: -function-sections -unique-section-names=false \
; RUN: -preserve-hot-data-section-prefix=false \
; RUN: -aarch64-enable-atomic-cfg-tidy=false -aarch64-min-jump-table-entries=2 \
; RUN: %s -o - 2>&1 | FileCheck %s --check-prefixes=NOHOT,JT


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 = "aarch64-unknown-linux-gnu"

Expand All @@ -58,6 +73,7 @@ target triple = "aarch64-unknown-linux-gnu"
; NUM: .section .rodata.hot.,"a",@progbits,unique,2
; FUNC: .section .rodata.hot.foo,"a",@progbits
; FUNCLESS: .section .rodata.hot.,"a",@progbits
; NOHOT: .section .rodata,"a",@progbits
; JT: .LJTI0_0:
; JT: .LJTI0_2:
; NUM: .section .rodata.unlikely.,"a",@progbits,unique,3
Expand Down
Loading
Loading