Skip to content

Commit

Permalink
[BOLT] Align constant islands to 8 bytes
Browse files Browse the repository at this point in the history
AArch64 requires CI to be aligned to 8 bytes due to access instructions
restrictions. E.g. the ldr with imm, where imm must be aligned to 8 bytes.

Differential Revision: https://reviews.llvm.org/D122065
  • Loading branch information
yota9 committed Mar 27, 2022
1 parent 8b245ab commit af9bdcf
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 4 deletions.
15 changes: 13 additions & 2 deletions bolt/include/bolt/Core/BinaryFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,9 @@ class BinaryFunction {

mutable MCSymbol *FunctionConstantIslandLabel{nullptr};
mutable MCSymbol *FunctionColdConstantIslandLabel{nullptr};

// Returns constant island alignment
uint16_t getAlignment() const { return sizeof(uint64_t); }
};

static constexpr uint64_t COUNT_NO_PROFILE =
Expand Down Expand Up @@ -2047,6 +2050,10 @@ class BinaryFunction {
return *std::prev(CodeIter) <= *DataIter;
}

uint16_t getConstantIslandAlignment() const {
return Islands ? Islands->getAlignment() : 1;
}

uint64_t
estimateConstantIslandSize(const BinaryFunction *OnBehalfOf = nullptr) const {
if (!Islands)
Expand Down Expand Up @@ -2074,9 +2081,13 @@ class BinaryFunction {
Size += NextMarker - *DataIter;
}

if (!OnBehalfOf)
for (BinaryFunction *ExternalFunc : Islands->Dependency)
if (!OnBehalfOf) {
for (BinaryFunction *ExternalFunc : Islands->Dependency) {
Size = alignTo(Size, ExternalFunc->getConstantIslandAlignment());
Size += ExternalFunc->estimateConstantIslandSize(this);
}
}

return Size;
}

Expand Down
7 changes: 7 additions & 0 deletions bolt/lib/Core/BinaryEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,13 @@ void BinaryEmitter::emitConstantIslands(BinaryFunction &BF, bool EmitColdPart,
if (Islands.DataOffsets.empty() && Islands.Dependency.empty())
return;

// AArch64 requires CI to be aligned to 8 bytes due to access instructions
// restrictions. E.g. the ldr with imm, where imm must be aligned to 8 bytes.
const uint16_t Alignment = OnBehalfOf
? OnBehalfOf->getConstantIslandAlignment()
: BF.getConstantIslandAlignment();
Streamer.emitCodeAlignment(Alignment, &*BC.STI);

if (!OnBehalfOf) {
if (!EmitColdPart)
Streamer.emitLabel(BF.getFunctionConstantIslandLabel());
Expand Down
3 changes: 3 additions & 0 deletions bolt/lib/Passes/LongJmp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ uint64_t LongJmpPass::tentativeLayoutRelocColdPart(
LLVM_DEBUG(dbgs() << Func->getPrintName() << " cold tentative: "
<< Twine::utohexstr(DotAddress) << "\n");
DotAddress += Func->estimateColdSize();
DotAddress = alignTo(DotAddress, Func->getConstantIslandAlignment());
DotAddress += Func->estimateConstantIslandSize();
}
return DotAddress;
Expand Down Expand Up @@ -364,6 +365,8 @@ uint64_t LongJmpPass::tentativeLayoutRelocMode(
DotAddress += Func->estimateSize();
else
DotAddress += Func->estimateHotSize();

DotAddress = alignTo(DotAddress, Func->getConstantIslandAlignment());
DotAddress += Func->estimateConstantIslandSize();
++CurrentIndex;
}
Expand Down
38 changes: 38 additions & 0 deletions bolt/test/AArch64/constant-island-alignment.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// This test checks that the constant island is aligned after BOLT tool.
// In case the nop before .Lci will be removed the pointer to exit function
// won't be alinged and the test will fail.

# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown \
# RUN: %s -o %t.o
# RUN: %clang %cflags -fPIC -pie %t.o -o %t.exe -Wl,-q \
# RUN: -nostartfiles -nodefaultlibs -lc
# RUN: llvm-bolt %t.exe -o %t.bolt -use-old-text=0 -lite=0 -trap-old-code
# RUN: llvm-objdump -d --disassemble-symbols='$d' %t.bolt | FileCheck %s

.text
.align 4
.global
.type dummy, %function
dummy:
add x0, x0, #1
ret

.global
.type exitOk, %function
exitOk:
mov x0, #0
bl exit

.global _start
.type _start, %function
_start:
adrp x0, .Lci
ldr x0, [x0, #:lo12:.Lci]
blr x0
mov x1, #1
bl exit
nop
# CHECK: {{0|8}} <$d>:
.Lci:
.xword exitOk
.xword 0
4 changes: 2 additions & 2 deletions bolt/test/runtime/AArch64/adrrelaxationpass.s
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ br:
.word 0xff

# CHECK: <main>:
# CHECK-NEXT: adr x0, #28
# CHECK-NEXT: adr x0, #{{[0-9][0-9]*}}
# CHECK-NEXT: adrp x1, 0x{{[1-8a-f][0-9a-f]*}}
# CHECK-NEXT: add x1, x1, #{{[1-8a-f][0-9a-f]*}}
# CHECK-NEXT: adrp x2, 0x{{[1-8a-f][0-9a-f]*}}
# CHECK-NEXT: add x2, x2, #{{[1-8a-f][0-9a-f]*}}
# CHECK-NEXT: adr x3, #4
# CHECK-NEXT: adr x3, #{{[0-9][0-9]*}}

0 comments on commit af9bdcf

Please sign in to comment.