[compiler-rt] [compiler-rt][RISC-V] Save-Restore for ILP32E/LP64E ABIs (PR #95390)
Sam Elliott via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 13 03:57:33 PDT 2024
https://github.com/lenary created https://github.com/llvm/llvm-project/pull/95390
This makes two significant changes, which I believe are both bugfixes.
- When compiling for the ILP32E/LP64E ABIs, even on a RISC-V machine with `i`, we should be using the ILP32E/LP64E save/restore routines, so use the right preprocessor macro.
- Saves/restores registers in batches that match the stack alignment for the ILP32E/LP64E ABIs, rather than the larger batches of the conventional ABIs. The implementations of the save routines are not tail-shared, to reduce the number of instructions. I think this also helps code size but I need to check this again.
I would expect (but haven't measured) that the majority of functions compiled for the ILP32E/LP64E ABIs will in fact use both callee-saved registers, and therefore there are still savings to be had, but I think those can come later, with more data (especially if those changes are just to the instruction sequences we use to save the registers, rather than the number and alignment of how this is done).
>From what I can tell, this matches the CFI information that both clang and GCC emit: https://godbolt.org/z/ozY3z8Yx5
>From 62e79f68397cb8d0672ba57a6a15c9cc4be8a34f Mon Sep 17 00:00:00 2001
From: Sam Elliott <quic_aelliott at quicinc.com>
Date: Thu, 13 Jun 2024 03:02:22 -0700
Subject: [PATCH] [compiler-rt][RISC-V] Save-Restore for ILP32E/LP64E ABIs
This makes two significant changes, which I believe are both bugfixes.
- When compiling for the ILP32E/LP64E ABIs, even on a RISC-V machine
with `i`, we should be using the ILP32E/LP64E save/restore routines,
so use the right preprocessor macro.
- Saves/restores registers in batches that match the stack alignment for
the ILP32E/LP64E ABIs, rather than the larger batches of the
conventional ABIs. The implementations of the save routines are not
tail-shared, to reduce the number of instructions. I think this also
helps code size but I need to check this again.
I would expect (but haven't measured) that the majority of functions
compiled for the ILP32E/LP64E ABIs will in fact use both callee-saved
registers, and therefore there are still savings to be had, but I think
those can come later, with more data (especially if those changes are
just to the instruction sequences we use to save the registers, rather
than the number and alignment of how this is done).
---
compiler-rt/lib/builtins/riscv/restore.S | 49 ++++++++++++++++--------
compiler-rt/lib/builtins/riscv/save.S | 48 +++++++++++++++--------
2 files changed, 65 insertions(+), 32 deletions(-)
diff --git a/compiler-rt/lib/builtins/riscv/restore.S b/compiler-rt/lib/builtins/riscv/restore.S
index 6f43842c8ca68..7816f74ed497e 100644
--- a/compiler-rt/lib/builtins/riscv/restore.S
+++ b/compiler-rt/lib/builtins/riscv/restore.S
@@ -14,15 +14,18 @@
// them falling through into each other and don't want the linker to
// accidentally split them up, garbage collect, or reorder them.
//
-// The entry points are grouped up into 2s for rv64 and 4s for rv32 since this
-// is the minimum grouping which will maintain the required 16-byte stack
-// alignment.
+// For the conventional ABIs, entry points are grouped up into 2s for rv64 and
+// 4s for rv32 since this is the minimum grouping which will maintain the
+// required 16-byte stack alignment.
+//
+// For the ilp32e/lp64e abis, entry points are grouped into 1s, since this is
+// the minimum grouping which will maintain the required 4-byte stack alignment.
.text
#if __riscv_xlen == 32
-#ifndef __riscv_32e
+#ifndef __riscv_abi_rve
.globl __riscv_restore_12
.type __riscv_restore_12, at function
@@ -92,24 +95,30 @@ __riscv_restore_0:
.globl __riscv_restore_2
.type __riscv_restore_2, at function
+__riscv_restore_2:
+ lw s1, 0(sp)
+ addi sp, sp, 4
+ // fallthrough into __riscv_restore_1/0
+
.globl __riscv_restore_1
.type __riscv_restore_1, at function
+__riscv_restore_1:
+ lw s0, 0(sp)
+ addi sp, sp, 4
+ // fallthrough into __riscv_restore_0
+
.globl __riscv_restore_0
.type __riscv_restore_0, at function
-__riscv_restore_2:
-__riscv_restore_1:
__riscv_restore_0:
- lw s1, 0(sp)
- lw s0, 4(sp)
- lw ra, 8(sp)
- addi sp, sp, 12
+ lw ra, 0(sp)
+ addi sp, sp, 4
ret
#endif
#elif __riscv_xlen == 64
-#ifndef __riscv_64e
+#ifndef __riscv_abi_rve
.globl __riscv_restore_12
.type __riscv_restore_12, at function
@@ -188,17 +197,23 @@ __riscv_restore_0:
.globl __riscv_restore_2
.type __riscv_restore_2, at function
+__riscv_restore_2:
+ ld s1, 0(sp)
+ addi sp, sp, 8
+ // fallthrough into __riscv_restore_1/0
+
.globl __riscv_restore_1
.type __riscv_restore_1, at function
+__riscv_restore_1:
+ ld s0, 0(sp)
+ addi sp, sp, 8
+ // fallthrough into __riscv_restore_0
+
.globl __riscv_restore_0
.type __riscv_restore_0, at function
-__riscv_restore_2:
-__riscv_restore_1:
__riscv_restore_0:
- ld s1, 0(sp)
- ld s0, 8(sp)
- ld ra, 16(sp)
- addi sp, sp, 24
+ ld ra, 0(sp)
+ addi sp, sp, 8
ret
#endif
diff --git a/compiler-rt/lib/builtins/riscv/save.S b/compiler-rt/lib/builtins/riscv/save.S
index 3e044179ff7f1..6b50bce022524 100644
--- a/compiler-rt/lib/builtins/riscv/save.S
+++ b/compiler-rt/lib/builtins/riscv/save.S
@@ -18,7 +18,7 @@
#if __riscv_xlen == 32
-#ifndef __riscv_32e
+#ifndef __riscv_abi_rve
.globl __riscv_save_12
.type __riscv_save_12, at function
@@ -98,24 +98,33 @@ __riscv_save_0:
.globl __riscv_save_2
.type __riscv_save_2, at function
- .globl __riscv_save_1
- .type __riscv_save_1, at function
- .globl __riscv_save_0
- .type __riscv_save_0, at function
__riscv_save_2:
-__riscv_save_1:
-__riscv_save_0:
addi sp, sp, -12
sw s1, 0(sp)
sw s0, 4(sp)
sw ra, 8(sp)
jr t0
+ .globl __riscv_save_1
+ .type __riscv_save_1, at function
+__riscv_save_1:
+ addi sp, sp, -8
+ sw s0, 0(sp)
+ sw ra, 4(sp)
+ jr t0
+
+ .globl __riscv_save_0
+ .type __riscv_save_0, at function
+__riscv_save_0:
+ addi sp, sp, -4
+ sw ra, 0(sp)
+ jr t0
+
#endif
#elif __riscv_xlen == 64
-#ifndef __riscv_64e
+#ifndef __riscv_abi_rve
.globl __riscv_save_12
.type __riscv_save_12, at function
@@ -208,18 +217,27 @@ __riscv_save_0:
.globl __riscv_save_2
.type __riscv_save_2, at function
+__riscv_save_2:
+ addi sp, sp, -24
+ sw s1, 0(sp)
+ sw s0, 8(sp)
+ sw ra, 16(sp)
+ jr t0
+
.globl __riscv_save_1
.type __riscv_save_1, at function
+__riscv_save_1:
+ addi sp, sp, -16
+ sw s0, 0(sp)
+ sw ra, 8(sp)
+ jr t0
+
.globl __riscv_save_0
.type __riscv_save_0, at function
-__riscv_save_2:
-__riscv_save_1:
__riscv_save_0:
- addi sp, sp, -24
- sd s1, 0(sp)
- sd s0, 8(sp)
- sd ra, 16(sp)
- jr t0
+ addi sp, sp, -8
+ sw ra, 0(sp)
+ jr t0
#endif
More information about the llvm-commits
mailing list