From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from nh502-vm11.bullet.mail.kks.yahoo.co.jp (nh502-vm11.bullet.mail.kks.yahoo.co.jp [183.79.56.156]) by sourceware.org (Postfix) with SMTP id 50C123857371 for ; Wed, 15 Jun 2022 12:23:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 50C123857371 Received: from [183.79.100.141] by nh502.bullet.mail.kks.yahoo.co.jp with NNFMP; 15 Jun 2022 12:23:01 -0000 Received: from [183.79.101.123] by t504.bullet.mail.kks.yahoo.co.jp with NNFMP; 15 Jun 2022 12:23:01 -0000 Received: from [127.0.0.1] by omp510.mail.kks.yahoo.co.jp with NNFMP; 15 Jun 2022 12:23:01 -0000 X-Yahoo-Newman-Property: ymail-3 X-Yahoo-Newman-Id: 856530.3986.bm@omp510.mail.kks.yahoo.co.jp Received: (qmail 65828 invoked by alias); 15 Jun 2022 12:23:01 -0000 Received: from unknown (HELO ?192.168.2.3?) (175.177.45.189 with ) by smtp5009.mail.kks.ynwp.yahoo.co.jp with SMTP; 15 Jun 2022 12:23:01 -0000 X-YMail-JAS: nvUQc74VM1nRVXeMrMFL2kCwaPUJVz1zb3WANji1RWwqBppmhKIgrdoyjXFrk9nxgYARsJwKxqU8c_EjO_J_7acTYV7HQlW9h04Qlxn8M6pUmEgdJce7J0Pg8RKuQTQ5V8zBm0GUhg-- X-Apparently-From: X-YMail-OSG: DPojSu8VM1nNkA3fA4RtiUqv2Tkfu2_GOphtYoreMnbsQQf lJlVRxm5kMD6bC2LkNmPnLgQxFg68mSmEJppkCCCAmDKoQOtOsaYQbNNdBs. xnRGX_boQaoBYJ7Ek7A0Ts.OqCZfmPzqdVksb1BPbsdw27ibsgDaAZtsMBiY G0rcQiRi9wrHE63nY.siHLO0nadXB5oY3HfQDTwQLZcB69EtyQHrO7_CK0Wa 2ChAnleU6tvZVHcSSQBQlT9nqiOv2VTRWNljLC5IjJwKxHPMcTqIn8MxC1LB oz7sRyVTLlzguIl50qXd2TujhJGOL227KrcRt38mfG2xJrCCR247Fl8Tx7qz .yVOAN3XaDlQDEz0mC3wlGZ0SemLKRka0GqvBtbDkAKlW4rnkkO_cBE9OgWu IQYagRQQ2dXALnXLdTIxKmNw.2r8BBBErj6UR2xHJBB3j4jbRT5Q2.AwjUGS N8LVBMzkdB3rD1chEEWWdAgrIG8uCJN9EVbiqC4dscxPLBrzHBWDHpzPsJrj lKhQpHy85iXyHibqwGm9..at8.7r.kbXYOtDHQwRR5wuh_yY5N8fmBT28wNk iUIKWlEo7oxdpBAw4geFwvqq1guCxEfJSq9p07CB7wf4VQzoSF4JxJMUadNf aFNiOP9ZC3IZh2udPaKq1x..cUaIGvbTJgSKVWCbnzl_jp2Gj8kTXynkW3WK 34.ncEWJhjSTBkYIh2mrdft3taaP3MmTaKydJykU0MNXOdETFf9alhsaHcU3 ObdIDthcsOXT7UvkkhRLBI0HcaqtJWFjFE5HIS5WkWkcNYAYWRU_M_Zo.6h3 7Xje0ahQASq.dTL9rDYncl09uYWOrh86L3Yhq39WfDhRhpEP0PQ0NxHDvGqJ Vn_nz7J2bVv6NMvUF69bZowFNEf5OsUM.wmtXDNfI1CknOwwcn8APbBLSRBi fOs1jkTEQL9AwP6TLOA-- Message-ID: Date: Wed, 15 Jun 2022 21:21:21 +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 From: Takayuki 'January June' Suwa Subject: [PATCH v2 2/5] xtensa: Add support for sibling call optimization To: Max Filippov Cc: GCC Patches References: Content-Language: en-US In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit 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, RCVD_IN_DNSWL_NONE, 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-List-Received-Date: Wed, 15 Jun 2022 12:23:08 -0000 On 2022/06/15 5:17, Max Filippov wrote: > Hi Suwa-san, hi! > This change results in a bunch of new regression test failures: > The code generated for e.g. gcc.c-torture/execute/921208-2.c looks like this: oh, PICed... indirect (incl. via function pointer, virtual functions and of course PIC ones in Xtensa ISA) sibcalls must be avoided if pointer to the target cannot be retained during function epilogue. otherwise, it will be look like this: > callx0 a14 > l32i.n a0, sp, 12 > l32i.n a14, sp, 0 // restored by the epilogue because A14 is callee-saved > mov.n a4, a12 > mov.n a5, a13 > l32i.n a12, sp, 8 > l32i.n a13, sp, 4 > l32r a3, .LC4 > movi.n a2, 0 > addi sp, sp, 16 > jx a14 // but A14 pointed to g@PLT in this function... luckily, no role is assigned from A9 to A11 in call0 ABI (A9 is already used inside of the pro/epilogue), and the "split2" stage is prior to "pro_and_epilogue"... === 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, and split ones in order to take care of the indirect sibcalls. gcc/testsuite/ChangeLog: * gcc.target/xtensa/sibcalls.c: New. --- gcc/config/xtensa/xtensa-protos.h | 4 +- gcc/config/xtensa/xtensa.cc | 58 +++++++++++++- gcc/config/xtensa/xtensa.md | 93 ++++++++++++++++++---- gcc/testsuite/gcc.target/xtensa/sibcalls.c | 20 +++++ 4 files changed, 155 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..d98f8236bdd 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,17 @@ 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 ATTRIBUTE_UNUSED, tree exp ATTRIBUTE_UNUSED) +{ + /* Do not allow sibcalls when windowed registers ABI is in effect. */ + if (TARGET_WINDOWED_ABI) + 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..3b05166988f 100644 --- a/gcc/config/xtensa/xtensa.md +++ b/gcc/config/xtensa/xtensa.md @@ -25,6 +25,7 @@ (A7_REG 7) (A8_REG 8) (A9_REG 9) + (A10_REG 10) (UNSPEC_NOP 2) (UNSPEC_PLT 3) @@ -2148,18 +2149,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 +2169,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 +2184,70 @@ (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_split + [(call (mem:SI (match_operand:SI 0 "register_operand")) + (match_operand 1 ""))] + "reload_completed + && !TARGET_WINDOWED_ABI && SIBLING_CALL_P (insn) + && IN_RANGE (REGNO (operands[0]), 12, 15)" + [(set (reg:SI A10_REG) + (match_dup 0)) + (call (mem:SI (reg:SI A10_REG)) + (match_dup 1))]) + +(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_split + [(set (match_operand 0 "register_operand") + (call (mem:SI (match_operand:SI 1 "register_operand")) + (match_operand 2 "")))] + "reload_completed + && !TARGET_WINDOWED_ABI && SIBLING_CALL_P (insn) + && IN_RANGE (REGNO (operands[1]), 12, 15)" + [(set (reg:SI A10_REG) + (match_dup 1)) + (set (match_dup 0) + (call (mem:SI (reg:SI A10_REG)) + (match_dup 2)))]) + (define_insn "entry" [(set (reg:SI A1_REG) (unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "i")] @@ -2260,7 +2315,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..d2b3fccf1e5 --- /dev/null +++ b/gcc/testsuite/gcc.target/xtensa/sibcalls.c @@ -0,0 +1,20 @@ +/* { 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); +} + +int test_2(int (*a)(void)) { + bar(0); + return a(); +} + +/* { dg-final { scan-assembler-not "ret" } } */ -- 2.20.1