Richi has asked the we break the wide-int patch so that the individual port and front end maintainers can review their parts without have to go through the entire patch. This patch covers the C++ front end.
Ok?
cp: * call.c: Include wide-int.h. (type_passed_as): Use INT_CST_LT instead of INT_CST_LT_UNSIGNED. (convert_for_arg_passing): Likewise. * class.c: Include wide-int.h. (end_of_class): Use INT_CST_LT instead of INT_CST_LT_UNSIGNED. (include_empty_classes): Likewise * cvt.c: Include wide-int.h. (ignore_overflows): Use wide_int_to_tree. * decl.c: Include wide-int.h. (check_array_designated_initializer): Use wide-int interfaces. (finish_enum_value_list): Use signop. (build_enumerator): Use wide-int interfaces. * init.c: Include wide-int.h. (build_new_1): Use wide-int interfaces. * mangle.c: Include wide-int.h. (write_integer_cst): Use wide-int interfaces. (write_array_type): Likewise. * tree.c: Include wide-int.h. (cp_tree_equal): Use wide-int interfaces. * typeck2.c: Include wide-int.h. (process_init_constructor_array): Use wide-int interfaces. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index c529c16..00ebed4 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see #include "c-family/c-objc.h" #include "timevar.h" #include "cgraph.h" +#include "wide-int.h" /* The various kinds of conversion. */ @@ -6495,8 +6496,7 @@ type_passed_as (tree type) else if (targetm.calls.promote_prototypes (type) && INTEGRAL_TYPE_P (type) && COMPLETE_TYPE_P (type) - && INT_CST_LT_UNSIGNED (TYPE_SIZE (type), - TYPE_SIZE (integer_type_node))) + && INT_CST_LT (TYPE_SIZE (type), TYPE_SIZE (integer_type_node))) type = integer_type_node; return type; @@ -6536,8 +6536,7 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain) else if (targetm.calls.promote_prototypes (type) && INTEGRAL_TYPE_P (type) && COMPLETE_TYPE_P (type) - && INT_CST_LT_UNSIGNED (TYPE_SIZE (type), - TYPE_SIZE (integer_type_node))) + && INT_CST_LT (TYPE_SIZE (type), TYPE_SIZE (integer_type_node))) val = cp_perform_integral_promotions (val, complain); if ((complain & tf_warning) && warn_suggest_attribute_format) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 00fec27..027d235 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see #include "hash-table.h" #include "gimple.h" #include "gimplify.h" +#include "wide-int.h" /* The number of nested classes being processed. If we are not in the scope of any class, this is zero. */ @@ -5831,7 +5832,7 @@ end_of_class (tree t, int include_virtuals_p) continue; offset = end_of_base (base_binfo); - if (INT_CST_LT_UNSIGNED (result, offset)) + if (INT_CST_LT (result, offset)) result = offset; } @@ -5841,7 +5842,7 @@ end_of_class (tree t, int include_virtuals_p) vec_safe_iterate (vbases, i, &base_binfo); i++) { offset = end_of_base (base_binfo); - if (INT_CST_LT_UNSIGNED (result, offset)) + if (INT_CST_LT (result, offset)) result = offset; } @@ -5921,7 +5922,7 @@ include_empty_classes (record_layout_info rli) CLASSTYPE_AS_BASE (rli->t) != NULL_TREE); rli_size = rli_size_unit_so_far (rli); if (TREE_CODE (rli_size) == INTEGER_CST - && INT_CST_LT_UNSIGNED (rli_size, eoc)) + && INT_CST_LT (rli_size, eoc)) { if (!abi_version_at_least (2)) /* In version 1 of the ABI, the size of a class that ends with diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 5264c5d..6d0e341 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "convert.h" #include "decl.h" #include "target.h" +#include "wide-int.h" static tree cp_convert_to_pointer (tree, tree, tsubst_flags_t); static tree convert_to_pointer_force (tree, tree, tsubst_flags_t); @@ -582,9 +583,7 @@ ignore_overflows (tree expr, tree orig) { gcc_assert (!TREE_OVERFLOW (orig)); /* Ensure constant sharing. */ - expr = build_int_cst_wide (TREE_TYPE (expr), - TREE_INT_CST_LOW (expr), - TREE_INT_CST_HIGH (expr)); + expr = wide_int_to_tree (TREE_TYPE (expr), expr); } return expr; } diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 500c81f..babfc88 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see #include "splay-tree.h" #include "plugin.h" #include "cgraph.h" +#include "wide-int.h" /* Possible cases of bad specifiers type used by bad_specifiers. */ enum bad_spec_place { @@ -4811,7 +4812,7 @@ check_array_designated_initializer (constructor_elt *ce, if (TREE_CODE (ce->index) == INTEGER_CST) { /* A C99 designator is OK if it matches the current index. */ - if (TREE_INT_CST_LOW (ce->index) == index) + if (wi::eq_p (ce->index, index)) return true; else sorry ("non-trivial designated initializers not supported"); @@ -12661,9 +12662,9 @@ finish_enum_value_list (tree enumtype) enumeration. We must do this before the type of MINNODE and MAXNODE are transformed, since tree_int_cst_min_precision relies on the TREE_TYPE of the value it is passed. */ - bool unsignedp = tree_int_cst_sgn (minnode) >= 0; - int lowprec = tree_int_cst_min_precision (minnode, unsignedp); - int highprec = tree_int_cst_min_precision (maxnode, unsignedp); + signop sgn = tree_int_cst_sgn (minnode) >= 0 ? UNSIGNED : SIGNED; + int lowprec = tree_int_cst_min_precision (minnode, sgn); + int highprec = tree_int_cst_min_precision (maxnode, sgn); int precision = MAX (lowprec, highprec); unsigned int itk; bool use_short_enum; @@ -12695,7 +12696,7 @@ finish_enum_value_list (tree enumtype) underlying_type = integer_types[itk]; if (underlying_type != NULL_TREE && TYPE_PRECISION (underlying_type) >= precision - && TYPE_UNSIGNED (underlying_type) == unsignedp) + && TYPE_SIGN (underlying_type) == sgn) break; } if (itk == itk_none) @@ -12742,12 +12743,11 @@ finish_enum_value_list (tree enumtype) = build_distinct_type_copy (underlying_type); TYPE_PRECISION (ENUM_UNDERLYING_TYPE (enumtype)) = precision; set_min_and_max_values_for_integral_type - (ENUM_UNDERLYING_TYPE (enumtype), precision, unsignedp); + (ENUM_UNDERLYING_TYPE (enumtype), precision, sgn); /* If -fstrict-enums, still constrain TYPE_MIN/MAX_VALUE. */ if (flag_strict_enums) - set_min_and_max_values_for_integral_type (enumtype, precision, - unsignedp); + set_min_and_max_values_for_integral_type (enumtype, precision, sgn); } else underlying_type = ENUM_UNDERLYING_TYPE (enumtype); @@ -12871,14 +12871,14 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc) value = error_mark_node; else { - double_int di = TREE_INT_CST (prev_value) - .add_with_sign (double_int_one, - false, &overflowed); + tree type = TREE_TYPE (prev_value); + signop sgn = TYPE_SIGN (type); + widest_int wi = wi::add (wi::to_widest (prev_value), 1, sgn, + &overflowed); if (!overflowed) { - tree type = TREE_TYPE (prev_value); - bool pos = TYPE_UNSIGNED (type) || !di.is_negative (); - if (!double_int_fits_to_tree_p (type, di)) + bool pos = !wi::neg_p (wi, sgn); + if (!wi::fits_to_tree_p (wi, type)) { unsigned int itk; for (itk = itk_int; itk != itk_none; itk++) @@ -12886,7 +12886,7 @@ build_enumerator (tree name, tree value, tree enumtype, location_t loc) type = integer_types[itk]; if (type != NULL_TREE && (pos || !TYPE_UNSIGNED (type)) - && double_int_fits_to_tree_p (type, di)) + && wi::fits_to_tree_p (wi, type)) break; } if (type && cxx_dialect < cxx11 @@ -12898,7 +12898,7 @@ incremented enumerator value is too large for %<long%>"); if (type == NULL_TREE) overflowed = true; else - value = double_int_to_tree (type, di); + value = wide_int_to_tree (type, wi); } if (overflowed) diff --git a/gcc/cp/init.c b/gcc/cp/init.c index fd43a4f..7b6f4e2 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "gimple.h" #include "gimplify.h" +#include "wide-int.h" static bool begin_init_stmts (tree *, tree *); static tree finish_init_stmts (bool, tree, tree); @@ -2246,10 +2247,10 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, /* For arrays, a bounds checks on the NELTS parameter. */ tree outer_nelts_check = NULL_TREE; bool outer_nelts_from_type = false; - double_int inner_nelts_count = double_int_one; + offset_int inner_nelts_count = 1; tree alloc_call, alloc_expr; /* Size of the inner array elements. */ - double_int inner_size; + offset_int inner_size; /* The address returned by the call to "operator new". This node is a VAR_DECL and is therefore reusable. */ tree alloc_node; @@ -2304,9 +2305,8 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, if (TREE_CODE (inner_nelts_cst) == INTEGER_CST) { bool overflow; - double_int result = TREE_INT_CST (inner_nelts_cst) - .mul_with_sign (inner_nelts_count, - false, &overflow); + offset_int result = wi::mul (wi::to_offset (inner_nelts_cst), + inner_nelts_count, SIGNED, &overflow); if (overflow) { if (complain & tf_error) @@ -2408,42 +2408,40 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, { /* Maximum available size in bytes. Half of the address space minus the cookie size. */ - double_int max_size - = double_int_one.llshift (TYPE_PRECISION (sizetype) - 1, - HOST_BITS_PER_DOUBLE_INT); + offset_int max_size + = wi::set_bit_in_zero <offset_int> (TYPE_PRECISION (sizetype) - 1); /* Maximum number of outer elements which can be allocated. */ - double_int max_outer_nelts; + offset_int max_outer_nelts; tree max_outer_nelts_tree; gcc_assert (TREE_CODE (size) == INTEGER_CST); cookie_size = targetm.cxx.get_cookie_size (elt_type); gcc_assert (TREE_CODE (cookie_size) == INTEGER_CST); - gcc_checking_assert (TREE_INT_CST (cookie_size).ult (max_size)); + gcc_checking_assert (wi::ltu_p (wi::to_offset (cookie_size), max_size)); /* Unconditionally subtract the cookie size. This decreases the maximum object size and is safe even if we choose not to use a cookie after all. */ - max_size -= TREE_INT_CST (cookie_size); + max_size -= wi::to_offset (cookie_size); bool overflow; - inner_size = TREE_INT_CST (size) - .mul_with_sign (inner_nelts_count, false, &overflow); - if (overflow || inner_size.ugt (max_size)) + inner_size = wi::mul (wi::to_offset (size), inner_nelts_count, SIGNED, + &overflow); + if (overflow || wi::gtu_p (inner_size, max_size)) { if (complain & tf_error) error ("size of array is too large"); return error_mark_node; } - max_outer_nelts = max_size.udiv (inner_size, TRUNC_DIV_EXPR); + + max_outer_nelts = wi::udiv_trunc (max_size, inner_size); /* Only keep the top-most seven bits, to simplify encoding the constant in the instruction stream. */ { - unsigned shift = HOST_BITS_PER_DOUBLE_INT - 7 - - (max_outer_nelts.high ? clz_hwi (max_outer_nelts.high) - : (HOST_BITS_PER_WIDE_INT + clz_hwi (max_outer_nelts.low))); - max_outer_nelts - = max_outer_nelts.lrshift (shift, HOST_BITS_PER_DOUBLE_INT) - .llshift (shift, HOST_BITS_PER_DOUBLE_INT); + unsigned shift = (max_outer_nelts.get_precision ()) - 7 + - wi::clz (max_outer_nelts); + max_outer_nelts = wi::lshift (wi::lrshift (max_outer_nelts, shift), + shift); } - max_outer_nelts_tree = double_int_to_tree (sizetype, max_outer_nelts); + max_outer_nelts_tree = wide_int_to_tree (sizetype, max_outer_nelts); size = size_binop (MULT_EXPR, size, convert (sizetype, nelts)); outer_nelts_check = fold_build2 (LE_EXPR, boolean_type_node, @@ -2524,7 +2522,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, cookie_size = NULL_TREE; /* No size arithmetic necessary, so the size check is not needed. */ - if (outer_nelts_check != NULL && inner_size.is_one ()) + if (outer_nelts_check != NULL && inner_size == 1) outer_nelts_check = NULL_TREE; } /* Perform the overflow check. */ @@ -2569,7 +2567,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, cookie_size = NULL_TREE; /* No size arithmetic necessary, so the size check is not needed. */ - if (outer_nelts_check != NULL && inner_size.is_one ()) + if (outer_nelts_check != NULL && inner_size == 1) outer_nelts_check = NULL_TREE; } diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 8a24d6c..31f78c7 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -57,6 +57,7 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "target.h" #include "cgraph.h" +#include "wide-int.h" /* Debugging support. */ @@ -1504,8 +1505,8 @@ static inline void write_integer_cst (const tree cst) { int sign = tree_int_cst_sgn (cst); - - if (TREE_INT_CST_HIGH (cst) + (sign < 0)) + widest_int abs_value = wi::abs (wi::to_widest (cst)); + if (!wi::fits_uhwi_p (abs_value)) { /* A bignum. We do this in chunks, each of which fits in a HOST_WIDE_INT. */ @@ -1531,8 +1532,7 @@ write_integer_cst (const tree cst) type = c_common_signed_or_unsigned_type (1, TREE_TYPE (cst)); base = build_int_cstu (type, chunk); - n = build_int_cst_wide (type, - TREE_INT_CST_LOW (cst), TREE_INT_CST_HIGH (cst)); + n = wide_int_to_tree (type, cst); if (sign < 0) { @@ -1559,14 +1559,9 @@ write_integer_cst (const tree cst) else { /* A small num. */ - unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (cst); - if (sign < 0) - { - write_char ('n'); - low = -low; - } - write_unsigned_number (low); + write_char ('n'); + write_unsigned_number (abs_value.to_uhwi ()); } } @@ -3225,12 +3220,12 @@ write_array_type (const tree type) { /* The ABI specifies that we should mangle the number of elements in the array, not the largest allowed index. */ - double_int dmax = tree_to_double_int (max) + double_int_one; + offset_int wmax = wi::to_offset (max) + 1; /* Truncate the result - this will mangle [0, SIZE_INT_MAX] number of elements as zero. */ - dmax = dmax.zext (TYPE_PRECISION (TREE_TYPE (max))); - gcc_assert (dmax.fits_uhwi ()); - write_unsigned_number (dmax.low); + wmax = wi::zext (wmax, TYPE_PRECISION (TREE_TYPE (max))); + gcc_assert (wi::fits_uhwi_p (wmax)); + write_unsigned_number (wmax.to_uhwi ()); } else { diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index a990a79..2e3b586 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple.h" #include "gimplify.h" #include "hash-table.h" +#include "wide-int.h" static tree bot_manip (tree *, int *, void *); static tree bot_replace (tree *, int *, void *); @@ -2605,8 +2606,7 @@ cp_tree_equal (tree t1, tree t2) switch (code1) { case INTEGER_CST: - return TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2) - && TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2); + return wi::to_widest (t1) == wi::to_widest (t2); case REAL_CST: return REAL_VALUES_EQUAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2)); diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 0f3b01d..5040226 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "cp-tree.h" #include "flags.h" #include "diagnostic-core.h" +#include "wide-int.h" static tree process_init_constructor (tree type, tree init, tsubst_flags_t complain); @@ -1122,12 +1123,10 @@ process_init_constructor_array (tree type, tree init, { tree domain = TYPE_DOMAIN (type); if (domain && TREE_CONSTANT (TYPE_MAX_VALUE (domain))) - len = (tree_to_double_int (TYPE_MAX_VALUE (domain)) - - tree_to_double_int (TYPE_MIN_VALUE (domain)) - + double_int_one) - .ext (TYPE_PRECISION (TREE_TYPE (domain)), - TYPE_UNSIGNED (TREE_TYPE (domain))) - .low; + len = wi::ext (wi::to_offset (TYPE_MAX_VALUE (domain)) + - wi::to_offset (TYPE_MIN_VALUE (domain)) + 1, + TYPE_PRECISION (TREE_TYPE (domain)), + TYPE_SIGN (TREE_TYPE (domain))).to_uhwi (); else unbounded = true; /* Take as many as there are. */ }