From patchwork Thu Jun 8 18:57:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew MacLeod X-Patchwork-Id: 70797 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 059483856251 for ; Thu, 8 Jun 2023 18:58:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 059483856251 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1686250683; bh=/1WXQmSbmVi0Nbsuc+wSrPlTdXQbs1erfXUTrZ+ozcc=; h=Date:To:Cc:Subject:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=yrfi3REJdz2SkENMCqxACe4iCB8emmt+UtZdSBkxug+221vf/lkCsHg/n70ewbib1 kMTU2IT2emvx8uGxOavzvDCK3XMhxYXe6xpl+gKGe79fX2kqM3bJzHv0MHyY5vTCLr /cn7d+sMeprrP2iyZJKsTvJGzl6W3FcCPdW/R/s8= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 6DC553858C2F for ; Thu, 8 Jun 2023 18:57:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6DC553858C2F Received: from mail-qk1-f200.google.com (mail-qk1-f200.google.com [209.85.222.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-266-f8tZeONbMRms0PDzKrwPAw-1; Thu, 08 Jun 2023 14:57:29 -0400 X-MC-Unique: f8tZeONbMRms0PDzKrwPAw-1 Received: by mail-qk1-f200.google.com with SMTP id af79cd13be357-75d53bab5a9so122640385a.2 for ; Thu, 08 Jun 2023 11:57:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686250648; x=1688842648; h=subject:from:cc:to:content-language:user-agent:mime-version:date :message-id:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=+ytaaAmFtUr9NVSD7a97rSULIv9DomOYNxx5jtVk98w=; b=BAutUs1O0ftTFW+4+pzFwS0pMWKLGPYfyhmpQLfADJr956WQrjNO48oSyKZzWKUuUL q+Y3+YZQgSo5l2BVSNTAQbLJCKTlROhzsrVi5DBnaH5vJpkKXKFFPspvT5D8qVeiB5ja 0Xrq3YZnVUojH15xspaFqws2RdTQ0blLNe0KitHzRwJtZflQc86JQJEEiC0jKDmFpKu9 waMUGCnYewUCavyPYtq9anjn4qV/eWRVJfHlI4tdG/tQ2j4Ia7EWuQ8bdAp8zVHg/nXg fNK8JiJT9hpt5S71X4lJsW04Pc3WJ3YyD0kCUAUJCURwZvxJ87NfEaMRzU6FukyGn2Oz sM7A== X-Gm-Message-State: AC+VfDwuwk5hDa6jmzQFxNTTJJrx0XZMZon0gC0+dWv3HVgAvhouuQtz eRiWdfj+RT9kT4QGR6DEG4BrIGVLg/YouJyTAKOR7UACbDEQjh7S5oAH6iD6Vqm9LpqP9dJe3X4 wOdJaAG4W+rr9RRKEpdV5PjYI6ZLKFw6hSHpSQmIvaAfilQAjF6tVLpORXh/YtMsDILsc/4UGq4 7teA== X-Received: by 2002:ac8:5741:0:b0:3f6:c609:e9da with SMTP id 1-20020ac85741000000b003f6c609e9damr9107987qtx.44.1686250648690; Thu, 08 Jun 2023 11:57:28 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ44e1t6cZiZPkkNyULL6Mr27wty6WdypN+NEtmyBG80RDwHZNrzGDrSc0iUz1M3OieQ2CaRLg== X-Received: by 2002:ac8:5741:0:b0:3f6:c609:e9da with SMTP id 1-20020ac85741000000b003f6c609e9damr9107962qtx.44.1686250648367; Thu, 08 Jun 2023 11:57:28 -0700 (PDT) Received: from ?IPV6:2607:fea8:51df:4200::ca58? ([2607:fea8:51df:4200::ca58]) by smtp.gmail.com with ESMTPSA id x12-20020ac84d4c000000b003e302c1f498sm561839qtv.37.2023.06.08.11.57.27 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 08 Jun 2023 11:57:27 -0700 (PDT) Message-ID: Date: Thu, 8 Jun 2023 14:57:26 -0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0 To: gcc-patches Cc: "hernandez, aldy" Subject: [COMMITTED 1/4] Fix floating point bug in fold_range. X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Andrew MacLeod via Gcc-patches From: Andrew MacLeod Reply-To: Andrew MacLeod Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" We currently do not have any floating point operators where operand 1 is a different type than the LHS. When we eventually do there is a bug in fold_range. If either operand is a known NAN, it returns a NAN of the type of operand 1 instead of the result type. This patch sets it to the correct type. Bootstraps on build-x86_64-pc-linux-gnu with no regressions. Pushed. Andrew From ff0ef34aa04f7767933541f58f016600a3462c84 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Wed, 7 Jun 2023 14:03:35 -0400 Subject: [PATCH 1/4] Fix floating point bug in fold_range. We currently do not have any floating point operators where operand 1 is a different type than the LHS. When we eventually do there is a bug in fold_range. If either operand is a known NAN, it returns a NAN of the type of operand 1 instead of the result type. * range-op-float.cc (range_operator_float::fold_range): Return NAN of the result type. --- gcc/range-op-float.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc index a99a6b01ed8..af598b60a79 100644 --- a/gcc/range-op-float.cc +++ b/gcc/range-op-float.cc @@ -57,7 +57,7 @@ range_operator_float::fold_range (frange &r, tree type, return true; if (op1.known_isnan () || op2.known_isnan ()) { - r.set_nan (op1.type ()); + r.set_nan (type); return true; } -- 2.40.1 From patchwork Thu Jun 8 18:57:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew MacLeod X-Patchwork-Id: 70798 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 889023856632 for ; Thu, 8 Jun 2023 18:58:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 889023856632 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1686250695; bh=l32jdCy5KHRFLqqd86in25KsOoppZ7U5TQv0Ss2dVJM=; h=Date:To:Cc:Subject:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=p3E3OHtEvSoR6w5ZIEIGHFQmmcpW+j75WZ5LsKUi3UcVk75GDScAgXsHKHMRMAhfQ 2g5h0WZYvu8mmQzIycgHjsM7VCOW0pRch7zOs3NlbDXUlL1pYO6c0rj/kLX4coMwIm 5QAhrMgmYhISANcOqcKeDudGWG1XgnsGt0CiKxig= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id BE023385701B for ; Thu, 8 Jun 2023 18:57:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BE023385701B Received: from mail-qv1-f70.google.com (mail-qv1-f70.google.com [209.85.219.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-604--tFhat0_MT-v2z1H1q4gxA-1; Thu, 08 Jun 2023 14:57:44 -0400 X-MC-Unique: -tFhat0_MT-v2z1H1q4gxA-1 Received: by mail-qv1-f70.google.com with SMTP id 6a1803df08f44-6260e66ec46so11098776d6.3 for ; Thu, 08 Jun 2023 11:57:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686250663; x=1688842663; h=subject:from:cc:to:content-language:user-agent:mime-version:date :message-id:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=ccuL1OEYpNoHItOJBxDcuwvVi+VSowGFeIU6rIOGKN4=; b=E3NpvotKLKzlAoM+ecq1dyk8TiZl8HBlHEw9NbGNX4Q1G0TsH57lqTEStJLwumu5Dk V4dHt7FTnZUjVst0WamQhPz+X60N2IEnEf+1hPvomQzahGFn1OGpIohB1Wk+3+bfGRuG 6tWLe1Idu31ZiVt7ppQHZ7ji8fq5yOsLmgR5Poiyn68mKLn9Pxmrz5zP+mcYrJ9lr0rh FB+TelA2UbxQJe1ExCitAhDjJ6bHsgRPSTMkLllLWoIhRGz3khYU7UjurpoczaaOkTgT 3qramKoTswEZS7zp0iAYZpeuCa5C7ZSCljocVtFDNc+IyCEkLahSZrdIwnYGniAE+0Sn HmjQ== X-Gm-Message-State: AC+VfDz58DYQAXE+pNuRv+dq+0gKuamCNlojU0/FMZO/RdiBuQgj3oi0 lRmBePb0ISOkBzM3NpHIkRBG0CxTe8N64rdKzSOXqnqqtSbohWkPgR4uhJWV+1KzYWLsK7F73MR sI3I6VQicy5DnGVrr5f8qqo3Ee2dJuQVFeBjzMRyOdO7qXEjtKoVhH5K1vFaeCR+XSocUC+0Jt8 uh4g== X-Received: by 2002:ad4:5fca:0:b0:626:3a98:95a with SMTP id jq10-20020ad45fca000000b006263a98095amr2689759qvb.22.1686250663150; Thu, 08 Jun 2023 11:57:43 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ471dhzlfkae4gVLNxWewZrm+1F+Z2ezxE1UPVno7XZwjGv7UbYQypbIG+SeNWz7efTwpYspw== X-Received: by 2002:ad4:5fca:0:b0:626:3a98:95a with SMTP id jq10-20020ad45fca000000b006263a98095amr2689746qvb.22.1686250662800; Thu, 08 Jun 2023 11:57:42 -0700 (PDT) Received: from ?IPV6:2607:fea8:51df:4200::ca58? ([2607:fea8:51df:4200::ca58]) by smtp.gmail.com with ESMTPSA id v14-20020a0ccd8e000000b006263784674esm611425qvm.14.2023.06.08.11.57.41 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 08 Jun 2023 11:57:42 -0700 (PDT) Message-ID: Date: Thu, 8 Jun 2023 14:57:41 -0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0 To: gcc-patches Cc: "hernandez, aldy" Subject: [COMMITTED 2/4] - Remove tree_code from range-operator. X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Andrew MacLeod via Gcc-patches From: Andrew MacLeod Reply-To: Andrew MacLeod Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Range_operator had a tree code added last release to facilitate bitmask operations.  This was intended to be a temporary change until we could figure out something more strategic going forward. This patch removes the tree_code and replaces it with a virtual routine to perform the masking. Each of the affected tree codes operators now call the bitmask routine via a virtual function.  At some point we may want to consolidate the code that CCP is using so that it resides in the range_operator, but the extensive parameter list used by that CCP routine makes that prohibitive to do at the moment. Bootstraps on x86_64-pc-linux-gnu with no regressions.  Pushed. Andrew From c5065669a36ba0c26841cb108d32f03058757e85 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Wed, 31 May 2023 10:55:28 -0400 Subject: [PATCH 2/4] Remove tree_code from range-operator. Range_operator had a tree code added last release to facilitate bitmask operations. This removes the tree_code and replaces it with a virtual routine to peform the masking. Remove any duplicate instances which are no longer needed. * range-op.cc (range_operator::fold_range): Call virtual routine. (range_operator::update_bitmask): New. (operator_equal::update_bitmask): New. (operator_not_equal::update_bitmask): New. (operator_lt::update_bitmask): New. (operator_le::update_bitmask): New. (operator_gt::update_bitmask): New. (operator_ge::update_bitmask): New. (operator_ge::update_bitmask): New. (operator_plus::update_bitmask): New. (operator_minus::update_bitmask): New. (operator_pointer_diff::update_bitmask): New. (operator_min::update_bitmask): New. (operator_max::update_bitmask): New. (operator_mult::update_bitmask): New. (operator_div:operator_div):New. (operator_div::update_bitmask): New. (operator_div::m_code): New member. (operator_exact_divide::operator_exact_divide): New constructor. (operator_lshift::update_bitmask): New. (operator_rshift::update_bitmask): New. (operator_bitwise_and::update_bitmask): New. (operator_bitwise_or::update_bitmask): New. (operator_bitwise_xor::update_bitmask): New. (operator_trunc_mod::update_bitmask): New. (op_ident, op_unknown, op_ptr_min_max): New. (op_nop, op_convert): Delete. (op_ssa, op_paren, op_obj_type): Delete. (op_realpart, op_imagpart): Delete. (op_ptr_min, op_ptr_max): Delete. (pointer_plus_operator:update_bitmask): New. (range_op_table::set): Do not use m_code. (integral_table::integral_table): Adjust to single instances. * range-op.h (range_operator::range_operator): Delete. (range_operator::m_code): Delete. (range_operator::update_bitmask): New. --- gcc/range-op.cc | 110 +++++++++++++++++++++++++++++++++--------------- gcc/range-op.h | 6 +-- 2 files changed, 79 insertions(+), 37 deletions(-) diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 3ab2c665901..2deca3bac93 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -286,7 +286,7 @@ range_operator::fold_range (irange &r, tree type, break; } op1_op2_relation_effect (r, type, lh, rh, rel); - update_known_bitmask (r, m_code, lh, rh); + update_bitmask (r, lh, rh); return true; } @@ -298,7 +298,7 @@ range_operator::fold_range (irange &r, tree type, wi_fold_in_parts (r, type, lh.lower_bound (), lh.upper_bound (), rh.lower_bound (), rh.upper_bound ()); op1_op2_relation_effect (r, type, lh, rh, rel); - update_known_bitmask (r, m_code, lh, rh); + update_bitmask (r, lh, rh); return true; } @@ -316,12 +316,12 @@ range_operator::fold_range (irange &r, tree type, if (r.varying_p ()) { op1_op2_relation_effect (r, type, lh, rh, rel); - update_known_bitmask (r, m_code, lh, rh); + update_bitmask (r, lh, rh); return true; } } op1_op2_relation_effect (r, type, lh, rh, rel); - update_known_bitmask (r, m_code, lh, rh); + update_bitmask (r, lh, rh); return true; } @@ -387,6 +387,14 @@ range_operator::op1_op2_relation_effect (irange &lhs_range ATTRIBUTE_UNUSED, return false; } +// Apply any known bitmask updates based on this operator. + +void +range_operator::update_bitmask (irange &, const irange &, + const irange &) const +{ +} + // Create and return a range from a pair of wide-ints that are known // to have overflowed (or underflowed). @@ -562,6 +570,8 @@ public: const irange &val, relation_trio = TRIO_VARYING) const; virtual relation_kind op1_op2_relation (const irange &lhs) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, EQ_EXPR, lh, rh); } } op_equal; // Check if the LHS range indicates a relation between OP1 and OP2. @@ -682,6 +692,8 @@ public: const irange &op1, relation_trio = TRIO_VARYING) const; virtual relation_kind op1_op2_relation (const irange &lhs) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, NE_EXPR, lh, rh); } } op_not_equal; // Check if the LHS range indicates a relation between OP1 and OP2. @@ -862,6 +874,8 @@ public: const irange &op1, relation_trio = TRIO_VARYING) const; virtual relation_kind op1_op2_relation (const irange &lhs) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, LT_EXPR, lh, rh); } } op_lt; // Check if the LHS range indicates a relation between OP1 and OP2. @@ -982,6 +996,8 @@ public: const irange &op1, relation_trio = TRIO_VARYING) const; virtual relation_kind op1_op2_relation (const irange &lhs) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, LE_EXPR, lh, rh); } } op_le; // Check if the LHS range indicates a relation between OP1 and OP2. @@ -1099,6 +1115,8 @@ public: const irange &op1, relation_trio = TRIO_VARYING) const; virtual relation_kind op1_op2_relation (const irange &lhs) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, GT_EXPR, lh, rh); } } op_gt; // Check if the LHS range indicates a relation between OP1 and OP2. @@ -1215,6 +1233,8 @@ public: const irange &op1, relation_trio = TRIO_VARYING) const; virtual relation_kind op1_op2_relation (const irange &lhs) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, GE_EXPR, lh, rh); } } op_ge; // Check if the LHS range indicates a relation between OP1 and OP2. @@ -1339,6 +1359,8 @@ public: virtual relation_kind lhs_op2_relation (const irange &lhs, const irange &op1, const irange &op2, relation_kind rel) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, PLUS_EXPR, lh, rh); } } op_plus; // Check to see if the range of OP2 indicates anything about the relation @@ -1648,6 +1670,8 @@ public: const irange &op1_range, const irange &op2_range, relation_kind rel) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, MINUS_EXPR, lh, rh); } } op_minus; void @@ -1801,6 +1825,8 @@ class operator_pointer_diff : public range_operator const irange &op1_range, const irange &op2_range, relation_kind rel) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, POINTER_DIFF_EXPR, lh, rh); } } op_pointer_diff; bool @@ -1822,6 +1848,8 @@ public: const wide_int &lh_ub, const wide_int &rh_lb, const wide_int &rh_ub) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, MIN_EXPR, lh, rh); } } op_min; void @@ -1844,6 +1872,8 @@ public: const wide_int &lh_ub, const wide_int &rh_lb, const wide_int &rh_ub) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, MAX_EXPR, lh, rh); } } op_max; void @@ -1952,6 +1982,8 @@ public: const irange &lhs, const irange &op1, relation_trio) const final override; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, MULT_EXPR, lh, rh); } } op_mult; bool @@ -2162,6 +2194,7 @@ operator_widen_mult_unsigned::wi_fold (irange &r, tree type, class operator_div : public cross_product_operator { public: + operator_div (tree_code div_kind) { m_code = div_kind; } virtual void wi_fold (irange &r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, @@ -2170,8 +2203,17 @@ public: virtual bool wi_op_overflows (wide_int &res, tree type, const wide_int &, const wide_int &) const final override; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, m_code, lh, rh); } +protected: + tree_code m_code; }; +static operator_div op_trunc_div (TRUNC_DIV_EXPR); +static operator_div op_floor_div (FLOOR_DIV_EXPR); +static operator_div op_round_div (ROUND_DIV_EXPR); +static operator_div op_ceil_div (CEIL_DIV_EXPR); + bool operator_div::wi_op_overflows (wide_int &res, tree type, const wide_int &w0, const wide_int &w1) const @@ -2265,6 +2307,7 @@ class operator_exact_divide : public operator_div { using range_operator::op1_range; public: + operator_exact_divide () : operator_div (EXACT_DIV_EXPR) { } virtual bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, @@ -2314,6 +2357,8 @@ public: tree type, const wide_int &, const wide_int &) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, LSHIFT_EXPR, lh, rh); } } op_lshift; class operator_rshift : public cross_product_operator @@ -2343,6 +2388,8 @@ public: const irange &op1, const irange &op2, relation_kind rel) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, RSHIFT_EXPR, lh, rh); } } op_rshift; @@ -2682,7 +2729,7 @@ private: const irange &outer) const; void fold_pair (irange &r, unsigned index, const irange &inner, const irange &outer) const; -}; +} op_cast; // Add a partial equivalence between the LHS and op1 for casts. @@ -3026,6 +3073,8 @@ public: const irange &op1, const irange &op2, relation_kind) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, BIT_AND_EXPR, lh, rh); } private: void simple_op1_range_solver (irange &r, tree type, const irange &lhs, @@ -3524,6 +3573,8 @@ public: const wide_int &lh_ub, const wide_int &rh_lb, const wide_int &rh_ub) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, BIT_IOR_EXPR, lh, rh); } } op_bitwise_or; void @@ -3636,6 +3687,8 @@ public: const irange &op1_range, const irange &op2_range, relation_kind rel) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, BIT_XOR_EXPR, lh, rh); } } op_bitwise_xor; void @@ -3777,6 +3830,8 @@ public: const irange &lhs, const irange &op1, relation_trio) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, TRUNC_MOD_EXPR, lh, rh); } } op_trunc_mod; void @@ -4046,7 +4101,7 @@ public: const irange &op1, const irange &op2, relation_kind rel) const; -}; +} op_ident; // Determine if there is a relationship between LHS and OP1. @@ -4091,7 +4146,7 @@ public: const irange &op1, const irange &op2, relation_trio rel = TRIO_VARYING) const; -}; +} op_unknown; bool operator_unknown::fold_range (irange &r, tree type, @@ -4365,6 +4420,8 @@ public: const irange &lhs, const irange &op1, relation_trio = TRIO_VARYING) const; + void update_bitmask (irange &r, const irange &lh, const irange &rh) const + { update_known_bitmask (r, POINTER_PLUS_EXPR, lh, rh); } } op_pointer_plus; void @@ -4436,7 +4493,7 @@ public: virtual void wi_fold (irange & r, tree type, const wide_int &lh_lb, const wide_int &lh_ub, const wide_int &rh_lb, const wide_int &rh_ub) const; -}; +} op_ptr_min_max; void pointer_min_max_operator::wi_fold (irange &r, tree type, @@ -4562,21 +4619,8 @@ range_op_table::set (enum tree_code code, range_operator &op) { gcc_checking_assert (m_range_tree[code] == NULL); m_range_tree[code] = &op; - gcc_checking_assert (op.m_code == ERROR_MARK || op.m_code == code); - op.m_code = code; } -// Shared operators that require separate instantiations because they -// do not share a common tree code. -static operator_cast op_nop, op_convert; -static operator_identity op_ssa, op_paren, op_obj_type; -static operator_unknown op_realpart, op_imagpart; -static pointer_min_max_operator op_ptr_min, op_ptr_max; -static operator_div op_trunc_div; -static operator_div op_floor_div; -static operator_div op_round_div; -static operator_div op_ceil_div; - // Instantiate a range op table for integral operations. class integral_table : public range_op_table @@ -4605,8 +4649,8 @@ integral_table::integral_table () set (EXACT_DIV_EXPR, op_exact_div); set (LSHIFT_EXPR, op_lshift); set (RSHIFT_EXPR, op_rshift); - set (NOP_EXPR, op_nop); - set (CONVERT_EXPR, op_convert); + set (NOP_EXPR, op_cast); + set (CONVERT_EXPR, op_cast); set (TRUTH_AND_EXPR, op_logical_and); set (BIT_AND_EXPR, op_bitwise_and); set (TRUTH_OR_EXPR, op_logical_or); @@ -4616,11 +4660,11 @@ integral_table::integral_table () set (TRUTH_NOT_EXPR, op_logical_not); set (BIT_NOT_EXPR, op_bitwise_not); set (INTEGER_CST, op_integer_cst); - set (SSA_NAME, op_ssa); - set (PAREN_EXPR, op_paren); - set (OBJ_TYPE_REF, op_obj_type); - set (IMAGPART_EXPR, op_imagpart); - set (REALPART_EXPR, op_realpart); + set (SSA_NAME, op_ident); + set (PAREN_EXPR, op_ident); + set (OBJ_TYPE_REF, op_ident); + set (IMAGPART_EXPR, op_unknown); + set (REALPART_EXPR, op_unknown); set (POINTER_DIFF_EXPR, op_pointer_diff); set (ABS_EXPR, op_abs); set (ABSU_EXPR, op_absu); @@ -4640,8 +4684,8 @@ pointer_table::pointer_table () { set (BIT_AND_EXPR, op_pointer_and); set (BIT_IOR_EXPR, op_pointer_or); - set (MIN_EXPR, op_ptr_min); - set (MAX_EXPR, op_ptr_max); + set (MIN_EXPR, op_ptr_min_max); + set (MAX_EXPR, op_ptr_min_max); set (POINTER_PLUS_EXPR, op_pointer_plus); set (EQ_EXPR, op_equal); @@ -4650,11 +4694,11 @@ pointer_table::pointer_table () set (LE_EXPR, op_le); set (GT_EXPR, op_gt); set (GE_EXPR, op_ge); - set (SSA_NAME, op_ssa); + set (SSA_NAME, op_ident); set (INTEGER_CST, op_integer_cst); set (ADDR_EXPR, op_addr); - set (NOP_EXPR, op_nop); - set (CONVERT_EXPR, op_convert); + set (NOP_EXPR, op_cast); + set (CONVERT_EXPR, op_cast); set (BIT_NOT_EXPR, op_bitwise_not); set (BIT_XOR_EXPR, op_bitwise_xor); diff --git a/gcc/range-op.h b/gcc/range-op.h index 03ef6b98542..5bfbc89df52 100644 --- a/gcc/range-op.h +++ b/gcc/range-op.h @@ -50,7 +50,6 @@ class range_operator { friend class range_op_table; public: - range_operator () : m_code (ERROR_MARK) { } // Perform an operation between 2 ranges and return it. virtual bool fold_range (irange &r, tree type, const irange &lh, @@ -114,9 +113,8 @@ protected: const wide_int &lb, const wide_int &ub, unsigned limit) const; - - // Tree code of the range operator or ERROR_MARK if unknown. - tree_code m_code; + // Apply any bitmasks implied by these ranges. + virtual void update_bitmask (irange &, const irange &, const irange &) const; }; // Like range_operator above, but for floating point operators. -- 2.40.1 From patchwork Thu Jun 8 18:57:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew MacLeod X-Patchwork-Id: 70800 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 034733856630 for ; Thu, 8 Jun 2023 18:59:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 034733856630 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1686250755; bh=ChLPfc1ulCrVljqwB94nmcV9MhDDK7RdwYOYqGH8MC8=; h=Date:To:Cc:Subject:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=GmeVHp6FiOSf1SvYXLKgDO09NtL1VZojeXap61Gvg0Za+rxmYcuiWuoaNU98I7jUJ d82VwbJ92DrmaDj9wT04/uo9mvZmP3g5Lt+t3m0z83sQ5ujHJa2HyMjKl6cT32seqM X5RDg/ZAGR+9rw53kIAfnZZs+UtxWEWTFkgT/l8U= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 4F8FC385661F for ; Thu, 8 Jun 2023 18:57:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4F8FC385661F Received: from mail-qt1-f200.google.com (mail-qt1-f200.google.com [209.85.160.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-519-KlmDDcQFOLOrW-1VJfmTgw-1; Thu, 08 Jun 2023 14:57:53 -0400 X-MC-Unique: KlmDDcQFOLOrW-1VJfmTgw-1 Received: by mail-qt1-f200.google.com with SMTP id d75a77b69052e-3f80f8e5eb1so12208311cf.1 for ; Thu, 08 Jun 2023 11:57:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686250672; x=1688842672; h=subject:from:cc:to:content-language:user-agent:mime-version:date :message-id:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=EG4bjqXvtjK+cACk8f8WyqAO2LSSg+gdTi0JFbN0Vw4=; b=fN/W7nGrzr2q8LirlbcAU1+NTLbEqq4npP4Sq6TN6qHhPrqsQVlzw2+ON13H35XR/u 9ktOmx7MCoap1vuV3KapmlI4LeEWe1Q9S+XXpGG47Sbl9HYdBSBRS3rCFRtITPvuZLxr cEmULoj+ipnm4owX4jcyGrgHN0RiMJLS5IRrzLonZ2OKe8+NTAehsIL1IYWbc7eAM/CS 0FguakGbYKikVBqtwTXfw/tbYyGGgExrjw7L4x6nmP6bVhxhYO03OJA218Tw5RRAshTZ 950W5a/pC8k4+WyBJvFy3vmkHLfkkrK3hogQiarDaNlzlSKn8Kv8vDBY9gOl7Ai2vfp2 2+hQ== X-Gm-Message-State: AC+VfDzVfZybF+F7w3e5Jm+txPonquaAta+s7U3aPLeIM7Gsdw95TmIi jlLTo7XjVmsrB9YYlc2x/GE8gN3z4FQfxGgL0i44ETraNUb4BXVKMDv5/4KS38oWldhBowyKvnW gEa8qQP8vaDRFAF903McMAookm8R4BbpcU+IKgP+O+rKuOg5xXuOGA6ENGKO3USN1Eby7OKf8LX U0Wg== X-Received: by 2002:ac8:5c05:0:b0:3f9:adc9:4785 with SMTP id i5-20020ac85c05000000b003f9adc94785mr8170670qti.51.1686250672479; Thu, 08 Jun 2023 11:57:52 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6+dPZi1rn22pL+k4b6R/JlRxRcY4sLad86Z0rE8L8hvUf9OO/6wn41zogvqts4sXXQTUHVTw== X-Received: by 2002:ac8:5c05:0:b0:3f9:adc9:4785 with SMTP id i5-20020ac85c05000000b003f9adc94785mr8170651qti.51.1686250672142; Thu, 08 Jun 2023 11:57:52 -0700 (PDT) Received: from ?IPV6:2607:fea8:51df:4200::ca58? ([2607:fea8:51df:4200::ca58]) by smtp.gmail.com with ESMTPSA id o16-20020a05622a009000b003ef2c959d1bsm548861qtw.67.2023.06.08.11.57.51 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 08 Jun 2023 11:57:51 -0700 (PDT) Message-ID: Date: Thu, 8 Jun 2023 14:57:50 -0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0 To: gcc-patches Cc: "hernandez, aldy" Subject: [COMMITTED 3/4] Unify range_operators to one class. X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Andrew MacLeod via Gcc-patches From: Andrew MacLeod Reply-To: Andrew MacLeod Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Range_operator and range_operator_float are 2 different classes, which was not the original intent. This makes generalized dispatch to the appropriate function more difficult.  The distinction between what is a float operator and what is an integral operator also blurs when some methods have multiple types.  ie, casts : INT = FLOAT and FLOAT = INT, or other mixed operations like INT = FLOAT < FLOAT This patch unifies all possible invocation patterns in one range_operator class. All the float operators now inherit from range_operator, and this allows the float table to use the general range_op_table class instead of re-implementing another kind of table.  THis paves the way for the next patch which provides generalized dispatch for the various routines from a VRANGE. There is little functional difference after this patch. Bootstraps on x86_64-pc-linux-gnu with no regressions.  Pushed. Andrew From e925119d520ac10674ed42faf14955aaf130c03b Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Wed, 31 May 2023 12:31:53 -0400 Subject: [PATCH 3/4] Unify range_operators to one class. Range_operator and range_operator_float are 2 different classes, making generalized dispatch difficult. The distinction between what is a float operator and what is an integral operator also blurs when some methods have multiple types. ie, casts : INT = FLOAT and FLOAT = INT This patch unifies all possible invocation patterns in one class, and switches the float table to use the general range_op_table. * gimple-range-op.cc (cfn_constant_float_p): Change base class. (cfn_pass_through_arg1): Adjust using statemenmt. (cfn_signbit): Change base class, adjust using statement. (cfn_copysign): Ditto. (cfn_sqrt): Ditto. (cfn_sincos): Ditto. * range-op-float.cc (fold_range): Change class to range_operator. (rv_fold): Ditto. (op1_range): Ditto (op2_range): Ditto (lhs_op1_relation): Ditto. (lhs_op2_relation): Ditto. (op1_op2_relation): Ditto. (foperator_*): Ditto. (class float_table): New. Inherit from range_op_table. (floating_tree_table) Change to range_op_table pointer. (class floating_op_table): Delete. * range-op.cc (operator_equal): Adjust using statement. (operator_not_equal): Ditto. (operator_lt, operator_le, operator_gt, operator_ge): Ditto. (operator_minus, operator_cast): Ditto. (operator_bitwise_and, pointer_plus_operator): Ditto. (get_float_handle): Change return type. * range-op.h (range_operator_float): Delete. Relocate all methods into class range_operator. (range_op_handler::m_float): Change type to range_operator. (floating_op_table): Delete. (floating_tree_table): Change type. --- gcc/gimple-range-op.cc | 27 ++--- gcc/range-op-float.cc | 222 +++++++++++++++++++---------------------- gcc/range-op.cc | 12 ++- gcc/range-op.h | 124 +++++++++++------------ 4 files changed, 183 insertions(+), 202 deletions(-) diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc index 59c47e2074d..293d76402e1 100644 --- a/gcc/gimple-range-op.cc +++ b/gcc/gimple-range-op.cc @@ -268,10 +268,10 @@ gimple_range_op_handler::calc_op2 (vrange &r, const vrange &lhs_range, // -------------------------------------------------------------------- // Implement range operator for float CFN_BUILT_IN_CONSTANT_P. -class cfn_constant_float_p : public range_operator_float +class cfn_constant_float_p : public range_operator { public: - using range_operator_float::fold_range; + using range_operator::fold_range; virtual bool fold_range (irange &r, tree type, const frange &lh, const irange &, relation_trio) const { @@ -319,6 +319,7 @@ class cfn_pass_through_arg1 : public range_operator { public: using range_operator::fold_range; + using range_operator::op1_range; virtual bool fold_range (irange &r, tree, const irange &lh, const irange &, relation_trio) const { @@ -334,11 +335,11 @@ public: } op_cfn_pass_through_arg1; // Implement range operator for CFN_BUILT_IN_SIGNBIT. -class cfn_signbit : public range_operator_float +class cfn_signbit : public range_operator { public: - using range_operator_float::fold_range; - using range_operator_float::op1_range; + using range_operator::fold_range; + using range_operator::op1_range; virtual bool fold_range (irange &r, tree type, const frange &lh, const irange &, relation_trio) const override { @@ -373,10 +374,10 @@ public: } op_cfn_signbit; // Implement range operator for CFN_BUILT_IN_COPYSIGN -class cfn_copysign : public range_operator_float +class cfn_copysign : public range_operator { public: - using range_operator_float::fold_range; + using range_operator::fold_range; virtual bool fold_range (frange &r, tree type, const frange &lh, const frange &rh, relation_trio) const override { @@ -464,11 +465,11 @@ frange_mpfr_arg1 (REAL_VALUE_TYPE *res_low, REAL_VALUE_TYPE *res_high, return true; } -class cfn_sqrt : public range_operator_float +class cfn_sqrt : public range_operator { public: - using range_operator_float::fold_range; - using range_operator_float::op1_range; + using range_operator::fold_range; + using range_operator::op1_range; virtual bool fold_range (frange &r, tree type, const frange &lh, const frange &, relation_trio) const final override @@ -599,11 +600,11 @@ public: } } op_cfn_sqrt; -class cfn_sincos : public range_operator_float +class cfn_sincos : public range_operator { public: - using range_operator_float::fold_range; - using range_operator_float::op1_range; + using range_operator::fold_range; + using range_operator::op1_range; cfn_sincos (combined_fn cfn) { m_cfn = cfn; } virtual bool fold_range (frange &r, tree type, const frange &lh, const frange &, diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc index af598b60a79..bb10accd78f 100644 --- a/gcc/range-op-float.cc +++ b/gcc/range-op-float.cc @@ -49,7 +49,7 @@ along with GCC; see the file COPYING3. If not see // Default definitions for floating point operators. bool -range_operator_float::fold_range (frange &r, tree type, +range_operator::fold_range (frange &r, tree type, const frange &op1, const frange &op2, relation_trio trio) const { @@ -121,7 +121,7 @@ range_operator_float::fold_range (frange &r, tree type, // MAYBE_NAN is set to TRUE if, in addition to any result in LB or // UB, the final range has the possibility of a NAN. void -range_operator_float::rv_fold (REAL_VALUE_TYPE &lb, +range_operator::rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan, tree type ATTRIBUTE_UNUSED, @@ -137,7 +137,7 @@ range_operator_float::rv_fold (REAL_VALUE_TYPE &lb, } bool -range_operator_float::fold_range (irange &r ATTRIBUTE_UNUSED, +range_operator::fold_range (irange &r ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, const frange &lh ATTRIBUTE_UNUSED, const irange &rh ATTRIBUTE_UNUSED, @@ -147,7 +147,7 @@ range_operator_float::fold_range (irange &r ATTRIBUTE_UNUSED, } bool -range_operator_float::fold_range (irange &r ATTRIBUTE_UNUSED, +range_operator::fold_range (irange &r ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, const frange &lh ATTRIBUTE_UNUSED, const frange &rh ATTRIBUTE_UNUSED, @@ -157,7 +157,7 @@ range_operator_float::fold_range (irange &r ATTRIBUTE_UNUSED, } bool -range_operator_float::op1_range (frange &r ATTRIBUTE_UNUSED, +range_operator::op1_range (frange &r ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, const frange &lhs ATTRIBUTE_UNUSED, const frange &op2 ATTRIBUTE_UNUSED, @@ -167,7 +167,7 @@ range_operator_float::op1_range (frange &r ATTRIBUTE_UNUSED, } bool -range_operator_float::op1_range (frange &r ATTRIBUTE_UNUSED, +range_operator::op1_range (frange &r ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, const irange &lhs ATTRIBUTE_UNUSED, const frange &op2 ATTRIBUTE_UNUSED, @@ -177,7 +177,7 @@ range_operator_float::op1_range (frange &r ATTRIBUTE_UNUSED, } bool -range_operator_float::op2_range (frange &r ATTRIBUTE_UNUSED, +range_operator::op2_range (frange &r ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, const frange &lhs ATTRIBUTE_UNUSED, const frange &op1 ATTRIBUTE_UNUSED, @@ -187,7 +187,7 @@ range_operator_float::op2_range (frange &r ATTRIBUTE_UNUSED, } bool -range_operator_float::op2_range (frange &r ATTRIBUTE_UNUSED, +range_operator::op2_range (frange &r ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, const irange &lhs ATTRIBUTE_UNUSED, const frange &op1 ATTRIBUTE_UNUSED, @@ -197,7 +197,7 @@ range_operator_float::op2_range (frange &r ATTRIBUTE_UNUSED, } relation_kind -range_operator_float::lhs_op1_relation (const frange &lhs ATTRIBUTE_UNUSED, +range_operator::lhs_op1_relation (const frange &lhs ATTRIBUTE_UNUSED, const frange &op1 ATTRIBUTE_UNUSED, const frange &op2 ATTRIBUTE_UNUSED, relation_kind) const @@ -206,7 +206,7 @@ range_operator_float::lhs_op1_relation (const frange &lhs ATTRIBUTE_UNUSED, } relation_kind -range_operator_float::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED, +range_operator::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED, const frange &op1 ATTRIBUTE_UNUSED, const frange &op2 ATTRIBUTE_UNUSED, relation_kind) const @@ -215,7 +215,7 @@ range_operator_float::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED, } relation_kind -range_operator_float::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED, +range_operator::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED, const frange &op1 ATTRIBUTE_UNUSED, const frange &op2 ATTRIBUTE_UNUSED, relation_kind) const @@ -224,7 +224,7 @@ range_operator_float::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED, } relation_kind -range_operator_float::lhs_op2_relation (const frange &lhs ATTRIBUTE_UNUSED, +range_operator::lhs_op2_relation (const frange &lhs ATTRIBUTE_UNUSED, const frange &op1 ATTRIBUTE_UNUSED, const frange &op2 ATTRIBUTE_UNUSED, relation_kind) const @@ -233,13 +233,7 @@ range_operator_float::lhs_op2_relation (const frange &lhs ATTRIBUTE_UNUSED, } relation_kind -range_operator_float::op1_op2_relation (const irange &lhs ATTRIBUTE_UNUSED) const -{ - return VREL_VARYING; -} - -relation_kind -range_operator_float::op1_op2_relation (const frange &lhs ATTRIBUTE_UNUSED) const +range_operator::op1_op2_relation (const frange &lhs ATTRIBUTE_UNUSED) const { return VREL_VARYING; } @@ -546,10 +540,10 @@ build_gt (frange &r, tree type, const frange &val) } -class foperator_identity : public range_operator_float +class foperator_identity : public range_operator { - using range_operator_float::fold_range; - using range_operator_float::op1_range; + using range_operator::fold_range; + using range_operator::op1_range; public: bool fold_range (frange &r, tree type ATTRIBUTE_UNUSED, const frange &op1, const frange &op2 ATTRIBUTE_UNUSED, @@ -568,12 +562,12 @@ public: public: } fop_identity; -class foperator_equal : public range_operator_float +class foperator_equal : public range_operator { - using range_operator_float::fold_range; - using range_operator_float::op1_range; - using range_operator_float::op2_range; - using range_operator_float::op1_op2_relation; + using range_operator::fold_range; + using range_operator::op1_range; + using range_operator::op2_range; + using range_operator::op1_op2_relation; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -697,11 +691,11 @@ foperator_equal::op1_range (frange &r, tree type, return true; } -class foperator_not_equal : public range_operator_float +class foperator_not_equal : public range_operator { - using range_operator_float::fold_range; - using range_operator_float::op1_range; - using range_operator_float::op1_op2_relation; + using range_operator::fold_range; + using range_operator::op1_range; + using range_operator::op1_op2_relation; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -819,12 +813,12 @@ foperator_not_equal::op1_range (frange &r, tree type, return true; } -class foperator_lt : public range_operator_float +class foperator_lt : public range_operator { - using range_operator_float::fold_range; - using range_operator_float::op1_range; - using range_operator_float::op2_range; - using range_operator_float::op1_op2_relation; + using range_operator::fold_range; + using range_operator::op1_range; + using range_operator::op2_range; + using range_operator::op1_op2_relation; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -935,12 +929,12 @@ foperator_lt::op2_range (frange &r, return true; } -class foperator_le : public range_operator_float +class foperator_le : public range_operator { - using range_operator_float::fold_range; - using range_operator_float::op1_range; - using range_operator_float::op2_range; - using range_operator_float::op1_op2_relation; + using range_operator::fold_range; + using range_operator::op1_range; + using range_operator::op2_range; + using range_operator::op1_op2_relation; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -1045,12 +1039,12 @@ foperator_le::op2_range (frange &r, return true; } -class foperator_gt : public range_operator_float +class foperator_gt : public range_operator { - using range_operator_float::fold_range; - using range_operator_float::op1_range; - using range_operator_float::op2_range; - using range_operator_float::op1_op2_relation; + using range_operator::fold_range; + using range_operator::op1_range; + using range_operator::op2_range; + using range_operator::op1_op2_relation; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -1165,12 +1159,12 @@ foperator_gt::op2_range (frange &r, return true; } -class foperator_ge : public range_operator_float +class foperator_ge : public range_operator { - using range_operator_float::fold_range; - using range_operator_float::op1_range; - using range_operator_float::op2_range; - using range_operator_float::op1_op2_relation; + using range_operator::fold_range; + using range_operator::op1_range; + using range_operator::op2_range; + using range_operator::op1_op2_relation; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -1278,11 +1272,11 @@ foperator_ge::op2_range (frange &r, tree type, // UNORDERED_EXPR comparison. -class foperator_unordered : public range_operator_float +class foperator_unordered : public range_operator { - using range_operator_float::fold_range; - using range_operator_float::op1_range; - using range_operator_float::op2_range; + using range_operator::fold_range; + using range_operator::op1_range; + using range_operator::op2_range; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -1352,11 +1346,11 @@ foperator_unordered::op1_range (frange &r, tree type, // ORDERED_EXPR comparison. -class foperator_ordered : public range_operator_float +class foperator_ordered : public range_operator { - using range_operator_float::fold_range; - using range_operator_float::op1_range; - using range_operator_float::op2_range; + using range_operator::fold_range; + using range_operator::op1_range; + using range_operator::op2_range; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -1421,10 +1415,10 @@ foperator_ordered::op1_range (frange &r, tree type, return true; } -class foperator_negate : public range_operator_float +class foperator_negate : public range_operator { - using range_operator_float::fold_range; - using range_operator_float::op1_range; + using range_operator::fold_range; + using range_operator::op1_range; public: bool fold_range (frange &r, tree type, const frange &op1, const frange &op2, @@ -1467,10 +1461,10 @@ public: } } fop_negate; -class foperator_abs : public range_operator_float +class foperator_abs : public range_operator { - using range_operator_float::fold_range; - using range_operator_float::op1_range; + using range_operator::fold_range; + using range_operator::op1_range; public: bool fold_range (frange &r, tree type, const frange &op1, const frange &, @@ -1566,11 +1560,11 @@ foperator_abs::op1_range (frange &r, tree type, return true; } -class foperator_unordered_lt : public range_operator_float +class foperator_unordered_lt : public range_operator { - using range_operator_float::fold_range; - using range_operator_float::op1_range; - using range_operator_float::op2_range; + using range_operator::fold_range; + using range_operator::op1_range; + using range_operator::op2_range; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -1677,11 +1671,11 @@ foperator_unordered_lt::op2_range (frange &r, tree type, return true; } -class foperator_unordered_le : public range_operator_float +class foperator_unordered_le : public range_operator { - using range_operator_float::fold_range; - using range_operator_float::op1_range; - using range_operator_float::op2_range; + using range_operator::fold_range; + using range_operator::op1_range; + using range_operator::op2_range; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -1784,11 +1778,11 @@ foperator_unordered_le::op2_range (frange &r, return true; } -class foperator_unordered_gt : public range_operator_float +class foperator_unordered_gt : public range_operator { - using range_operator_float::fold_range; - using range_operator_float::op1_range; - using range_operator_float::op2_range; + using range_operator::fold_range; + using range_operator::op1_range; + using range_operator::op2_range; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -1895,11 +1889,11 @@ foperator_unordered_gt::op2_range (frange &r, return true; } -class foperator_unordered_ge : public range_operator_float +class foperator_unordered_ge : public range_operator { - using range_operator_float::fold_range; - using range_operator_float::op1_range; - using range_operator_float::op2_range; + using range_operator::fold_range; + using range_operator::op1_range; + using range_operator::op2_range; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -2005,11 +1999,11 @@ foperator_unordered_ge::op2_range (frange &r, tree type, return true; } -class foperator_unordered_equal : public range_operator_float +class foperator_unordered_equal : public range_operator { - using range_operator_float::fold_range; - using range_operator_float::op1_range; - using range_operator_float::op2_range; + using range_operator::fold_range; + using range_operator::op1_range; + using range_operator::op2_range; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -2086,11 +2080,11 @@ foperator_unordered_equal::op1_range (frange &r, tree type, return true; } -class foperator_ltgt : public range_operator_float +class foperator_ltgt : public range_operator { - using range_operator_float::fold_range; - using range_operator_float::op1_range; - using range_operator_float::op2_range; + using range_operator::fold_range; + using range_operator::op1_range; + using range_operator::op2_range; public: bool fold_range (irange &r, tree type, const frange &op1, const frange &op2, @@ -2374,10 +2368,10 @@ float_widen_lhs_range (tree type, const frange &lhs) return ret; } -class foperator_plus : public range_operator_float +class foperator_plus : public range_operator { - using range_operator_float::op1_range; - using range_operator_float::op2_range; + using range_operator::op1_range; + using range_operator::op2_range; public: virtual bool op1_range (frange &r, tree type, const frange &lhs, @@ -2424,10 +2418,10 @@ private: } fop_plus; -class foperator_minus : public range_operator_float +class foperator_minus : public range_operator { - using range_operator_float::op1_range; - using range_operator_float::op2_range; + using range_operator::op1_range; + using range_operator::op2_range; public: virtual bool op1_range (frange &r, tree type, const frange &lhs, @@ -2476,7 +2470,7 @@ private: } fop_minus; -class foperator_mult_div_base : public range_operator_float +class foperator_mult_div_base : public range_operator { protected: // Given CP[0] to CP[3] floating point values rounded to -INF, @@ -2503,8 +2497,8 @@ protected: class foperator_mult : public foperator_mult_div_base { - using range_operator_float::op1_range; - using range_operator_float::op2_range; + using range_operator::op1_range; + using range_operator::op2_range; public: virtual bool op1_range (frange &r, tree type, const frange &lhs, @@ -2659,8 +2653,8 @@ private: class foperator_div : public foperator_mult_div_base { - using range_operator_float::op1_range; - using range_operator_float::op2_range; + using range_operator::op1_range; + using range_operator::op2_range; public: virtual bool op1_range (frange &r, tree type, const frange &lhs, @@ -2814,12 +2808,16 @@ private: } fop_div; // Instantiate a range_op_table for floating point operations. -static floating_op_table global_floating_table; +class float_table : public range_op_table +{ + public: + float_table (); +} global_floating_table; // Pointer to the float table so the dispatch code can access it. -floating_op_table *floating_tree_table = &global_floating_table; +range_op_table *floating_tree_table = &global_floating_table; -floating_op_table::floating_op_table () +float_table::float_table () { set (SSA_NAME, fop_identity); set (PAREN_EXPR, fop_identity); @@ -2852,24 +2850,6 @@ floating_op_table::floating_op_table () set (RDIV_EXPR, fop_div); } -// Return a pointer to the range_operator_float instance, if there is -// one associated with tree_code CODE. - -range_operator_float * -floating_op_table::operator[] (enum tree_code code) -{ - return m_range_tree[code]; -} - -// Add OP to the handler table for CODE. - -void -floating_op_table::set (enum tree_code code, range_operator_float &op) -{ - gcc_checking_assert (m_range_tree[code] == NULL); - m_range_tree[code] = &op; -} - #if CHECKING_P #include "selftest.h" diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 2deca3bac93..203c30f6e94 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -556,6 +556,7 @@ class operator_equal : public range_operator using range_operator::fold_range; using range_operator::op1_range; using range_operator::op2_range; + using range_operator::op1_op2_relation; public: virtual bool fold_range (irange &r, tree type, const irange &op1, @@ -678,6 +679,7 @@ class operator_not_equal : public range_operator using range_operator::fold_range; using range_operator::op1_range; using range_operator::op2_range; + using range_operator::op1_op2_relation; public: virtual bool fold_range (irange &r, tree type, const irange &op1, @@ -860,6 +862,7 @@ class operator_lt : public range_operator using range_operator::fold_range; using range_operator::op1_range; using range_operator::op2_range; + using range_operator::op1_op2_relation; public: virtual bool fold_range (irange &r, tree type, const irange &op1, @@ -982,6 +985,7 @@ class operator_le : public range_operator using range_operator::fold_range; using range_operator::op1_range; using range_operator::op2_range; + using range_operator::op1_op2_relation; public: virtual bool fold_range (irange &r, tree type, const irange &op1, @@ -1101,6 +1105,7 @@ class operator_gt : public range_operator using range_operator::fold_range; using range_operator::op1_range; using range_operator::op2_range; + using range_operator::op1_op2_relation; public: virtual bool fold_range (irange &r, tree type, const irange &op1, @@ -1219,6 +1224,7 @@ class operator_ge : public range_operator using range_operator::fold_range; using range_operator::op1_range; using range_operator::op2_range; + using range_operator::op1_op2_relation; public: virtual bool fold_range (irange &r, tree type, const irange &op1, @@ -1647,6 +1653,7 @@ class operator_minus : public range_operator using range_operator::fold_range; using range_operator::op1_range; using range_operator::op2_range; + using range_operator::lhs_op1_relation; public: virtual bool op1_range (irange &r, tree type, const irange &lhs, @@ -2710,6 +2717,7 @@ class operator_cast: public range_operator { using range_operator::fold_range; using range_operator::op1_range; + using range_operator::lhs_op1_relation; public: virtual bool fold_range (irange &r, tree type, const irange &op1, @@ -3055,6 +3063,7 @@ class operator_bitwise_and : public range_operator { using range_operator::op1_range; using range_operator::op2_range; + using range_operator::lhs_op1_relation; public: virtual bool op1_range (irange &r, tree type, const irange &lhs, @@ -4410,6 +4419,7 @@ operator_addr_expr::op1_range (irange &r, tree type, class pointer_plus_operator : public range_operator { + using range_operator::op2_range; public: virtual void wi_fold (irange &r, tree type, const wide_int &lh_lb, @@ -4719,7 +4729,7 @@ get_handler (enum tree_code code, tree type) // Return the floating point operator for CODE or NULL if none available. -static inline range_operator_float * +static inline range_operator * get_float_handler (enum tree_code code, tree) { return (*floating_tree_table)[code]; diff --git a/gcc/range-op.h b/gcc/range-op.h index 5bfbc89df52..cad16f4cd20 100644 --- a/gcc/range-op.h +++ b/gcc/range-op.h @@ -45,6 +45,11 @@ along with GCC; see the file COPYING3. If not see // non-zero. This is mostly for logical true false, but can serve other // purposes. // ie 0 = op1 - op2 implies op2 has the same range as op1. +// +// 4 - All supported range combinations are explicitly specified. +// Any desired combinations should be implemented for each operator. +// When new range classes are added, new matching prototypes should be +// added. class range_operator { @@ -55,6 +60,18 @@ public: const irange &lh, const irange &rh, relation_trio = TRIO_VARYING) const; + virtual bool fold_range (frange &r, tree type, + const frange &lh, + const frange &rh, + relation_trio = TRIO_VARYING) const; + virtual bool fold_range (irange &r, tree type, + const frange &lh, + const irange &rh, + relation_trio = TRIO_VARYING) const; + virtual bool fold_range (irange &r, tree type, + const frange &lh, + const frange &rh, + relation_trio = TRIO_VARYING) const; // Return the range for op[12] in the general case. LHS is the range for // the LHS of the expression, OP[12]is the range for the other @@ -71,10 +88,28 @@ public: const irange &lhs, const irange &op2, relation_trio = TRIO_VARYING) const; + virtual bool op1_range (frange &r, tree type, + const frange &lhs, + const frange &op2, + relation_trio = TRIO_VARYING) const; + virtual bool op1_range (frange &r, tree type, + const irange &lhs, + const frange &op2, + relation_trio = TRIO_VARYING) const; + + virtual bool op2_range (irange &r, tree type, const irange &lhs, const irange &op1, relation_trio = TRIO_VARYING) const; + virtual bool op2_range (frange &r, tree type, + const frange &lhs, + const frange &op1, + relation_trio = TRIO_VARYING) const; + virtual bool op2_range (frange &r, tree type, + const irange &lhs, + const frange &op1, + relation_trio = TRIO_VARYING) const; // The following routines are used to represent relations between the // various operations. If the caller knows where the symbolics are, @@ -84,11 +119,30 @@ public: const irange &op1, const irange &op2, relation_kind = VREL_VARYING) const; + virtual relation_kind lhs_op1_relation (const frange &lhs, + const frange &op1, + const frange &op2, + relation_kind = VREL_VARYING) const; + virtual relation_kind lhs_op1_relation (const irange &lhs, + const frange &op1, + const frange &op2, + relation_kind = VREL_VARYING) const; + virtual relation_kind lhs_op2_relation (const irange &lhs, const irange &op1, const irange &op2, relation_kind = VREL_VARYING) const; + virtual relation_kind lhs_op2_relation (const frange &lhs, + const frange &op1, + const frange &op2, + relation_kind = VREL_VARYING) const; + virtual relation_kind lhs_op2_relation (const irange &lhs, + const frange &op1, + const frange &op2, + relation_kind = VREL_VARYING) const; + virtual relation_kind op1_op2_relation (const irange &lhs) const; + virtual relation_kind op1_op2_relation (const frange &lhs) const; protected: // Perform an integral operation between 2 sub-ranges and return it. virtual void wi_fold (irange &r, tree type, @@ -115,17 +169,8 @@ protected: unsigned limit) const; // Apply any bitmasks implied by these ranges. virtual void update_bitmask (irange &, const irange &, const irange &) const; -}; - -// Like range_operator above, but for floating point operators. -class range_operator_float -{ -public: - virtual bool fold_range (frange &r, tree type, - const frange &lh, - const frange &rh, - relation_trio = TRIO_VARYING) const; + // Perform an float operation between 2 ranges and return it. virtual void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan, tree type, @@ -134,50 +179,6 @@ public: const REAL_VALUE_TYPE &rh_lb, const REAL_VALUE_TYPE &rh_ub, relation_kind) const; - // Unary operations have the range of the LHS as op2. - virtual bool fold_range (irange &r, tree type, - const frange &lh, - const irange &rh, - relation_trio = TRIO_VARYING) const; - virtual bool fold_range (irange &r, tree type, - const frange &lh, - const frange &rh, - relation_trio = TRIO_VARYING) const; - virtual bool op1_range (frange &r, tree type, - const frange &lhs, - const frange &op2, - relation_trio = TRIO_VARYING) const; - virtual bool op1_range (frange &r, tree type, - const irange &lhs, - const frange &op2, - relation_trio = TRIO_VARYING) const; - virtual bool op2_range (frange &r, tree type, - const frange &lhs, - const frange &op1, - relation_trio = TRIO_VARYING) const; - virtual bool op2_range (frange &r, tree type, - const irange &lhs, - const frange &op1, - relation_trio = TRIO_VARYING) const; - - virtual relation_kind lhs_op1_relation (const frange &lhs, - const frange &op1, - const frange &op2, - relation_kind = VREL_VARYING) const; - virtual relation_kind lhs_op1_relation (const irange &lhs, - const frange &op1, - const frange &op2, - relation_kind = VREL_VARYING) const; - virtual relation_kind lhs_op2_relation (const frange &lhs, - const frange &op1, - const frange &op2, - relation_kind = VREL_VARYING) const; - virtual relation_kind lhs_op2_relation (const irange &lhs, - const frange &op1, - const frange &op2, - relation_kind = VREL_VARYING) const; - virtual relation_kind op1_op2_relation (const irange &lhs) const; - virtual relation_kind op1_op2_relation (const frange &lhs) const; }; class range_op_handler @@ -212,7 +213,7 @@ protected: void set_op_handler (enum tree_code code, tree type); bool m_valid; range_operator *m_int; - range_operator_float *m_float; + range_operator *m_float; }; extern bool range_cast (vrange &, tree type); @@ -294,20 +295,9 @@ private: range_operator *m_range_tree[MAX_TREE_CODES]; }; -// Like above, but for floating point operators. - -class floating_op_table -{ -public: - floating_op_table (); - range_operator_float *operator[] (enum tree_code code); -private: - void set (enum tree_code code, range_operator_float &op); - range_operator_float *m_range_tree[MAX_TREE_CODES]; -}; // This holds the range op table for floating point operations. -extern floating_op_table *floating_tree_table; +extern range_op_table *floating_tree_table; extern range_operator *ptr_op_widen_mult_signed; extern range_operator *ptr_op_widen_mult_unsigned; -- 2.40.1 From patchwork Thu Jun 8 18:58:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew MacLeod X-Patchwork-Id: 70799 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BE69D385C6FB for ; Thu, 8 Jun 2023 18:59:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BE69D385C6FB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1686250742; bh=PqF0D72Kin6eBNb1S3ehzB7gYAv1z/N+T8kARdPcDxY=; h=Date:To:Cc:Subject:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=OIKBSx4tdExTaCBvFIkoO5Xl6CZItzg60N1vB8F0f3tVInWY7vBRLpUo1TZcRJ9Vx qz8eOgqKfYzbCnSe5EZXY4LMG7EnIYHnkczoKzvATf8vK5NlSLgt6u/NlqvnAUaAfq BEahQvLkwlO5X/Q8OtSCQNxki9robL9yDfUuDaGc= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 8385F385624C for ; Thu, 8 Jun 2023 18:58:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8385F385624C Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-534-BZWXIT0sPTWT-NsAgkEixQ-1; Thu, 08 Jun 2023 14:58:04 -0400 X-MC-Unique: BZWXIT0sPTWT-NsAgkEixQ-1 Received: by mail-qt1-f199.google.com with SMTP id d75a77b69052e-3f9a7a41baeso9970351cf.1 for ; Thu, 08 Jun 2023 11:58:04 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686250684; x=1688842684; h=subject:from:cc:to:content-language:user-agent:mime-version:date :message-id:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=LSHWKRKOc0o6Xc8lN3uKHD3T3A+8gIMFWOM+IJfO4+I=; b=GHa+WaII7E9u4JPkJcdksRQMotw95Zp4riPnwGfxFXiGwr0mtYAMjurpC7UNxuP8bE /Z5z53uAHMNdXcVS67/5oXjiBccNxfA3V+dKMctGCXP1DQV1RY9k9/AFJl9syZ1U7qsT FTY0UnpmjeVyj7p8TQx1GSX6rW8oJ6pwt7NaYR3J2iSoh29K/0AcABQhTZ5El4y2PJdr QhSljEuAT62xCGTdFk0RsjX0DArGNhSxp4Gk+/12HJR56Vp8T4Jz6yIdAl8sEiFYics5 4ixZkU0XThjTMCz+icbgjUFpbY7g6HMJ7h8OCBrJNvCD5kOOdg2hgJh7vu7nK9REGVP+ owXA== X-Gm-Message-State: AC+VfDxwjX0L2/wxSopJausYizbLBOXYCN/57POquXYXMz1bBB4H4n+2 l6R/5zbvRlxdgsp7fEsE/UYG+Dd7WmKCCz6uosl8FryIg5/rF9slKs+CRKIRpigMDzeATMP/IdK nUi2cmayrSsnKsi2HS0bUZ40KdBV8ztDr+sxOtkciM2TCvojBYL27XxFKpQdbVVddQNQiQp2d+d 7OrQ== X-Received: by 2002:a05:622a:291:b0:3f1:630:8659 with SMTP id z17-20020a05622a029100b003f106308659mr7514163qtw.53.1686250683786; Thu, 08 Jun 2023 11:58:03 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ4mvpTkOfvgRvgZNqPdRVgcPMQbDoCtCmCtTn2FJn2TFGXdWV2nJ86APc1mi4NetH+Ww1sTmg== X-Received: by 2002:a05:622a:291:b0:3f1:630:8659 with SMTP id z17-20020a05622a029100b003f106308659mr7514141qtw.53.1686250683412; Thu, 08 Jun 2023 11:58:03 -0700 (PDT) Received: from ?IPV6:2607:fea8:51df:4200::ca58? ([2607:fea8:51df:4200::ca58]) by smtp.gmail.com with ESMTPSA id z4-20020ac87104000000b003f6be76a5c1sm572266qto.6.2023.06.08.11.58.02 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 08 Jun 2023 11:58:02 -0700 (PDT) Message-ID: Date: Thu, 8 Jun 2023 14:58:01 -0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0 To: gcc-patches Cc: "hernandez, aldy" Subject: [COMMITTED 4/4] Provide a new dispatch mechanism for range-ops. X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Andrew MacLeod via Gcc-patches From: Andrew MacLeod Reply-To: Andrew MacLeod Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" This patch introduces a new dispatch mechanism for range_op_handler. Instead of ad-hoc if then elses based on is_a and is_a,frange *>, the discriminators in class vrange are used for each operand to create a triplet, ie (III for "LHS = Irange, op1 = Irange, op2 = Irange", and IFI for "Irange Frange Irange") These triplets are then used ina  switch to dispatch the call to the approriate one in range_operator for those types.  And added bonus is that if there is a pattern that is not recognized, we no longer trap.. Tthe dispatch routine simply returns the same thing as a default routine does in range_operator.. either false or VREL_VARYING depending on the signature. This will make adding additional range types much simplier going forward, and aleviates the need to check for supported types before invoking routines like fold_range. As part fo the rework, this patch also simplifies range_op_handler to now only contain a single pointer to a range_operator instead of 2 pointers and a flag.   This is enabled by the previous patch which unifies all range operators to one class. And added bonus is a bit of a compile time improvement for VRP and threading, as well as other clients due to less conditional checks at dispatch time. It only amounts to about a 0.75% improvement in those passes for the moment... but every little bit helps. Bootstraps on x86_64-pc-linux-gnu with no regressions.  Pushed. Andrew From f36f25792b3cb0b9067f318dd4d5c968f75a5c3d Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Wed, 31 May 2023 13:10:31 -0400 Subject: [PATCH 4/4] Provide a new dispatch mechanism for range-ops. Simplify range_op_handler to have a single range_operator pointer and provide a more flexible dispatch mechanism for calls via generic vrange classes. This is more extensible for adding new classes of range support. Any unsupported dispatch patterns will simply return FALSE now rather than generating compile time exceptions, aleviating the need to constantly check for supoprted types. * gimple-range-op.cc (gimple_range_op_handler::gimple_range_op_handler): Adjust. (gimple_range_op_handler::maybe_builtin_call): Adjust. * gimple-range-op.h (operand1, operand2): Use m_operator. * range-op.cc (integral_table, pointer_table): Relocate. (get_op_handler): Rename from get_handler and handle all types. (range_op_handler::range_op_handler): Relocate. (range_op_handler::set_op_handler): Relocate and adjust. (range_op_handler::range_op_handler): Relocate. (dispatch_trio): New. (RO_III, RO_IFI, RO_IFF, RO_FFF, RO_FIF, RO_FII): New consts. (range_op_handler::dispatch_kind): New. (range_op_handler::fold_range): Relocate and Use new dispatch value. (range_op_handler::op1_range): Ditto. (range_op_handler::op2_range): Ditto. (range_op_handler::lhs_op1_relation): Ditto. (range_op_handler::lhs_op2_relation): Ditto. (range_op_handler::op1_op2_relation): Ditto. (range_op_handler::set_op_handler): Use m_operator member. * range-op.h (range_op_handler::operator bool): Use m_operator. (range_op_handler::dispatch_kind): New. (range_op_handler::m_valid): Delete. (range_op_handler::m_int): Delete (range_op_handler::m_float): Delete (range_op_handler::m_operator): New. (range_op_table::operator[]): Relocate from .cc file. (range_op_table::set): Ditto. * value-range.h (class vrange): Make range_op_handler a friend. --- gcc/gimple-range-op.cc | 84 +++----- gcc/gimple-range-op.h | 4 +- gcc/range-op.cc | 470 ++++++++++++++++++++++------------------- gcc/range-op.h | 27 ++- gcc/value-range.h | 1 + 5 files changed, 306 insertions(+), 280 deletions(-) diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc index 293d76402e1..b6b10e47b78 100644 --- a/gcc/gimple-range-op.cc +++ b/gcc/gimple-range-op.cc @@ -144,7 +144,7 @@ gimple_range_op_handler::gimple_range_op_handler (gimple *s) if (type) set_op_handler (code, type); - if (m_valid) + if (m_operator) switch (gimple_code (m_stmt)) { case GIMPLE_COND: @@ -152,7 +152,7 @@ gimple_range_op_handler::gimple_range_op_handler (gimple *s) m_op2 = gimple_cond_rhs (m_stmt); // Check that operands are supported types. One check is enough. if (!Value_Range::supports_type_p (TREE_TYPE (m_op1))) - m_valid = false; + m_operator = NULL; return; case GIMPLE_ASSIGN: m_op1 = gimple_range_base_of_assignment (m_stmt); @@ -171,7 +171,7 @@ gimple_range_op_handler::gimple_range_op_handler (gimple *s) m_op2 = gimple_assign_rhs2 (m_stmt); // Check that operands are supported types. One check is enough. if ((m_op1 && !Value_Range::supports_type_p (TREE_TYPE (m_op1)))) - m_valid = false; + m_operator = NULL; return; default: gcc_unreachable (); @@ -1193,7 +1193,6 @@ gimple_range_op_handler::maybe_non_standard () { case WIDEN_MULT_EXPR: { - m_valid = false; m_op1 = gimple_assign_rhs1 (m_stmt); m_op2 = gimple_assign_rhs2 (m_stmt); tree ret = gimple_assign_lhs (m_stmt); @@ -1210,14 +1209,13 @@ gimple_range_op_handler::maybe_non_standard () if ((signed1 ^ signed2) && signed_ret) return; - m_valid = true; if (signed2 && !signed1) std::swap (m_op1, m_op2); if (signed1 || signed2) - m_int = signed_op; + m_operator = signed_op; else - m_int = unsigned_op; + m_operator = unsigned_op; break; } default: @@ -1246,47 +1244,41 @@ gimple_range_op_handler::maybe_builtin_call () { case CFN_BUILT_IN_CONSTANT_P: m_op1 = gimple_call_arg (call, 0); - m_valid = true; if (irange::supports_p (TREE_TYPE (m_op1))) - m_int = &op_cfn_constant_p; + m_operator = &op_cfn_constant_p; else if (frange::supports_p (TREE_TYPE (m_op1))) - m_float = &op_cfn_constant_float_p; + m_operator = &op_cfn_constant_float_p; else - m_valid = false; + m_operator = NULL; break; CASE_FLT_FN (CFN_BUILT_IN_SIGNBIT): m_op1 = gimple_call_arg (call, 0); - m_float = &op_cfn_signbit; - m_valid = true; + m_operator = &op_cfn_signbit; break; CASE_CFN_COPYSIGN_ALL: m_op1 = gimple_call_arg (call, 0); m_op2 = gimple_call_arg (call, 1); - m_float = &op_cfn_copysign; - m_valid = true; + m_operator = &op_cfn_copysign; break; CASE_CFN_SQRT: CASE_CFN_SQRT_FN: m_op1 = gimple_call_arg (call, 0); - m_float = &op_cfn_sqrt; - m_valid = true; + m_operator = &op_cfn_sqrt; break; CASE_CFN_SIN: CASE_CFN_SIN_FN: m_op1 = gimple_call_arg (call, 0); - m_float = &op_cfn_sin; - m_valid = true; + m_operator = &op_cfn_sin; break; CASE_CFN_COS: CASE_CFN_COS_FN: m_op1 = gimple_call_arg (call, 0); - m_float = &op_cfn_cos; - m_valid = true; + m_operator = &op_cfn_cos; break; case CFN_BUILT_IN_TOUPPER: @@ -1294,68 +1286,57 @@ gimple_range_op_handler::maybe_builtin_call () // Only proceed If the argument is compatible with the LHS. m_op1 = gimple_call_arg (call, 0); if (range_compatible_p (type, TREE_TYPE (m_op1))) - { - m_valid = true; - m_int = (func == CFN_BUILT_IN_TOLOWER) ? &op_cfn_tolower - : &op_cfn_toupper; - } + m_operator = (func == CFN_BUILT_IN_TOLOWER) ? &op_cfn_tolower + : &op_cfn_toupper; break; CASE_CFN_FFS: m_op1 = gimple_call_arg (call, 0); - m_int = &op_cfn_ffs; - m_valid = true; + m_operator = &op_cfn_ffs; break; CASE_CFN_POPCOUNT: m_op1 = gimple_call_arg (call, 0); - m_int = &op_cfn_popcount; - m_valid = true; + m_operator = &op_cfn_popcount; break; CASE_CFN_CLZ: m_op1 = gimple_call_arg (call, 0); - m_valid = true; if (gimple_call_internal_p (call)) - m_int = &op_cfn_clz_internal; + m_operator = &op_cfn_clz_internal; else - m_int = &op_cfn_clz; + m_operator = &op_cfn_clz; break; CASE_CFN_CTZ: m_op1 = gimple_call_arg (call, 0); - m_valid = true; if (gimple_call_internal_p (call)) - m_int = &op_cfn_ctz_internal; + m_operator = &op_cfn_ctz_internal; else - m_int = &op_cfn_ctz; + m_operator = &op_cfn_ctz; break; CASE_CFN_CLRSB: m_op1 = gimple_call_arg (call, 0); - m_valid = true; - m_int = &op_cfn_clrsb; + m_operator = &op_cfn_clrsb; break; case CFN_UBSAN_CHECK_ADD: m_op1 = gimple_call_arg (call, 0); m_op2 = gimple_call_arg (call, 1); - m_valid = true; - m_int = &op_cfn_ubsan_add; + m_operator = &op_cfn_ubsan_add; break; case CFN_UBSAN_CHECK_SUB: m_op1 = gimple_call_arg (call, 0); m_op2 = gimple_call_arg (call, 1); - m_valid = true; - m_int = &op_cfn_ubsan_sub; + m_operator = &op_cfn_ubsan_sub; break; case CFN_UBSAN_CHECK_MUL: m_op1 = gimple_call_arg (call, 0); m_op2 = gimple_call_arg (call, 1); - m_valid = true; - m_int = &op_cfn_ubsan_mul; + m_operator = &op_cfn_ubsan_mul; break; case CFN_BUILT_IN_STRLEN: @@ -1365,8 +1346,7 @@ gimple_range_op_handler::maybe_builtin_call () == TYPE_PRECISION (TREE_TYPE (lhs)))) { m_op1 = gimple_call_arg (call, 0); - m_valid = true; - m_int = &op_cfn_strlen; + m_operator = &op_cfn_strlen; } break; } @@ -1378,21 +1358,18 @@ gimple_range_op_handler::maybe_builtin_call () // This call will ensure all the asserts are triggered. oacc_get_ifn_dim_arg (call); m_op1 = gimple_call_arg (call, 0); - m_valid = true; - m_int = &op_cfn_goacc_dim_size; + m_operator = &op_cfn_goacc_dim_size; break; case CFN_GOACC_DIM_POS: // This call will ensure all the asserts are triggered. oacc_get_ifn_dim_arg (call); m_op1 = gimple_call_arg (call, 0); - m_valid = true; - m_int = &op_cfn_goacc_dim_pos; + m_operator = &op_cfn_goacc_dim_pos; break; CASE_CFN_PARITY: - m_valid = true; - m_int = &op_cfn_parity; + m_operator = &op_cfn_parity; break; default: @@ -1400,9 +1377,8 @@ gimple_range_op_handler::maybe_builtin_call () unsigned arg; if (gimple_call_fnspec (call).returns_arg (&arg) && arg == 0) { - m_valid = true; m_op1 = gimple_call_arg (call, 0); - m_int = &op_cfn_pass_through_arg1; + m_operator = &op_cfn_pass_through_arg1; } break; } diff --git a/gcc/gimple-range-op.h b/gcc/gimple-range-op.h index 1bf63c5ce6f..e7bb0095440 100644 --- a/gcc/gimple-range-op.h +++ b/gcc/gimple-range-op.h @@ -32,8 +32,8 @@ public: gimple_range_op_handler (gimple *s); inline gimple *stmt () const { return m_stmt; } inline tree lhs () const { return gimple_get_lhs (m_stmt); } - tree operand1 () const { gcc_checking_assert (m_valid); return m_op1; } - tree operand2 () const { gcc_checking_assert (m_valid); return m_op2; } + tree operand1 () const { gcc_checking_assert (m_operator); return m_op1; } + tree operand2 () const { gcc_checking_assert (m_operator); return m_op2; } bool calc_op1 (vrange &r, const vrange &lhs_range); bool calc_op1 (vrange &r, const vrange &lhs_range, const vrange &op2_range, relation_trio = TRIO_VARYING); diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 203c30f6e94..4d122de3026 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -48,6 +48,256 @@ along with GCC; see the file COPYING3. If not see #include "range-op.h" #include "tree-ssa-ccp.h" +// Instantiate a range op table for integral operations. + +class integral_table : public range_op_table +{ +public: + integral_table (); +} integral_tree_table; + +// Instantiate a range op table for pointer operations. + +class pointer_table : public range_op_table +{ +public: + pointer_table (); +} pointer_tree_table; + + +// The tables are hidden and accessed via a simple extern function. + +range_operator * +get_op_handler (enum tree_code code, tree type) +{ + // First check if there is a pointer specialization. + if (POINTER_TYPE_P (type)) + return pointer_tree_table[code]; + if (INTEGRAL_TYPE_P (type)) + return integral_tree_table[code]; + if (frange::supports_p (type)) + return (*floating_tree_table)[code]; + return NULL; +} + +range_op_handler::range_op_handler () +{ + m_operator = NULL; +} + +void +range_op_handler::set_op_handler (tree_code code, tree type) +{ + m_operator = get_op_handler (code, type); +} + +range_op_handler::range_op_handler (tree_code code, tree type) +{ + set_op_handler (code, type); +} + +// Create a dispatch pattern for value range discriminators LHS, OP1, and OP2. +// This is used to produce a unique value for each dispatch pattern. Shift +// values are based on the size of the m_discriminator field in value_range.h. + +constexpr unsigned +dispatch_trio (unsigned lhs, unsigned op1, unsigned op2) +{ + return ((lhs << 8) + (op1 << 4) + (op2)); +} + +// These are the supported dispatch patterns. These map to the parameter list +// of the routines in range_operator. Note the last 3 characters are +// shorthand for the LHS, OP1, and OP2 range discriminator class. + +const unsigned RO_III = dispatch_trio (VR_IRANGE, VR_IRANGE, VR_IRANGE); +const unsigned RO_IFI = dispatch_trio (VR_IRANGE, VR_FRANGE, VR_IRANGE); +const unsigned RO_IFF = dispatch_trio (VR_IRANGE, VR_FRANGE, VR_FRANGE); +const unsigned RO_FFF = dispatch_trio (VR_FRANGE, VR_FRANGE, VR_FRANGE); +const unsigned RO_FIF = dispatch_trio (VR_FRANGE, VR_IRANGE, VR_FRANGE); +const unsigned RO_FII = dispatch_trio (VR_FRANGE, VR_IRANGE, VR_IRANGE); + +// Return a dispatch value for parameter types LHS, OP1 and OP2. + +unsigned +range_op_handler::dispatch_kind (const vrange &lhs, const vrange &op1, + const vrange& op2) const +{ + return dispatch_trio (lhs.m_discriminator, op1.m_discriminator, + op2.m_discriminator); +} + +// Dispatch a call to fold_range based on the types of R, LH and RH. + +bool +range_op_handler::fold_range (vrange &r, tree type, + const vrange &lh, + const vrange &rh, + relation_trio rel) const +{ + gcc_checking_assert (m_operator); + switch (dispatch_kind (r, lh, rh)) + { + case RO_III: + return m_operator->fold_range (as_a (r), type, + as_a (lh), + as_a (rh), rel); + case RO_IFI: + return m_operator->fold_range (as_a (r), type, + as_a (lh), + as_a (rh), rel); + case RO_IFF: + return m_operator->fold_range (as_a (r), type, + as_a (lh), + as_a (rh), rel); + case RO_FFF: + return m_operator->fold_range (as_a (r), type, + as_a (lh), + as_a (rh), rel); + default: + return false; + } +} + +// Dispatch a call to op1_range based on the types of R, LHS and OP2. + +bool +range_op_handler::op1_range (vrange &r, tree type, + const vrange &lhs, + const vrange &op2, + relation_trio rel) const +{ + gcc_checking_assert (m_operator); + + if (lhs.undefined_p ()) + return false; + switch (dispatch_kind (r, lhs, op2)) + { + case RO_III: + return m_operator->op1_range (as_a (r), type, + as_a (lhs), + as_a (op2), rel); + case RO_FIF: + return m_operator->op1_range (as_a (r), type, + as_a (lhs), + as_a (op2), rel); + case RO_FFF: + return m_operator->op1_range (as_a (r), type, + as_a (lhs), + as_a (op2), rel); + default: + return false; + } +} + +// Dispatch a call to op2_range based on the types of R, LHS and OP1. + +bool +range_op_handler::op2_range (vrange &r, tree type, + const vrange &lhs, + const vrange &op1, + relation_trio rel) const +{ + gcc_checking_assert (m_operator); + if (lhs.undefined_p ()) + return false; + + switch (dispatch_kind (r, lhs, op1)) + { + case RO_III: + return m_operator->op2_range (as_a (r), type, + as_a (lhs), + as_a (op1), rel); + case RO_FIF: + return m_operator->op2_range (as_a (r), type, + as_a (lhs), + as_a (op1), rel); + case RO_FFF: + return m_operator->op2_range (as_a (r), type, + as_a (lhs), + as_a (op1), rel); + default: + return false; + } +} + +// Dispatch a call to lhs_op1_relation based on the types of LHS, OP1 and OP2. + +relation_kind +range_op_handler::lhs_op1_relation (const vrange &lhs, + const vrange &op1, + const vrange &op2, + relation_kind rel) const +{ + gcc_checking_assert (m_operator); + + switch (dispatch_kind (lhs, op1, op2)) + { + case RO_III: + return m_operator->lhs_op1_relation (as_a (lhs), + as_a (op1), + as_a (op2), rel); + case RO_IFF: + return m_operator->lhs_op1_relation (as_a (lhs), + as_a (op1), + as_a (op2), rel); + case RO_FFF: + return m_operator->lhs_op1_relation (as_a (lhs), + as_a (op1), + as_a (op2), rel); + default: + return VREL_VARYING; + } +} + +// Dispatch a call to lhs_op2_relation based on the types of LHS, OP1 and OP2. + +relation_kind +range_op_handler::lhs_op2_relation (const vrange &lhs, + const vrange &op1, + const vrange &op2, + relation_kind rel) const +{ + gcc_checking_assert (m_operator); + switch (dispatch_kind (lhs, op1, op2)) + { + case RO_III: + return m_operator->lhs_op2_relation (as_a (lhs), + as_a (op1), + as_a (op2), rel); + case RO_IFF: + return m_operator->lhs_op2_relation (as_a (lhs), + as_a (op1), + as_a (op2), rel); + case RO_FFF: + return m_operator->lhs_op2_relation (as_a (lhs), + as_a (op1), + as_a (op2), rel); + default: + return VREL_VARYING; + } +} + +// Dispatch a call to op1_op2_relation based on the type of LHS. + +relation_kind +range_op_handler::op1_op2_relation (const vrange &lhs) const +{ + gcc_checking_assert (m_operator); + switch (dispatch_kind (lhs, lhs, lhs)) + { + case RO_III: + return m_operator->op1_op2_relation (as_a (lhs)); + + case RO_FFF: + return m_operator->op1_op2_relation (as_a (lhs)); + + default: + return VREL_VARYING; + } +} + + // Convert irange bitmasks into a VALUE MASK pair suitable for calling CCP. static void @@ -4612,33 +4862,6 @@ pointer_or_operator::wi_fold (irange &r, tree type, r.set_varying (type); } -// Return a pointer to the range_operator instance, if there is one -// associated with tree_code CODE. - -range_operator * -range_op_table::operator[] (enum tree_code code) -{ - gcc_checking_assert (code > 0 && code < MAX_TREE_CODES); - return m_range_tree[code]; -} - -// Add OP to the handler table for CODE. - -void -range_op_table::set (enum tree_code code, range_operator &op) -{ - gcc_checking_assert (m_range_tree[code] == NULL); - m_range_tree[code] = &op; -} - -// Instantiate a range op table for integral operations. - -class integral_table : public range_op_table -{ -public: - integral_table (); -} integral_tree_table; - integral_table::integral_table () { set (EQ_EXPR, op_equal); @@ -4682,14 +4905,6 @@ integral_table::integral_table () set (ADDR_EXPR, op_addr); } -// Instantiate a range op table for pointer operations. - -class pointer_table : public range_op_table -{ -public: - pointer_table (); -} pointer_tree_table; - pointer_table::pointer_table () { set (BIT_AND_EXPR, op_pointer_and); @@ -4714,191 +4929,6 @@ pointer_table::pointer_table () set (BIT_XOR_EXPR, op_bitwise_xor); } -// The tables are hidden and accessed via a simple extern function. - -static inline range_operator * -get_handler (enum tree_code code, tree type) -{ - // First check if there is a pointer specialization. - if (POINTER_TYPE_P (type)) - return pointer_tree_table[code]; - if (INTEGRAL_TYPE_P (type)) - return integral_tree_table[code]; - return NULL; -} - -// Return the floating point operator for CODE or NULL if none available. - -static inline range_operator * -get_float_handler (enum tree_code code, tree) -{ - return (*floating_tree_table)[code]; -} - -void -range_op_handler::set_op_handler (tree_code code, tree type) -{ - if (irange::supports_p (type)) - { - m_float = NULL; - m_int = get_handler (code, type); - m_valid = m_int != NULL; - } - else if (frange::supports_p (type)) - { - m_int = NULL; - m_float = get_float_handler (code, type); - m_valid = m_float != NULL; - } - else - { - m_int = NULL; - m_float = NULL; - m_valid = false; - } -} - -range_op_handler::range_op_handler () -{ - m_int = NULL; - m_float = NULL; - m_valid = false; -} - -range_op_handler::range_op_handler (tree_code code, tree type) -{ - set_op_handler (code, type); -} - - -bool -range_op_handler::fold_range (vrange &r, tree type, - const vrange &lh, - const vrange &rh, - relation_trio rel) const -{ - gcc_checking_assert (m_valid); - if (m_int) - return m_int->fold_range (as_a (r), type, - as_a (lh), - as_a (rh), rel); - - if (is_a (r)) - { - if (is_a (rh)) - return m_float->fold_range (as_a (r), type, - as_a (lh), - as_a (rh), rel); - else - return m_float->fold_range (as_a (r), type, - as_a (lh), - as_a (rh), rel); - } - return m_float->fold_range (as_a (r), type, - as_a (lh), - as_a (rh), rel); -} - -bool -range_op_handler::op1_range (vrange &r, tree type, - const vrange &lhs, - const vrange &op2, - relation_trio rel) const -{ - gcc_checking_assert (m_valid); - - if (lhs.undefined_p ()) - return false; - if (m_int) - return m_int->op1_range (as_a (r), type, - as_a (lhs), - as_a (op2), rel); - - if (is_a (lhs)) - return m_float->op1_range (as_a (r), type, - as_a (lhs), - as_a (op2), rel); - return m_float->op1_range (as_a (r), type, - as_a (lhs), - as_a (op2), rel); -} - -bool -range_op_handler::op2_range (vrange &r, tree type, - const vrange &lhs, - const vrange &op1, - relation_trio rel) const -{ - gcc_checking_assert (m_valid); - if (lhs.undefined_p ()) - return false; - if (m_int) - return m_int->op2_range (as_a (r), type, - as_a (lhs), - as_a (op1), rel); - - if (is_a (lhs)) - return m_float->op2_range (as_a (r), type, - as_a (lhs), - as_a (op1), rel); - return m_float->op2_range (as_a (r), type, - as_a (lhs), - as_a (op1), rel); -} - -relation_kind -range_op_handler::lhs_op1_relation (const vrange &lhs, - const vrange &op1, - const vrange &op2, - relation_kind rel) const -{ - gcc_checking_assert (m_valid); - if (m_int) - return m_int->lhs_op1_relation (as_a (lhs), - as_a (op1), - as_a (op2), rel); - - if (is_a (lhs)) - return m_float->lhs_op1_relation (as_a (lhs), - as_a (op1), - as_a (op2), rel); - return m_float->lhs_op1_relation (as_a (lhs), - as_a (op1), - as_a (op2), rel); -} - -relation_kind -range_op_handler::lhs_op2_relation (const vrange &lhs, - const vrange &op1, - const vrange &op2, - relation_kind rel) const -{ - gcc_checking_assert (m_valid); - if (m_int) - return m_int->lhs_op2_relation (as_a (lhs), - as_a (op1), - as_a (op2), rel); - - if (is_a (lhs)) - return m_float->lhs_op2_relation (as_a (lhs), - as_a (op1), - as_a (op2), rel); - return m_float->lhs_op2_relation (as_a (lhs), - as_a (op1), - as_a (op2), rel); -} - -relation_kind -range_op_handler::op1_op2_relation (const vrange &lhs) const -{ - gcc_checking_assert (m_valid); - if (m_int) - return m_int->op1_op2_relation (as_a (lhs)); - if (is_a (lhs)) - return m_float->op1_op2_relation (as_a (lhs)); - return m_float->op1_op2_relation (as_a (lhs)); -} - // Cast the range in R to TYPE. bool diff --git a/gcc/range-op.h b/gcc/range-op.h index cad16f4cd20..7af58736c3f 100644 --- a/gcc/range-op.h +++ b/gcc/range-op.h @@ -186,7 +186,7 @@ class range_op_handler public: range_op_handler (); range_op_handler (enum tree_code code, tree type); - inline operator bool () const { return m_valid; } + inline operator bool () const { return m_operator != NULL; } bool fold_range (vrange &r, tree type, const vrange &lh, @@ -210,10 +210,10 @@ public: relation_kind = VREL_VARYING) const; relation_kind op1_op2_relation (const vrange &lhs) const; protected: + unsigned dispatch_kind (const vrange &lhs, const vrange &op1, + const vrange& op2) const; void set_op_handler (enum tree_code code, tree type); - bool m_valid; - range_operator *m_int; - range_operator *m_float; + range_operator *m_operator; }; extern bool range_cast (vrange &, tree type); @@ -296,6 +296,25 @@ private: }; +// Return a pointer to the range_operator instance, if there is one +// associated with tree_code CODE. + +inline range_operator * +range_op_table::operator[] (enum tree_code code) +{ + gcc_checking_assert (code > 0 && code < MAX_TREE_CODES); + return m_range_tree[code]; +} + +// Add OP to the handler table for CODE. + +inline void +range_op_table::set (enum tree_code code, range_operator &op) +{ + gcc_checking_assert (m_range_tree[code] == NULL); + m_range_tree[code] = &op; +} + // This holds the range op table for floating point operations. extern range_op_table *floating_tree_table; diff --git a/gcc/value-range.h b/gcc/value-range.h index 2b4ebabe7c8..9103e9c41c7 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -77,6 +77,7 @@ class GTY((user)) vrange template friend bool is_a (vrange &); friend class Value_Range; friend void streamer_write_vrange (struct output_block *, const vrange &); + friend class range_op_handler; public: virtual void accept (const class vrange_visitor &v) const = 0; virtual void set (tree, tree, value_range_kind = VR_RANGE); -- 2.40.1