Skip to content

[BOLT][RISCV] Set minimum function alignment to 2 for RVC #69837

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 23, 2023
Merged
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
9 changes: 1 addition & 8 deletions bolt/include/bolt/Core/BinaryFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1721,14 +1721,7 @@ class BinaryFunction {
// 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;
return BC.MIB->getMinFunctionAlignment();
}

Align getMinAlign() const { return Align(getMinAlignment()); }
Expand Down
6 changes: 6 additions & 0 deletions bolt/include/bolt/Core/MCPlusBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -2077,6 +2077,12 @@ class MCPlusBuilder {
return BlocksVectorTy();
}

virtual uint16_t getMinFunctionAlignment() const {
// We have to use at least 2-byte alignment for functions because of C++
// ABI.
return 2;
}

// AliasMap caches a mapping of registers to the set of registers that
// alias (are sub or superregs of itself, including itself).
std::vector<BitVector> AliasMap;
Expand Down
2 changes: 2 additions & 0 deletions bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1643,6 +1643,8 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {

return Relocation({RelOffset, RelSymbol, RelType, RelAddend, 0});
}

uint16_t getMinFunctionAlignment() const override { return 4; }
};

} // end anonymous namespace
Expand Down
8 changes: 8 additions & 0 deletions bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "bolt/Core/MCPlusBuilder.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
Expand Down Expand Up @@ -490,6 +491,13 @@ class RISCVMCPlusBuilder : public MCPlusBuilder {
assert(Second.getOpcode() == RISCV::JALR);
return true;
}

uint16_t getMinFunctionAlignment() const override {
if (STI->hasFeature(RISCV::FeatureStdExtC) ||
STI->hasFeature(RISCV::FeatureStdExtZca))
return 2;
return 4;
}
};

} // end anonymous namespace
Expand Down
38 changes: 38 additions & 0 deletions bolt/test/RISCV/function-alignment.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
## Test that BOLT uses a minimum function alignment of 4 (or 2 for RVC) bytes.

# RUN: llvm-mc -triple=riscv64 -filetype=obj -o %t.o %s
# RUN: ld.lld -q -o %t %t.o
# RUN: llvm-bolt --align-functions=1 --use-old-text=0 -o %t.bolt %t
# RUN: llvm-nm -n %t.bolt | FileCheck %s

# RUN: llvm-mc -triple=riscv64 -mattr=+c -filetype=obj -o %t-c.o %s
# RUN: ld.lld -q -o %t-c %t-c.o
# RUN: llvm-bolt --align-functions=1 --use-old-text=0 -o %t-c.bolt %t-c
# RUN: llvm-nm -n %t-c.bolt | FileCheck --check-prefix=CHECK-C %s

# CHECK: {{[048c]}} T _start
# CHECK-NEXT: {{[048c]}} T dummy

# CHECK-C: {{[02468ace]}} T _start
# CHECK-C-NEXT: {{[02468ace]}} T dummy

.text

# Make sure input binary is only 1 byte aligned. BOLT should increase the
# alignment to 2 or 4 bytes.
.byte 0
.balign 1

.globl _start
.type _start, @function
_start:
# Dummy reloc to force relocation mode.
.reloc 0, R_RISCV_NONE
ret
.size _start, .-_start

.globl dummy
.type dummy, @function
dummy:
ret
.size dummy, .-dummy