From 6d3b6847bcb36221185a6259d19d743f4cfe1b5a Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Sat, 10 Jun 2023 17:06:36 -0400 Subject: [PATCH 16/17] Provide interface for non-standard operators. THis removes the hack introduced for WIDEN_MULT which exported a pointer to the operator and the gimple-range-op.cc set the operator to this pointer whenn it was appropriate. Instead, we simple change the range-op table to be unsigned indexed, and add new opcodes to the end of the table, allowing them to be indexed directly via range_op_handler::range_op. * gimple-range-op.cc (gimple_range_op_handler::maybe_non_standard): Use range_op_handler directly. * range-op.cc (range_op_handler::range_op_handler): Unsigned param instead of tree-code. (ptr_op_widen_plus_signed): Delete. (ptr_op_widen_plus_unsigned): Delete. (ptr_op_widen_mult_signed): Delete. (ptr_op_widen_mult_unsigned): Delete. (range_op_table::initialize_integral_ops): Add new opcodes. * range-op.h (range_op_handler): Use unsigned. (OP_WIDEN_MULT_SIGNED): New. (OP_WIDEN_MULT_UNSIGNED): New. (OP_WIDEN_PLUS_SIGNED): New. (OP_WIDEN_PLUS_UNSIGNED): New. (RANGE_OP_TABLE_SIZE): New. (range_op_table::operator []): Use unsigned. (range_op_table::set): Use unsigned. (m_range_tree): Make unsigned. (ptr_op_widen_mult_signed): Remove. (ptr_op_widen_mult_unsigned): Remove. (ptr_op_widen_plus_signed): Remove. (ptr_op_widen_plus_unsigned): Remove. --- gcc/gimple-range-op.cc | 11 +++++++---- gcc/range-op.cc | 11 ++++++----- gcc/range-op.h | 26 ++++++++++++++++---------- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc index 021a9108ecf..72c7b866f90 100644 --- a/gcc/gimple-range-op.cc +++ b/gcc/gimple-range-op.cc @@ -1168,8 +1168,11 @@ public: void gimple_range_op_handler::maybe_non_standard () { - range_operator *signed_op = ptr_op_widen_mult_signed; - range_operator *unsigned_op = ptr_op_widen_mult_unsigned; + range_op_handler signed_op (OP_WIDEN_MULT_SIGNED); + gcc_checking_assert (signed_op); + range_op_handler unsigned_op (OP_WIDEN_MULT_UNSIGNED); + gcc_checking_assert (unsigned_op); + if (gimple_code (m_stmt) == GIMPLE_ASSIGN) switch (gimple_assign_rhs_code (m_stmt)) { @@ -1195,9 +1198,9 @@ gimple_range_op_handler::maybe_non_standard () std::swap (m_op1, m_op2); if (signed1 || signed2) - m_operator = signed_op; + m_operator = signed_op.range_op (); else - m_operator = unsigned_op; + m_operator = unsigned_op.range_op (); break; } default: diff --git a/gcc/range-op.cc b/gcc/range-op.cc index a271e00fa07..8a661fdb042 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -135,7 +135,7 @@ range_op_handler::range_op_handler () // Create a range_op_handler for CODE. Use a default operatoer if CODE // does not have an entry. -range_op_handler::range_op_handler (tree_code code) +range_op_handler::range_op_handler (unsigned code) { m_operator = operator_table[code]; if (!m_operator) @@ -1726,7 +1726,6 @@ public: const wide_int &rh_lb, const wide_int &rh_ub) const; } op_widen_plus_signed; -range_operator *ptr_op_widen_plus_signed = &op_widen_plus_signed; void operator_widen_plus_signed::wi_fold (irange &r, tree type, @@ -1760,7 +1759,6 @@ public: const wide_int &rh_lb, const wide_int &rh_ub) const; } op_widen_plus_unsigned; -range_operator *ptr_op_widen_plus_unsigned = &op_widen_plus_unsigned; void operator_widen_plus_unsigned::wi_fold (irange &r, tree type, @@ -2184,7 +2182,6 @@ public: const wide_int &rh_ub) const; } op_widen_mult_signed; -range_operator *ptr_op_widen_mult_signed = &op_widen_mult_signed; void operator_widen_mult_signed::wi_fold (irange &r, tree type, @@ -2217,7 +2214,6 @@ public: const wide_int &rh_ub) const; } op_widen_mult_unsigned; -range_operator *ptr_op_widen_mult_unsigned = &op_widen_mult_unsigned; void operator_widen_mult_unsigned::wi_fold (irange &r, tree type, @@ -4298,6 +4294,11 @@ range_op_table::initialize_integral_ops () set (IMAGPART_EXPR, op_unknown); set (REALPART_EXPR, op_unknown); set (ABSU_EXPR, op_absu); + set (OP_WIDEN_MULT_SIGNED, op_widen_mult_signed); + set (OP_WIDEN_MULT_UNSIGNED, op_widen_mult_unsigned); + set (OP_WIDEN_PLUS_SIGNED, op_widen_plus_signed); + set (OP_WIDEN_PLUS_UNSIGNED, op_widen_plus_unsigned); + } #if CHECKING_P diff --git a/gcc/range-op.h b/gcc/range-op.h index 8243258eea5..3602bc4e123 100644 --- a/gcc/range-op.h +++ b/gcc/range-op.h @@ -185,7 +185,7 @@ class range_op_handler { public: range_op_handler (); - range_op_handler (enum tree_code code); + range_op_handler (unsigned); operator bool () const; range_operator *range_op () const; @@ -262,31 +262,37 @@ extern void wi_set_zero_nonzero_bits (tree type, wide_int &maybe_nonzero, wide_int &mustbe_nonzero); +// These are extra operators that do not fit in the normal scheme of things. +// Add them to the end of the tree-code vector, and provide a name for +// each allowing for easy access when required. + +#define OP_WIDEN_MULT_SIGNED ((unsigned) MAX_TREE_CODES) +#define OP_WIDEN_MULT_UNSIGNED ((unsigned) MAX_TREE_CODES + 1) +#define OP_WIDEN_PLUS_SIGNED ((unsigned) MAX_TREE_CODES + 2) +#define OP_WIDEN_PLUS_UNSIGNED ((unsigned) MAX_TREE_CODES + 3) +#define RANGE_OP_TABLE_SIZE ((unsigned) MAX_TREE_CODES + 4) + // This implements the range operator tables as local objects. class range_op_table { public: range_op_table (); - inline range_operator *operator[] (enum tree_code code) + inline range_operator *operator[] (unsigned code) { - gcc_checking_assert (code >= 0 && code < MAX_TREE_CODES); + gcc_checking_assert (code < RANGE_OP_TABLE_SIZE); return m_range_tree[code]; } protected: - inline void set (enum tree_code code, range_operator &op) + inline void set (unsigned code, range_operator &op) { + gcc_checking_assert (code < RANGE_OP_TABLE_SIZE); gcc_checking_assert (m_range_tree[code] == NULL); m_range_tree[code] = &op; } - range_operator *m_range_tree[MAX_TREE_CODES]; + range_operator *m_range_tree[RANGE_OP_TABLE_SIZE]; void initialize_integral_ops (); void initialize_pointer_ops (); void initialize_float_ops (); }; - -extern range_operator *ptr_op_widen_mult_signed; -extern range_operator *ptr_op_widen_mult_unsigned; -extern range_operator *ptr_op_widen_plus_signed; -extern range_operator *ptr_op_widen_plus_unsigned; #endif // GCC_RANGE_OP_H -- 2.40.1