[llvm] [BOLT][NFC] Set minimal alignment for BF (PR #67707)
Vladislav Khmelevsky via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 3 03:06:27 PDT 2023
https://github.com/yota9 updated https://github.com/llvm/llvm-project/pull/67707
>From 3ee97eb401a562e403aba78e9da102bcc7773730 Mon Sep 17 00:00:00 2001
From: Vladislav Khmelevsky <och95 at yandex.ru>
Date: Tue, 3 Oct 2023 14:02:40 +0400
Subject: [PATCH] [BOLT] Return proper minimal alignment from BF
Currently minimal alignment of function is hardcoded to 2 bytes.
Add 2 more cases:
1. In case BF is data in code return the alignment of CI as minimal
alignment
2. For aarch64 and riscv platforms return the minimal value of 4 (added
test for aarch64)
Otherwise fallback to returning the 2 as it previously was.
---
bolt/include/bolt/Core/BinaryFunction.h | 21 ++++++++++++---
bolt/lib/Core/BinaryEmitter.cpp | 2 +-
bolt/lib/Core/BinaryFunction.cpp | 2 --
bolt/lib/Passes/Aligner.cpp | 16 -----------
bolt/lib/Passes/LongJmp.cpp | 4 +--
bolt/test/AArch64/bf_min_alignment.s | 35 +++++++++++++++++++++++++
6 files changed, 55 insertions(+), 25 deletions(-)
create mode 100644 bolt/test/AArch64/bf_min_alignment.s
diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h
index dea1d55b15026e4..a4c9eb4265ec9aa 100644
--- a/bolt/include/bolt/Core/BinaryFunction.h
+++ b/bolt/include/bolt/Core/BinaryFunction.h
@@ -192,9 +192,6 @@ class BinaryFunction {
static constexpr uint64_t COUNT_NO_PROFILE =
BinaryBasicBlock::COUNT_NO_PROFILE;
- /// We have to use at least 2-byte alignment for functions because of C++ ABI.
- static constexpr unsigned MinAlign = 2;
-
static const char TimerGroupName[];
static const char TimerGroupDesc[];
@@ -1720,8 +1717,24 @@ class BinaryFunction {
return *this;
}
- Align getAlign() const { return Align(Alignment); }
+ uint16_t getMinAlignment() const {
+ // Align data in code BFs minimum to CI alignment
+ if (!size() && hasIslandsInfo())
+ return getConstantIslandAlignment();
+
+ // Minimal code alignment on AArch64 and RISCV is 4
+ if (BC.isAArch64() || BC.isRISCV())
+ return 4;
+
+ // We have to use at least 2-byte alignment for functions because
+ // of C++ ABI.
+ return 2;
+ }
+
+ Align getMinAlign() const { return Align(getMinAlignment()); }
+
uint16_t getAlignment() const { return Alignment; }
+ Align getAlign() const { return Align(getAlignment()); }
BinaryFunction &setMaxAlignmentBytes(uint16_t MaxAlignBytes) {
MaxAlignmentBytes = MaxAlignBytes;
diff --git a/bolt/lib/Core/BinaryEmitter.cpp b/bolt/lib/Core/BinaryEmitter.cpp
index 95ab63521c06a56..6c17f69d7aeceb5 100644
--- a/bolt/lib/Core/BinaryEmitter.cpp
+++ b/bolt/lib/Core/BinaryEmitter.cpp
@@ -309,7 +309,7 @@ bool BinaryEmitter::emitFunction(BinaryFunction &Function,
// tentative layout.
Section->ensureMinAlignment(Align(opts::AlignFunctions));
- Streamer.emitCodeAlignment(Align(BinaryFunction::MinAlign), &*BC.STI);
+ Streamer.emitCodeAlignment(Function.getMinAlign(), &*BC.STI);
uint16_t MaxAlignBytes = FF.isSplitFragment()
? Function.getMaxColdAlignmentBytes()
: Function.getMaxAlignmentBytes();
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index 6cf1cfb50a9c12c..02a896558e17ced 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -164,8 +164,6 @@ bool shouldPrint(const BinaryFunction &Function) {
namespace llvm {
namespace bolt {
-constexpr unsigned BinaryFunction::MinAlign;
-
template <typename R> static bool emptyRange(const R &Range) {
return Range.begin() == Range.end();
}
diff --git a/bolt/lib/Passes/Aligner.cpp b/bolt/lib/Passes/Aligner.cpp
index c5b63d881e17991..7c387525434bd39 100644
--- a/bolt/lib/Passes/Aligner.cpp
+++ b/bolt/lib/Passes/Aligner.cpp
@@ -158,22 +158,6 @@ void AlignerPass::runOnFunctions(BinaryContext &BC) {
BinaryContext::IndependentCodeEmitter Emitter =
BC.createIndependentMCCodeEmitter();
- // Align objects that contains constant islands and no code
- // to at least 8 bytes.
- if (!BF.size() && BF.hasIslandsInfo()) {
- uint16_t Alignment = BF.getConstantIslandAlignment();
- // Check if we're forcing output alignment and it is greater than minimal
- // CI required one
- if (!opts::UseCompactAligner && Alignment < opts::AlignFunctions &&
- opts::AlignFunctions <= opts::AlignFunctionsMaxBytes)
- Alignment = opts::AlignFunctions;
-
- BF.setAlignment(Alignment);
- BF.setMaxAlignmentBytes(Alignment);
- BF.setMaxColdAlignmentBytes(Alignment);
- return;
- }
-
if (opts::UseCompactAligner)
alignCompact(BF, Emitter.MCE.get());
else
diff --git a/bolt/lib/Passes/LongJmp.cpp b/bolt/lib/Passes/LongJmp.cpp
index 31bb8000dda00c3..ccfc950704b89ee 100644
--- a/bolt/lib/Passes/LongJmp.cpp
+++ b/bolt/lib/Passes/LongJmp.cpp
@@ -290,7 +290,7 @@ uint64_t LongJmpPass::tentativeLayoutRelocColdPart(
for (BinaryFunction *Func : SortedFunctions) {
if (!Func->isSplit())
continue;
- DotAddress = alignTo(DotAddress, BinaryFunction::MinAlign);
+ DotAddress = alignTo(DotAddress, Func->getMinAlignment());
uint64_t Pad =
offsetToAlignment(DotAddress, llvm::Align(Func->getAlignment()));
if (Pad <= Func->getMaxColdAlignmentBytes())
@@ -349,7 +349,7 @@ uint64_t LongJmpPass::tentativeLayoutRelocMode(
DotAddress = alignTo(DotAddress, opts::AlignText);
}
- DotAddress = alignTo(DotAddress, BinaryFunction::MinAlign);
+ DotAddress = alignTo(DotAddress, Func->getMinAlignment());
uint64_t Pad =
offsetToAlignment(DotAddress, llvm::Align(Func->getAlignment()));
if (Pad <= Func->getMaxAlignmentBytes())
diff --git a/bolt/test/AArch64/bf_min_alignment.s b/bolt/test/AArch64/bf_min_alignment.s
new file mode 100644
index 000000000000000..2dd06b373a79801
--- /dev/null
+++ b/bolt/test/AArch64/bf_min_alignment.s
@@ -0,0 +1,35 @@
+// This tests checks the minimum alignment of the AARch64 function
+// is equal to 4. Otherwise the jitlinker would fail to link the
+// binary since the size of the first function after reorder is not
+// not a multiple of 4.
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
+# RUN: %clang %cflags -fPIC -pie %t.o -o %t.exe -nostdlib -Wl,-q
+# RUN: link_fdata %s %t.o %t.fdata
+# RUN: llvm-bolt %t.exe -o %t.bolt --use-old-text=0 --lite=0 \
+# RUN: --align-functions-max-bytes=1 \
+# RUN: --data %t.fdata --reorder-functions=exec-count
+# RUN: llvm-nm -n %t.bolt | FileCheck %s
+
+# CHECK: {{0|4|8|c}} T dummy
+# CHECK-NEXT: {{0|4|8|c}} T _start
+
+ .text
+ .align 4
+ .global _start
+ .type _start, %function
+_start:
+# FDATA: 0 [unknown] 0 1 _start 0 0 1
+ bl dymmy
+ ret
+ .size _start, .-_start
+
+ .global dummy
+ .type dummy, %function
+dummy:
+# FDATA: 0 [unknown] 0 1 dummy 0 0 42
+ adr x0, .Lci
+ ret
+.Lci:
+ .byte 0
+ .size dummy, .-dummy
More information about the llvm-commits
mailing list