[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