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 991893857C65 for ; Thu, 17 Dec 2020 00:22:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 991893857C65 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 4CBCC31B; Wed, 16 Dec 2020 16:22:03 -0800 (PST) Received: from localhost (e121540-lin.manchester.arm.com [10.32.98.126]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BFFD53F718; Wed, 16 Dec 2020 16:22:02 -0800 (PST) From: Richard Sandiford To: Jeff Law via Gcc-patches Mail-Followup-To: Jeff Law via Gcc-patches , Jeff Law , richard.sandiford@arm.com Subject: Re: [16/23] recog: Add a way of temporarily undoing changes References: <9686974b-fb4e-5d87-2962-a08f87c75c33@redhat.com> Date: Thu, 17 Dec 2020 00:22:00 +0000 In-Reply-To: <9686974b-fb4e-5d87-2962-a08f87c75c33@redhat.com> (Jeff Law via Gcc-patches's message of "Wed, 25 Nov 2020 13:27:14 -0700") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: Thu, 17 Dec 2020 00:22:05 -0000 Jeff Law via Gcc-patches writes: > On 11/13/20 1:19 AM, Richard Sandiford via Gcc-patches wrote: >> In some cases, it can be convenient to roll back the changes that >> have been made by validate_change to see how things looked before, >> then reroll the changes. For example, this makes it possible >> to defer calculating the cost of an instruction until we know that >> the result is actually needed. It can also make dumps easier to read. >> >> This patch adds a couple of helper functions for doing that. >> >> gcc/ >> * recog.h (temporarily_undo_changes, redo_changes): Declare. >> * recog.c (swap_change, temporarily_undo_changes): New functions. >> (redo_changes): Likewise. > OK...=C2=A0 But... > + >> +/* Temporarily undo all the changes numbered NUM and up, with a view >> + to reapplying them later. The next call to the changes machinery >> + must be: >> + >> + redo_changes (NUM) >> + >> + otherwise things will end up in an invalid state. */ > It'd be nice if we had state validation in the other routines. Somebody > is likely to mess this up at some point... Yeah, good point, can definitely see myself doing that. :-) Here's the version I committed, with temporarily_undone_changes tracking what has been undone. Thanks, Richard gcc/ * recog.h (temporarily_undo_changes, redo_changes): Declare. * recog.c (temporarily_undone_changes): New variable. (validate_change_1, confirm_change_group): Check that it's zero. (cancel_changes): Likewise. (swap_change, temporarily_undo_changes): New functions. (redo_changes): Likewise. --- gcc/recog.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/recog.h | 2 ++ 2 files changed, 50 insertions(+) diff --git a/gcc/recog.c b/gcc/recog.c index 65125b8f0d1..cee481f4fa0 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -193,6 +193,7 @@ static change_t *changes; static int changes_allocated; =20 static int num_changes =3D 0; +static int temporarily_undone_changes =3D 0; =20 /* Validate a proposed change to OBJECT. LOC is the location in the rtl at which NEW_RTX will be placed. If NEW_LEN is >=3D 0, XVECLEN (NEW_RT= X, 0) @@ -218,6 +219,7 @@ static bool validate_change_1 (rtx object, rtx *loc, rtx new_rtx, bool in_group, bool unshare, int new_len =3D -1) { + gcc_assert (temporarily_undone_changes =3D=3D 0); rtx old =3D *loc; =20 /* Single-element parallels aren't valid and won't match anything. @@ -506,6 +508,7 @@ confirm_change_group (void) int i; rtx last_object =3D NULL; =20 + gcc_assert (temporarily_undone_changes =3D=3D 0); for (i =3D 0; i < num_changes; i++) { rtx object =3D changes[i].object; @@ -561,6 +564,7 @@ num_validated_changes (void) void cancel_changes (int num) { + gcc_assert (temporarily_undone_changes =3D=3D 0); int i; =20 /* Back out all the changes. Do this in the opposite order in which @@ -577,6 +581,50 @@ cancel_changes (int num) num_changes =3D num; } =20 +/* Swap the status of change NUM from being applied to not being applied, + or vice versa. */ + +static void +swap_change (int num) +{ + if (changes[num].old_len >=3D 0) + std::swap (XVECLEN (*changes[num].loc, 0), changes[num].old_len); + else + std::swap (*changes[num].loc, changes[num].old); + if (changes[num].object && !MEM_P (changes[num].object)) + std::swap (INSN_CODE (changes[num].object), changes[num].old_code); +} + +/* Temporarily undo all the changes numbered NUM and up, with a view + to reapplying them later. The next call to the changes machinery + must be: + + redo_changes (NUM) + + otherwise things will end up in an invalid state. */ + +void +temporarily_undo_changes (int num) +{ + gcc_assert (temporarily_undone_changes =3D=3D 0 && num <=3D num_changes); + for (int i =3D num_changes - 1; i >=3D num; i--) + swap_change (i); + temporarily_undone_changes =3D num_changes - num; +} + +/* Redo the changes that were temporarily undone by: + + temporarily_undo_changes (NUM). */ + +void +redo_changes (int num) +{ + gcc_assert (temporarily_undone_changes =3D=3D num_changes - num); + for (int i =3D num; i < num_changes; ++i) + swap_change (i); + temporarily_undone_changes =3D 0; +} + /* Reduce conditional compilation elsewhere. */ /* A subroutine of validate_replace_rtx_1 that tries to simplify the resul= ting rtx. */ diff --git a/gcc/recog.h b/gcc/recog.h index e152e2bb591..facf36e7c08 100644 --- a/gcc/recog.h +++ b/gcc/recog.h @@ -96,6 +96,8 @@ extern void confirm_change_group (void); extern int apply_change_group (void); extern int num_validated_changes (void); extern void cancel_changes (int); +extern void temporarily_undo_changes (int); +extern void redo_changes (int); extern int constrain_operands (int, alternative_mask); extern int constrain_operands_cached (rtx_insn *, int); extern int memory_address_addr_space_p (machine_mode, rtx, addr_space_t);