From patchwork Thu Jan 3 09:21:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 1020210 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-493315-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="q/oz4QtJ"; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="f7Ux/gR5"; dkim-atps=neutral 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 43Vj9f0d7Zz9s9G for ; Thu, 3 Jan 2019 20:22:13 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=e9ohpZ3gHJmvEOqGZHUb5Cv4EgKIIQemmnoI//bRDOdk+3Puw9 /EQ7WYLdPDD9WDCHcYHHTzP7q+K0I3oQ5y2WSOwxLMloHqsdWree/2GG3jErWJ6l KghtfGLV8t//m+kpW7YnyxGs2eb35esj+CYZ73r/HS4au+DpDcXVXk+8s= 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:date :from:to:cc:subject:message-id:mime-version:content-type; s= default; bh=oyKtkwj1nA+HROy+8ey900mswkQ=; b=q/oz4QtJbsmPnD4d2UvG z6t/5ZZzaFoKuBDBs5rVnVfncduxs8FO68t3n7VHRuBAEvYVCUp2W6UQbGRbfAFv GyQ5QKUeAHeGxng/SitLBglLUAiZctSTKRygNAANhcqbInEf2M11v3/jwBEFtYCP Z306Ngc9HUU8DFnwg5PSl6g= Received: (qmail 87550 invoked by alias); 3 Jan 2019 09:22:05 -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 87538 invoked by uid 89); 3 Jan 2019 09:22:05 -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=Development, australia, Australia, HX-HELO:sk:mail-pf X-HELO: mail-pf1-f193.google.com Received: from mail-pf1-f193.google.com (HELO mail-pf1-f193.google.com) (209.85.210.193) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 03 Jan 2019 09:22:01 +0000 Received: by mail-pf1-f193.google.com with SMTP id q1so16421036pfi.5 for ; Thu, 03 Jan 2019 01:22:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :user-agent; bh=CURPnaWRErYT1lVY1V5ZBIMSynEJi4/Oeup1kOVO2Os=; b=f7Ux/gR5WToO9/r2dfs8dY4/gOlBm/4Dsk7DyN9eKuJC4EMAEJisUxDJx143gDzkmR DjkNedT94ABFrlcfutTf7q3tHmnAWvKngYl2fagHObEQOs9k/SyAZ9fjsTUJSRA3GErM WRyvt+pdtiCqh/pmzxBmtU6SHWHvYG4IZ47ZA54+DnYIkFHAAUaoIMJISHXzfzl4Bnep BhJOcpgLB13LAEUcZ0JoI2SAWu35P/Vp4eBahGeKHhK/uiQbCAAT2eh4G/duPxuigw/q 8V4SswK7u/m8ZpVDrwztvU/0WNUJs//iLNMWrv3lMpBjn69duLgjCGo3lj/rehs+qpo3 gUyQ== Received: from bubble.grove.modra.org ([58.175.241.133]) by smtp.gmail.com with ESMTPSA id o7sm73929049pfb.34.2019.01.03.01.21.58 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 03 Jan 2019 01:21:58 -0800 (PST) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 7661B80631; Thu, 3 Jan 2019 19:51:54 +1030 (ACDT) Date: Thu, 3 Jan 2019 19:51:54 +1030 From: Alan Modra To: gcc-patches@gcc.gnu.org Cc: Richard Sandiford Subject: [PATCH] genattrtab bit-rot, and if_then_else in values Message-ID: <20190103092154.GZ30978@bubble.grove.modra.org> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.9.4 (2018-02-28) X-IsSubscribed: yes This patch started off just by adding if_then_else support in write_attr_value to be able to write a saner expression for powerpc tls_gdld_nomark length. (*) Then I noticed bit-rot in functions used to calculate insn_default_length, insn_min_length, and length_unit_log (which are used by the shorten_branches pass). These functions don't handle a const_int length value and return an "unknown" status that isn't used, or in the case of or_attr_value, doesn't need to be used. min_attr_value also attempts to return INT_MAX for the unhandled rtl case, but this can get lost in recursive calls. I fixed that problem by returning INT_MIN instead, and translating that to INT_MAX in the only caller of min_attr_value. Bootstrapped and regression tested powerpc64le-linux and x86_64-linux. OK to apply? * genattrtab.c (max_attr_value, min_attr_value, or_attr_value): Delete "unknownp" parameter. Adjust callers. Handle CONST_INT and PLUS. (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. *) I want to use something like the following in a fix for PR88614. (set (attr "length") (plus (if_then_else (match_test "TARGET_CMODEL != CMODEL_SMALL") (const_int 8) (const_int 4)) (plus (if_then_else (match_test "GET_CODE (operands[1]) != SYMBOL_REF") (plus (if_then_else (match_test "!rs6000_speculate_indirect_jumps") (const_int 4) (const_int 0)) (if_then_else (match_test "DEFAULT_ABI == ABI_AIX") (const_int 4) (const_int 0))) (const_int 0)) (if_then_else (match_test "DEFAULT_ABI != ABI_V4") (const_int 8) (const_int 4))))) diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index 2cd04cdb06f..c86b3587cd9 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 int or_attr_value (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,20 @@ write_length_unit_log (FILE *outf) struct attr_value *av; struct insn_ent *ie; unsigned int length_unit_log, length_or; - int unknown = 0; + length_or = ~0; if (length_attr) { - length_or = or_attr_value (length_attr->default_val->value, &unknown); + length_or = or_attr_value (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 |= or_attr_value (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++; - } + length_or = ~length_or; + for (length_unit_log = 0; length_or & 1; length_or >>= 1) + length_unit_log++; + fprintf (outf, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log); } @@ -3753,11 +3750,11 @@ 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, return the maximum CONST_INT or CONST_STRING + argument encountered. Return INT_MAX if the value is unknown. */ static int -max_attr_value (rtx exp, int *unknownp) +max_attr_value (rtx exp) { int current_max; int i, n; @@ -3768,25 +3765,39 @@ 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 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 +3805,11 @@ 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, return the minimum CONST_INT or CONST_STRING + argument encountered. Return INT_MIN if the value is unknown. */ static int -min_attr_value (rtx exp, int *unknownp) +min_attr_value (rtx exp) { int current_min; int i, n; @@ -3809,26 +3820,40 @@ 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 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; } @@ -3836,11 +3861,11 @@ min_attr_value (rtx exp, int *unknownp) } /* 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. */ + CONST_INT or CONST_STRING arguments encountered. Return -1 if the + numeric value is not known. */ static int -or_attr_value (rtx exp, int *unknownp) +or_attr_value (rtx exp) { int current_or; int i; @@ -3851,19 +3876,33 @@ or_attr_value (rtx exp, int *unknownp) current_or = atoi (XSTR (exp, 0)); break; + case CONST_INT: + current_or = INTVAL (exp); + break; + + case PLUS: + current_or = or_attr_value (XEXP (exp, 0)); + if (current_or != -1) + { + int n = current_or; + current_or = or_attr_value (XEXP (exp, 1)); + if (current_or != -1) + current_or += n; + } + break; + case COND: - current_or = or_attr_value (XEXP (exp, 1), unknownp); + current_or = or_attr_value (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 |= or_attr_value (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 = or_attr_value (XEXP (exp, 1)); + current_or |= or_attr_value (XEXP (exp, 2)); break; default: - *unknownp = 1; current_or = -1; break; } @@ -4343,6 +4382,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 (); }