From patchwork Sat Apr 29 10:59:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fei Gao X-Patchwork-Id: 1775208 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Q7mj95HK9z23t4 for ; Sat, 29 Apr 2023 21:00:29 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B2029385770C for ; Sat, 29 Apr 2023 11:00:27 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from azure-sdnproxy.icoremail.net (azure-sdnproxy.icoremail.net [52.187.6.220]) by sourceware.org (Postfix) with ESMTP id 505963858C50 for ; Sat, 29 Apr 2023 11:00:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 505963858C50 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=eswincomputing.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=eswincomputing.com Received: from localhost.localdomain (unknown [10.12.130.31]) by app2 (Coremail) with SMTP id EggMCgAHTpS7+ExklBEPAA--.25048S4; Sat, 29 Apr 2023 19:00:12 +0800 (CST) From: Fei Gao To: gcc-patches@gcc.gnu.org Cc: kito.cheng@gmail.com, palmer@dabbelt.com, jeffreyalaw@gmail.com, Fei Gao Subject: [PATCH V2] RISC-V: decouple stack allocation for rv32e w/o save-restore. Date: Sat, 29 Apr 2023 10:59:59 +0000 Message-Id: <20230429105959.23211-1-gaofei@eswincomputing.com> X-Mailer: git-send-email 2.17.1 X-CM-TRANSID: EggMCgAHTpS7+ExklBEPAA--.25048S4 X-Coremail-Antispam: 1UD129KBjvJXoWxKryxAw4kWr47Kw4Duw18AFb_yoW7KF43pa 95ZFsay3y8ZFZ3Arsrtr18ZF15Jws3GFy5CrWIyrWIvw4DArW8t3sFy3W3AFW7CFn5Zw4a 9F4akr1a93WDGaDanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUkF14x267AKxVW8JVW5JwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK02 1l84ACjcxK6xIIjxv20xvE14v26r1j6r1xM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r1j 6r4UM28EF7xvwVC2z280aVAFwI0_Cr1j6rxdM28EF7xvwVC2z280aVCY1x0267AKxVW0oV Cq3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0 I7IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r 4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwCY02Avz4vE-syl42xK 82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGw C20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48J MIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E14v26r1j6r4UMI IF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E 87Iv6xkF7I0E14v26r1j6r4UYxBIdaVFxhVjvjDU0xZFpf9x0JUdHUDUUUUU= X-CM-SenderInfo: xjdrwv3l6h245lqf0zpsxwx03jof0z/ X-Spam-Status: No, score=-10.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" Currently in rv32e, stack allocation for GPR callee-saved registers is always 12 bytes w/o save-restore. Actually, for the case without save-restore, less stack memory can be reserved. This patch decouples stack allocation for rv32e w/o save-restore and makes riscv_compute_frame_info more readable. output of testcase rv32e_stack.c before patch: addi sp,sp,-16 sw ra,12(sp) call getInt sw a0,0(sp) lw a0,0(sp) call PrintInts lw a5,0(sp) mv a0,a5 lw ra,12(sp) addi sp,sp,16 jr ra after patch: addi sp,sp,-8 sw ra,4(sp) call getInt sw a0,0(sp) lw a0,0(sp) call PrintInts lw a5,0(sp) mv a0,a5 lw ra,4(sp) addi sp,sp,8 jr ra gcc/ChangeLog: * config/riscv/riscv.cc (riscv_avoid_save_libcall): helper function for riscv_use_save_libcall. (riscv_use_save_libcall): call riscv_avoid_save_libcall. (riscv_compute_frame_info): restructure to decouple stack allocation for rv32e w/o save-restore. gcc/testsuite/ChangeLog: * gcc.target/riscv/rv32e_stack.c: New test. --- gcc/config/riscv/riscv.cc | 58 ++++++++++++-------- gcc/testsuite/gcc.target/riscv/rv32e_stack.c | 14 +++++ 2 files changed, 50 insertions(+), 22 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rv32e_stack.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 5d2550871c7..8b32977e296 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -4772,12 +4772,27 @@ riscv_save_reg_p (unsigned int regno) return false; } +/* Return TRUE if a libcall to save/restore GPRs should be + avoided. FALSE otherwise. */ +static bool +riscv_avoid_save_libcall (void) +{ + if (!TARGET_SAVE_RESTORE + || crtl->calls_eh_return + || frame_pointer_needed + || cfun->machine->interrupt_handler_p + || cfun->machine->varargs_size != 0 + || crtl->args.pretend_args_size != 0) + return true; + + return false; +} + /* Determine whether to call GPR save/restore routines. */ static bool riscv_use_save_libcall (const struct riscv_frame_info *frame) { - if (!TARGET_SAVE_RESTORE || crtl->calls_eh_return || frame_pointer_needed - || cfun->machine->interrupt_handler_p) + if (riscv_avoid_save_libcall ()) return false; return frame->save_libcall_adjustment != 0; @@ -4857,7 +4872,7 @@ riscv_compute_frame_info (void) struct riscv_frame_info *frame; poly_int64 offset; bool interrupt_save_prologue_temp = false; - unsigned int regno, i, num_x_saved = 0, num_f_saved = 0; + unsigned int regno, i, num_x_saved = 0, num_f_saved = 0, x_save_size = 0; frame = &cfun->machine->frame; @@ -4895,24 +4910,14 @@ riscv_compute_frame_info (void) frame->fmask |= 1 << (regno - FP_REG_FIRST), num_f_saved++; } - /* At the bottom of the frame are any outgoing stack arguments. */ - offset = riscv_stack_align (crtl->outgoing_args_size); - /* Next are local stack variables. */ - offset += riscv_stack_align (get_frame_size ()); - /* The virtual frame pointer points above the local variables. */ - frame->frame_pointer_offset = offset; - /* Next are the callee-saved FPRs. */ - if (frame->fmask) - offset += riscv_stack_align (num_f_saved * UNITS_PER_FP_REG); - frame->fp_sp_offset = offset - UNITS_PER_FP_REG; - /* Next are the callee-saved GPRs. */ if (frame->mask) { - unsigned x_save_size = riscv_stack_align (num_x_saved * UNITS_PER_WORD); + x_save_size = riscv_stack_align (num_x_saved * UNITS_PER_WORD); unsigned num_save_restore = 1 + riscv_save_libcall_count (frame->mask); /* Only use save/restore routines if they don't alter the stack size. */ - if (riscv_stack_align (num_save_restore * UNITS_PER_WORD) == x_save_size) + if (riscv_stack_align (num_save_restore * UNITS_PER_WORD) == x_save_size + && !riscv_avoid_save_libcall ()) { /* Libcall saves/restores 3 registers at once, so we need to allocate 12 bytes for callee-saved register. */ @@ -4921,9 +4926,21 @@ riscv_compute_frame_info (void) frame->save_libcall_adjustment = x_save_size; } - - offset += x_save_size; } + + /* At the bottom of the frame are any outgoing stack arguments. */ + offset = riscv_stack_align (crtl->outgoing_args_size); + /* Next are local stack variables. */ + offset += riscv_stack_align (get_frame_size ()); + /* The virtual frame pointer points above the local variables. */ + frame->frame_pointer_offset = offset; + /* Next are the callee-saved FPRs. */ + if (frame->fmask) + offset += riscv_stack_align (num_f_saved * UNITS_PER_FP_REG); + frame->fp_sp_offset = offset - UNITS_PER_FP_REG; + /* Next are the callee-saved GPRs. */ + if (frame->mask) + offset += x_save_size; frame->gp_sp_offset = offset - UNITS_PER_WORD; /* The hard frame pointer points above the callee-saved GPRs. */ frame->hard_frame_pointer_offset = offset; @@ -4935,11 +4952,8 @@ riscv_compute_frame_info (void) padding. */ frame->arg_pointer_offset = offset - crtl->args.pretend_args_size; frame->total_size = offset; - /* Next points the incoming stack pointer and any incoming arguments. */ - /* Only use save/restore routines when the GPRs are atop the frame. */ - if (known_ne (frame->hard_frame_pointer_offset, frame->total_size)) - frame->save_libcall_adjustment = 0; + /* Next points the incoming stack pointer and any incoming arguments. */ } /* Make sure that we're not trying to eliminate to the wrong hard frame diff --git a/gcc/testsuite/gcc.target/riscv/rv32e_stack.c b/gcc/testsuite/gcc.target/riscv/rv32e_stack.c new file mode 100644 index 00000000000..cec90ede4b5 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rv32e_stack.c @@ -0,0 +1,14 @@ +/* { dg-do compile} */ +/* { dg-options "-O0 -march=rv32e -mabi=ilp32e -fomit-frame-pointer" } */ + +int getInt(); +void PrintInts(int); + +int callPrintInts() +{ + int i = getInt(); + PrintInts(i); + return i; +} + +/* { dg-final { scan-assembler-not "addi sp,sp,-16" } } */