From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-44.mimecast.com (us-smtp-delivery-44.mimecast.com [205.139.111.44]) by sourceware.org (Postfix) with ESMTPS id 136C13844764 for ; Sat, 4 May 2024 08:31:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 136C13844764 Authentication-Results: sourceware.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=none smtp.mailfrom=localhost.redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 136C13844764 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=205.139.111.44 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1714811470; cv=none; b=dytFWcD6td1pw2/ak8IJx4hLCVEGWsvAG2v0k7zUPpWYXVUqM1FnxYCDdxiVQeyojx47yiMPLjvKw+XoyXGmBufDrZsQINqDcdn1wswo5WJOdvIPVGMTHbR/LpyLPpR6xGqZJzOc1+Ny6QQBfHCmTwklZLzIWOSenz3raV4mWfk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1714811470; c=relaxed/simple; bh=MJqgz+USqRDrtCS4wjWR7bbDGh9PgRGUPfjX9H4jjf0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=IKQsb4hRJDQVVeIClczYe6q96I7WI6FoZvFkQzVywec7jqbMyoJTDo2yhNrdPGgMo9RRMbkm8TYxZzCegpa2UmayC6ZdndtxqbIrfISEj9VsmISQg2ydtOLodi/OmWUY1kP11WRbs9S4/9OEgH6xqeWPRsqn7KKhxECdGfHh0g8= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1714811463; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AJYnIrxFNHK+0ixt3sDHTrOkd5oM9bhfkj+M3RN8CMQ=; b=TQ1W1+TiyvYiNQPtIIIfCoqCe9dDa8aJtyOGANClH0aqDhRzmirSJ8hlojirOrRk5kX3GA iXTlCxL7UnPvUAfBIThrSzqVTflF+seV/Tk0gwV1J7lNbPvGaPmxRIzbUUW5bRxnd20L3p 8hzRLYW03kACG5ai4EBd0wWn7aCuwCo= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-590-_GQG1CrlPfOp8KW_At0YSQ-1; Sat, 04 May 2024 04:31:01 -0400 X-MC-Unique: _GQG1CrlPfOp8KW_At0YSQ-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 9E6748001B2 for ; Sat, 4 May 2024 08:31:01 +0000 (UTC) Received: from abulafia.quesejoda.com (unknown [10.39.192.71]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 102BAEC682; Sat, 4 May 2024 08:31:00 +0000 (UTC) Received: from abulafia.quesejoda.com (localhost [127.0.0.1]) by abulafia.quesejoda.com (8.18.1/8.17.1) with ESMTPS id 4448Uxrp139812 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Sat, 4 May 2024 10:30:59 +0200 Received: (from aldyh@localhost) by abulafia.quesejoda.com (8.18.1/8.18.1/Submit) id 4448UxRn139811; Sat, 4 May 2024 10:30:59 +0200 From: Aldy Hernandez To: GCC patches Cc: Andrew MacLeod , Aldy Hernandez Subject: [COMMITTED 07/23] Implement range-op dispatch for prange. Date: Sat, 4 May 2024 10:30:35 +0200 Message-ID: <20240504083056.139719-8-aldyh@redhat.com> In-Reply-To: <20240504083056.139719-1-aldyh@redhat.com> References: <20240504083056.139719-1-aldyh@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.5 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=WINDOWS-1252; x-default=true X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,NO_DNS_FOR_FROM,RCVD_IN_DNSWL_LOW,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: This patch adds the range-op dispatch code for prange, and adds some temporary sanity checks (for flag_checking only) to make sure we handle all the pointer/integer variants. In order to make sure I got all the combinations right, I started with a clean slate, trapping on all pointer operands. Then I added support for each one piecemeal. To verify the work, I added a pointers_handled_p() helper that is implemented for each range-op entry and returns TRUE iff the operator can handle a given combination of pointers. If this helper returns false, we will trap, because it indicates an operator that was not implemented. This is temporary checking code, and I will rip it out once the the dust has settled in a few days. gcc/ChangeLog: =09* range-op-mixed.h: Add using declarator for all classes. =09* range-op-ptr.cc (range_operator::pointers_handled_p): New. =09(range_operator::fold_range): New. =09(range_operator::op1_op2_relation_effect): New. =09(range_operator::op1_range): New. =09(range_operator::op2_range): New. =09(range_operator::op1_op2_relation): New. =09(range_operator::lhs_op1_relation): New. =09(range_operator::update_bitmask): New. =09(class pointer_plus_operator): New. =09(class operator_pointer_diff): New. =09(class hybrid_min_operator): New. =09(class hybrid_max_operator): New. =09* range-op.cc: Add RO_PPP, RO_PPI, RO_IPP, RO_IPI, RO_PIP, RO_PII. =09(range_op_handler::discriminator_fail): New. =09(has_pointer_operand_p): New. =09(range_op_handler::fold_range): Add pointer support. =09(range_op_handler::op1_range): Same. =09(range_op_handler::op2_range): Same. =09(range_op_handler::lhs_op1_relation): Same. =09(range_op_handler::lhs_op2_relation): Same. =09(range_op_handler::op1_op2_relation): Same. =09(class operator_div): Add using. =09(class operator_lshift): Add using. =09(class operator_rshift):Add using. =09(class operator_trunc_mod):Add using. =09(class operator_absu):Add using. =09* range-op.h (enum range_op_dispatch_type): New. =09Add extern definitions for RO_*. --- gcc/range-op-mixed.h | 19 ++++ gcc/range-op-ptr.cc | 220 +++++++++++++++++++++++++++++++++++++++++++ gcc/range-op.cc | 124 ++++++++++++++++++++++++ gcc/range-op.h | 111 ++++++++++++++++++++++ 4 files changed, 474 insertions(+) diff --git a/gcc/range-op-mixed.h b/gcc/range-op-mixed.h index 3ee7c9d6e0d..8163a4b53ca 100644 --- a/gcc/range-op-mixed.h +++ b/gcc/range-op-mixed.h @@ -111,6 +111,7 @@ public: using range_operator::op1_range; using range_operator::op2_range; using range_operator::op1_op2_relation; + using range_operator::update_bitmask; bool fold_range (irange &r, tree type, =09=09 const irange &op1, const irange &op2, =09=09 relation_trio =3D TRIO_VARYING) const final override; @@ -150,6 +151,7 @@ public: using range_operator::op1_range; using range_operator::op2_range; using range_operator::op1_op2_relation; + using range_operator::update_bitmask; bool fold_range (irange &r, tree type, =09=09 const irange &op1, const irange &op2, =09=09 relation_trio =3D TRIO_VARYING) const final override; @@ -189,6 +191,7 @@ public: using range_operator::op1_range; using range_operator::op2_range; using range_operator::op1_op2_relation; + using range_operator::update_bitmask; bool fold_range (irange &r, tree type, =09=09 const irange &op1, const irange &op2, =09=09 relation_trio =3D TRIO_VARYING) const final override; @@ -225,6 +228,7 @@ public: using range_operator::op1_range; using range_operator::op2_range; using range_operator::op1_op2_relation; + using range_operator::update_bitmask; bool fold_range (irange &r, tree type, =09=09 const irange &op1, const irange &op2, =09=09 relation_trio =3D TRIO_VARYING) const final override; @@ -264,6 +268,7 @@ public: using range_operator::op1_range; using range_operator::op2_range; using range_operator::op1_op2_relation; + using range_operator::update_bitmask; bool fold_range (irange &r, tree type, =09=09 const irange &op1, const irange &op2, =09=09 relation_trio =3D TRIO_VARYING) const final override; @@ -302,6 +307,7 @@ public: using range_operator::op1_range; using range_operator::op2_range; using range_operator::op1_op2_relation; + using range_operator::update_bitmask; bool fold_range (irange &r, tree type, =09=09 const irange &op1, const irange &op2, =09=09 relation_trio =3D TRIO_VARYING) const final override; @@ -376,6 +382,7 @@ public: using range_operator::fold_range; using range_operator::op1_range; using range_operator::lhs_op1_relation; + using range_operator::update_bitmask; bool fold_range (irange &r, tree type, =09=09 const irange &op1, const irange &op2, =09=09 relation_trio rel =3D TRIO_VARYING) const final override; @@ -402,6 +409,7 @@ public: using range_operator::op2_range; using range_operator::lhs_op1_relation; using range_operator::lhs_op2_relation; + using range_operator::update_bitmask; bool op1_range (irange &r, tree type, =09=09 const irange &lhs, const irange &op2, =09=09 relation_trio) const final override; @@ -445,6 +453,7 @@ class operator_abs : public range_operator public: using range_operator::fold_range; using range_operator::op1_range; + using range_operator::update_bitmask; bool fold_range (frange &r, tree type, =09=09 const frange &op1, const frange &, =09=09 relation_trio =3D TRIO_VARYING) const final override; @@ -473,6 +482,8 @@ public: using range_operator::op1_range; using range_operator::op2_range; using range_operator::lhs_op1_relation; + using range_operator::op1_op2_relation_effect; + using range_operator::update_bitmask; bool op1_range (irange &r, tree type, =09=09 const irange &lhs, const irange &op2, =09=09 relation_trio) const final override; @@ -556,6 +567,7 @@ class operator_mult : public cross_product_operator public: using range_operator::op1_range; using range_operator::op2_range; + using range_operator::update_bitmask; bool op1_range (irange &r, tree type, =09=09 const irange &lhs, const irange &op2, =09=09 relation_trio) const final override; @@ -608,6 +620,7 @@ class operator_bitwise_not : public range_operator public: using range_operator::fold_range; using range_operator::op1_range; + using range_operator::update_bitmask; bool fold_range (irange &r, tree type, =09=09 const irange &lh, const irange &rh, =09=09 relation_trio rel =3D TRIO_VARYING) const final override; @@ -626,6 +639,8 @@ class operator_bitwise_xor : public range_operator public: using range_operator::op1_range; using range_operator::op2_range; + using range_operator::op1_op2_relation_effect; + using range_operator::update_bitmask; bool op1_range (irange &r, tree type, =09=09 const irange &lhs, const irange &op2, =09=09 relation_trio rel =3D TRIO_VARYING) const final override; @@ -654,6 +669,7 @@ public: using range_operator::op1_range; using range_operator::op2_range; using range_operator::lhs_op1_relation; + using range_operator::update_bitmask; bool op1_range (irange &r, tree type, =09=09 const irange &lhs, const irange &op2, =09=09 relation_trio rel =3D TRIO_VARYING) const override; @@ -682,6 +698,7 @@ class operator_bitwise_or : public range_operator public: using range_operator::op1_range; using range_operator::op2_range; + using range_operator::update_bitmask; bool op1_range (irange &r, tree type, =09=09 const irange &lhs, const irange &op2, =09=09 relation_trio rel =3D TRIO_VARYING) const override; @@ -702,6 +719,7 @@ protected: class operator_min : public range_operator { public: + using range_operator::update_bitmask; void update_bitmask (irange &r, const irange &lh, =09=09 const irange &rh) const override; // Check compatibility of all operands. @@ -716,6 +734,7 @@ protected: class operator_max : public range_operator { public: + using range_operator::update_bitmask; void update_bitmask (irange &r, const irange &lh, const irange &rh) const override; // Check compatibility of all operands. diff --git a/gcc/range-op-ptr.cc b/gcc/range-op-ptr.cc index 7343ef635f3..560c798b90a 100644 --- a/gcc/range-op-ptr.cc +++ b/gcc/range-op-ptr.cc @@ -49,8 +49,222 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-ccp.h" #include "range-op-mixed.h" =20 +// Return TRUE if a range-op folder TYPE either handles or can safely +// ignore the dispatch pattern in DISPATCH. Return FALSE for any +// combination not handled, which will result in a hard fail up the +// chain. + +bool +range_operator::pointers_handled_p (range_op_dispatch_type ATTRIBUTE_UNUSE= D, +=09=09=09=09 unsigned dispatch ATTRIBUTE_UNUSED) const +{ + return false; +} + +bool +range_operator::fold_range (prange &r, tree type, +=09=09=09 const prange &op1, +=09=09=09 const prange &op2, +=09=09=09 relation_trio trio) const +{ + relation_kind rel =3D trio.op1_op2 (); + r.set_varying (type); + op1_op2_relation_effect (r, type, op1, op2, rel); + return true; +} + +bool +range_operator::fold_range (prange &r, tree type, +=09=09=09 const prange &op1, +=09=09=09 const irange &op2, +=09=09=09 relation_trio trio) const +{ + relation_kind rel =3D trio.op1_op2 (); + r.set_varying (type); + op1_op2_relation_effect (r, type, op1, op2, rel); + return true; +} + +bool +range_operator::fold_range (irange &r, tree type, +=09=09=09 const prange &op1, +=09=09=09 const prange &op2, +=09=09=09 relation_trio trio) const +{ + relation_kind rel =3D trio.op1_op2 (); + r.set_varying (type); + op1_op2_relation_effect (r, type, op1, op2, rel); + return true; +} + +bool +range_operator::fold_range (prange &r, tree type, +=09=09=09 const irange &op1, +=09=09=09 const prange &op2, +=09=09=09 relation_trio trio) const +{ + relation_kind rel =3D trio.op1_op2 (); + r.set_varying (type); + op1_op2_relation_effect (r, type, op1, op2, rel); + return true; +} + +bool +range_operator::fold_range (irange &r, tree type, +=09=09=09 const prange &op1, +=09=09=09 const irange &op2, +=09=09=09 relation_trio trio) const +{ + relation_kind rel =3D trio.op1_op2 (); + r.set_varying (type); + op1_op2_relation_effect (r, type, op1, op2, rel); + return true; +} + +bool +range_operator::op1_op2_relation_effect (prange &, tree, +=09=09=09=09=09 const prange &, +=09=09=09=09=09 const prange &, +=09=09=09=09=09 relation_kind) const +{ + return false; +} + +bool +range_operator::op1_op2_relation_effect (prange &, tree, +=09=09=09=09=09 const prange &, +=09=09=09=09=09 const irange &, +=09=09=09=09=09 relation_kind) const +{ + return false; +} + +bool +range_operator::op1_op2_relation_effect (irange &, tree, +=09=09=09=09=09 const prange &, +=09=09=09=09=09 const prange &, +=09=09=09=09=09 relation_kind) const +{ + return false; +} + +bool +range_operator::op1_op2_relation_effect (prange &, tree, +=09=09=09=09=09 const irange &, +=09=09=09=09=09 const prange &, +=09=09=09=09=09 relation_kind) const +{ + return false; +} + +bool +range_operator::op1_op2_relation_effect (irange &, tree, +=09=09=09=09=09 const prange &, +=09=09=09=09=09 const irange &, +=09=09=09=09=09 relation_kind) const +{ + return false; +} + +bool +range_operator::op1_range (prange &, tree, +=09=09=09 const prange &lhs ATTRIBUTE_UNUSED, +=09=09=09 const prange &op2 ATTRIBUTE_UNUSED, +=09=09=09 relation_trio) const +{ + return false; +} + +bool +range_operator::op1_range (prange &, tree, +=09=09=09 const irange &lhs ATTRIBUTE_UNUSED, +=09=09=09 const prange &op2 ATTRIBUTE_UNUSED, +=09=09=09 relation_trio) const +{ + return false; +} + +bool +range_operator::op1_range (prange &, tree, +=09=09=09 const prange &lhs ATTRIBUTE_UNUSED, +=09=09=09 const irange &op2 ATTRIBUTE_UNUSED, +=09=09=09 relation_trio) const +{ + return false; +} + +bool +range_operator::op1_range (irange &, tree, +=09=09=09 const prange &lhs ATTRIBUTE_UNUSED, +=09=09=09 const irange &op2 ATTRIBUTE_UNUSED, +=09=09=09 relation_trio) const +{ + return false; +} + +bool +range_operator::op2_range (prange &, tree, +=09=09=09 const irange &lhs ATTRIBUTE_UNUSED, +=09=09=09 const prange &op1 ATTRIBUTE_UNUSED, +=09=09=09 relation_trio) const +{ + return false; +} + +bool +range_operator::op2_range (irange &, tree, +=09=09=09 const prange &lhs ATTRIBUTE_UNUSED, +=09=09=09 const prange &op1 ATTRIBUTE_UNUSED, +=09=09=09 relation_trio) const +{ + return false; +} + +relation_kind +range_operator::op1_op2_relation (const irange &lhs ATTRIBUTE_UNUSED, +=09=09=09=09 const prange &op1 ATTRIBUTE_UNUSED, +=09=09=09=09 const prange &op2 ATTRIBUTE_UNUSED) const +{ + return VREL_VARYING; +} + +relation_kind +range_operator::lhs_op1_relation (const prange &lhs ATTRIBUTE_UNUSED, +=09=09=09=09 const irange &op1 ATTRIBUTE_UNUSED, +=09=09=09=09 const irange &op2 ATTRIBUTE_UNUSED, +=09=09=09=09 relation_kind rel ATTRIBUTE_UNUSED) const +{ + return VREL_VARYING; +} + +relation_kind +range_operator::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED, +=09=09=09=09 const prange &op1 ATTRIBUTE_UNUSED, +=09=09=09=09 const prange &op2 ATTRIBUTE_UNUSED, +=09=09=09=09 relation_kind rel ATTRIBUTE_UNUSED) const +{ + return VREL_VARYING; +} + +relation_kind +range_operator::lhs_op1_relation (const prange &lhs ATTRIBUTE_UNUSED, +=09=09=09=09 const prange &op1 ATTRIBUTE_UNUSED, +=09=09=09=09 const prange &op2 ATTRIBUTE_UNUSED, +=09=09=09=09 relation_kind rel ATTRIBUTE_UNUSED) const +{ + return VREL_VARYING; +} + +void +range_operator::update_bitmask (irange &, +=09=09=09=09const prange &, +=09=09=09=09const prange &) const +{ +} + class pointer_plus_operator : public range_operator { + using range_operator::update_bitmask; using range_operator::op2_range; public: virtual void wi_fold (irange &r, tree type, @@ -245,6 +459,8 @@ pointer_or_operator::wi_fold (irange &r, tree type, =20 class operator_pointer_diff : public range_operator { + using range_operator::update_bitmask; + using range_operator::op1_op2_relation_effect; virtual bool op1_op2_relation_effect (irange &lhs_range, =09=09=09=09=09tree type, =09=09=09=09=09const irange &op1_range, @@ -274,6 +490,7 @@ operator_pointer_diff::op1_op2_relation_effect (irange = &lhs_range, tree type, class hybrid_and_operator : public operator_bitwise_and { public: + using range_operator::update_bitmask; using range_operator::op1_range; using range_operator::op2_range; using range_operator::lhs_op1_relation; @@ -330,6 +547,7 @@ public: class hybrid_or_operator : public operator_bitwise_or { public: + using range_operator::update_bitmask; using range_operator::op1_range; using range_operator::op2_range; using range_operator::lhs_op1_relation; @@ -376,6 +594,7 @@ public: =20 class hybrid_min_operator : public operator_min { + using range_operator::update_bitmask; public: void update_bitmask (irange &r, const irange &lh, =09=09 const irange &rh) const final override @@ -397,6 +616,7 @@ public: =20 class hybrid_max_operator : public operator_max { + using range_operator::update_bitmask; public: void update_bitmask (irange &r, const irange &lh, =09=09 const irange &rh) const final override diff --git a/gcc/range-op.cc b/gcc/range-op.cc index ab3a4f0b200..65f3843227d 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -181,6 +181,12 @@ const unsigned RO_IFF =3D dispatch_trio (VR_IRANGE, VR= _FRANGE, VR_FRANGE); const unsigned RO_FFF =3D dispatch_trio (VR_FRANGE, VR_FRANGE, VR_FRANGE); const unsigned RO_FIF =3D dispatch_trio (VR_FRANGE, VR_IRANGE, VR_FRANGE); const unsigned RO_FII =3D dispatch_trio (VR_FRANGE, VR_IRANGE, VR_IRANGE); +const unsigned RO_PPP =3D dispatch_trio (VR_PRANGE, VR_PRANGE, VR_PRANGE); +const unsigned RO_PPI =3D dispatch_trio (VR_PRANGE, VR_PRANGE, VR_IRANGE); +const unsigned RO_IPP =3D dispatch_trio (VR_IRANGE, VR_PRANGE, VR_PRANGE); +const unsigned RO_IPI =3D dispatch_trio (VR_IRANGE, VR_PRANGE, VR_IRANGE); +const unsigned RO_PIP =3D dispatch_trio (VR_PRANGE, VR_IRANGE, VR_PRANGE); +const unsigned RO_PII =3D dispatch_trio (VR_PRANGE, VR_IRANGE, VR_IRANGE); =20 // Return a dispatch value for parameter types LHS, OP1 and OP2. =20 @@ -192,6 +198,28 @@ range_op_handler::dispatch_kind (const vrange &lhs, co= nst vrange &op1, =09=09=09op2.m_discriminator); } =20 +void +range_op_handler::discriminator_fail (const vrange &r1, +=09=09=09=09 const vrange &r2, +=09=09=09=09 const vrange &r3) const +{ + const char name[] =3D "IPF"; + gcc_checking_assert (r1.m_discriminator < sizeof (name) - 1); + gcc_checking_assert (r2.m_discriminator < sizeof (name) - 1); + gcc_checking_assert (r3.m_discriminator < sizeof (name) - 1); + fprintf (stderr, "DISCRIMINATOR FAIL. Dispatch =3D=3D=3D=3D> RO_%c%c%c = <=3D=3D=3D=3D\n", +=09 name[r1.m_discriminator], +=09 name[r2.m_discriminator], +=09 name[r3.m_discriminator]); + gcc_unreachable (); +} + +static inline bool +has_pointer_operand_p (const vrange &r1, const vrange &r2, const vrange &r= 3) +{ + return is_a (r1) || is_a (r2) || is_a (r3); +} + // Dispatch a call to fold_range based on the types of R, LH and RH. =20 bool @@ -204,6 +232,10 @@ range_op_handler::fold_range (vrange &r, tree type, #if CHECKING_P if (!lh.undefined_p () && !rh.undefined_p ()) gcc_assert (m_operator->operand_check_p (type, lh.type (), rh.type ())= ); + if (has_pointer_operand_p (r, lh, rh) + && !m_operator->pointers_handled_p (DISPATCH_FOLD_RANGE, +=09=09=09=09=09 dispatch_kind (r, lh, rh))) + discriminator_fail (r, lh, rh); #endif switch (dispatch_kind (r, lh, rh)) { @@ -227,6 +259,26 @@ range_op_handler::fold_range (vrange &r, tree type, =09return m_operator->fold_range (as_a (r), type, =09=09=09=09 as_a (lh), =09=09=09=09 as_a (rh), rel); + case RO_PPP: +=09return m_operator->fold_range (as_a (r), type, +=09=09=09=09 as_a (lh), +=09=09=09=09 as_a (rh), rel); + case RO_PPI: +=09return m_operator->fold_range (as_a (r), type, +=09=09=09=09 as_a (lh), +=09=09=09=09 as_a (rh), rel); + case RO_IPP: +=09return m_operator->fold_range (as_a (r), type, +=09=09=09=09 as_a (lh), +=09=09=09=09 as_a (rh), rel); + case RO_PIP: +=09return m_operator->fold_range (as_a (r), type, +=09=09=09=09 as_a (lh), +=09=09=09=09 as_a (rh), rel); + case RO_IPI: +=09return m_operator->fold_range (as_a (r), type, +=09=09=09=09 as_a (lh), +=09=09=09=09 as_a (rh), rel); default: =09return false; } @@ -246,6 +298,10 @@ range_op_handler::op1_range (vrange &r, tree type, #if CHECKING_P if (!op2.undefined_p ()) gcc_assert (m_operator->operand_check_p (lhs.type (), type, op2.type (= ))); + if (has_pointer_operand_p (r, lhs, op2) + && !m_operator->pointers_handled_p (DISPATCH_OP1_RANGE, +=09=09=09=09=09 dispatch_kind (r, lhs, op2))) + discriminator_fail (r, lhs, op2); #endif switch (dispatch_kind (r, lhs, op2)) { @@ -253,6 +309,22 @@ range_op_handler::op1_range (vrange &r, tree type, =09return m_operator->op1_range (as_a (r), type, =09=09=09=09 as_a (lhs), =09=09=09=09 as_a (op2), rel); + case RO_PPP: +=09return m_operator->op1_range (as_a (r), type, +=09=09=09=09 as_a (lhs), +=09=09=09=09 as_a (op2), rel); + case RO_PIP: +=09return m_operator->op1_range (as_a (r), type, +=09=09=09=09 as_a (lhs), +=09=09=09=09 as_a (op2), rel); + case RO_PPI: +=09return m_operator->op1_range (as_a (r), type, +=09=09=09=09 as_a (lhs), +=09=09=09=09 as_a (op2), rel); + case RO_IPI: +=09return m_operator->op1_range (as_a (r), type, +=09=09=09=09 as_a (lhs), +=09=09=09=09 as_a (op2), rel); case RO_FIF: =09return m_operator->op1_range (as_a (r), type, =09=09=09=09 as_a (lhs), @@ -280,6 +352,10 @@ range_op_handler::op2_range (vrange &r, tree type, #if CHECKING_P if (!op1.undefined_p ()) gcc_assert (m_operator->operand_check_p (lhs.type (), op1.type (), typ= e)); + if (has_pointer_operand_p (r, lhs, op1) + && !m_operator->pointers_handled_p (DISPATCH_OP2_RANGE, +=09=09=09=09=09 dispatch_kind (r, lhs, op1))) + discriminator_fail (r, lhs, op1); #endif switch (dispatch_kind (r, lhs, op1)) { @@ -287,6 +363,14 @@ range_op_handler::op2_range (vrange &r, tree type, =09return m_operator->op2_range (as_a (r), type, =09=09=09=09 as_a (lhs), =09=09=09=09 as_a (op1), rel); + case RO_PIP: +=09return m_operator->op2_range (as_a (r), type, +=09=09=09=09 as_a (lhs), +=09=09=09=09 as_a (op1), rel); + case RO_IPP: +=09return m_operator->op2_range (as_a (r), type, +=09=09=09=09 as_a (lhs), +=09=09=09=09 as_a (op1), rel); case RO_FIF: =09return m_operator->op2_range (as_a (r), type, =09=09=09=09 as_a (lhs), @@ -309,6 +393,12 @@ range_op_handler::lhs_op1_relation (const vrange &lhs, =09=09=09=09 relation_kind rel) const { gcc_checking_assert (m_operator); +#if CHECKING_P + if (has_pointer_operand_p (lhs, op1, op2) + && !m_operator->pointers_handled_p (DISPATCH_LHS_OP1_RELATION, +=09=09=09=09=09 dispatch_kind (lhs, op1, op2))) + discriminator_fail (lhs, op1, op2); +#endif =20 switch (dispatch_kind (lhs, op1, op2)) { @@ -316,6 +406,18 @@ range_op_handler::lhs_op1_relation (const vrange &lhs, =09return m_operator->lhs_op1_relation (as_a (lhs), =09=09=09=09=09 as_a (op1), =09=09=09=09=09 as_a (op2), rel); + case RO_PPP: +=09return m_operator->lhs_op1_relation (as_a (lhs), +=09=09=09=09=09 as_a (op1), +=09=09=09=09=09 as_a (op2), rel); + case RO_IPP: +=09return m_operator->lhs_op1_relation (as_a (lhs), +=09=09=09=09=09 as_a (op1), +=09=09=09=09=09 as_a (op2), rel); + case RO_PII: +=09return m_operator->lhs_op1_relation (as_a (lhs), +=09=09=09=09=09 as_a (op1), +=09=09=09=09=09 as_a (op2), rel); case RO_IFF: =09return m_operator->lhs_op1_relation (as_a (lhs), =09=09=09=09=09 as_a (op1), @@ -338,6 +440,12 @@ range_op_handler::lhs_op2_relation (const vrange &lhs, =09=09=09=09 relation_kind rel) const { gcc_checking_assert (m_operator); +#if CHECKING_P + if (has_pointer_operand_p (lhs, op1, op2) + && !m_operator->pointers_handled_p (DISPATCH_LHS_OP2_RELATION, +=09=09=09=09=09 dispatch_kind (lhs, op1, op2))) + discriminator_fail (lhs, op1, op2); +#endif switch (dispatch_kind (lhs, op1, op2)) { case RO_III: @@ -365,6 +473,12 @@ range_op_handler::op1_op2_relation (const vrange &lhs, =09=09=09=09 const vrange &op2) const { gcc_checking_assert (m_operator); +#if CHECKING_P + if (has_pointer_operand_p (lhs, op1, op2) + && !m_operator->pointers_handled_p (DISPATCH_OP1_OP2_RELATION, +=09=09=09=09=09 dispatch_kind (lhs, op1, op2))) + discriminator_fail (lhs, op1, op2); +#endif switch (dispatch_kind (lhs, op1, op2)) { case RO_III: @@ -372,6 +486,11 @@ range_op_handler::op1_op2_relation (const vrange &lhs, =09=09=09=09=09 as_a (op1), =09=09=09=09=09 as_a (op2)); =20 + case RO_IPP: +=09return m_operator->op1_op2_relation (as_a (lhs), +=09=09=09=09=09 as_a (op1), +=09=09=09=09=09 as_a (op2)); + case RO_IFF: =09return m_operator->op1_op2_relation (as_a (lhs), =09=09=09=09=09 as_a (op1), @@ -2327,6 +2446,7 @@ operator_widen_mult_unsigned::wi_fold (irange &r, tre= e type, =20 class operator_div : public cross_product_operator { + using range_operator::update_bitmask; public: operator_div (tree_code div_kind) { m_code =3D div_kind; } virtual void wi_fold (irange &r, tree type, @@ -2474,6 +2594,7 @@ class operator_lshift : public cross_product_operator { using range_operator::fold_range; using range_operator::op1_range; + using range_operator::update_bitmask; public: virtual bool op1_range (irange &r, tree type, const irange &lhs, =09=09=09 const irange &op2, relation_trio rel =3D TRIO_VARYING) @@ -2503,6 +2624,7 @@ class operator_rshift : public cross_product_operator using range_operator::fold_range; using range_operator::op1_range; using range_operator::lhs_op1_relation; + using range_operator::update_bitmask; public: virtual bool fold_range (irange &r, tree type, const irange &op1, =09=09=09 const irange &op2, relation_trio rel =3D TRIO_VARYING) @@ -3883,6 +4005,7 @@ class operator_trunc_mod : public range_operator { using range_operator::op1_range; using range_operator::op2_range; + using range_operator::update_bitmask; public: virtual void wi_fold (irange &r, tree type, =09=09 const wide_int &lh_lb, @@ -4305,6 +4428,7 @@ operator_abs::update_bitmask (irange &r, const irange= &lh, =20 class operator_absu : public range_operator { + using range_operator::update_bitmask; public: virtual void wi_fold (irange &r, tree type, =09=09=09const wide_int &lh_lb, const wide_int &lh_ub, diff --git a/gcc/range-op.h b/gcc/range-op.h index 44a3e4f009f..2bad5a90e11 100644 --- a/gcc/range-op.h +++ b/gcc/range-op.h @@ -22,6 +22,16 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_RANGE_OP_H #define GCC_RANGE_OP_H =20 +enum range_op_dispatch_type +{ + DISPATCH_FOLD_RANGE, + DISPATCH_OP1_RANGE, + DISPATCH_OP2_RANGE, + DISPATCH_LHS_OP1_RELATION, + DISPATCH_LHS_OP2_RELATION, + DISPATCH_OP1_OP2_RELATION +}; + // This class is implemented for each kind of operator supported by // the range generator. It serves various purposes. // @@ -76,6 +86,26 @@ public: =09=09=09 const irange &lh, =09=09=09 const irange &rh, =09=09=09 relation_trio =3D TRIO_VARYING) const; + virtual bool fold_range (prange &r, tree type, +=09=09=09 const prange &lh, +=09=09=09 const prange &rh, +=09=09=09 relation_trio =3D TRIO_VARYING) const; + virtual bool fold_range (prange &r, tree type, +=09=09=09 const prange &lh, +=09=09=09 const irange &rh, +=09=09=09 relation_trio =3D TRIO_VARYING) const; + virtual bool fold_range (irange &r, tree type, +=09=09=09 const prange &lh, +=09=09=09 const prange &rh, +=09=09=09 relation_trio =3D TRIO_VARYING) const; + virtual bool fold_range (prange &r, tree type, +=09=09=09 const irange &lh, +=09=09=09 const prange &rh, +=09=09=09 relation_trio =3D TRIO_VARYING) const; + virtual bool fold_range (irange &r, tree type, +=09=09=09 const prange &lh, +=09=09=09 const irange &rh, +=09=09=09 relation_trio =3D TRIO_VARYING) const; =20 // Return the range for op[12] in the general case. LHS is the range fo= r // the LHS of the expression, OP[12]is the range for the other @@ -92,6 +122,22 @@ public: =09=09=09 const irange &lhs, =09=09=09 const irange &op2, =09=09=09 relation_trio =3D TRIO_VARYING) const; + virtual bool op1_range (prange &r, tree type, +=09=09=09 const prange &lhs, +=09=09=09 const prange &op2, +=09=09=09 relation_trio =3D TRIO_VARYING) const; + virtual bool op1_range (prange &r, tree type, +=09=09=09 const irange &lhs, +=09=09=09 const prange &op2, +=09=09=09 relation_trio =3D TRIO_VARYING) const; + virtual bool op1_range (prange &r, tree type, +=09=09=09 const prange &lhs, +=09=09=09 const irange &op2, +=09=09=09 relation_trio =3D TRIO_VARYING) const; + virtual bool op1_range (irange &r, tree type, +=09=09=09 const prange &lhs, +=09=09=09 const irange &op2, +=09=09=09 relation_trio =3D TRIO_VARYING) const; virtual bool op1_range (frange &r, tree type, =09=09=09 const frange &lhs, =09=09=09 const frange &op2, @@ -106,6 +152,14 @@ public: =09=09=09 const irange &lhs, =09=09=09 const irange &op1, =09=09=09 relation_trio =3D TRIO_VARYING) const; + virtual bool op2_range (prange &r, tree type, +=09=09=09 const irange &lhs, +=09=09=09 const prange &op1, +=09=09=09 relation_trio =3D TRIO_VARYING) const; + virtual bool op2_range (irange &r, tree type, +=09=09=09 const prange &lhs, +=09=09=09 const prange &op1, +=09=09=09 relation_trio =3D TRIO_VARYING) const; virtual bool op2_range (frange &r, tree type, =09=09=09 const frange &lhs, =09=09=09 const frange &op1, @@ -123,6 +177,18 @@ public: =09=09=09=09=09 const irange &op1, =09=09=09=09=09 const irange &op2, =09=09=09=09=09 relation_kind =3D VREL_VARYING) const; + virtual relation_kind lhs_op1_relation (const prange &lhs, +=09=09=09=09=09 const prange &op1, +=09=09=09=09=09 const prange &op2, +=09=09=09=09=09 relation_kind =3D VREL_VARYING) const; + virtual relation_kind lhs_op1_relation (const prange &lhs, +=09=09=09=09=09 const irange &op1, +=09=09=09=09=09 const irange &op2, +=09=09=09=09=09 relation_kind =3D VREL_VARYING) const; + virtual relation_kind lhs_op1_relation (const irange &lhs, +=09=09=09=09=09 const prange &op1, +=09=09=09=09=09 const prange &op2, +=09=09=09=09=09 relation_kind =3D VREL_VARYING) const; virtual relation_kind lhs_op1_relation (const frange &lhs, =09=09=09=09=09 const frange &op1, =09=09=09=09=09 const frange &op2, @@ -148,6 +214,9 @@ public: virtual relation_kind op1_op2_relation (const irange &lhs, =09=09=09=09=09 const irange &op1, =09=09=09=09=09 const irange &op2) const; + virtual relation_kind op1_op2_relation (const irange &lhs, +=09=09=09=09=09 const prange &op1, +=09=09=09=09=09 const prange &op2) const; virtual relation_kind op1_op2_relation (const irange &lhs, =09=09=09=09=09 const frange &op1, =09=09=09=09=09 const frange &op2) const; @@ -160,6 +229,7 @@ public: =20 // Compatability check for operands. virtual bool operand_check_p (tree, tree, tree) const; + virtual bool pointers_handled_p (enum range_op_dispatch_type, unsigned) = const; =20 protected: // Perform an integral operation between 2 sub-ranges and return it. @@ -173,6 +243,26 @@ protected: =09=09=09=09=09const irange &op1_range, =09=09=09=09=09const irange &op2_range, =09=09=09=09=09relation_kind rel) const; + virtual bool op1_op2_relation_effect (prange &lhs_range, tree type, +=09=09=09=09=09const prange &op1_range, +=09=09=09=09=09const prange &op2_range, +=09=09=09=09=09relation_kind rel) const; + virtual bool op1_op2_relation_effect (prange &lhs_range, tree type, +=09=09=09=09=09const prange &op1_range, +=09=09=09=09=09const irange &op2_range, +=09=09=09=09=09relation_kind rel) const; + virtual bool op1_op2_relation_effect (irange &lhs_range, tree type, +=09=09=09=09=09const prange &op1_range, +=09=09=09=09=09const prange &op2_range, +=09=09=09=09=09relation_kind rel) const; + virtual bool op1_op2_relation_effect (prange &lhs_range, tree type, +=09=09=09=09=09const irange &op1_range, +=09=09=09=09=09const prange &op2_range, +=09=09=09=09=09relation_kind rel) const; + virtual bool op1_op2_relation_effect (irange &lhs_range, tree type, +=09=09=09=09=09const prange &op1_range, +=09=09=09=09=09const irange &op2_range, +=09=09=09=09=09relation_kind rel) const; // Called by fold range to split small subranges into parts. void wi_fold_in_parts (irange &r, tree type, =09=09=09 const wide_int &lh_lb, @@ -187,6 +277,7 @@ protected: =09=09=09 unsigned limit) const; // Apply any bitmasks implied by these ranges. virtual void update_bitmask (irange &, const irange &, const irange &) c= onst; + virtual void update_bitmask (irange &, const prange &, const prange &) c= onst; =20 // Perform an float operation between 2 ranges and return it. virtual void rv_fold (frange &r, tree type, @@ -234,6 +325,9 @@ public: protected: unsigned dispatch_kind (const vrange &lhs, const vrange &op1, =09=09=09 const vrange& op2) const; + void discriminator_fail (const vrange &, +=09=09=09 const vrange &, +=09=09=09 const vrange &) const; range_operator *m_operator; }; =20 @@ -316,4 +410,21 @@ protected: void initialize_pointer_ops (); void initialize_float_ops (); }; + +// Temporary exports so the pointers_handled_p() sanity code can see +// which pointer combination is being attempted. This will be deleted +// once pointers_handled_p is gone. +extern const unsigned RO_III; +extern const unsigned RO_IFI; +extern const unsigned RO_IFF; +extern const unsigned RO_FFF; +extern const unsigned RO_FIF; +extern const unsigned RO_FII; +extern const unsigned RO_PPP; +extern const unsigned RO_PPI; +extern const unsigned RO_IPP; +extern const unsigned RO_IPI; +extern const unsigned RO_PIP; +extern const unsigned RO_PII; + #endif // GCC_RANGE_OP_H --=20 2.44.0