public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Aldy Hernandez <aldyh@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-34] Move common code from range-op.cc to header files. Date: Fri, 29 Apr 2022 09:09:06 +0000 (GMT) [thread overview] Message-ID: <20220429090906.58CD53857344@sourceware.org> (raw) https://gcc.gnu.org/g:9eb38e88ce8003c0b852144da3c265b6785ede3c commit r13-34-g9eb38e88ce8003c0b852144da3c265b6785ede3c Author: Aldy Hernandez <aldyh@redhat.com> Date: Thu Apr 28 20:19:14 2022 +0200 Move common code from range-op.cc to header files. In preparation for the agnostication of ranger, this patch moves common code that can be shared between 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. Diff: --- 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); } \f -// 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
reply other threads:[~2022-04-29 9:09 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220429090906.58CD53857344@sourceware.org \ --to=aldyh@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).