[llvm] [BOLT][RISCV] Set minimum function alignment to 2 for RVC (PR #69837)
Job Noorman via llvm-commits
llvm-commits at lists.llvm.org
Sun Oct 22 23:55:25 PDT 2023
https://github.com/mtvec updated https://github.com/llvm/llvm-project/pull/69837
>From bfe06abdab86352adda9a81830b8ecfc63a47ab6 Mon Sep 17 00:00:00 2001
From: Job Noorman <jnoorman at igalia.com>
Date: Sat, 21 Oct 2023 12:55:57 +0200
Subject: [PATCH 1/2] [BOLT][RISCV] Set minimum function alignment to 2 for RVC
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.
---
bolt/include/bolt/Core/BinaryFunction.h | 9 +----
bolt/include/bolt/Core/MCPlusBuilder.h | 6 +++
.../Target/AArch64/AArch64MCPlusBuilder.cpp | 2 +
bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp | 5 +++
bolt/test/RISCV/function-alignment.s | 38 +++++++++++++++++++
5 files changed, 52 insertions(+), 8 deletions(-)
create mode 100644 bolt/test/RISCV/function-alignment.s
diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h
index a4c9eb4265ec9aa..c67ddccbf4892a7 100644
--- a/bolt/include/bolt/Core/BinaryFunction.h
+++ b/bolt/include/bolt/Core/BinaryFunction.h
@@ -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()); }
diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h b/bolt/include/bolt/Core/MCPlusBuilder.h
index b6817c1d7f45ed3..d136c627bc5cc10 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -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;
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index c2a4607411a49e1..b31813680f12122 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -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
diff --git a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp
index 85855fbf3ab97f4..236acc4fee47ddd 100644
--- a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp
+++ b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp
@@ -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"
@@ -490,6 +491,10 @@ class RISCVMCPlusBuilder : public MCPlusBuilder {
assert(Second.getOpcode() == RISCV::JALR);
return true;
}
+
+ uint16_t getMinFunctionAlignment() const override {
+ return STI->getFeatureBits()[RISCV::FeatureStdExtC] ? 2 : 4;
+ }
};
} // end anonymous namespace
diff --git a/bolt/test/RISCV/function-alignment.s b/bolt/test/RISCV/function-alignment.s
new file mode 100644
index 000000000000000..c52cff9e2347a5c
--- /dev/null
+++ b/bolt/test/RISCV/function-alignment.s
@@ -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
>From ee5408d97a8a694e2dfcd60c82710b5941f6353f Mon Sep 17 00:00:00 2001
From: Job Noorman <jnoorman at igalia.com>
Date: Sat, 21 Oct 2023 15:31:25 +0200
Subject: [PATCH 2/2] Use `hasFeature` and include Zca in 2-byte alignment
---
bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp
index 236acc4fee47ddd..c2bc597950b859c 100644
--- a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp
+++ b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp
@@ -493,7 +493,10 @@ class RISCVMCPlusBuilder : public MCPlusBuilder {
}
uint16_t getMinFunctionAlignment() const override {
- return STI->getFeatureBits()[RISCV::FeatureStdExtC] ? 2 : 4;
+ if (STI->hasFeature(RISCV::FeatureStdExtC) ||
+ STI->hasFeature(RISCV::FeatureStdExtZca))
+ return 2;
+ return 4;
}
};
More information about the llvm-commits
mailing list