From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 58556 invoked by alias); 19 Sep 2018 15:23:17 -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 58165 invoked by uid 89); 19 Sep 2018 15:23:16 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.0 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KHOP_DYNAMIC,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy=becoming, alternatives, RTXs, recog.h X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0a-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.156.1) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 19 Sep 2018 15:23:14 +0000 Received: from pps.filterd (m0098410.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w8JFKmQf072525 for ; Wed, 19 Sep 2018 11:23:11 -0400 Received: from e06smtp05.uk.ibm.com (e06smtp05.uk.ibm.com [195.75.94.101]) by mx0a-001b2d01.pphosted.com with ESMTP id 2mkrn41f7u-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 19 Sep 2018 11:23:11 -0400 Received: from localhost by e06smtp05.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 19 Sep 2018 16:23:05 +0100 Received: from b06cxnps4076.portsmouth.uk.ibm.com (9.149.109.198) by e06smtp05.uk.ibm.com (192.168.101.135) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Wed, 19 Sep 2018 16:23:02 +0100 Received: from d06av23.portsmouth.uk.ibm.com (d06av23.portsmouth.uk.ibm.com [9.149.105.59]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w8JFN13H58916882 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 19 Sep 2018 15:23:01 GMT Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2EA92A404D; Wed, 19 Sep 2018 18:22:46 +0100 (BST) Received: from d06av23.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E25B6A405E; Wed, 19 Sep 2018 18:22:45 +0100 (BST) Received: from white.boeblingen.de.ibm.com (unknown [9.152.99.112]) by d06av23.portsmouth.uk.ibm.com (Postfix) with ESMTP; Wed, 19 Sep 2018 18:22:45 +0100 (BST) From: Ilya Leoshkevich To: gcc-patches@gcc.gnu.org Cc: krebbel@linux.ibm.com, rdapp@linux.ibm.com, Ilya Leoshkevich Subject: [PATCH] Change EQ_ATTR_ALT to support up to 64 alternatives Date: Wed, 19 Sep 2018 15:51:00 -0000 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit x-cbid: 18091915-0020-0000-0000-000002C8831A X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18091915-0021-0000-0000-00002115FF91 Message-Id: <20180919152246.55456-1-iii@linux.ibm.com> X-IsSubscribed: yes X-SW-Source: 2018-09/txt/msg01070.txt.bz2 On S/390 there is a need to support more than 32 instruction alternatives per define_insn. Currently this is not explicitly prohibited or unsupported: MAX_RECOG_ALTERNATIVES is equal 35, and, futhermore, the related code uses uint64_t for bitmaps in most places. However, genattrtab contains the logic to convert (eq_attr "attribute" "value") RTXs to (eq_attr_alt bitmap) RTXs, where bitmap contains alternatives, whose "attribute" has the corresponding "value". Unfortunately, bitmap is only 32 bits. When adding the 33rd alternative, this led to (eq_attr "type" "larl") becoming (eq_attr_alt -1050625 1), where -1050625 == 0xffeff7ff. The cleared bits 12, 21 and 32 correspond to two existing and one newly added insn of type "larl". compute_alternative_mask sign extended this to 0xffffffffffeff7ff, which contained non-existent alternatives, and this made simplify_test_exp fail with "invalid alternative specified". I'm not sure why it didn't fail the same way before, since the top bit, which led to sign extension, should have been set even with 32 alternatives. Maybe simplify_test_exp was not called for "type" attribute for some reason? This patch widens EQ_ATTR_ALT bitmap to 64 bits, making it possible to gracefully handle up to 64 alternatives. It eliminates the problem with the 33rd alternative on S/390. gcc/ChangeLog: 2018-09-18 Ilya Leoshkevich * genattrtab.c (mk_attr_alt): Use alternative_mask. (attr_rtx_1): Adjust caching to match the new EQ_ATTR_ALT field types. (check_attr_test): Use alternative_mask. (get_attr_value): Likewise. (compute_alternative_mask): Use alternative_mask and XWINT. (make_alternative_compare): Use alternative_mask. (attr_alt_subset_p): Use XWINT. (attr_alt_subset_of_compl_p): Likewise. (attr_alt_intersection): Likewise. (attr_alt_union): Likewise. (attr_alt_complement): Likewise. (mk_attr_alt): Use alternative_mask. (simplify_test_exp): Use alternative_mask and XWINT. (write_test_expr): Use alternative_mask and XWINT, adjust bit number calculation to support 64 bits. Generate code that checks 64-bit masks. (main): Use alternative_mask. * rtl.def (EQ_ATTR_ALT): Change field types from ii to ww. --- gcc/genattrtab.c | 127 +++++++++++++++++++++++++---------------------- gcc/recog.h | 2 +- gcc/rtl.def | 2 +- 3 files changed, 71 insertions(+), 60 deletions(-) diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index f9b0bc94b0f..f8ff054fc7c 100644 --- a/gcc/genattrtab.c +++ b/gcc/genattrtab.c @@ -228,7 +228,9 @@ static int *insn_n_alternatives; /* Stores, for each insn code, a bitmap that has bits on for each possible alternative. */ -static uint64_t *insn_alternatives; +/* Keep this in sync with recog.h. */ +typedef uint64_t alternative_mask; +static alternative_mask *insn_alternatives; /* Used to simplify expressions. */ @@ -256,7 +258,7 @@ static char *attr_printf (unsigned int, const char *, ...) ATTRIBUTE_PRINTF_2; static rtx make_numeric_value (int); static struct attr_desc *find_attr (const char **, int); -static rtx mk_attr_alt (uint64_t); +static rtx mk_attr_alt (alternative_mask); static char *next_comma_elt (const char **); static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int); static rtx copy_boolean (rtx); @@ -494,26 +496,26 @@ attr_rtx_1 (enum rtx_code code, va_list p) } } else if (GET_RTX_LENGTH (code) == 2 - && GET_RTX_FORMAT (code)[0] == 'i' - && GET_RTX_FORMAT (code)[1] == 'i') + && GET_RTX_FORMAT (code)[0] == 'w' + && GET_RTX_FORMAT (code)[1] == 'w') { - int arg0 = va_arg (p, int); - int arg1 = va_arg (p, int); + HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT); + HOST_WIDE_INT arg1 = va_arg (p, HOST_WIDE_INT); hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1)); for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next) if (h->hashcode == hashcode && GET_CODE (h->u.rtl) == code - && XINT (h->u.rtl, 0) == arg0 - && XINT (h->u.rtl, 1) == arg1) + && XWINT (h->u.rtl, 0) == arg0 + && XWINT (h->u.rtl, 1) == arg1) return h->u.rtl; if (h == 0) { rtl_obstack = hash_obstack; rt_val = rtx_alloc (code); - XINT (rt_val, 0) = arg0; - XINT (rt_val, 1) = arg1; + XWINT (rt_val, 0) = arg0; + XWINT (rt_val, 1) = arg1; } } else if (code == CONST_INT) @@ -703,7 +705,8 @@ check_attr_test (file_location loc, rtx exp, attr_desc *attr) if (attr2 == NULL) { if (! strcmp (XSTR (exp, 0), "alternative")) - return mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp, 1))); + return mk_attr_alt (((alternative_mask) 1) + << atoi (XSTR (exp, 1))); else fatal_at (loc, "unknown attribute `%s' in definition of" " attribute `%s'", XSTR (exp, 0), attr->name); @@ -750,7 +753,7 @@ check_attr_test (file_location loc, rtx exp, attr_desc *attr) name_ptr = XSTR (exp, 1); while ((p = next_comma_elt (&name_ptr)) != NULL) - set |= ((uint64_t) 1) << atoi (p); + set |= ((alternative_mask) 1) << atoi (p); return mk_attr_alt (set); } @@ -1224,7 +1227,7 @@ get_attr_value (file_location loc, rtx value, struct attr_desc *attr, int insn_code) { struct attr_value *av; - uint64_t num_alt = 0; + alternative_mask num_alt = 0; value = make_canonical (loc, attr, value); if (compares_alternatives_p (value)) @@ -1868,7 +1871,7 @@ insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int ins This routine is passed an expression and either AND or IOR. It returns a bitmask indicating which alternatives are mentioned within EXP. */ -static uint64_t +static alternative_mask compute_alternative_mask (rtx exp, enum rtx_code code) { const char *string; @@ -1887,11 +1890,11 @@ compute_alternative_mask (rtx exp, enum rtx_code code) else if (GET_CODE (exp) == EQ_ATTR_ALT) { - if (code == AND && XINT (exp, 1)) - return XINT (exp, 0); + if (code == AND && XWINT (exp, 1)) + return XWINT (exp, 0); - if (code == IOR && !XINT (exp, 1)) - return XINT (exp, 0); + if (code == IOR && !XWINT (exp, 1)) + return XWINT (exp, 0); return 0; } @@ -1899,15 +1902,15 @@ compute_alternative_mask (rtx exp, enum rtx_code code) return 0; if (string[1] == 0) - return ((uint64_t) 1) << (string[0] - '0'); - return ((uint64_t) 1) << atoi (string); + return ((alternative_mask) 1) << (string[0] - '0'); + return ((alternative_mask) 1) << atoi (string); } /* Given I, a single-bit mask, return RTX to compare the `alternative' attribute with the value represented by that bit. */ static rtx -make_alternative_compare (uint64_t mask) +make_alternative_compare (alternative_mask mask) { return mk_attr_alt (mask); } @@ -2286,19 +2289,19 @@ simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index) static bool attr_alt_subset_p (rtx s1, rtx s2) { - switch ((XINT (s1, 1) << 1) | XINT (s2, 1)) + switch ((XWINT (s1, 1) << 1) | XWINT (s2, 1)) { case (0 << 1) | 0: - return !(XINT (s1, 0) &~ XINT (s2, 0)); + return !(XWINT (s1, 0) &~ XWINT (s2, 0)); case (0 << 1) | 1: - return !(XINT (s1, 0) & XINT (s2, 0)); + return !(XWINT (s1, 0) & XWINT (s2, 0)); case (1 << 1) | 0: return false; case (1 << 1) | 1: - return !(XINT (s2, 0) &~ XINT (s1, 0)); + return !(XWINT (s2, 0) &~ XWINT (s1, 0)); default: gcc_unreachable (); @@ -2310,16 +2313,16 @@ attr_alt_subset_p (rtx s1, rtx s2) static bool attr_alt_subset_of_compl_p (rtx s1, rtx s2) { - switch ((XINT (s1, 1) << 1) | XINT (s2, 1)) + switch ((XWINT (s1, 1) << 1) | XWINT (s2, 1)) { case (0 << 1) | 0: - return !(XINT (s1, 0) & XINT (s2, 0)); + return !(XWINT (s1, 0) & XWINT (s2, 0)); case (0 << 1) | 1: - return !(XINT (s1, 0) & ~XINT (s2, 0)); + return !(XWINT (s1, 0) & ~XWINT (s2, 0)); case (1 << 1) | 0: - return !(XINT (s2, 0) &~ XINT (s1, 0)); + return !(XWINT (s2, 0) &~ XWINT (s1, 0)); case (1 << 1) | 1: return false; @@ -2336,25 +2339,25 @@ attr_alt_intersection (rtx s1, rtx s2) { int result; - switch ((XINT (s1, 1) << 1) | XINT (s2, 1)) + switch ((XWINT (s1, 1) << 1) | XWINT (s2, 1)) { case (0 << 1) | 0: - result = XINT (s1, 0) & XINT (s2, 0); + result = XWINT (s1, 0) & XWINT (s2, 0); break; case (0 << 1) | 1: - result = XINT (s1, 0) & ~XINT (s2, 0); + result = XWINT (s1, 0) & ~XWINT (s2, 0); break; case (1 << 1) | 0: - result = XINT (s2, 0) & ~XINT (s1, 0); + result = XWINT (s2, 0) & ~XWINT (s1, 0); break; case (1 << 1) | 1: - result = XINT (s1, 0) | XINT (s2, 0); + result = XWINT (s1, 0) | XWINT (s2, 0); break; default: gcc_unreachable (); } - return attr_rtx (EQ_ATTR_ALT, result, XINT (s1, 1) & XINT (s2, 1)); + return attr_rtx (EQ_ATTR_ALT, result, XWINT (s1, 1) & XWINT (s2, 1)); } /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */ @@ -2364,25 +2367,25 @@ attr_alt_union (rtx s1, rtx s2) { int result; - switch ((XINT (s1, 1) << 1) | XINT (s2, 1)) + switch ((XWINT (s1, 1) << 1) | XWINT (s2, 1)) { case (0 << 1) | 0: - result = XINT (s1, 0) | XINT (s2, 0); + result = XWINT (s1, 0) | XWINT (s2, 0); break; case (0 << 1) | 1: - result = XINT (s2, 0) & ~XINT (s1, 0); + result = XWINT (s2, 0) & ~XWINT (s1, 0); break; case (1 << 1) | 0: - result = XINT (s1, 0) & ~XINT (s2, 0); + result = XWINT (s1, 0) & ~XWINT (s2, 0); break; case (1 << 1) | 1: - result = XINT (s1, 0) & XINT (s2, 0); + result = XWINT (s1, 0) & XWINT (s2, 0); break; default: gcc_unreachable (); } - return attr_rtx (EQ_ATTR_ALT, result, XINT (s1, 1) | XINT (s2, 1)); + return attr_rtx (EQ_ATTR_ALT, result, XWINT (s1, 1) | XWINT (s2, 1)); } /* Return EQ_ATTR_ALT expression representing complement of S. */ @@ -2390,16 +2393,16 @@ attr_alt_union (rtx s1, rtx s2) static rtx attr_alt_complement (rtx s) { - return attr_rtx (EQ_ATTR_ALT, XINT (s, 0), 1 - XINT (s, 1)); + return attr_rtx (EQ_ATTR_ALT, XWINT (s, 0), 1 - XWINT (s, 1)); } /* Return EQ_ATTR_ALT expression representing set containing elements set in E. */ static rtx -mk_attr_alt (uint64_t e) +mk_attr_alt (alternative_mask e) { - return attr_rtx (EQ_ATTR_ALT, (int)e, 0); + return attr_rtx (EQ_ATTR_ALT, e, 0); } /* Given an expression, see if it can be simplified for a particular insn @@ -2419,7 +2422,7 @@ simplify_test_exp (rtx exp, int insn_code, int insn_index) struct attr_value *av; struct insn_ent *ie; struct attr_value_list *iv; - uint64_t i; + alternative_mask i; rtx newexp = exp; bool left_alt, right_alt; @@ -2484,14 +2487,14 @@ simplify_test_exp (rtx exp, int insn_code, int insn_index) && XSTR (XEXP (left, 0), 0) == alternative_name); else left_alt = (GET_CODE (left) == EQ_ATTR_ALT - && XINT (left, 1)); + && XWINT (left, 1)); if (GET_CODE (right) == NOT) right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR && XSTR (XEXP (right, 0), 0) == alternative_name); else right_alt = (GET_CODE (right) == EQ_ATTR_ALT - && XINT (right, 1)); + && XWINT (right, 1)); if (insn_code >= 0 && (GET_CODE (left) == AND @@ -2602,12 +2605,12 @@ simplify_test_exp (rtx exp, int insn_code, int insn_index) else if (insn_code >= 0 && (GET_CODE (left) == IOR || (GET_CODE (left) == EQ_ATTR_ALT - && !XINT (left, 1)) + && !XWINT (left, 1)) || (GET_CODE (left) == EQ_ATTR && XSTR (left, 0) == alternative_name) || GET_CODE (right) == IOR || (GET_CODE (right) == EQ_ATTR_ALT - && !XINT (right, 1)) + && !XWINT (right, 1)) || (GET_CODE (right) == EQ_ATTR && XSTR (right, 0) == alternative_name))) { @@ -2688,14 +2691,15 @@ simplify_test_exp (rtx exp, int insn_code, int insn_index) break; case EQ_ATTR_ALT: - if (!XINT (exp, 0)) - return XINT (exp, 1) ? true_rtx : false_rtx; + if (!XWINT (exp, 0)) + return XWINT (exp, 1) ? true_rtx : false_rtx; break; case EQ_ATTR: if (XSTR (exp, 0) == alternative_name) { - newexp = mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp, 1))); + newexp = mk_attr_alt (((alternative_mask) 1) + << atoi (XSTR (exp, 1))); break; } @@ -3568,7 +3572,8 @@ write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags, case EQ_ATTR_ALT: { - int set = XINT (exp, 0), bit = 0; + alternative_mask set = XWINT (exp, 0); + int bit = 0; if (flags & FLG_BITWISE) fatal ("EQ_ATTR_ALT not valid inside comparison"); @@ -3578,6 +3583,11 @@ write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags, if (!(set & (set - 1))) { + if (!(set & 0xffffffff)) + { + bit += 32; + set >>= 32; + } if (!(set & 0xffff)) { bit += 16; @@ -3602,12 +3612,13 @@ write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags, bit++; fprintf (outf, "which_alternative %s= %d", - XINT (exp, 1) ? "!" : "=", bit); + XWINT (exp, 1) ? "!" : "=", bit); } else { - fprintf (outf, "%s((1 << which_alternative) & %#x)", - XINT (exp, 1) ? "!" : "", set); + fprintf (outf, "%s((1ULL << which_alternative) & %#" + PRIx64 "ULL)", + XWINT (exp, 1) ? "!" : "", set); } } break; @@ -5220,11 +5231,11 @@ main (int argc, const char **argv) /* Make `insn_alternatives'. */ int num_insn_codes = get_num_insn_codes (); - insn_alternatives = oballocvec (uint64_t, num_insn_codes); + insn_alternatives = oballocvec (alternative_mask, num_insn_codes); for (id = defs; id; id = id->next) if (id->insn_code >= 0) insn_alternatives[id->insn_code] - = (((uint64_t) 1) << id->num_alternatives) - 1; + = (((alternative_mask) 1) << id->num_alternatives) - 1; /* Make `insn_n_alternatives'. */ insn_n_alternatives = oballocvec (int, num_insn_codes); diff --git a/gcc/recog.h b/gcc/recog.h index eca62803458..3d417ea23ac 100644 --- a/gcc/recog.h +++ b/gcc/recog.h @@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see a type that has at least MAX_RECOG_ALTERNATIVES + 1 bits, with the extra bit giving an invalid value that can be used to mean "uninitialized". */ #define MAX_RECOG_ALTERNATIVES 35 -typedef uint64_t alternative_mask; +typedef uint64_t alternative_mask; /* Keep in sync with genattrtab.c. */ /* A mask of all alternatives. */ #define ALL_ALTERNATIVES ((alternative_mask) -1) diff --git a/gcc/rtl.def b/gcc/rtl.def index 0ed27505545..b4282ab7ffd 100644 --- a/gcc/rtl.def +++ b/gcc/rtl.def @@ -1310,7 +1310,7 @@ DEF_RTL_EXPR(EQ_ATTR, "eq_attr", "ss", RTX_EXTRA) /* A special case of the above representing a set of alternatives. The first operand is bitmap of the set, the second one is the default value. */ -DEF_RTL_EXPR(EQ_ATTR_ALT, "eq_attr_alt", "ii", RTX_EXTRA) +DEF_RTL_EXPR(EQ_ATTR_ALT, "eq_attr_alt", "ww", RTX_EXTRA) /* A conditional expression which is true if the specified flag is true for the insn being scheduled in reorg. -- 2.19.0