From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22694 invoked by alias); 6 Jan 2019 22:36:43 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 22683 invoked by uid 89); 6 Jan 2019 22:36:43 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=Hx-spam-relays-external:209.85.210.195, H*RU:209.85.210.195, revised, australia X-HELO: mail-pf1-f195.google.com Received: from mail-pf1-f195.google.com (HELO mail-pf1-f195.google.com) (209.85.210.195) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 06 Jan 2019 22:36:39 +0000 Received: by mail-pf1-f195.google.com with SMTP id b7so20863005pfi.8 for ; Sun, 06 Jan 2019 14:36:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=+Hu7hmK1lyZgay3RrwGqOf62kZGpcoYHquns5ZNMgJ4=; b=ahgqB2U2+VwA3wBDuy0ZXy9LD82vJVOenfWCqLlo9cPC0gwnZ5rA5lGu7VJujS6URx InkxAfwZ/69GI9ysb/2AYTDYS9kcD/P5fbEm2fnomaGYL/OxJDEz9An/qeTMaUer2eKz E3FyMfHPZ5YWPigZ6+LukXegd3a+ERNejt3mG6rHh3w6Jv3fg/xQhBgViI7RNCStSrZg ej2OINizcJVIH+w9pZ0KF+hIVi535yt519SQwbdELrlq3gjW/ZX+zrFBXz3OzTySBzSl eJdehmBmtNCKSH9FgqN2i4ofRD0x2gJ32GgIdehEgdr23zpMEt3GxSD+txBT6vUy0LAu A+1A== Return-Path: Received: from bubble.grove.modra.org ([58.175.241.133]) by smtp.gmail.com with ESMTPSA id e86sm100824588pfb.6.2019.01.06.14.36.36 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 06 Jan 2019 14:36:36 -0800 (PST) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id B209E8065D; Mon, 7 Jan 2019 09:06:32 +1030 (ACDT) Date: Sun, 06 Jan 2019 22:36:00 -0000 From: Alan Modra To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: Re: [PATCH] genattrtab bit-rot, and if_then_else in values Message-ID: <20190106223632.GF3170@bubble.grove.modra.org> References: <20190103092154.GZ30978@bubble.grove.modra.org> <87a7khsyjz.fsf@arm.com> <20190103143637.GA3170@bubble.grove.modra.org> <87lg41r7nb.fsf@arm.com> <87h8epr2ao.fsf@arm.com> <20190104001952.GB3170@bubble.grove.modra.org> <87imz4pqf8.fsf@arm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <87imz4pqf8.fsf@arm.com> User-Agent: Mutt/1.9.4 (2018-02-28) X-IsSubscribed: yes X-SW-Source: 2019-01/txt/msg00252.txt.bz2 On Fri, Jan 04, 2019 at 12:18:03PM +0000, Richard Sandiford wrote: > Alan Modra writes: > > On Thu, Jan 03, 2019 at 07:03:59PM +0000, Richard Sandiford wrote: > >> Richard Sandiford writes: > >> > This still seems risky and isn't what the name and function comment > > > > OK, how about this delta from the previous patch to ameliorate the > > maintenance risk? > > attr_value_alignment seems clearer, and means that we can handle > things like: > > (mult (symbol_ref "...") (const_int 4)) OK, revised patch as follows, handling MINUS and MULT in the max/min value functions too. * genattrtab.c (max_attr_value, min_attr_value, or_attr_value): Delete "unknownp" parameter. Adjust callers. Handle CONST_INT, PLUS, MINUS, and MULT. (attr_value_aligned): Renamed from or_attr_value. (min_attr_value): Return INT_MIN for unhandled rtl case.. (min_fn): ..and translate to INT_MAX here. (write_length_unit_log): Modify to cope without "unknown". (write_attr_value): Handle IF_THEN_ELSE. diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index 2cd04cdb06f..b8adf704009 100644 --- a/gcc/genattrtab.c +++ b/gcc/genattrtab.c @@ -266,9 +266,9 @@ static int compares_alternatives_p (rtx); static void make_internal_attr (const char *, rtx, int); static void insert_insn_ent (struct attr_value *, struct insn_ent *); static void walk_attr_value (rtx); -static int max_attr_value (rtx, int*); -static int min_attr_value (rtx, int*); -static int or_attr_value (rtx, int*); +static int max_attr_value (rtx); +static int min_attr_value (rtx); +static unsigned int attr_value_alignment (rtx); static rtx simplify_test_exp (rtx, int, int); static rtx simplify_test_exp_in_temp (rtx, int, int); static rtx copy_rtx_unchanging (rtx); @@ -1550,15 +1550,16 @@ one_fn (rtx exp ATTRIBUTE_UNUSED) static rtx max_fn (rtx exp) { - int unknown; - return make_numeric_value (max_attr_value (exp, &unknown)); + return make_numeric_value (max_attr_value (exp)); } static rtx min_fn (rtx exp) { - int unknown; - return make_numeric_value (min_attr_value (exp, &unknown)); + int val = min_attr_value (exp); + if (val < 0) + val = INT_MAX; + return make_numeric_value (val); } static void @@ -1568,24 +1569,21 @@ write_length_unit_log (FILE *outf) struct attr_value *av; struct insn_ent *ie; unsigned int length_unit_log, length_or; - int unknown = 0; if (length_attr) { - length_or = or_attr_value (length_attr->default_val->value, &unknown); + length_or = attr_value_alignment (length_attr->default_val->value); for (av = length_attr->first_value; av; av = av->next) for (ie = av->first_insn; ie; ie = ie->next) - length_or |= or_attr_value (av->value, &unknown); - } + length_or |= attr_value_alignment (av->value); - if (length_attr == NULL || unknown) - length_unit_log = 0; - else - { length_or = ~length_or; for (length_unit_log = 0; length_or & 1; length_or >>= 1) length_unit_log++; } + else + length_unit_log = 0; + fprintf (outf, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log); } @@ -3753,11 +3751,12 @@ write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags, return attrs_cached; } -/* Given an attribute value, return the maximum CONST_STRING argument - encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */ +/* Given an attribute value expression, return the maximum value that + might be evaluated assuming all conditionals are independent. + Return INT_MAX if the value can't be calculated by this function. */ static int -max_attr_value (rtx exp, int *unknownp) +max_attr_value (rtx exp) { int current_max; int i, n; @@ -3768,25 +3767,62 @@ max_attr_value (rtx exp, int *unknownp) current_max = atoi (XSTR (exp, 0)); break; + case CONST_INT: + current_max = INTVAL (exp); + break; + + case PLUS: + current_max = max_attr_value (XEXP (exp, 0)); + if (current_max != INT_MAX) + { + n = current_max; + current_max = max_attr_value (XEXP (exp, 1)); + if (current_max != INT_MAX) + current_max += n; + } + break; + + case MINUS: + current_max = max_attr_value (XEXP (exp, 0)); + if (current_max != INT_MAX) + { + n = min_attr_value (XEXP (exp, 1)); + if (n == INT_MIN) + current_max = INT_MAX; + else + current_max -= n; + } + break; + + case MULT: + current_max = max_attr_value (XEXP (exp, 0)); + if (current_max != INT_MAX) + { + n = current_max; + current_max = max_attr_value (XEXP (exp, 1)); + if (current_max != INT_MAX) + current_max *= n; + } + break; + case COND: - current_max = max_attr_value (XEXP (exp, 1), unknownp); + current_max = max_attr_value (XEXP (exp, 1)); for (i = 0; i < XVECLEN (exp, 0); i += 2) { - n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp); + n = max_attr_value (XVECEXP (exp, 0, i + 1)); if (n > current_max) current_max = n; } break; case IF_THEN_ELSE: - current_max = max_attr_value (XEXP (exp, 1), unknownp); - n = max_attr_value (XEXP (exp, 2), unknownp); + current_max = max_attr_value (XEXP (exp, 1)); + n = max_attr_value (XEXP (exp, 2)); if (n > current_max) current_max = n; break; default: - *unknownp = 1; current_max = INT_MAX; break; } @@ -3794,11 +3830,12 @@ max_attr_value (rtx exp, int *unknownp) return current_max; } -/* Given an attribute value, return the minimum CONST_STRING argument - encountered. Set *UNKNOWNP and return 0 if the value is unknown. */ +/* Given an attribute value expression, return the minimum value that + might be evaluated assuming all conditionals are independent. + Return INT_MIN if the value can't be calculated by this function. */ static int -min_attr_value (rtx exp, int *unknownp) +min_attr_value (rtx exp) { int current_min; int i, n; @@ -3809,40 +3846,77 @@ min_attr_value (rtx exp, int *unknownp) current_min = atoi (XSTR (exp, 0)); break; + case CONST_INT: + current_min = INTVAL (exp); + break; + + case PLUS: + current_min = min_attr_value (XEXP (exp, 0)); + if (current_min != INT_MIN) + { + n = current_min; + current_min = min_attr_value (XEXP (exp, 1)); + if (current_min != INT_MIN) + current_min += n; + } + break; + + case MINUS: + current_min = min_attr_value (XEXP (exp, 0)); + if (current_min != INT_MIN) + { + n = max_attr_value (XEXP (exp, 1)); + if (n == INT_MAX) + current_min = INT_MIN; + else + current_min -= n; + } + break; + + case MULT: + current_min = min_attr_value (XEXP (exp, 0)); + if (current_min != INT_MIN) + { + n = current_min; + current_min = min_attr_value (XEXP (exp, 1)); + if (current_min != INT_MIN) + current_min *= n; + } + break; + case COND: - current_min = min_attr_value (XEXP (exp, 1), unknownp); + current_min = min_attr_value (XEXP (exp, 1)); for (i = 0; i < XVECLEN (exp, 0); i += 2) { - n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp); + n = min_attr_value (XVECEXP (exp, 0, i + 1)); if (n < current_min) current_min = n; } break; case IF_THEN_ELSE: - current_min = min_attr_value (XEXP (exp, 1), unknownp); - n = min_attr_value (XEXP (exp, 2), unknownp); + current_min = min_attr_value (XEXP (exp, 1)); + n = min_attr_value (XEXP (exp, 2)); if (n < current_min) current_min = n; break; default: - *unknownp = 1; - current_min = INT_MAX; + current_min = INT_MIN; break; } return current_min; } -/* Given an attribute value, return the result of ORing together all - CONST_STRING arguments encountered. Set *UNKNOWNP and return -1 - if the numeric value is not known. */ +/* Given an attribute value expression, return the alignment of values + assuming conditionals are independent. Returns 0 if EXP is known to + be zero, and 1 if the value can't be calculated by this function. */ -static int -or_attr_value (rtx exp, int *unknownp) +static unsigned int +attr_value_alignment (rtx exp) { - int current_or; + unsigned int current_or; int i; switch (GET_CODE (exp)) @@ -3851,24 +3925,38 @@ or_attr_value (rtx exp, int *unknownp) current_or = atoi (XSTR (exp, 0)); break; + case CONST_INT: + current_or = INTVAL (exp); + break; + + case PLUS: + case MINUS: + current_or = attr_value_alignment (XEXP (exp, 0)); + current_or |= attr_value_alignment (XEXP (exp, 1)); + break; + + case MULT: + current_or = attr_value_alignment (XEXP (exp, 0)); + current_or *= attr_value_alignment (XEXP (exp, 1)); + break; + case COND: - current_or = or_attr_value (XEXP (exp, 1), unknownp); + current_or = attr_value_alignment (XEXP (exp, 1)); for (i = 0; i < XVECLEN (exp, 0); i += 2) - current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp); + current_or |= attr_value_alignment (XVECEXP (exp, 0, i + 1)); break; case IF_THEN_ELSE: - current_or = or_attr_value (XEXP (exp, 1), unknownp); - current_or |= or_attr_value (XEXP (exp, 2), unknownp); + current_or = attr_value_alignment (XEXP (exp, 1)); + current_or |= attr_value_alignment (XEXP (exp, 2)); break; default: - *unknownp = 1; - current_or = -1; + current_or = 1; break; } - return current_or; + return current_or & -current_or; } /* Scan an attribute value, possibly a conditional, and record what actions @@ -4343,6 +4431,16 @@ write_attr_value (FILE *outf, struct attr_desc *attr, rtx value) write_attr_value (outf, attr, XEXP (value, 1)); break; + case IF_THEN_ELSE: + fprintf (outf, "("); + write_test_expr (outf, XEXP (value, 0), 0, 0, false); + fprintf (outf, " ? "); + write_attr_value (outf, attr, XEXP (value, 1)); + fprintf (outf, " : "); + write_attr_value (outf, attr, XEXP (value, 2)); + fprintf (outf, ")"); + break; + default: gcc_unreachable (); } -- Alan Modra Australia Development Lab, IBM