Skip to content

Commit b6b4928

Browse files
authored
[BOLT][RISCV] Set minimum function alignment to 2 for RVC (#69837)
In #67707, the minimum function alignment on RISC-V was set to 4. When RVC (compressed instructions) is enabled, the minimum alignment can be reduced to 2. This patch implements this by delegating the choice of minimum alignment to a new `MCPlusBuilder::getMinFunctionAlignment` function. This way, the target-dependent code in `BinaryFunction` is minimized.
1 parent 2ad9fde commit b6b4928

File tree

5 files changed

+55
-8
lines changed

5 files changed

+55
-8
lines changed

bolt/include/bolt/Core/BinaryFunction.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,14 +1721,7 @@ class BinaryFunction {
17211721
// Align data in code BFs minimum to CI alignment
17221722
if (!size() && hasIslandsInfo())
17231723
return getConstantIslandAlignment();
1724-
1725-
// Minimal code alignment on AArch64 and RISCV is 4
1726-
if (BC.isAArch64() || BC.isRISCV())
1727-
return 4;
1728-
1729-
// We have to use at least 2-byte alignment for functions because
1730-
// of C++ ABI.
1731-
return 2;
1724+
return BC.MIB->getMinFunctionAlignment();
17321725
}
17331726

17341727
Align getMinAlign() const { return Align(getMinAlignment()); }

bolt/include/bolt/Core/MCPlusBuilder.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2077,6 +2077,12 @@ class MCPlusBuilder {
20772077
return BlocksVectorTy();
20782078
}
20792079

2080+
virtual uint16_t getMinFunctionAlignment() const {
2081+
// We have to use at least 2-byte alignment for functions because of C++
2082+
// ABI.
2083+
return 2;
2084+
}
2085+
20802086
// AliasMap caches a mapping of registers to the set of registers that
20812087
// alias (are sub or superregs of itself, including itself).
20822088
std::vector<BitVector> AliasMap;

bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1643,6 +1643,8 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
16431643

16441644
return Relocation({RelOffset, RelSymbol, RelType, RelAddend, 0});
16451645
}
1646+
1647+
uint16_t getMinFunctionAlignment() const override { return 4; }
16461648
};
16471649

16481650
} // end anonymous namespace

bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "bolt/Core/MCPlusBuilder.h"
1616
#include "llvm/BinaryFormat/ELF.h"
1717
#include "llvm/MC/MCInst.h"
18+
#include "llvm/MC/MCSubtargetInfo.h"
1819
#include "llvm/Support/Debug.h"
1920
#include "llvm/Support/ErrorHandling.h"
2021
#include "llvm/Support/Format.h"
@@ -490,6 +491,13 @@ class RISCVMCPlusBuilder : public MCPlusBuilder {
490491
assert(Second.getOpcode() == RISCV::JALR);
491492
return true;
492493
}
494+
495+
uint16_t getMinFunctionAlignment() const override {
496+
if (STI->hasFeature(RISCV::FeatureStdExtC) ||
497+
STI->hasFeature(RISCV::FeatureStdExtZca))
498+
return 2;
499+
return 4;
500+
}
493501
};
494502

495503
} // end anonymous namespace

bolt/test/RISCV/function-alignment.s

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
## Test that BOLT uses a minimum function alignment of 4 (or 2 for RVC) bytes.
2+
3+
# RUN: llvm-mc -triple=riscv64 -filetype=obj -o %t.o %s
4+
# RUN: ld.lld -q -o %t %t.o
5+
# RUN: llvm-bolt --align-functions=1 --use-old-text=0 -o %t.bolt %t
6+
# RUN: llvm-nm -n %t.bolt | FileCheck %s
7+
8+
# RUN: llvm-mc -triple=riscv64 -mattr=+c -filetype=obj -o %t-c.o %s
9+
# RUN: ld.lld -q -o %t-c %t-c.o
10+
# RUN: llvm-bolt --align-functions=1 --use-old-text=0 -o %t-c.bolt %t-c
11+
# RUN: llvm-nm -n %t-c.bolt | FileCheck --check-prefix=CHECK-C %s
12+
13+
# CHECK: {{[048c]}} T _start
14+
# CHECK-NEXT: {{[048c]}} T dummy
15+
16+
# CHECK-C: {{[02468ace]}} T _start
17+
# CHECK-C-NEXT: {{[02468ace]}} T dummy
18+
19+
.text
20+
21+
# Make sure input binary is only 1 byte aligned. BOLT should increase the
22+
# alignment to 2 or 4 bytes.
23+
.byte 0
24+
.balign 1
25+
26+
.globl _start
27+
.type _start, @function
28+
_start:
29+
# Dummy reloc to force relocation mode.
30+
.reloc 0, R_RISCV_NONE
31+
ret
32+
.size _start, .-_start
33+
34+
.globl dummy
35+
.type dummy, @function
36+
dummy:
37+
ret
38+
.size dummy, .-dummy

0 commit comments

Comments
 (0)