From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id AC7A2385843A for ; Sun, 13 Nov 2022 09:32:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org AC7A2385843A Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 847B923A for ; Sun, 13 Nov 2022 01:32:46 -0800 (PST) Received: from localhost (e121540-lin.manchester.arm.com [10.32.98.62]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id E453A3F73D for ; Sun, 13 Nov 2022 01:32:39 -0800 (PST) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [PATCH] builtins: Commonise default handling of nonlocal_goto Date: Sun, 13 Nov 2022 09:32:38 +0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Spam-Status: No, score=-42.2 required=5.0 tests=BAYES_00,GIT_PATCH_0,KAM_DMARC_NONE,KAM_DMARC_STATUS,KAM_LAZY_DOMAIN_SECURITY,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: expand_builtin_longjmp and expand_builtin_nonlocal_goto both emit nonlocal gotos. They first try to use a target-provided pattern and fall back to generic code otherwise. These pieces of generic code are almost identical, and having them inline like this makes it difficult to define a nonlocal_goto pattern that only wants to add extra steps, not change the default ones. Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install? Richard gcc/ * builtins.h (emit_standard_nonlocal_goto): Declare. * builtins.cc (emit_standard_nonlocal_goto): New function, commonizing code from... (expand_builtin_longjmp, expand_builtin_nonlocal_goto): ...here. * genemit.cc (main): Emit an include of builtins.h. --- gcc/builtins.cc | 103 +++++++++++++++++++++--------------------------- gcc/builtins.h | 1 + gcc/genemit.cc | 1 + 3 files changed, 47 insertions(+), 58 deletions(-) diff --git a/gcc/builtins.cc b/gcc/builtins.cc index 4dc1ca672b2..2507745c17a 100644 --- a/gcc/builtins.cc +++ b/gcc/builtins.cc @@ -998,6 +998,49 @@ expand_builtin_setjmp_receiver (rtx receiver_label) emit_insn (gen_blockage ()); } +/* Emit the standard sequence for a nonlocal_goto. The arguments are + the operands to the .md pattern. */ + +void +emit_standard_nonlocal_goto (rtx value, rtx label, rtx stack, rtx fp) +{ + emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); + emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); + + label = copy_to_reg (label); + + /* Restore the frame pointer and stack pointer. We must use a + temporary since the setjmp buffer may be a local. */ + fp = copy_to_reg (fp); + emit_stack_restore (SAVE_NONLOCAL, stack); + + /* Ensure the frame pointer move is not optimized. */ + emit_insn (gen_blockage ()); + emit_clobber (hard_frame_pointer_rtx); + emit_clobber (frame_pointer_rtx); + emit_move_insn (hard_frame_pointer_rtx, fp); + + /* USE of hard_frame_pointer_rtx added for consistency; + not clear if really needed. */ + emit_use (hard_frame_pointer_rtx); + emit_use (stack_pointer_rtx); + + /* If the architecture is using a GP register, we must + conservatively assume that the target function makes use of it. + The prologue of functions with nonlocal gotos must therefore + initialize the GP register to the appropriate value, and we + must then make sure that this value is live at the point + of the jump. (Note that this doesn't necessarily apply + to targets with a nonlocal_goto pattern; they are free + to implement it in their own way. Note also that this is + a no-op if the GP register is a global invariant.) */ + unsigned regnum = PIC_OFFSET_TABLE_REGNUM; + if (value == const0_rtx && regnum != INVALID_REGNUM && fixed_regs[regnum]) + emit_use (pic_offset_table_rtx); + + emit_indirect_jump (label); +} + /* __builtin_longjmp is passed a pointer to an array of five words (not all will be used on all machines). It operates similarly to the C library function of the same name, but is more efficient. Much of @@ -1049,27 +1092,7 @@ expand_builtin_longjmp (rtx buf_addr, rtx value) what that value is, because builtin_setjmp does not use it. */ emit_insn (targetm.gen_nonlocal_goto (value, lab, stack, fp)); else - { - emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); - emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); - - lab = copy_to_reg (lab); - - /* Restore the frame pointer and stack pointer. We must use a - temporary since the setjmp buffer may be a local. */ - fp = copy_to_reg (fp); - emit_stack_restore (SAVE_NONLOCAL, stack); - - /* Ensure the frame pointer move is not optimized. */ - emit_insn (gen_blockage ()); - emit_clobber (hard_frame_pointer_rtx); - emit_clobber (frame_pointer_rtx); - emit_move_insn (hard_frame_pointer_rtx, fp); - - emit_use (hard_frame_pointer_rtx); - emit_use (stack_pointer_rtx); - emit_indirect_jump (lab); - } + emit_standard_nonlocal_goto (value, lab, stack, fp); } /* Search backwards and mark the jump insn as a non-local goto. @@ -1201,43 +1224,7 @@ expand_builtin_nonlocal_goto (tree exp) if (targetm.have_nonlocal_goto ()) emit_insn (targetm.gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp)); else - { - emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); - emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); - - r_label = copy_to_reg (r_label); - - /* Restore the frame pointer and stack pointer. We must use a - temporary since the setjmp buffer may be a local. */ - r_fp = copy_to_reg (r_fp); - emit_stack_restore (SAVE_NONLOCAL, r_sp); - - /* Ensure the frame pointer move is not optimized. */ - emit_insn (gen_blockage ()); - emit_clobber (hard_frame_pointer_rtx); - emit_clobber (frame_pointer_rtx); - emit_move_insn (hard_frame_pointer_rtx, r_fp); - - /* USE of hard_frame_pointer_rtx added for consistency; - not clear if really needed. */ - emit_use (hard_frame_pointer_rtx); - emit_use (stack_pointer_rtx); - - /* If the architecture is using a GP register, we must - conservatively assume that the target function makes use of it. - The prologue of functions with nonlocal gotos must therefore - initialize the GP register to the appropriate value, and we - must then make sure that this value is live at the point - of the jump. (Note that this doesn't necessarily apply - to targets with a nonlocal_goto pattern; they are free - to implement it in their own way. Note also that this is - a no-op if the GP register is a global invariant.) */ - unsigned regnum = PIC_OFFSET_TABLE_REGNUM; - if (regnum != INVALID_REGNUM && fixed_regs[regnum]) - emit_use (pic_offset_table_rtx); - - emit_indirect_jump (r_label); - } + emit_standard_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp); /* Search backwards to the jump insn and mark it as a non-local goto. */ diff --git a/gcc/builtins.h b/gcc/builtins.h index 5ad830c9fbf..5c86b241fea 100644 --- a/gcc/builtins.h +++ b/gcc/builtins.h @@ -150,6 +150,7 @@ extern char target_percent_c[3]; extern char target_percent_s_newline[4]; extern bool target_char_cst_p (tree t, char *p); extern rtx get_memory_rtx (tree exp, tree len); +extern void emit_standard_nonlocal_goto (rtx, rtx, rtx, rtx); extern internal_fn associated_internal_fn (combined_fn, tree); extern internal_fn associated_internal_fn (tree); diff --git a/gcc/genemit.cc b/gcc/genemit.cc index 909ac89a16b..c3e2152a491 100644 --- a/gcc/genemit.cc +++ b/gcc/genemit.cc @@ -905,6 +905,7 @@ from the machine description file `md'. */\n\n"); printf ("#include \"tm-constrs.h\"\n"); printf ("#include \"ggc.h\"\n"); printf ("#include \"target.h\"\n\n"); + printf ("#include \"builtins.h\"\n\n"); /* Read the machine description. */ -- 2.25.1