From patchwork Sun Aug 3 14:32:41 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 376051 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 7D5C214009B for ; Mon, 4 Aug 2014 00:33:15 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:references:date:in-reply-to:message-id:mime-version :content-type; q=dns; s=default; b=XvGn7ji2bHMYLZMXPBAggeIr0Uneb oT85Io7dUwkZPMz0f52H3J62/NR1buZsaXrT5WEGctqqy7mlE2+9g+FQhfZohQed 0YVhesAUCKrsVNikt09l+RgJ1AKEg9xU9/SzB7MHgHYuEZzZihKqhtWqdZp0r85/ BbRXiA8tqboTYQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:references:date:in-reply-to:message-id:mime-version :content-type; s=default; bh=8KVJYfK8e6P7nwxzpRUY29FMwrA=; b=hzg BseEtVv4+1XK0BMRu1rg8lIwc5yUiO1RZBMz2IwzMRKkIU83ZIvapi+n/eDIIX5A EdZK5+kIwJffZcuj38FbzSNJITD3ByqPxeEQc1oDrCA5qnjRe3FI/h7iS6O4YbmU 3W5V1s2cGu+2bLuz/yjOsoHcTKDacSyHrdrIYYh8= Received: (qmail 12873 invoked by alias); 3 Aug 2014 14:32:56 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 12818 invoked by uid 89); 3 Aug 2014 14:32:55 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-we0-f171.google.com Received: from mail-we0-f171.google.com (HELO mail-we0-f171.google.com) (74.125.82.171) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Sun, 03 Aug 2014 14:32:45 +0000 Received: by mail-we0-f171.google.com with SMTP id p10so6521826wes.30 for ; Sun, 03 Aug 2014 07:32:42 -0700 (PDT) X-Received: by 10.181.13.112 with SMTP id ex16mr20983346wid.58.1407076362209; Sun, 03 Aug 2014 07:32:42 -0700 (PDT) Received: from localhost ([95.145.138.172]) by mx.google.com with ESMTPSA id w7sm30471026wiy.6.2014.08.03.07.32.41 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 03 Aug 2014 07:32:41 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, rdsandiford@googlemail.com Subject: [PATCH 40/50] rtlanal.c:for_each_inc_dec References: <87y4v5d77q.fsf@googlemail.com> Date: Sun, 03 Aug 2014 15:32:41 +0100 In-Reply-To: <87y4v5d77q.fsf@googlemail.com> (Richard Sandiford's message of "Sun, 03 Aug 2014 14:38:01 +0100") Message-ID: <8761i97ieu.fsf@googlemail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 The old for_each_inc_dec callback had a for_each_rtx-like return value, with >0 being returned directly, 0 meaning "continue" and <0 meaning "skip subrtxes". But there's no reason to distinguish the latter two cases since auto-inc/dec expressions aren't allowed to contain other auto-inc/dec expressions. And if for_each_rtx is going away, there's no longer any consistency argument for using the same interface. gcc/ * rtl.h (for_each_inc_dec_fn): Remove special case for -1. * cselib.c (cselib_record_autoinc_cb): Update accordingly. (cselib_record_sets): Likewise. * dse.c (emit_inc_dec_insn_before, check_for_inc_dec_1) (check_for_inc_dec): Likewise. * rtlanal.c (for_each_inc_dec_ops): Delete. (for_each_inc_dec_find_inc_dec): Take the MEM as argument, rather than a pointer to the memory address. Replace for_each_inc_dec_ops argument with separate function and data arguments. Abort on non-autoinc addresses. (for_each_inc_dec_find_mem): Delete. (for_each_inc_dec): Use FOR_EACH_SUBRTX_VAR to visit every autoinc MEM. Index: gcc/rtl.h =================================================================== --- gcc/rtl.h 2014-08-03 11:25:31.042163078 +0100 +++ gcc/rtl.h 2014-08-03 11:25:31.324165866 +0100 @@ -2293,9 +2293,8 @@ extern int for_each_rtx (rtx *, rtx_func within MEM that sets DEST to SRC + SRCOFF, or SRC if SRCOFF is NULL. The callback is passed the same opaque ARG passed to for_each_inc_dec. Return zero to continue looking for other - autoinc operations, -1 to skip OP's operands, and any other value - to interrupt the traversal and return that value to the caller of - for_each_inc_dec. */ + autoinc operations or any other value to interrupt the traversal and + return that value to the caller of for_each_inc_dec. */ typedef int (*for_each_inc_dec_fn) (rtx mem, rtx op, rtx dest, rtx src, rtx srcoff, void *arg); extern int for_each_inc_dec (rtx *, for_each_inc_dec_fn, void *arg); Index: gcc/cselib.c =================================================================== --- gcc/cselib.c 2014-08-03 11:25:09.536950464 +0100 +++ gcc/cselib.c 2014-08-03 11:25:31.323165856 +0100 @@ -2464,7 +2464,7 @@ cselib_record_autoinc_cb (rtx mem ATTRIB data->n_sets++; - return -1; + return 0; } /* Record the effects of any sets and autoincs in INSN. */ @@ -2523,7 +2523,7 @@ cselib_record_sets (rtx insn) data.sets = sets; data.n_sets = n_sets_before_autoinc = n_sets; - for_each_inc_dec (&insn, cselib_record_autoinc_cb, &data); + for_each_inc_dec (&PATTERN (insn), cselib_record_autoinc_cb, &data); n_sets = data.n_sets; /* Look up the values that are read. Do this before invalidating the Index: gcc/dse.c =================================================================== --- gcc/dse.c 2014-08-03 11:25:25.192105241 +0100 +++ gcc/dse.c 2014-08-03 11:25:31.323165856 +0100 @@ -895,7 +895,7 @@ emit_inc_dec_insn_before (rtx mem ATTRIB emit_insn_before (new_insn, insn); - return -1; + return 0; } /* Before we delete INSN_INFO->INSN, make sure that the auto inc/dec, if it @@ -908,7 +908,8 @@ check_for_inc_dec_1 (insn_info_t insn_in rtx insn = insn_info->insn; rtx note = find_reg_note (insn, REG_INC, NULL_RTX); if (note) - return for_each_inc_dec (&insn, emit_inc_dec_insn_before, insn_info) == 0; + return for_each_inc_dec (&PATTERN (insn), emit_inc_dec_insn_before, + insn_info) == 0; return true; } @@ -927,7 +928,8 @@ check_for_inc_dec (rtx insn) insn_info.fixed_regs_live = NULL; note = find_reg_note (insn, REG_INC, NULL_RTX); if (note) - return for_each_inc_dec (&insn, emit_inc_dec_insn_before, &insn_info) == 0; + return for_each_inc_dec (&PATTERN (insn), emit_inc_dec_insn_before, + &insn_info) == 0; return true; } Index: gcc/rtlanal.c =================================================================== --- gcc/rtlanal.c 2014-08-03 11:25:31.043163088 +0100 +++ gcc/rtlanal.c 2014-08-03 11:25:31.325165876 +0100 @@ -3105,49 +3105,32 @@ for_each_rtx (rtx *x, rtx_function f, vo -/* Data structure that holds the internal state communicated between - for_each_inc_dec, for_each_inc_dec_find_mem and - for_each_inc_dec_find_inc_dec. */ - -struct for_each_inc_dec_ops { - /* The function to be called for each autoinc operation found. */ - for_each_inc_dec_fn fn; - /* The opaque argument to be passed to it. */ - void *arg; - /* The MEM we're visiting, if any. */ - rtx mem; -}; - -static int for_each_inc_dec_find_mem (rtx *r, void *d); - -/* Find PRE/POST-INC/DEC/MODIFY operations within *R, extract the - operands of the equivalent add insn and pass the result to the - operator specified by *D. */ +/* MEM has a PRE/POST-INC/DEC/MODIFY address X. Extract the operands of + the equivalent add insn and pass the result to FN, using DATA as the + final argument. */ static int -for_each_inc_dec_find_inc_dec (rtx *r, void *d) +for_each_inc_dec_find_inc_dec (rtx mem, for_each_inc_dec_fn fn, void *data) { - rtx x = *r; - struct for_each_inc_dec_ops *data = (struct for_each_inc_dec_ops *)d; - + rtx x = XEXP (mem, 0); switch (GET_CODE (x)) { case PRE_INC: case POST_INC: { - int size = GET_MODE_SIZE (GET_MODE (data->mem)); + int size = GET_MODE_SIZE (GET_MODE (mem)); rtx r1 = XEXP (x, 0); rtx c = gen_int_mode (size, GET_MODE (r1)); - return data->fn (data->mem, x, r1, r1, c, data->arg); + return fn (mem, x, r1, r1, c, data); } case PRE_DEC: case POST_DEC: { - int size = GET_MODE_SIZE (GET_MODE (data->mem)); + int size = GET_MODE_SIZE (GET_MODE (mem)); rtx r1 = XEXP (x, 0); rtx c = gen_int_mode (-size, GET_MODE (r1)); - return data->fn (data->mem, x, r1, r1, c, data->arg); + return fn (mem, x, r1, r1, c, data); } case PRE_MODIFY: @@ -3155,69 +3138,43 @@ for_each_inc_dec_find_inc_dec (rtx *r, v { rtx r1 = XEXP (x, 0); rtx add = XEXP (x, 1); - return data->fn (data->mem, x, r1, add, NULL, data->arg); - } - - case MEM: - { - rtx save = data->mem; - int ret = for_each_inc_dec_find_mem (r, d); - data->mem = save; - return ret; + return fn (mem, x, r1, add, NULL, data); } default: - return 0; - } -} - -/* If *R is a MEM, find PRE/POST-INC/DEC/MODIFY operations within its - address, extract the operands of the equivalent add insn and pass - the result to the operator specified by *D. */ - -static int -for_each_inc_dec_find_mem (rtx *r, void *d) -{ - rtx x = *r; - if (x != NULL_RTX && MEM_P (x)) - { - struct for_each_inc_dec_ops *data = (struct for_each_inc_dec_ops *) d; - int result; - - data->mem = x; - - result = for_each_rtx (&XEXP (x, 0), for_each_inc_dec_find_inc_dec, - data); - if (result) - return result; - - return -1; + gcc_unreachable (); } - return 0; } -/* Traverse *X looking for MEMs, and for autoinc operations within - them. For each such autoinc operation found, call FN, passing it +/* Traverse *LOC looking for MEMs that have autoinc addresses. + For each such autoinc operation found, call FN, passing it the innermost enclosing MEM, the operation itself, the RTX modified by the operation, two RTXs (the second may be NULL) that, once added, represent the value to be held by the modified RTX - afterwards, and ARG. FN is to return -1 to skip looking for other - autoinc operations within the visited operation, 0 to continue the - traversal, or any other value to have it returned to the caller of + afterwards, and DATA. FN is to return 0 to continue the + traversal or any other value to have it returned to the caller of for_each_inc_dec. */ int -for_each_inc_dec (rtx *x, +for_each_inc_dec (rtx *loc, for_each_inc_dec_fn fn, - void *arg) + void *data) { - struct for_each_inc_dec_ops data; - - data.fn = fn; - data.arg = arg; - data.mem = NULL; - - return for_each_rtx (x, for_each_inc_dec_find_mem, &data); + subrtx_var_iterator::array_type array; + FOR_EACH_SUBRTX_VAR (iter, array, *loc, NONCONST) + { + rtx mem = *iter; + if (mem + && MEM_P (mem) + && GET_RTX_CLASS (GET_CODE (XEXP (mem, 0))) == RTX_AUTOINC) + { + int res = for_each_inc_dec_find_inc_dec (mem, fn, data); + if (res != 0) + return res; + iter.skip_subrtxes (); + } + } + return 0; }