From patchwork Sun Nov 13 09:32:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 1703194 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=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=jffb/aKq; dkim-atps=neutral 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 4N96gR42s2z23mj for ; Sun, 13 Nov 2022 20:33:02 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 90A19385842E for ; Sun, 13 Nov 2022 09:33:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 90A19385842E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1668331980; bh=k7hZfV2uwTxDevFfFbdvTOW4HvYGyk5J/bqaAVlZP28=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=jffb/aKqIZYcCT6FPANNT+OlXur+xb85C9iQc620rQNlLDEWqWmoMZKZrd0pL3r1M 1cOhFr/bPAjvyHehCCTivs68c+oEFFo3EBoE5RPydbOT70Bkh8R/uUqyizJHjOaxOk qTV18r9eioi0Y8uPaCpZPC8NNR+sJrrWz6RP4IZg= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org 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 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) 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 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 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: Richard Sandiford via Gcc-patches From: Richard Sandiford Reply-To: Richard Sandiford Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" 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. */