From patchwork Fri Apr 29 09:02:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aldy Hernandez X-Patchwork-Id: 53344 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 66121385735C for ; Fri, 29 Apr 2022 09:10:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 66121385735C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1651223433; bh=mXD/OlF9dXXeJDgFuB3EH9kGZMTyByIOIXxavfzO2EQ=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=BuLEdj6/M9RCTN9he6KvvhwGTQcV/0vxpx8/i1RSsrKobLPaq0C2lHEzoEQOJNCqc 1i7t8hDlaJgH7itgAEYqG+eHW1Zsvo7T8kMJkaPEE7nFusSylk1sUIybsIYrFezcGM 2UhpINGYvT1Ix54VNxWdIj+SCNyv06kYcB5qJyNw= 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 8B266385736E for ; Fri, 29 Apr 2022 09:08:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8B266385736E Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-67-0pN72GGcMaugSwoulNQCwQ-1; Fri, 29 Apr 2022 05:07:58 -0400 X-MC-Unique: 0pN72GGcMaugSwoulNQCwQ-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 4D4E23C01B87 for ; Fri, 29 Apr 2022 09:07:55 +0000 (UTC) Received: from abulafia (unknown [10.39.192.47]) by smtp.corp.redhat.com (Postfix) with ESMTPS id AD32014A5066; Fri, 29 Apr 2022 09:07:54 +0000 (UTC) Received: from abulafia (localhost [127.0.0.1]) by abulafia (8.17.1/8.17.1) with ESMTPS id 23T97q1g731759 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 29 Apr 2022 11:07:52 +0200 Received: (from aldyh@localhost) by abulafia (8.17.1/8.17.1/Submit) id 23T97q1h731711; Fri, 29 Apr 2022 11:07:52 +0200 To: GCC patches Subject: [COMMITTED] Move common code from range-op.cc to header files. Date: Fri, 29 Apr 2022 11:02:36 +0200 Message-Id: <20220429090236.718140-5-aldyh@redhat.com> In-Reply-To: <20220429090236.718140-1-aldyh@redhat.com> References: <20220429090236.718140-1-aldyh@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.85 on 10.11.54.7 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-21.8 required=5.0 tests=BAYES_00, DKIM_INVALID, DKIM_SIGNED, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Aldy Hernandez via Gcc-patches From: Aldy Hernandez Reply-To: Aldy Hernandez Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" In preparation for the agnostication of ranger, this patch moves common code that can be shared with non-integer ranges (initially pointers) into the relevant header files. This is a relatively non-invasive change, as any changes that would need to be ported to GCC 12, would occur in the range-op entries themselves, not in the supporting glue which I'm moving. Tested and benchmarked on x86-64 Linux. gcc/ChangeLog: * range-op.cc (empty_range_varying): Move to range-op.h. (range_true): Move to range.h. (range_false): Same. (range_true_and_false): Same. (enum bool_range_state): Move to range-op.h. (relop_early_resolve): Same. (operator_equal::op1_op2_relation): Abstract code to... (equal_op1_op2_relation): ...here. (operator_not_equal::op1_op2_relation): Abstract code to... (not_equal_op1_op2_relation): ...here. (operator_lt::op1_op2_relation): Abstract code to... (lt_op1_op2_relation): ...here. (operator_le::op1_op2_relation): Abstract code to... (le_op1_op2_relation): ...here. (operator_gt::op1_op2_relation): Abstract code to... (gt_op1_op2_relation): ...here. (operator_ge::op1_op2_relation): Abstract code to... (ge_op1_op2_relation): ...here. (class range_op_table): Move to range-op.h. * range-op.h (equal_op1_op2_relation): Moved from range-op.cc. (not_equal_op1_op2_relation): Same. (lt_op1_op2_relation): Same. (le_op1_op2_relation): Same. (gt_op1_op2_relation): Same. (ge_op1_op2_relation): Same. (enum bool_range_state): Same. (get_bool_state): Same. (empty_range_varying): Same. (relop_early_resolve): Same. (class range_op_table): Same. * range.h (range_true): Same. (range_false): Same. (range_true_and_false): Same. --- gcc/range-op.cc | 140 +++++++++++++++--------------------------------- gcc/range-op.h | 72 +++++++++++++++++++++++++ gcc/range.h | 28 ++++++++++ 3 files changed, 143 insertions(+), 97 deletions(-) diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 464a1f839fd..fa962507b92 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -63,24 +63,6 @@ min_limit (const_tree type) return wi::min_value (TYPE_PRECISION (type) , TYPE_SIGN (type)); } -// If the range of either op1 or op2 is undefined, set the result to -// varying and return TRUE. If the caller truely cares about a result, -// they should pass in a varying if it has an undefined that it wants -// treated as a varying. - -inline bool -empty_range_varying (irange &r, tree type, - const irange &op1, const irange & op2) -{ - if (op1.undefined_p () || op2.undefined_p ()) - { - r.set_varying (type); - return true; - } - else - return false; -} - // Return false if shifting by OP is undefined behavior. Otherwise, return // true and the range it is to be shifted by. This allows trimming out of // undefined ranges, leaving only valid ranges if there are any. @@ -432,39 +414,10 @@ create_possibly_reversed_range (irange &r, tree type, r.set (wide_int_to_tree (type, new_lb), wide_int_to_tree (type, new_ub)); } -// Return an irange instance that is a boolean TRUE. - -static inline int_range<1> -range_true (tree type) -{ - unsigned prec = TYPE_PRECISION (type); - return int_range<1> (type, wi::one (prec), wi::one (prec)); -} - -// Return an irange instance that is a boolean FALSE. - -static inline int_range<1> -range_false (tree type) -{ - unsigned prec = TYPE_PRECISION (type); - return int_range<1> (type, wi::zero (prec), wi::zero (prec)); -} - -// Return an irange that covers both true and false. - -static inline int_range<1> -range_true_and_false (tree type) -{ - unsigned prec = TYPE_PRECISION (type); - return int_range<1> (type, wi::zero (prec), wi::one (prec)); -} - -enum bool_range_state { BRS_FALSE, BRS_TRUE, BRS_EMPTY, BRS_FULL }; - // Return the summary information about boolean range LHS. If EMPTY/FULL, // return the equivalent range for TYPE in R; if FALSE/TRUE, do nothing. -static bool_range_state +bool_range_state get_bool_state (irange &r, const irange &lhs, tree val_type) { // If there is no result, then this is unexecutable. @@ -488,37 +441,6 @@ get_bool_state (irange &r, const irange &lhs, tree val_type) return BRS_TRUE; } -// For relation opcodes, first try to see if the supplied relation -// forces a true or false result, and return that. -// Then check for undefined operands. If none of this applies, -// return false. - -static inline bool -relop_early_resolve (irange &r, tree type, const irange &op1, - const irange &op2, relation_kind rel, - relation_kind my_rel) -{ - // If known relation is a complete subset of this relation, always true. - if (relation_union (rel, my_rel) == my_rel) - { - r = range_true (type); - return true; - } - - // If known relation has no subset of this relation, always false. - if (relation_intersect (rel, my_rel) == VREL_EMPTY) - { - r = range_false (type); - return true; - } - - // If either operand is undefined, return VARYING. - if (empty_range_varying (r, type, op1, op2)) - return true; - - return false; -} - class operator_equal : public range_operator { @@ -541,7 +463,7 @@ public: // Check if the LHS range indicates a relation between OP1 and OP2. enum tree_code -operator_equal::op1_op2_relation (const irange &lhs) const +equal_op1_op2_relation (const irange &lhs) { if (lhs.undefined_p ()) return VREL_EMPTY; @@ -556,6 +478,12 @@ operator_equal::op1_op2_relation (const irange &lhs) const return VREL_NONE; } +enum tree_code +operator_equal::op1_op2_relation (const irange &lhs) const +{ + return equal_op1_op2_relation (lhs); +} + bool operator_equal::fold_range (irange &r, tree type, @@ -651,7 +579,7 @@ public: // Check if the LHS range indicates a relation between OP1 and OP2. enum tree_code -operator_not_equal::op1_op2_relation (const irange &lhs) const +not_equal_op1_op2_relation (const irange &lhs) { if (lhs.undefined_p ()) return VREL_EMPTY; @@ -666,6 +594,12 @@ operator_not_equal::op1_op2_relation (const irange &lhs) const return VREL_NONE; } +enum tree_code +operator_not_equal::op1_op2_relation (const irange &lhs) const +{ + return not_equal_op1_op2_relation (lhs); +} + bool operator_not_equal::fold_range (irange &r, tree type, const irange &op1, @@ -821,7 +755,7 @@ public: // Check if the LHS range indicates a relation between OP1 and OP2. enum tree_code -operator_lt::op1_op2_relation (const irange &lhs) const +lt_op1_op2_relation (const irange &lhs) { if (lhs.undefined_p ()) return VREL_EMPTY; @@ -836,6 +770,12 @@ operator_lt::op1_op2_relation (const irange &lhs) const return VREL_NONE; } +enum tree_code +operator_lt::op1_op2_relation (const irange &lhs) const +{ + return lt_op1_op2_relation (lhs); +} + bool operator_lt::fold_range (irange &r, tree type, const irange &op1, @@ -923,7 +863,7 @@ public: // Check if the LHS range indicates a relation between OP1 and OP2. enum tree_code -operator_le::op1_op2_relation (const irange &lhs) const +le_op1_op2_relation (const irange &lhs) { if (lhs.undefined_p ()) return VREL_EMPTY; @@ -938,6 +878,12 @@ operator_le::op1_op2_relation (const irange &lhs) const return VREL_NONE; } +enum tree_code +operator_le::op1_op2_relation (const irange &lhs) const +{ + return le_op1_op2_relation (lhs); +} + bool operator_le::fold_range (irange &r, tree type, const irange &op1, @@ -1025,7 +971,7 @@ public: // Check if the LHS range indicates a relation between OP1 and OP2. enum tree_code -operator_gt::op1_op2_relation (const irange &lhs) const +gt_op1_op2_relation (const irange &lhs) { if (lhs.undefined_p ()) return VREL_EMPTY; @@ -1040,6 +986,12 @@ operator_gt::op1_op2_relation (const irange &lhs) const return VREL_NONE; } +enum tree_code +operator_gt::op1_op2_relation (const irange &lhs) const +{ + return gt_op1_op2_relation (lhs); +} + bool operator_gt::fold_range (irange &r, tree type, @@ -1126,7 +1078,7 @@ public: // Check if the LHS range indicates a relation between OP1 and OP2. enum tree_code -operator_ge::op1_op2_relation (const irange &lhs) const +ge_op1_op2_relation (const irange &lhs) { if (lhs.undefined_p ()) return VREL_EMPTY; @@ -1141,6 +1093,12 @@ operator_ge::op1_op2_relation (const irange &lhs) const return VREL_NONE; } +enum tree_code +operator_ge::op1_op2_relation (const irange &lhs) const +{ + return ge_op1_op2_relation (lhs); +} + bool operator_ge::fold_range (irange &r, tree type, const irange &op1, @@ -3993,18 +3951,6 @@ pointer_or_operator::wi_fold (irange &r, tree type, r.set_varying (type); } -// This implements the range operator tables as local objects in this file. - -class range_op_table -{ -public: - inline range_operator *operator[] (enum tree_code code); -protected: - void set (enum tree_code code, range_operator &op); -private: - range_operator *m_range_tree[MAX_TREE_CODES]; -}; - // Return a pointer to the range_operator instance, if there is one // associated with tree_code CODE. diff --git a/gcc/range-op.h b/gcc/range-op.h index a51969c2211..c93eb844547 100644 --- a/gcc/range-op.h +++ b/gcc/range-op.h @@ -112,4 +112,76 @@ extern void wi_set_zero_nonzero_bits (tree type, wide_int &maybe_nonzero, wide_int &mustbe_nonzero); +// op1_op2_relation methods that are the same across irange and frange. +enum tree_code equal_op1_op2_relation (const irange &lhs); +enum tree_code not_equal_op1_op2_relation (const irange &lhs); +enum tree_code lt_op1_op2_relation (const irange &lhs); +enum tree_code le_op1_op2_relation (const irange &lhs); +enum tree_code gt_op1_op2_relation (const irange &lhs); +enum tree_code ge_op1_op2_relation (const irange &lhs); + +enum bool_range_state { BRS_FALSE, BRS_TRUE, BRS_EMPTY, BRS_FULL }; +bool_range_state get_bool_state (irange &r, const irange &lhs, tree val_type); + +// If the range of either op1 or op2 is undefined, set the result to +// varying and return TRUE. If the caller truely cares about a result, +// they should pass in a varying if it has an undefined that it wants +// treated as a varying. + +inline bool +empty_range_varying (irange &r, tree type, + const irange &op1, const irange & op2) +{ + if (op1.undefined_p () || op2.undefined_p ()) + { + r.set_varying (type); + return true; + } + else + return false; +} + +// For relation opcodes, first try to see if the supplied relation +// forces a true or false result, and return that. +// Then check for undefined operands. If none of this applies, +// return false. + +inline bool +relop_early_resolve (irange &r, tree type, const irange &op1, + const irange &op2, relation_kind rel, + relation_kind my_rel) +{ + // If known relation is a complete subset of this relation, always true. + if (relation_union (rel, my_rel) == my_rel) + { + r = range_true (type); + return true; + } + + // If known relation has no subset of this relation, always false. + if (relation_intersect (rel, my_rel) == VREL_EMPTY) + { + r = range_false (type); + return true; + } + + // If either operand is undefined, return VARYING. + if (empty_range_varying (r, type, op1, op2)) + return true; + + return false; +} + +// This implements the range operator tables as local objects. + +class range_op_table +{ +public: + range_operator *operator[] (enum tree_code code); +protected: + void set (enum tree_code code, range_operator &op); +private: + range_operator *m_range_tree[MAX_TREE_CODES]; +}; + #endif // GCC_RANGE_OP_H diff --git a/gcc/range.h b/gcc/range.h index 5eb784b2d54..5c70c66566c 100644 --- a/gcc/range.h +++ b/gcc/range.h @@ -25,4 +25,32 @@ value_range range_zero (tree type); value_range range_nonzero (tree type); value_range range_positives (tree type); value_range range_negatives (tree type); + +// Return an irange instance that is a boolean TRUE. + +static inline int_range<1> +range_true (tree type) +{ + unsigned prec = TYPE_PRECISION (type); + return int_range<1> (type, wi::one (prec), wi::one (prec)); +} + +// Return an irange instance that is a boolean FALSE. + +static inline int_range<1> +range_false (tree type) +{ + unsigned prec = TYPE_PRECISION (type); + return int_range<1> (type, wi::zero (prec), wi::zero (prec)); +} + +// Return an irange that covers both true and false. + +static inline int_range<1> +range_true_and_false (tree type) +{ + unsigned prec = TYPE_PRECISION (type); + return int_range<1> (type, wi::zero (prec), wi::one (prec)); +} + #endif // GCC_RANGE_H