From patchwork Tue Jun 14 03:36:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takayuki 'January June' Suwa X-Patchwork-Id: 55065 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A9CE5384144C for ; Tue, 14 Jun 2022 03:57:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A9CE5384144C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1655179022; bh=oGSvvVDhAuHJH10pXVTJwrsKLXweACNXE4YvmiM4c1o=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=Zm2tDGYAUwE/yabwgz73bjRtac+t7QtLC2SD7Njjs/yMyupkyuThY8RpuT7+XfHwr wk/Bi4lJmIxyUVQ0eV/sPGv6kChIli+Y7E63mhKeZn8rohbjYPLqjbTjlhpGhtQ3nX a36UFeHHxchgjdQb0fDIKldPDGBZnW2uJTTiLfsI= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from nh605-vm7.bullet.mail.ssk.yahoo.co.jp (nh605-vm7.bullet.mail.ssk.yahoo.co.jp [182.22.90.80]) by sourceware.org (Postfix) with SMTP id 2392F384F010 for ; Tue, 14 Jun 2022 03:54:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2392F384F010 Received: from [182.22.66.103] by nh605.bullet.mail.ssk.yahoo.co.jp with NNFMP; 14 Jun 2022 03:54:37 -0000 Received: from [182.22.91.204] by t601.bullet.mail.ssk.yahoo.co.jp with NNFMP; 14 Jun 2022 03:54:37 -0000 Received: from [127.0.0.1] by omp607.mail.ssk.yahoo.co.jp with NNFMP; 14 Jun 2022 03:54:37 -0000 X-Yahoo-Newman-Property: ymail-3 X-Yahoo-Newman-Id: 420111.59718.bm@omp607.mail.ssk.yahoo.co.jp Received: (qmail 32940 invoked by alias); 14 Jun 2022 03:54:37 -0000 Received: from unknown (HELO ?192.168.2.3?) (175.177.45.163 with ) by smtp6003.mail.ssk.ynwp.yahoo.co.jp with SMTP; 14 Jun 2022 03:54:37 -0000 X-YMail-JAS: Lr4cGw4VM1lFnZdESlk6rnjZmZv1KzWpGGJzz.yGwcB0IPpT.mv6ktiXELE62EZPGNzb04.Qm9m8gvADBKRuhDK1EEKW38WUgFtAx7uAtmIftodonJ4yosoMmRDWgFOD._gY2TpInQ-- X-Apparently-From: X-YMail-OSG: HwnILiIVM1my3RpjVmzNYZVYAktiV_O7qXcup.7p2NGxxAW ghoiV9_XVoMFnBUhBq2OX0n9hl4Vs2Fn2QPqrMzteuctTOsMaqby4ObwpkI4 42XgLspGPj6rKFNcUW4RCfwMHD5oGJ8jH6XOtwJcKGfDh7GlFWc.dLK2zPVT F3OFhAbwpyC1U9QT6vzLX2cQOczvLexWFk3RGEcskE3m1onRJg_FYSwJFf.n DBHsTM52K2cQfzKuHCg5r7ZehHktXTQHXna5CCiUue7ACXb35E5WLo3GMvMQ 4HhkOTyv6_xo.wVgJzmwiK5U5T6ud0KQa2bcunpETvKl88uP3jrulpHH3Qsg d5_FS9xnZhgYjjK1Q_TVNXRQCCqDkAUi_dbVhSun.XElIuh0LrxOrDCB3dhx e6fEB.esyAh9pPKVH.iNtGjuT7_OC4bTQnfXi7GZxX.ko3KlEqoakkLDFKdg r4BvCYRuQbgzQUVJDUpk9jTN_Ibw8mbmgb5MsN7x9vaRUZ4McJvPW22daH3y lA2PuFr09C9Wz9qOwTxcUg9TwWN25TkoSXeurJUzSZI8vOVn1dY1UMAdHXMw _E19CLIbCBUYg69UTSoIIERWbwTCRuDieoQlkdlqQsE_KSc9pN6vUHXKGABG vcQursJUnY6g_IfYw3RYUiKg5d_7FT4n64V67WLGb_vhBjLHled9ZLiw_Xog Z01lHrpeS4Y6gr3TuiNS9kaXmOqWHFCGyWFHC6pMEpn2PRV__WlVzRf3cvo4 Zpcigm6fV8eCTeUrNJmk2oQpKsRiL6jlPabKBR39Xn._5j.CjQyxLh8Fmugh jQqn80jKWeaqwbiFLLjPFvkLJRtn9sRZszfi_jiPO5SDioIKQXZ65B5g4aIS 7418IwcGDoO9XjSP_wJSTGRInPBKWzfuAZ1rjXmf.RJyb6HyIwLPrPq4SLZv _uAn4gBabFB3qzt753w-- Message-ID: Date: Tue, 14 Jun 2022 12:36:10 +0900 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.10.0 Content-Language: en-US To: GCC Patches Subject: [PATCH 2/5] xtensa: Add support for sibling call optimization X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, 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: , X-Patchwork-Original-From: Takayuki 'January June' Suwa via Gcc-patches From: Takayuki 'January June' Suwa Reply-To: Takayuki 'January June' Suwa Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" This patch introduces support for sibling call optimization, when call0 ABI is in effect. gcc/ChangeLog: * config/xtensa/xtensa-protos.h (xtensa_prepare_expand_call, xtensa_emit_sibcall): New prototypes. (xtensa_expand_epilogue): Add new argument that specifies whether or not sibling call. * config/xtensa/xtensa.cc (TARGET_FUNCTION_OK_FOR_SIBCALL): New macro definition. (xtensa_prepare_expand_call): New function in order to share the common code. (xtensa_emit_sibcall, xtensa_function_ok_for_sibcall): New functions. (xtensa_expand_epilogue): Add new argument sibcall_p and use it for sibling call handling. * config/xtensa/xtensa.md (call, call_value): Use xtensa_prepare_expand_call. (call_internal, call_value_internal): Add the condition in order to be disabled if sibling call. (sibcall, sibcall_value, sibcall_epilogue): New expansions. (sibcall_internal, sibcall_value_internal): New insn patterns. gcc/testsuite/ChangeLog: * gcc.target/xtensa/sibcalls.c: New. --- gcc/config/xtensa/xtensa-protos.h | 4 +- gcc/config/xtensa/xtensa.cc | 63 ++++++++++++++++++-- gcc/config/xtensa/xtensa.md | 68 +++++++++++++++++----- gcc/testsuite/gcc.target/xtensa/sibcalls.c | 15 +++++ 4 files changed, 130 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/gcc.target/xtensa/sibcalls.c diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h index 168ad70710b..e020a332b03 100644 --- a/gcc/config/xtensa/xtensa-protos.h +++ b/gcc/config/xtensa/xtensa-protos.h @@ -53,7 +53,9 @@ extern void xtensa_expand_atomic (enum rtx_code, rtx, rtx, rtx, bool); extern void xtensa_emit_loop_end (rtx_insn *, rtx *); extern char *xtensa_emit_branch (bool, rtx *); extern char *xtensa_emit_movcc (bool, bool, bool, rtx *); +extern void xtensa_prepare_expand_call (int, rtx *); extern char *xtensa_emit_call (int, rtx *); +extern char *xtensa_emit_sibcall (int, rtx *); extern bool xtensa_tls_referenced_p (rtx); extern enum rtx_code xtensa_shlrd_which_direction (rtx, rtx); @@ -73,7 +75,7 @@ extern int xtensa_dbx_register_number (int); extern long compute_frame_size (poly_int64); extern bool xtensa_use_return_instruction_p (void); extern void xtensa_expand_prologue (void); -extern void xtensa_expand_epilogue (void); +extern void xtensa_expand_epilogue (bool); extern void order_regs_for_local_alloc (void); extern enum reg_class xtensa_regno_to_class (int regno); extern HOST_WIDE_INT xtensa_initial_elimination_offset (int from, int to); diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc index 58b6eb0b711..b97f37ac956 100644 --- a/gcc/config/xtensa/xtensa.cc +++ b/gcc/config/xtensa/xtensa.cc @@ -189,7 +189,7 @@ static bool xtensa_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to); static HOST_WIDE_INT xtensa_starting_frame_offset (void); static unsigned HOST_WIDE_INT xtensa_asan_shadow_offset (void); - +static bool xtensa_function_ok_for_sibcall (tree, tree); static rtx xtensa_delegitimize_address (rtx); @@ -347,6 +347,9 @@ static rtx xtensa_delegitimize_address (rtx); #undef TARGET_DELEGITIMIZE_ADDRESS #define TARGET_DELEGITIMIZE_ADDRESS xtensa_delegitimize_address +#undef TARGET_FUNCTION_OK_FOR_SIBCALL +#define TARGET_FUNCTION_OK_FOR_SIBCALL xtensa_function_ok_for_sibcall + struct gcc_target targetm = TARGET_INITIALIZER; @@ -2127,6 +2130,20 @@ xtensa_emit_movcc (bool inverted, bool isfp, bool isbool, rtx *operands) } +void +xtensa_prepare_expand_call (int callop, rtx *operands) +{ + rtx addr = XEXP (operands[callop], 0); + + if (flag_pic && SYMBOL_REF_P (addr) + && (!SYMBOL_REF_LOCAL_P (addr) || SYMBOL_REF_EXTERNAL_P (addr))) + addr = gen_sym_PLT (addr); + + if (!call_insn_operand (addr, VOIDmode)) + XEXP (operands[callop], 0) = copy_to_mode_reg (Pmode, addr); +} + + char * xtensa_emit_call (int callop, rtx *operands) { @@ -2145,6 +2162,24 @@ xtensa_emit_call (int callop, rtx *operands) } +char * +xtensa_emit_sibcall (int callop, rtx *operands) +{ + static char result[64]; + rtx tgt = operands[callop]; + + if (GET_CODE (tgt) == CONST_INT) + sprintf (result, "j.l\t" HOST_WIDE_INT_PRINT_HEX ", a9", + INTVAL (tgt)); + else if (register_operand (tgt, VOIDmode)) + sprintf (result, "jx\t%%%d", callop); + else + sprintf (result, "j.l\t%%%d, a9", callop); + + return result; +} + + bool xtensa_legitimate_address_p (machine_mode mode, rtx addr, bool strict) { @@ -3270,7 +3305,7 @@ xtensa_expand_prologue (void) } void -xtensa_expand_epilogue (void) +xtensa_expand_epilogue (bool sibcall_p) { if (!TARGET_WINDOWED_ABI) { @@ -3304,10 +3339,13 @@ xtensa_expand_epilogue (void) if (xtensa_call_save_reg(regno)) { rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset)); + rtx reg; offset -= UNITS_PER_WORD; - emit_move_insn (gen_rtx_REG (SImode, regno), + emit_move_insn (reg = gen_rtx_REG (SImode, regno), gen_frame_mem (SImode, x)); + if (regno == A0_REG && sibcall_p) + emit_use (reg); } } @@ -3342,7 +3380,8 @@ xtensa_expand_epilogue (void) EH_RETURN_STACKADJ_RTX)); } cfun->machine->epilogue_done = true; - emit_jump_insn (gen_return ()); + if (!sibcall_p) + emit_jump_insn (gen_return ()); } bool @@ -4869,6 +4908,22 @@ xtensa_asan_shadow_offset (void) return HOST_WIDE_INT_UC (0x10000000); } +/* Implement TARGET_FUNCTION_OK_FOR_SIBCALL. */ +static bool +xtensa_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED) +{ + /* Do not allow tailcalls if the Windowed Register Option is + configured. */ + if (TARGET_WINDOWED_ABI) + return false; + + /* Do not allow indirect tailcalls. */ + if (decl == NULL) + return false; + + return true; +} + static rtx xtensa_delegitimize_address (rtx op) { diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md index 5d0f346b01a..181f935e3c3 100644 --- a/gcc/config/xtensa/xtensa.md +++ b/gcc/config/xtensa/xtensa.md @@ -2148,18 +2148,13 @@ (match_operand 1 "" ""))] "" { - rtx addr = XEXP (operands[0], 0); - if (flag_pic && GET_CODE (addr) == SYMBOL_REF - && (!SYMBOL_REF_LOCAL_P (addr) || SYMBOL_REF_EXTERNAL_P (addr))) - addr = gen_sym_PLT (addr); - if (!call_insn_operand (addr, VOIDmode)) - XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr); + xtensa_prepare_expand_call (0, operands); }) (define_insn "call_internal" [(call (mem (match_operand:SI 0 "call_insn_operand" "nir")) (match_operand 1 "" "i"))] - "" + "!SIBLING_CALL_P (insn)" { return xtensa_emit_call (0, operands); } @@ -2173,19 +2168,14 @@ (match_operand 2 "" "")))] "" { - rtx addr = XEXP (operands[1], 0); - if (flag_pic && GET_CODE (addr) == SYMBOL_REF - && (!SYMBOL_REF_LOCAL_P (addr) || SYMBOL_REF_EXTERNAL_P (addr))) - addr = gen_sym_PLT (addr); - if (!call_insn_operand (addr, VOIDmode)) - XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr); + xtensa_prepare_expand_call (1, operands); }) (define_insn "call_value_internal" [(set (match_operand 0 "register_operand" "=a") (call (mem (match_operand:SI 1 "call_insn_operand" "nir")) (match_operand 2 "" "i")))] - "" + "!SIBLING_CALL_P (insn)" { return xtensa_emit_call (1, operands); } @@ -2193,6 +2183,46 @@ (set_attr "mode" "none") (set_attr "length" "3")]) +(define_expand "sibcall" + [(call (match_operand 0 "memory_operand" "") + (match_operand 1 "" ""))] + "!TARGET_WINDOWED_ABI" +{ + xtensa_prepare_expand_call (0, operands); +}) + +(define_insn "sibcall_internal" + [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "nir")) + (match_operand 1 "" "i"))] + "!TARGET_WINDOWED_ABI && SIBLING_CALL_P (insn)" +{ + return xtensa_emit_sibcall (0, operands); +} + [(set_attr "type" "call") + (set_attr "mode" "none") + (set_attr "length" "3")]) + +(define_expand "sibcall_value" + [(set (match_operand 0 "register_operand" "") + (call (match_operand 1 "memory_operand" "") + (match_operand 2 "" "")))] + "!TARGET_WINDOWED_ABI" +{ + xtensa_prepare_expand_call (1, operands); +}) + +(define_insn "sibcall_value_internal" + [(set (match_operand 0 "register_operand" "=a") + (call (mem:SI (match_operand:SI 1 "call_insn_operand" "nir")) + (match_operand 2 "" "i")))] + "!TARGET_WINDOWED_ABI && SIBLING_CALL_P (insn)" +{ + return xtensa_emit_sibcall (1, operands); +} + [(set_attr "type" "call") + (set_attr "mode" "none") + (set_attr "length" "3")]) + (define_insn "entry" [(set (reg:SI A1_REG) (unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "i")] @@ -2260,7 +2290,15 @@ [(return)] "" { - xtensa_expand_epilogue (); + xtensa_expand_epilogue (false); + DONE; +}) + +(define_expand "sibcall_epilogue" + [(return)] + "!TARGET_WINDOWED_ABI" +{ + xtensa_expand_epilogue (true); DONE; }) diff --git a/gcc/testsuite/gcc.target/xtensa/sibcalls.c b/gcc/testsuite/gcc.target/xtensa/sibcalls.c new file mode 100644 index 00000000000..50a7b1aa431 --- /dev/null +++ b/gcc/testsuite/gcc.target/xtensa/sibcalls.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mabi=call0 -foptimize-sibling-calls" } */ + +extern int foo(int); +extern void bar(int); + +int test_0(int a) { + return foo(a); +} + +void test_1(int a) { + bar(a); +} + +/* { dg-final { scan-assembler-not "ret" } } */