[wide-int] Make trees more like rtxes
Richard Biener
rguenther@suse.de
Wed Oct 23 09:30:00 GMT 2013
On Tue, 22 Oct 2013, Richard Sandiford wrote:
> Hi Richard,
>
> As discussed on IRC yesterday, I'd misunderstood what you were asking for,
> and thought that we still wanted "maximum precision" to be the default for
> trees. This patch makes them behave like rtxes by default. E.g.:
>
> wi::add (t1, t2)
>
> requires trees t1 and t2 to have the same precision and produces a
> wide_int result.
>
> wi::add (t1, 1)
> wi::add (1, t1)
>
> still work but now produce a wide_int result that has the same precision
> as t1. On IRC you said:
>
> <richi> IMHO only addr_wide_int + addr_wide_int should give addr_wide_int
> ...
> <richi> addr_wide_int + tree would be disallowed or compute in 'tree' precision
>
> <richi> addr_wide_int + rtx is disallowed, right?
> <richi> so it should be disallowed for tree, too
>
> The patch does that by adding:
>
> wi::address (t)
>
> for when we want to extend tree t to addr_wide_int precision and:
>
> wi::extend (t)
>
> for when we want to extend it to max_wide_int precision. (Better names
> welcome.) These act just like addr_wide_int (t) and max_wide_int (t)
> would on current sources, except that they use the tree representation
> directly, so there's no copying.
Good. Better names - ah well, wi::to_max_wide_int (t) and
wi::to_addr_wide_int (t)? Btw, "addr_wide_int" is an odd name as it
has at least the precision of the maximum _bit_ offset possible, right?
So more like [bit_]offset_wide_int? Or just [bit_]offset_int?
And then wi::to_offset (t) and wi::to_max (t)?
> Making them like rtxes means that it's no longer possible to have:
>
> addr_wide_int foo = t;
>
> and:
>
> addr_wide_int (t)
>
> since the idea is that a bare "t" always means a number in t's precision,
> just like for rtxes. So one downside is that you need to write:
>
> addr_wide_int foo = wi::address (t);
>
> There aren't many places where we initialise a variable directly though.
> In some ways it might even be an advantage, because it makes the site of
> the extension obvious for:
>
> void foo (addr_wide_int);
> ...
> foo (t); // fails to compile
> foo (wi::address (t)); // OK
>
> E.g. there are some places where we always want to sign-extend instead
> of using TYPE_UNSIGNED (TREE_TYPE (t)).
Yes, having it obvious in the source where this happens is good.
> Most of the patch is mechanical and many of the "wi::address (...)"s
> and "wi::extend (...)"s reinstate "addr_wide_int (...)"s and
> "max_wide_int (...)"s from the initial implementation. Sorry for the
> run-around on this.
>
> One change I'd like to point out though is:
>
> @@ -7287,7 +7287,9 @@ native_encode_int (const_tree expr, unsi
> for (byte = 0; byte < total_bytes; byte++)
> {
> int bitpos = byte * BITS_PER_UNIT;
> - value = wi::extract_uhwi (expr, bitpos, BITS_PER_UNIT);
> + /* Extend EXPR according to TYPE_SIGN if the precision isn't a whole
> + number of bytes. */
> + value = wi::extract_uhwi (wi::extend (expr), bitpos, BITS_PER_UNIT);
>
> if (total_bytes > UNITS_PER_WORD)
> {
>
> I think this preserves the existing trunk behaviour but I wasn't sure
> whether it was supposed to work like that or whether upper bits should
> be zero.
I think the upper bits are undefined, the trunk native_interpret_int
does
result = double_int::from_buffer (ptr, total_bytes);
return double_int_to_tree (type, result);
where the call to double_int_to_tree re-extends according to the types
precision and sign. wide_int_to_tree doesn't though?
> This patch is purely about getting the semantics right. I'll try
> out some optimisation ideas if this is OK.
>
> The patch applies on top of the patch to make the upper bits undefined
> on read by default:
>
> http://gcc.gnu.org/ml/gcc-patches/2013-10/msg01610.html
>
> although I've since found one bug with that; the decompose routine should be:
>
> /* If an unsigned constant occupies a whole number of HWIs and has the
> upper bit set, its representation includes an extra zero HWI,
> so that the representation can be used for wider precisions.
> Trim the length if we're accessing the tree in its own precision. */
> if (__builtin_expect (len > max_len, 0))
> do
> len--;
> while (len > 1 && val[len - 1] == -1 && val[len - 2] < 0);
> ^^^^^^^^^^^^^^^^^^^^
>
> Tested on x86_64-linux-gnu and powerpc64-linux-gnu. OK for wide-int?
Ok.
Thanks,
Richard.
> Thanks,
> Richard
>
>
> Index: gcc/alias.c
> ===================================================================
> --- gcc/alias.c 2013-10-22 10:18:04.416965373 +0100
> +++ gcc/alias.c 2013-10-22 10:18:20.376102089 +0100
> @@ -2352,9 +2352,9 @@ adjust_offset_for_component_ref (tree x,
> return;
> }
>
> - woffset = xoffset;
> - woffset += wi::udiv_trunc (addr_wide_int (DECL_FIELD_BIT_OFFSET (field)),
> - BITS_PER_UNIT);
> + woffset = (wi::address (xoffset)
> + + wi::udiv_trunc (wi::address (DECL_FIELD_BIT_OFFSET (field)),
> + BITS_PER_UNIT));
>
> if (!wi::fits_uhwi_p (woffset))
> {
> Index: gcc/cp/init.c
> ===================================================================
> --- gcc/cp/init.c 2013-10-22 10:18:04.417965382 +0100
> +++ gcc/cp/init.c 2013-10-22 10:18:20.376102089 +0100
> @@ -2300,7 +2300,7 @@ build_new_1 (vec<tree, va_gc> **placemen
> if (TREE_CODE (inner_nelts_cst) == INTEGER_CST)
> {
> bool overflow;
> - addr_wide_int result = wi::mul (addr_wide_int (inner_nelts_cst),
> + addr_wide_int result = wi::mul (wi::address (inner_nelts_cst),
> inner_nelts_count, SIGNED,
> &overflow);
> if (overflow)
> @@ -2417,9 +2417,9 @@ build_new_1 (vec<tree, va_gc> **placemen
> /* 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 -= cookie_size;
> + max_size -= wi::address (cookie_size);
> bool overflow;
> - inner_size = wi::mul (addr_wide_int (size), inner_nelts_count, SIGNED,
> + inner_size = wi::mul (wi::address (size), inner_nelts_count, SIGNED,
> &overflow);
> if (overflow || wi::gtu_p (inner_size, max_size))
> {
> Index: gcc/cp/mangle.c
> ===================================================================
> --- gcc/cp/mangle.c 2013-10-22 10:18:04.418965390 +0100
> +++ gcc/cp/mangle.c 2013-10-22 10:18:20.377102098 +0100
> @@ -3223,7 +3223,7 @@ 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. */
> - addr_wide_int wmax = addr_wide_int (max) + 1;
> + addr_wide_int wmax = wi::address (max) + 1;
> /* Truncate the result - this will mangle [0, SIZE_INT_MAX]
> number of elements as zero. */
> wmax = wi::zext (wmax, TYPE_PRECISION (TREE_TYPE (max)));
> Index: gcc/cp/tree.c
> ===================================================================
> --- gcc/cp/tree.c 2013-10-22 10:18:04.419965399 +0100
> +++ gcc/cp/tree.c 2013-10-22 10:18:20.378102106 +0100
> @@ -2603,7 +2603,7 @@ cp_tree_equal (tree t1, tree t2)
> switch (code1)
> {
> case INTEGER_CST:
> - return max_wide_int (t1) == max_wide_int (t2);
> + return wi::extend (t1) == wi::extend (t2);
>
> case REAL_CST:
> return REAL_VALUES_EQUAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2));
> Index: gcc/cp/typeck2.c
> ===================================================================
> --- gcc/cp/typeck2.c 2013-10-22 10:18:04.420965408 +0100
> +++ gcc/cp/typeck2.c 2013-10-22 10:18:20.378102106 +0100
> @@ -1119,8 +1119,8 @@ process_init_constructor_array (tree typ
> {
> tree domain = TYPE_DOMAIN (type);
> if (domain && TREE_CONSTANT (TYPE_MAX_VALUE (domain)))
> - len = wi::ext (addr_wide_int (TYPE_MAX_VALUE (domain))
> - - TYPE_MIN_VALUE (domain) + 1,
> + len = wi::ext (wi::address (TYPE_MAX_VALUE (domain))
> + - wi::address (TYPE_MIN_VALUE (domain)) + 1,
> TYPE_PRECISION (TREE_TYPE (domain)),
> TYPE_SIGN (TREE_TYPE (domain))).to_uhwi ();
> else
> Index: gcc/dwarf2out.c
> ===================================================================
> --- gcc/dwarf2out.c 2013-10-22 10:18:04.426965459 +0100
> +++ gcc/dwarf2out.c 2013-10-22 10:18:20.381102132 +0100
> @@ -10312,7 +10312,7 @@ wide_int_type_size_in_bits (const_tree t
> else if (TYPE_SIZE (type) == NULL_TREE)
> return 0;
> else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
> - return TYPE_SIZE (type);
> + return wi::address (TYPE_SIZE (type));
> else
> return TYPE_ALIGN (type);
> }
> @@ -14721,7 +14721,7 @@ field_byte_offset (const_tree decl)
> if (TREE_CODE (bit_position (decl)) != INTEGER_CST)
> return 0;
>
> - bitpos_int = bit_position (decl);
> + bitpos_int = wi::address (bit_position (decl));
>
> #ifdef PCC_BITFIELD_TYPE_MATTERS
> if (PCC_BITFIELD_TYPE_MATTERS)
> @@ -14747,7 +14747,7 @@ field_byte_offset (const_tree decl)
>
> /* If the size of the field is not constant, use the type size. */
> if (TREE_CODE (field_size_tree) == INTEGER_CST)
> - field_size_in_bits = field_size_tree;
> + field_size_in_bits = wi::address (field_size_tree);
> else
> field_size_in_bits = type_size_in_bits;
>
> Index: gcc/expmed.c
> ===================================================================
> --- gcc/expmed.c 2013-10-22 10:18:04.428965476 +0100
> +++ gcc/expmed.c 2013-10-22 10:18:20.382102140 +0100
> @@ -1821,9 +1821,7 @@ extract_fixed_bit_field (enum machine_mo
> lshift_value (enum machine_mode mode, unsigned HOST_WIDE_INT value,
> int bitpos)
> {
> - return
> - immed_wide_int_const (wi::lshift (max_wide_int (value),
> - bitpos), mode);
> + return immed_wide_int_const (wi::lshift (value, bitpos), mode);
> }
>
> /* Extract a bit field that is split across two words
> Index: gcc/expr.c
> ===================================================================
> --- gcc/expr.c 2013-10-22 10:18:04.431965502 +0100
> +++ gcc/expr.c 2013-10-22 10:18:20.384102157 +0100
> @@ -6581,7 +6581,7 @@ get_inner_reference (tree exp, HOST_WIDE
> switch (TREE_CODE (exp))
> {
> case BIT_FIELD_REF:
> - bit_offset += TREE_OPERAND (exp, 2);
> + bit_offset += wi::address (TREE_OPERAND (exp, 2));
> break;
>
> case COMPONENT_REF:
> @@ -6596,7 +6596,7 @@ get_inner_reference (tree exp, HOST_WIDE
> break;
>
> offset = size_binop (PLUS_EXPR, offset, this_offset);
> - bit_offset += DECL_FIELD_BIT_OFFSET (field);
> + bit_offset += wi::address (DECL_FIELD_BIT_OFFSET (field));
>
> /* ??? Right now we don't do anything with DECL_OFFSET_ALIGN. */
> }
> @@ -6675,7 +6675,7 @@ get_inner_reference (tree exp, HOST_WIDE
> this conversion. */
> if (TREE_CODE (offset) == INTEGER_CST)
> {
> - addr_wide_int tem = wi::sext (addr_wide_int (offset),
> + addr_wide_int tem = wi::sext (wi::address (offset),
> TYPE_PRECISION (sizetype));
> tem = wi::lshift (tem, (BITS_PER_UNIT == 8
> ? 3 : exact_log2 (BITS_PER_UNIT)));
> Index: gcc/fold-const.c
> ===================================================================
> --- gcc/fold-const.c 2013-10-22 10:18:04.437965553 +0100
> +++ gcc/fold-const.c 2013-10-22 10:18:20.386102175 +0100
> @@ -1581,7 +1581,7 @@ fold_convert_const_int_from_int (tree ty
> /* Given an integer constant, make new constant with new type,
> appropriately sign-extended or truncated. Use max_wide_int
> so that any extension is done according ARG1's type. */
> - return force_fit_type (type, max_wide_int (arg1),
> + return force_fit_type (type, wi::extend (arg1),
> !POINTER_TYPE_P (TREE_TYPE (arg1)),
> TREE_OVERFLOW (arg1));
> }
> @@ -1622,7 +1622,7 @@ fold_convert_const_int_from_real (enum t
> if (REAL_VALUE_ISNAN (r))
> {
> overflow = true;
> - val = max_wide_int (0);
> + val = wi::zero (TYPE_PRECISION (type));
> }
>
> /* See if R is less than the lower bound or greater than the
> @@ -1635,7 +1635,7 @@ fold_convert_const_int_from_real (enum t
> if (REAL_VALUES_LESS (r, l))
> {
> overflow = true;
> - val = max_wide_int (lt);
> + val = lt;
> }
> }
>
> @@ -1648,7 +1648,7 @@ fold_convert_const_int_from_real (enum t
> if (REAL_VALUES_LESS (u, r))
> {
> overflow = true;
> - val = max_wide_int (ut);
> + val = ut;
> }
> }
> }
> @@ -6611,7 +6611,7 @@ fold_single_bit_test (location_t loc, en
> not overflow, adjust BITNUM and INNER. */
> if (TREE_CODE (inner) == RSHIFT_EXPR
> && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST
> - && wi::ltu_p (wi::add (TREE_OPERAND (inner, 1), bitnum),
> + && wi::ltu_p (wi::extend (TREE_OPERAND (inner, 1)) + bitnum,
> TYPE_PRECISION (type)))
> {
> bitnum += tree_to_hwi (TREE_OPERAND (inner, 1));
> @@ -7287,7 +7287,9 @@ native_encode_int (const_tree expr, unsi
> for (byte = 0; byte < total_bytes; byte++)
> {
> int bitpos = byte * BITS_PER_UNIT;
> - value = wi::extract_uhwi (expr, bitpos, BITS_PER_UNIT);
> + /* Extend EXPR according to TYPE_SIGN if the precision isn't a whole
> + number of bytes. */
> + value = wi::extract_uhwi (wi::extend (expr), bitpos, BITS_PER_UNIT);
>
> if (total_bytes > UNITS_PER_WORD)
> {
> @@ -10450,7 +10452,7 @@ fold_binary_loc (location_t loc,
> code11 = TREE_CODE (tree11);
> if (code01 == INTEGER_CST
> && code11 == INTEGER_CST
> - && (wi::add (tree01, tree11)
> + && (wi::extend (tree01) + wi::extend (tree11)
> == element_precision (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
> {
> tem = build2_loc (loc, LROTATE_EXPR,
> Index: gcc/fortran/trans-array.c
> ===================================================================
> --- gcc/fortran/trans-array.c 2013-10-22 10:18:04.440965579 +0100
> +++ gcc/fortran/trans-array.c 2013-10-22 10:18:20.387102183 +0100
> @@ -5385,7 +5385,7 @@ gfc_conv_array_initializer (tree type, g
> else
> gfc_conv_structure (&se, expr, 1);
>
> - wtmp = addr_wide_int (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1;
> + wtmp = wi::address (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1;
> gcc_assert (wtmp != 0);
> /* This will probably eat buckets of memory for large arrays. */
> while (wtmp != 0)
> Index: gcc/gimple-fold.c
> ===================================================================
> --- gcc/gimple-fold.c 2013-10-22 10:18:04.441965588 +0100
> +++ gcc/gimple-fold.c 2013-10-22 10:19:05.060484982 +0100
> @@ -2821,14 +2821,14 @@ fold_array_ctor_reference (tree type, tr
> /* Static constructors for variably sized objects makes no sense. */
> gcc_assert (TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST);
> index_type = TREE_TYPE (TYPE_MIN_VALUE (domain_type));
> - low_bound = TYPE_MIN_VALUE (domain_type);
> + low_bound = wi::address (TYPE_MIN_VALUE (domain_type));
> }
> else
> low_bound = 0;
> /* Static constructors for variably sized objects makes no sense. */
> gcc_assert (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor))))
> == INTEGER_CST);
> - elt_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor)));
> + elt_size = wi::address (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor))));
>
> /* We can handle only constantly sized accesses that are known to not
> be larger than size of array element. */
> @@ -2866,12 +2866,12 @@ fold_array_ctor_reference (tree type, tr
> if (cfield)
> {
> if (TREE_CODE (cfield) == INTEGER_CST)
> - max_index = index = cfield;
> + max_index = index = wi::address (cfield);
> else
> {
> gcc_assert (TREE_CODE (cfield) == RANGE_EXPR);
> - index = TREE_OPERAND (cfield, 0);
> - max_index = TREE_OPERAND (cfield, 1);
> + index = wi::address (TREE_OPERAND (cfield, 0));
> + max_index = wi::address (TREE_OPERAND (cfield, 1));
> }
> }
> else
> @@ -2913,7 +2913,7 @@ fold_nonarray_ctor_reference (tree type,
> tree field_offset = DECL_FIELD_BIT_OFFSET (cfield);
> tree field_size = DECL_SIZE (cfield);
> addr_wide_int bitoffset;
> - addr_wide_int byte_offset_cst = byte_offset;
> + addr_wide_int byte_offset_cst = wi::address (byte_offset);
> addr_wide_int bitoffset_end, access_end;
>
> /* Variable sized objects in static constructors makes no sense,
> @@ -2925,10 +2925,11 @@ fold_nonarray_ctor_reference (tree type,
> : TREE_CODE (TREE_TYPE (cfield)) == ARRAY_TYPE));
>
> /* Compute bit offset of the field. */
> - bitoffset = wi::add (field_offset, byte_offset_cst * BITS_PER_UNIT);
> + bitoffset = (wi::address (field_offset)
> + + byte_offset_cst * BITS_PER_UNIT);
> /* Compute bit offset where the field ends. */
> if (field_size != NULL_TREE)
> - bitoffset_end = bitoffset + field_size;
> + bitoffset_end = bitoffset + wi::address (field_size);
> else
> bitoffset_end = 0;
>
> @@ -3043,8 +3044,8 @@ fold_const_aggregate_ref_1 (tree t, tree
> if ((TREE_CODE (low_bound) == INTEGER_CST)
> && (tree_fits_uhwi_p (unit_size)))
> {
> - addr_wide_int woffset
> - = wi::sext (addr_wide_int (idx) - low_bound,
> + addr_wide_int woffset
> + = wi::sext (wi::address (idx) - wi::address (low_bound),
> TYPE_PRECISION (TREE_TYPE (idx)));
>
> if (wi::fits_shwi_p (woffset))
> Index: gcc/gimple-ssa-strength-reduction.c
> ===================================================================
> --- gcc/gimple-ssa-strength-reduction.c 2013-10-22 10:18:04.444965613 +0100
> +++ gcc/gimple-ssa-strength-reduction.c 2013-10-22 10:18:20.389102200 +0100
> @@ -792,7 +792,7 @@ backtrace_base_for_ref (tree *pbase)
> {
> /* X = B + (1 * S), S is integer constant. */
> *pbase = base_cand->base_expr;
> - return base_cand->stride;
> + return wi::extend (base_cand->stride);
> }
> else if (base_cand->kind == CAND_ADD
> && TREE_CODE (base_cand->stride) == INTEGER_CST
> @@ -860,14 +860,14 @@ restructure_reference (tree *pbase, tree
> type = TREE_TYPE (TREE_OPERAND (base, 1));
>
> mult_op0 = TREE_OPERAND (offset, 0);
> - c3 = TREE_OPERAND (offset, 1);
> + c3 = wi::extend (TREE_OPERAND (offset, 1));
>
> if (TREE_CODE (mult_op0) == PLUS_EXPR)
>
> if (TREE_CODE (TREE_OPERAND (mult_op0, 1)) == INTEGER_CST)
> {
> t2 = TREE_OPERAND (mult_op0, 0);
> - c2 = TREE_OPERAND (mult_op0, 1);
> + c2 = wi::extend (TREE_OPERAND (mult_op0, 1));
> }
> else
> return false;
> @@ -877,7 +877,7 @@ restructure_reference (tree *pbase, tree
> if (TREE_CODE (TREE_OPERAND (mult_op0, 1)) == INTEGER_CST)
> {
> t2 = TREE_OPERAND (mult_op0, 0);
> - c2 = -(max_wide_int)TREE_OPERAND (mult_op0, 1);
> + c2 = -wi::extend (TREE_OPERAND (mult_op0, 1));
> }
> else
> return false;
> @@ -979,7 +979,7 @@ create_mul_ssa_cand (gimple gs, tree bas
> ============================
> X = B + ((i' * S) * Z) */
> base = base_cand->base_expr;
> - index = base_cand->index * base_cand->stride;
> + index = base_cand->index * wi::extend (base_cand->stride);
> stride = stride_in;
> ctype = base_cand->cand_type;
> if (has_single_use (base_in))
> @@ -1035,7 +1035,7 @@ create_mul_imm_cand (gimple gs, tree bas
> X = (B + i') * (S * c) */
> base = base_cand->base_expr;
> index = base_cand->index;
> - temp = wi::mul (base_cand->stride, stride_in);
> + temp = wi::extend (base_cand->stride) * wi::extend (stride_in);
> stride = wide_int_to_tree (TREE_TYPE (stride_in), temp);
> ctype = base_cand->cand_type;
> if (has_single_use (base_in))
> @@ -1065,7 +1065,7 @@ create_mul_imm_cand (gimple gs, tree bas
> ===========================
> X = (B + S) * c */
> base = base_cand->base_expr;
> - index = base_cand->stride;
> + index = wi::extend (base_cand->stride);
> stride = stride_in;
> ctype = base_cand->cand_type;
> if (has_single_use (base_in))
> @@ -1166,7 +1166,7 @@ create_add_ssa_cand (gimple gs, tree bas
> ===========================
> X = Y + ((+/-1 * S) * B) */
> base = base_in;
> - index = addend_cand->stride;
> + index = wi::extend (addend_cand->stride);
> if (subtract_p)
> index = -index;
> stride = addend_cand->base_expr;
> @@ -1216,7 +1216,7 @@ create_add_ssa_cand (gimple gs, tree bas
> ===========================
> Value: X = Y + ((-1 * S) * B) */
> base = base_in;
> - index = subtrahend_cand->stride;
> + index = wi::extend (subtrahend_cand->stride);
> index = -index;
> stride = subtrahend_cand->base_expr;
> ctype = TREE_TYPE (base_in);
> @@ -1272,7 +1272,8 @@ create_add_imm_cand (gimple gs, tree bas
> signop sign = TYPE_SIGN (TREE_TYPE (base_cand->stride));
>
> if (TREE_CODE (base_cand->stride) == INTEGER_CST
> - && wi::multiple_of_p (index_in, base_cand->stride, sign, &multiple))
> + && wi::multiple_of_p (index_in, wi::extend (base_cand->stride),
> + sign, &multiple))
> {
> /* Y = (B + i') * S, S constant, c = kS for some integer k
> X = Y + c
> @@ -1360,7 +1361,7 @@ slsr_process_add (gimple gs, tree rhs1,
> max_wide_int index;
>
> /* Record an interpretation for the add-immediate. */
> - index = rhs2;
> + index = wi::extend (rhs2);
> if (subtract_p)
> index = -index;
>
> @@ -2027,7 +2028,7 @@ replace_unconditional_candidate (slsr_ca
> return;
>
> basis = lookup_cand (c->basis);
> - bump = cand_increment (c) * c->stride;
> + bump = cand_increment (c) * wi::extend (c->stride);
>
> replace_mult_candidate (c, gimple_assign_lhs (basis->cand_stmt), bump);
> }
> @@ -2078,7 +2079,7 @@ create_add_on_incoming_edge (slsr_cand_t
> {
> tree bump_tree;
> enum tree_code code = PLUS_EXPR;
> - max_wide_int bump = increment * c->stride;
> + max_wide_int bump = increment * wi::extend (c->stride);
> if (wi::neg_p (bump))
> {
> code = MINUS_EXPR;
> @@ -2246,7 +2247,7 @@ replace_conditional_candidate (slsr_cand
> name = create_phi_basis (c, lookup_cand (c->def_phi)->cand_stmt,
> basis_name, loc, KNOWN_STRIDE);
> /* Replace C with an add of the new basis phi and a constant. */
> - bump = c->index * c->stride;
> + bump = c->index * wi::extend (c->stride);
>
> replace_mult_candidate (c, name, bump);
> }
> Index: gcc/ipa-prop.c
> ===================================================================
> --- gcc/ipa-prop.c 2013-10-22 10:18:04.445965622 +0100
> +++ gcc/ipa-prop.c 2013-10-22 10:18:20.390102209 +0100
> @@ -3640,8 +3640,7 @@ ipa_modify_call_arguments (struct cgraph
> if (TYPE_ALIGN (type) > align)
> align = TYPE_ALIGN (type);
> }
> - misalign += (wi::sext (addr_wide_int (off),
> - TYPE_PRECISION (TREE_TYPE (off)))
> + misalign += (addr_wide_int::from (off, SIGNED)
> * BITS_PER_UNIT).to_short_addr ();
> misalign = misalign & (align - 1);
> if (misalign != 0)
> Index: gcc/predict.c
> ===================================================================
> --- gcc/predict.c 2013-10-22 10:18:04.445965622 +0100
> +++ gcc/predict.c 2013-10-22 10:18:20.390102209 +0100
> @@ -1300,10 +1300,10 @@ predict_iv_comparison (struct loop *loop
> bool overflow, overall_overflow = false;
> max_wide_int compare_count, tem, loop_count;
>
> - max_wide_int loop_bound = loop_bound_var;
> - max_wide_int compare_bound = compare_var;
> - max_wide_int base = compare_base;
> - max_wide_int compare_step = compare_step_var;
> + max_wide_int loop_bound = wi::extend (loop_bound_var);
> + max_wide_int compare_bound = wi::extend (compare_var);
> + max_wide_int base = wi::extend (compare_base);
> + max_wide_int compare_step = wi::extend (compare_step_var);
>
> /* (loop_bound - base) / compare_step */
> tem = wi::sub (loop_bound, base, SIGNED, &overflow);
> Index: gcc/stor-layout.c
> ===================================================================
> --- gcc/stor-layout.c 2013-10-22 10:18:04.446965630 +0100
> +++ gcc/stor-layout.c 2013-10-22 10:18:20.391102217 +0100
> @@ -2198,11 +2198,10 @@ layout_type (tree type)
> && TYPE_UNSIGNED (TREE_TYPE (lb))
> && tree_int_cst_lt (ub, lb))
> {
> - unsigned prec = TYPE_PRECISION (TREE_TYPE (lb));
> lb = wide_int_to_tree (ssizetype,
> - wi::sext (addr_wide_int (lb), prec));
> + addr_wide_int::from (lb, SIGNED));
> ub = wide_int_to_tree (ssizetype,
> - wi::sext (addr_wide_int (ub), prec));
> + addr_wide_int::from (ub, SIGNED));
> }
> length
> = fold_convert (sizetype,
> Index: gcc/tree-affine.c
> ===================================================================
> --- gcc/tree-affine.c 2013-10-22 10:18:04.446965630 +0100
> +++ gcc/tree-affine.c 2013-10-22 10:18:20.391102217 +0100
> @@ -269,7 +269,7 @@ tree_to_aff_combination (tree expr, tree
> switch (code)
> {
> case INTEGER_CST:
> - aff_combination_const (comb, type, expr);
> + aff_combination_const (comb, type, wi::extend (expr));
> return;
>
> case POINTER_PLUS_EXPR:
> @@ -292,7 +292,7 @@ tree_to_aff_combination (tree expr, tree
> if (TREE_CODE (cst) != INTEGER_CST)
> break;
> tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
> - aff_combination_scale (comb, cst);
> + aff_combination_scale (comb, wi::extend (cst));
> return;
>
> case NEGATE_EXPR:
> @@ -383,7 +383,7 @@ add_elt_to_tree (tree expr, tree type, t
> {
> elt = convert_to_ptrofftype (elt);
> elt = fold_build1 (NEGATE_EXPR, TREE_TYPE (elt), elt);
> - scale = max_wide_int (1);
> + scale = 1;
> }
>
> if (scale == 1)
> Index: gcc/tree-dfa.c
> ===================================================================
> --- gcc/tree-dfa.c 2013-10-22 10:18:04.472965853 +0100
> +++ gcc/tree-dfa.c 2013-10-22 10:18:20.391102217 +0100
> @@ -422,7 +422,7 @@ get_ref_base_and_extent (tree exp, HOST_
> switch (TREE_CODE (exp))
> {
> case BIT_FIELD_REF:
> - bit_offset += TREE_OPERAND (exp, 2);
> + bit_offset += wi::address (TREE_OPERAND (exp, 2));
> break;
>
> case COMPONENT_REF:
> @@ -432,11 +432,11 @@ get_ref_base_and_extent (tree exp, HOST_
>
> if (this_offset && TREE_CODE (this_offset) == INTEGER_CST)
> {
> - addr_wide_int woffset = this_offset;
> + addr_wide_int woffset = wi::address (this_offset);
> woffset = wi::lshift (woffset,
> (BITS_PER_UNIT == 8
> ? 3 : exact_log2 (BITS_PER_UNIT)));
> - woffset += DECL_FIELD_BIT_OFFSET (field);
> + woffset += wi::address (DECL_FIELD_BIT_OFFSET (field));
> bit_offset += woffset;
>
> /* If we had seen a variable array ref already and we just
> @@ -497,10 +497,10 @@ get_ref_base_and_extent (tree exp, HOST_
> && (unit_size = array_ref_element_size (exp),
> TREE_CODE (unit_size) == INTEGER_CST))
> {
> - addr_wide_int woffset
> - = wi::sext (addr_wide_int (index) - low_bound,
> + addr_wide_int woffset
> + = wi::sext (wi::address (index) - wi::address (low_bound),
> TYPE_PRECISION (TREE_TYPE (index)));
> - woffset *= addr_wide_int (unit_size);
> + woffset *= wi::address (unit_size);
> woffset = wi::lshift (woffset,
> (BITS_PER_UNIT == 8
> ? 3 : exact_log2 (BITS_PER_UNIT)));
> Index: gcc/tree-predcom.c
> ===================================================================
> --- gcc/tree-predcom.c 2013-10-22 10:18:04.473965862 +0100
> +++ gcc/tree-predcom.c 2013-10-22 10:18:20.392102226 +0100
> @@ -618,7 +618,7 @@ aff_combination_dr_offset (struct data_r
>
> tree_to_aff_combination_expand (DR_OFFSET (dr), type, offset,
> &name_expansions);
> - aff_combination_const (&delta, type, DR_INIT (dr));
> + aff_combination_const (&delta, type, wi::extend (DR_INIT (dr)));
> aff_combination_add (offset, &delta);
> }
>
> Index: gcc/tree-pretty-print.c
> ===================================================================
> --- gcc/tree-pretty-print.c 2013-10-22 10:18:04.474965870 +0100
> +++ gcc/tree-pretty-print.c 2013-10-22 10:18:20.392102226 +0100
> @@ -1509,7 +1509,7 @@ dump_generic_node (pretty_printer *buffe
> {
> tree minv = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (node)));
> is_array_init = true;
> - curidx = minv;
> + curidx = wi::extend (minv);
> }
> FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (node), ix, field, val)
> {
> @@ -1523,7 +1523,7 @@ dump_generic_node (pretty_printer *buffe
> }
> else if (is_array_init
> && (TREE_CODE (field) != INTEGER_CST
> - || curidx != field))
> + || curidx != wi::extend (field)))
> {
> pp_left_bracket (buffer);
> if (TREE_CODE (field) == RANGE_EXPR)
> @@ -1534,12 +1534,12 @@ dump_generic_node (pretty_printer *buffe
> dump_generic_node (buffer, TREE_OPERAND (field, 1), spc,
> flags, false);
> if (TREE_CODE (TREE_OPERAND (field, 1)) == INTEGER_CST)
> - curidx = TREE_OPERAND (field, 1);
> + curidx = wi::extend (TREE_OPERAND (field, 1));
> }
> else
> dump_generic_node (buffer, field, spc, flags, false);
> if (TREE_CODE (field) == INTEGER_CST)
> - curidx = field;
> + curidx = wi::extend (field);
> pp_string (buffer, "]=");
> }
> }
> Index: gcc/tree-ssa-address.c
> ===================================================================
> --- gcc/tree-ssa-address.c 2013-10-22 10:18:04.474965870 +0100
> +++ gcc/tree-ssa-address.c 2013-10-22 10:18:20.392102226 +0100
> @@ -203,8 +203,7 @@ addr_for_mem_ref (struct mem_address *ad
>
> if (addr->offset && !integer_zerop (addr->offset))
> {
> - addr_wide_int dc = wi::sext (addr_wide_int (addr->offset),
> - TYPE_PRECISION (TREE_TYPE (addr->offset)));
> + addr_wide_int dc = addr_wide_int::from (addr->offset, SIGNED);
> off = immed_wide_int_const (dc, pointer_mode);
> }
> else
> Index: gcc/tree-ssa-ccp.c
> ===================================================================
> --- gcc/tree-ssa-ccp.c 2013-10-22 10:18:04.475965878 +0100
> +++ gcc/tree-ssa-ccp.c 2013-10-22 10:18:20.393102234 +0100
> @@ -202,7 +202,7 @@ dump_lattice_value (FILE *outf, const ch
> }
> else
> {
> - wide_int cval = wi::bit_and_not (val.value, val.mask);
> + wide_int cval = wi::bit_and_not (wi::extend (val.value), val.mask);
> fprintf (outf, "%sCONSTANT ", prefix);
> print_hex (cval, outf);
> fprintf (outf, " (");
> @@ -432,8 +432,8 @@ valid_lattice_transition (prop_value_t o
> /* Bit-lattices have to agree in the still valid bits. */
> if (TREE_CODE (old_val.value) == INTEGER_CST
> && TREE_CODE (new_val.value) == INTEGER_CST)
> - return (wi::bit_and_not (old_val.value, new_val.mask)
> - == wi::bit_and_not (new_val.value, new_val.mask));
> + return (wi::bit_and_not (wi::extend (old_val.value), new_val.mask)
> + == wi::bit_and_not (wi::extend (new_val.value), new_val.mask));
>
> /* Otherwise constant values have to agree. */
> return operand_equal_p (old_val.value, new_val.value, 0);
> @@ -458,7 +458,8 @@ set_lattice_value (tree var, prop_value_
> && TREE_CODE (new_val.value) == INTEGER_CST
> && TREE_CODE (old_val->value) == INTEGER_CST)
> {
> - max_wide_int diff = wi::bit_xor (new_val.value, old_val->value);
> + max_wide_int diff = (wi::extend (new_val.value)
> + ^ wi::extend (old_val->value));
> new_val.mask = new_val.mask | old_val->mask | diff;
> }
>
> @@ -505,7 +506,7 @@ value_to_wide_int (prop_value_t val)
> {
> if (val.value
> && TREE_CODE (val.value) == INTEGER_CST)
> - return val.value;
> + return wi::extend (val.value);
>
> return 0;
> }
> @@ -908,7 +909,7 @@ ccp_lattice_meet (prop_value_t *val1, pr
> For INTEGER_CSTs mask unequal bits. If no equal bits remain,
> drop to varying. */
> val1->mask = (val1->mask | val2->mask
> - | (wi::bit_xor (val1->value, val2->value)));
> + | (wi::extend (val1->value) ^ wi::extend (val2->value)));
> if (val1->mask == -1)
> {
> val1->lattice_val = VARYING;
> Index: gcc/tree-ssa-loop-ivcanon.c
> ===================================================================
> --- gcc/tree-ssa-loop-ivcanon.c 2013-10-22 10:18:04.476965887 +0100
> +++ gcc/tree-ssa-loop-ivcanon.c 2013-10-22 10:18:20.393102234 +0100
> @@ -927,7 +927,7 @@ canonicalize_loop_induction_variables (s
> by find_loop_niter_by_eval. Be sure to keep it for future. */
> if (niter && TREE_CODE (niter) == INTEGER_CST)
> {
> - record_niter_bound (loop, niter,
> + record_niter_bound (loop, wi::extend (niter),
> exit == single_likely_exit (loop), true);
> }
>
> Index: gcc/tree-ssa-loop-ivopts.c
> ===================================================================
> --- gcc/tree-ssa-loop-ivopts.c 2013-10-22 10:18:04.478965904 +0100
> +++ gcc/tree-ssa-loop-ivopts.c 2013-10-22 10:18:20.394102243 +0100
> @@ -1590,7 +1590,7 @@ constant_multiple_of (tree top, tree bot
> if (!constant_multiple_of (TREE_OPERAND (top, 0), bot, &res))
> return false;
>
> - *mul = wi::sext (res * mby, precision);
> + *mul = wi::sext (res * wi::extend (mby), precision);
> return true;
>
> case PLUS_EXPR:
> @@ -1608,8 +1608,8 @@ constant_multiple_of (tree top, tree bot
> if (TREE_CODE (bot) != INTEGER_CST)
> return false;
>
> - p0 = wi::sext (top, precision);
> - p1 = wi::sext (bot, precision);
> + p0 = max_wide_int::from (top, SIGNED);
> + p1 = max_wide_int::from (bot, SIGNED);
> if (p1 == 0)
> return false;
> *mul = wi::sext (wi::divmod_trunc (p0, p1, SIGNED, &res), precision);
> @@ -4632,7 +4632,7 @@ may_eliminate_iv (struct ivopts_data *da
> max_niter = desc->max;
> if (stmt_after_increment (loop, cand, use->stmt))
> max_niter += 1;
> - period_value = period;
> + period_value = wi::extend (period);
> if (wi::gtu_p (max_niter, period_value))
> {
> /* See if we can take advantage of inferred loop bound information. */
> Index: gcc/tree-ssa-loop-niter.c
> ===================================================================
> --- gcc/tree-ssa-loop-niter.c 2013-10-22 10:18:04.480965921 +0100
> +++ gcc/tree-ssa-loop-niter.c 2013-10-22 10:18:20.394102243 +0100
> @@ -69,7 +69,6 @@ split_to_var_and_offset (tree expr, tree
> {
> tree type = TREE_TYPE (expr);
> tree op0, op1;
> - max_wide_int off;
> bool negate = false;
>
> *var = expr;
> @@ -90,18 +89,15 @@ split_to_var_and_offset (tree expr, tree
> break;
>
> *var = op0;
> - off = op1;
> /* Always sign extend the offset. */
> - off = wi::sext (off, TYPE_PRECISION (type));
> - wi::to_mpz (off, offset, SIGNED);
> + wi::to_mpz (op1, offset, SIGNED);
> if (negate)
> mpz_neg (offset, offset);
> break;
>
> case INTEGER_CST:
> *var = build_int_cst_type (type, 0);
> - off = expr;
> - wi::to_mpz (off, offset, TYPE_SIGN (type));
> + wi::to_mpz (expr, offset, TYPE_SIGN (type));
> break;
>
> default:
> @@ -810,7 +806,7 @@ number_of_iterations_lt_to_ne (tree type
> niter->may_be_zero = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
> niter->may_be_zero,
> noloop);
> - bounds_add (bnds, mod, type);
> + bounds_add (bnds, wi::extend (mod), type);
> *delta = fold_build2 (PLUS_EXPR, niter_type, *delta, mod);
>
> ret = true;
> @@ -926,10 +922,10 @@ assert_loop_rolls_lt (tree type, affine_
> /* First check whether the answer does not follow from the bounds we gathered
> before. */
> if (integer_nonzerop (iv0->step))
> - dstep = iv0->step;
> + dstep = wi::extend (iv0->step);
> else
> {
> - dstep = wi::sext (iv1->step, TYPE_PRECISION (type));
> + dstep = wi::sext (wi::extend (iv1->step), TYPE_PRECISION (type));
> dstep = -dstep;
> }
>
> @@ -1913,7 +1909,7 @@ number_of_iterations_exit (struct loop *
>
> /* If NITER has simplified into a constant, update MAX. */
> if (TREE_CODE (niter->niter) == INTEGER_CST)
> - niter->max = niter->niter;
> + niter->max = wi::extend (niter->niter);
>
> if (integer_onep (niter->assumptions))
> return true;
> @@ -2387,12 +2383,12 @@ derive_constant_upper_bound_ops (tree ty
> else
> maxt = upper_bound_in_type (type, type);
>
> - max = maxt;
> + max = wi::extend (maxt);
>
> switch (code)
> {
> case INTEGER_CST:
> - return op0;
> + return wi::extend (op0);
>
> CASE_CONVERT:
> subtype = TREE_TYPE (op0);
> @@ -2429,8 +2425,7 @@ derive_constant_upper_bound_ops (tree ty
> /* Canonicalize to OP0 - CST. Consider CST to be signed, in order to
> choose the most logical way how to treat this constant regardless
> of the signedness of the type. */
> - cst = op1;
> - cst = wi::sext (cst, TYPE_PRECISION (type));
> + cst = wi::sext (wi::extend (op1), TYPE_PRECISION (type));
> if (code != MINUS_EXPR)
> cst = -cst;
>
> @@ -2490,13 +2485,13 @@ derive_constant_upper_bound_ops (tree ty
> return max;
>
> bnd = derive_constant_upper_bound (op0);
> - return wi::udiv_floor (bnd, op1);
> + return wi::udiv_floor (bnd, wi::extend (op1));
>
> case BIT_AND_EXPR:
> if (TREE_CODE (op1) != INTEGER_CST
> || tree_int_cst_sign_bit (op1))
> return max;
> - return op1;
> + return wi::extend (op1);
>
> case SSA_NAME:
> stmt = SSA_NAME_DEF_STMT (op0);
> @@ -2575,7 +2570,7 @@ record_estimate (struct loop *loop, tree
> if (TREE_CODE (bound) != INTEGER_CST)
> realistic = false;
> else
> - gcc_checking_assert (i_bound == bound);
> + gcc_checking_assert (i_bound == wi::extend (bound));
> if (!upper && !realistic)
> return;
>
> @@ -3363,7 +3358,7 @@ estimate_numbers_of_iterations_loop (str
> && TREE_CODE (loop->nb_iterations) == INTEGER_CST)
> {
> loop->any_upper_bound = true;
> - loop->nb_iterations_upper_bound = loop->nb_iterations;
> + loop->nb_iterations_upper_bound = wi::extend (loop->nb_iterations);
> }
> }
>
> Index: gcc/tree-ssa-pre.c
> ===================================================================
> --- gcc/tree-ssa-pre.c 2013-10-22 10:18:04.481965930 +0100
> +++ gcc/tree-ssa-pre.c 2013-10-22 10:18:20.395102252 +0100
> @@ -1581,9 +1581,9 @@ phi_translate_1 (pre_expr expr, bitmap_s
> && TREE_CODE (op[1]) == INTEGER_CST
> && TREE_CODE (op[2]) == INTEGER_CST)
> {
> - addr_wide_int off = op[0];
> - off += -addr_wide_int (op[1]);
> - off *= addr_wide_int (op[2]);
> + addr_wide_int off = ((wi::address (op[0])
> + - wi::address (op[1]))
> + * wi::address (op[2]));
> if (wi::fits_shwi_p (off))
> newop.off = off.to_shwi ();
> }
> Index: gcc/tree-ssa-sccvn.c
> ===================================================================
> --- gcc/tree-ssa-sccvn.c 2013-10-22 10:18:04.483965947 +0100
> +++ gcc/tree-ssa-sccvn.c 2013-10-22 10:18:20.396102260 +0100
> @@ -801,8 +801,8 @@ copy_reference_ops_from_ref (tree ref, v
> if (tree_to_hwi (bit_offset) % BITS_PER_UNIT == 0)
> {
> addr_wide_int off
> - = (addr_wide_int (this_offset)
> - + wi::lrshift (addr_wide_int (bit_offset),
> + = (wi::address (this_offset)
> + + wi::lrshift (wi::address (bit_offset),
> BITS_PER_UNIT == 8
> ? 3 : exact_log2 (BITS_PER_UNIT)));
> if (wi::fits_shwi_p (off))
> @@ -822,9 +822,9 @@ copy_reference_ops_from_ref (tree ref, v
> && TREE_CODE (temp.op1) == INTEGER_CST
> && TREE_CODE (temp.op2) == INTEGER_CST)
> {
> - addr_wide_int off = temp.op0;
> - off += -addr_wide_int (temp.op1);
> - off *= addr_wide_int (temp.op2);
> + addr_wide_int off = ((wi::address (temp.op0)
> + - wi::address (temp.op1))
> + * wi::address (temp.op2));
> if (wi::fits_shwi_p (off))
> temp.off = off.to_shwi();
> }
> @@ -1146,8 +1146,7 @@ vn_reference_fold_indirect (vec<vn_refer
> gcc_checking_assert (addr_base && TREE_CODE (addr_base) != MEM_REF);
> if (addr_base != TREE_OPERAND (op->op0, 0))
> {
> - addr_wide_int off = wi::sext (addr_wide_int (mem_op->op0),
> - TYPE_PRECISION (TREE_TYPE (mem_op->op0)));
> + addr_wide_int off = addr_wide_int::from (mem_op->op0, SIGNED);
> off += addr_offset;
> mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off);
> op->op0 = build_fold_addr_expr (addr_base);
> @@ -1180,8 +1179,7 @@ vn_reference_maybe_forwprop_address (vec
> && code != POINTER_PLUS_EXPR)
> return;
>
> - off = wi::sext (addr_wide_int (mem_op->op0),
> - TYPE_PRECISION (TREE_TYPE (mem_op->op0)));
> + off = addr_wide_int::from (mem_op->op0, SIGNED);
>
> /* The only thing we have to do is from &OBJ.foo.bar add the offset
> from .foo.bar to the preceding MEM_REF offset and replace the
> @@ -1211,7 +1209,7 @@ vn_reference_maybe_forwprop_address (vec
> || TREE_CODE (ptroff) != INTEGER_CST)
> return;
>
> - off += ptroff;
> + off += wi::address (ptroff);
> op->op0 = ptr;
> }
>
> @@ -1369,9 +1367,9 @@ valueize_refs_1 (vec<vn_reference_op_s>
> && TREE_CODE (vro->op1) == INTEGER_CST
> && TREE_CODE (vro->op2) == INTEGER_CST)
> {
> - addr_wide_int off = vro->op0;
> - off += -addr_wide_int (vro->op1);
> - off *= addr_wide_int (vro->op2);
> + addr_wide_int off = ((wi::address (vro->op0)
> + - wi::address (vro->op1))
> + * wi::address (vro->op2));
> if (wi::fits_shwi_p (off))
> vro->off = off.to_shwi ();
> }
> Index: gcc/tree-ssa-structalias.c
> ===================================================================
> --- gcc/tree-ssa-structalias.c 2013-10-22 10:18:04.485965964 +0100
> +++ gcc/tree-ssa-structalias.c 2013-10-22 10:18:20.397102269 +0100
> @@ -3012,8 +3012,7 @@ get_constraint_for_ptr_offset (tree ptr,
> else
> {
> /* Sign-extend the offset. */
> - addr_wide_int soffset = wi::sext (addr_wide_int (offset),
> - TYPE_PRECISION (TREE_TYPE (offset)));
> + addr_wide_int soffset = addr_wide_int::from (offset, SIGNED);
> if (!wi::fits_shwi_p (soffset))
> rhsoffset = UNKNOWN_OFFSET;
> else
> Index: gcc/tree-vrp.c
> ===================================================================
> --- gcc/tree-vrp.c 2013-10-22 10:18:04.488965990 +0100
> +++ gcc/tree-vrp.c 2013-10-22 10:30:40.213441286 +0100
> @@ -3849,7 +3849,7 @@ adjust_range_with_scev (value_range_t *v
> signop sgn = TYPE_SIGN (TREE_TYPE (step));
> bool overflow;
>
> - wtmp = wi::mul (step, nit, sgn, &overflow);
> + wtmp = wi::mul (wi::extend (step), nit, sgn, &overflow);
> /* If the multiplication overflowed we can't do a meaningful
> adjustment. Likewise if the result doesn't fit in the type
> of the induction variable. For a signed type we have to
> @@ -6292,7 +6292,7 @@ search_for_addr_array (tree t, location_
> return;
>
> idx = mem_ref_offset (t);
> - idx = wi::sdiv_trunc (idx, el_sz);
> + idx = wi::sdiv_trunc (idx, wi::address (el_sz));
> if (wi::lts_p (idx, 0))
> {
> if (dump_file && (dump_flags & TDF_DETAILS))
> @@ -6305,7 +6305,8 @@ search_for_addr_array (tree t, location_
> "array subscript is below array bounds");
> TREE_NO_WARNING (t) = 1;
> }
> - else if (wi::gts_p (idx, addr_wide_int (up_bound) - low_bound + 1))
> + else if (wi::gts_p (idx, (wi::address (up_bound)
> + - wi::address (low_bound) + 1)))
> {
> if (dump_file && (dump_flags & TDF_DETAILS))
> {
> @@ -8731,11 +8732,11 @@ range_fits_type_p (value_range_t *vr, un
>
> /* Then we can perform the conversion on both ends and compare
> the result for equality. */
> - tem = wi::ext (vr->min, dest_precision, dest_sgn);
> - if (tem != vr->min)
> + tem = wi::ext (wi::extend (vr->min), dest_precision, dest_sgn);
> + if (tem != wi::extend (vr->min))
> return false;
> - tem = wi::ext (vr->max, dest_precision, dest_sgn);
> - if (tem != vr->max)
> + tem = wi::ext (wi::extend (vr->max), dest_precision, dest_sgn);
> + if (tem != wi::extend (vr->max))
> return false;
>
> return true;
> @@ -9021,8 +9022,8 @@ simplify_conversion_using_ranges (gimple
>
> /* Simulate the conversion chain to check if the result is equal if
> the middle conversion is removed. */
> - innermin = innervr->min;
> - innermax = innervr->max;
> + innermin = wi::extend (innervr->min);
> + innermax = wi::extend (innervr->max);
>
> inner_prec = TYPE_PRECISION (TREE_TYPE (innerop));
> middle_prec = TYPE_PRECISION (TREE_TYPE (middleop));
> @@ -9482,7 +9483,8 @@ vrp_finalize (void)
> && (TREE_CODE (vr_value[i]->max) == INTEGER_CST))
> {
> if (vr_value[i]->type == VR_RANGE)
> - set_range_info (name, vr_value[i]->min, vr_value[i]->max);
> + set_range_info (name, wi::extend (vr_value[i]->min),
> + wi::extend (vr_value[i]->max));
> else if (vr_value[i]->type == VR_ANTI_RANGE)
> {
> /* VR_ANTI_RANGE ~[min, max] is encoded compactly as
> @@ -9496,16 +9498,14 @@ vrp_finalize (void)
> && integer_zerop (vr_value[i]->min)
> && integer_zerop (vr_value[i]->max))
> {
> - max_wide_int tmmwi
> - = max_wide_int::from (wi::max_value (TYPE_PRECISION (TREE_TYPE (name)),
> - UNSIGNED),
> - UNSIGNED);
> - set_range_info (name, 1, tmmwi);
> + unsigned prec = TYPE_PRECISION (TREE_TYPE (name));
> + set_range_info (name, 1,
> + wi::mask <max_wide_int> (prec, false));
> }
> else
> set_range_info (name,
> - max_wide_int (vr_value[i]->max) + 1,
> - max_wide_int (vr_value[i]->min) - 1);
> + wi::extend (vr_value[i]->max) + 1,
> + wi::extend (vr_value[i]->min) - 1);
> }
> }
> }
> Index: gcc/tree.c
> ===================================================================
> --- gcc/tree.c 2013-10-22 10:18:04.492966024 +0100
> +++ gcc/tree.c 2013-10-22 10:18:20.400102295 +0100
> @@ -4317,8 +4317,7 @@ build_simple_mem_ref_loc (location_t loc
> addr_wide_int
> mem_ref_offset (const_tree t)
> {
> - tree toff = TREE_OPERAND (t, 1);
> - return wi::sext (addr_wide_int (toff), TYPE_PRECISION (TREE_TYPE (toff)));
> + return addr_wide_int::from (TREE_OPERAND (t, 1), SIGNED);
> }
>
> /* Return an invariant ADDR_EXPR of type TYPE taking the address of BASE
> @@ -6891,26 +6890,17 @@ type_num_arguments (const_tree type)
> int
> tree_int_cst_equal (const_tree t1, const_tree t2)
> {
> - unsigned int prec1, prec2;
> if (t1 == t2)
> return 1;
>
> if (t1 == 0 || t2 == 0)
> return 0;
>
> - if (TREE_CODE (t1) != INTEGER_CST
> - || TREE_CODE (t2) != INTEGER_CST)
> - return 0;
> -
> - prec1 = TYPE_PRECISION (TREE_TYPE (t1));
> - prec2 = TYPE_PRECISION (TREE_TYPE (t2));
> + if (TREE_CODE (t1) == INTEGER_CST
> + && TREE_CODE (t2) == INTEGER_CST
> + && wi::extend (t1) == wi::extend (t2))
> + return 1;
>
> - if (prec1 == prec2)
> - return wi::eq_p (t1, t2);
> - else if (prec1 < prec2)
> - return wide_int::from (t1, prec2, TYPE_SIGN (TREE_TYPE (t1))) == t2;
> - else
> - return wide_int::from (t2, prec1, TYPE_SIGN (TREE_TYPE (t2))) == t1;
> return 0;
> }
>
> @@ -7080,7 +7070,7 @@ simple_cst_equal (const_tree t1, const_t
> switch (code1)
> {
> case INTEGER_CST:
> - return wi::eq_p (t1, t2);
> + return wi::extend (t1) == wi::extend (t2);
>
> case REAL_CST:
> return REAL_VALUES_IDENTICAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2));
> Index: gcc/tree.h
> ===================================================================
> --- gcc/tree.h 2013-10-22 10:18:04.494966041 +0100
> +++ gcc/tree.h 2013-10-22 10:18:20.400102295 +0100
> @@ -5239,7 +5239,7 @@ #define ANON_AGGRNAME_FORMAT "__anon_%d"
> template <>
> struct int_traits <const_tree>
> {
> - static const enum precision_type precision_type = FLEXIBLE_PRECISION;
> + static const enum precision_type precision_type = VAR_PRECISION;
> static const bool host_dependent_precision = false;
> static unsigned int get_precision (const_tree);
> static wi::storage_ref decompose (HOST_WIDE_INT *, unsigned int,
> @@ -5248,6 +5248,34 @@ #define ANON_AGGRNAME_FORMAT "__anon_%d"
>
> template <>
> struct int_traits <tree> : public int_traits <const_tree> {};
> +
> + template <int N>
> + class extended_tree
> + {
> + private:
> + const_tree m_t;
> +
> + public:
> + extended_tree (const_tree);
> +
> + unsigned int get_precision () const;
> + const HOST_WIDE_INT *get_val () const;
> + unsigned int get_len () const;
> + };
> +
> + template <>
> + template <int N>
> + struct int_traits <extended_tree <N> >
> + {
> + static const enum precision_type precision_type = CONST_PRECISION;
> + static const bool host_dependent_precision = false;
> + static const unsigned int precision = N;
> + };
> +
> + generic_wide_int <extended_tree <MAX_BITSIZE_MODE_ANY_INT> >
> + extend (const_tree);
> +
> + generic_wide_int <extended_tree <ADDR_MAX_PRECISION> > address (const_tree);
> }
>
> inline unsigned int
> @@ -5265,9 +5293,8 @@ wi::int_traits <const_tree>::decompose (
> const HOST_WIDE_INT *val = (const HOST_WIDE_INT *) &TREE_INT_CST_ELT (x, 0);
> unsigned int max_len = ((precision + HOST_BITS_PER_WIDE_INT - 1)
> / HOST_BITS_PER_WIDE_INT);
> - unsigned int xprecision = get_precision (x);
>
> - gcc_assert (precision >= xprecision);
> + gcc_checking_assert (precision == get_precision (x));
>
> /* If an unsigned constant occupies a whole number of HWIs and has the
> upper bit set, its representation includes an extra zero HWI,
> @@ -5282,6 +5309,46 @@ wi::int_traits <const_tree>::decompose (
> return wi::storage_ref (val, len, precision);
> }
>
> +inline generic_wide_int <wi::extended_tree <MAX_BITSIZE_MODE_ANY_INT> >
> +wi::extend (const_tree t)
> +{
> + return t;
> +}
> +
> +inline generic_wide_int <wi::extended_tree <ADDR_MAX_PRECISION> >
> +wi::address (const_tree t)
> +{
> + return t;
> +}
> +
> +template <int N>
> +inline wi::extended_tree <N>::extended_tree (const_tree t)
> + : m_t (t)
> +{
> + gcc_checking_assert (TYPE_PRECISION (TREE_TYPE (t)) <= N);
> +}
> +
> +template <int N>
> +inline unsigned int
> +wi::extended_tree <N>::get_precision () const
> +{
> + return N;
> +}
> +
> +template <int N>
> +inline const HOST_WIDE_INT *
> +wi::extended_tree <N>::get_val () const
> +{
> + return &TREE_INT_CST_ELT (m_t, 0);
> +}
> +
> +template <int N>
> +inline unsigned int
> +wi::extended_tree <N>::get_len () const
> +{
> + return TREE_INT_CST_NUNITS (m_t);
> +}
> +
> namespace wi
> {
> template <typename T>
> Index: gcc/varasm.c
> ===================================================================
> --- gcc/varasm.c 2013-10-22 10:18:04.495966050 +0100
> +++ gcc/varasm.c 2013-10-22 10:18:20.401102303 +0100
> @@ -4812,10 +4812,10 @@ array_size_for_constructor (tree val)
>
> /* Compute the total number of array elements. */
> tmp = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (val)));
> - i = addr_wide_int (max_index) - tmp + 1;
> + i = wi::address (max_index) - wi::address (tmp) + 1;
>
> /* Multiply by the array element unit size to find number of bytes. */
> - i *= addr_wide_int (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (val))));
> + i *= wi::address (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (val))));
>
> gcc_assert (wi::fits_uhwi_p (i));
> return i.to_uhwi ();
> @@ -4899,8 +4899,10 @@ output_constructor_regular_field (oc_loc
> but we are using an unsigned sizetype. */
> unsigned prec = TYPE_PRECISION (sizetype);
> addr_wide_int idx
> - = wi::sext (addr_wide_int (local->index) - local->min_index, prec);
> - fieldpos = (idx * TYPE_SIZE_UNIT (TREE_TYPE (local->val))).to_shwi ();
> + = wi::sext (wi::address (local->index)
> + - wi::address (local->min_index), prec);
> + fieldpos = (idx * wi::address (TYPE_SIZE_UNIT (TREE_TYPE (local->val))))
> + .to_shwi ();
> }
> else if (local->field != NULL_TREE)
> fieldpos = int_byte_position (local->field);
> Index: gcc/wide-int.h
> ===================================================================
> --- gcc/wide-int.h 2013-10-22 10:17:29.995670564 +0100
> +++ gcc/wide-int.h 2013-10-22 10:18:20.402102312 +0100
> @@ -251,6 +251,46 @@ #define ADDR_MAX_BITSIZE 64
> #define ADDR_MAX_PRECISION \
> ((ADDR_MAX_BITSIZE + 4 + HOST_BITS_PER_WIDE_INT - 1) & ~(HOST_BITS_PER_WIDE_INT - 1))
>
> +/* The type of result produced by a binary operation on types T1 and T2.
> + Defined purely for brevity. */
> +#define WI_BINARY_RESULT(T1, T2) \
> + typename wi::binary_traits <T1, T2>::result_type
> +
> +/* The type of result produced by a unary operation on type T. */
> +#define WI_UNARY_RESULT(T) \
> + typename wi::unary_traits <T>::result_type
> +
> +/* Define a variable RESULT to hold the result of a binary operation on
> + X and Y, which have types T1 and T2 respectively. Define VAR to
> + point to the blocks of RESULT. Once the user of the macro has
> + filled in VAR, it should call RESULT.set_len to set the number
> + of initialized blocks. */
> +#define WI_BINARY_RESULT_VAR(RESULT, VAL, T1, X, T2, Y) \
> + WI_BINARY_RESULT (T1, T2) RESULT = \
> + wi::int_traits <WI_BINARY_RESULT (T1, T2)>::get_binary_result (X, Y); \
> + HOST_WIDE_INT *VAL = RESULT.write_val ()
> +
> +/* Similar for the result of a unary operation on X, which has type T. */
> +#define WI_UNARY_RESULT_VAR(RESULT, VAL, T, X) \
> + WI_UNARY_RESULT (T) RESULT = \
> + wi::int_traits <WI_UNARY_RESULT (T)>::get_binary_result (X, X); \
> + HOST_WIDE_INT *VAL = RESULT.write_val ()
> +
> +template <typename T> struct generic_wide_int;
> +template <int N> struct fixed_wide_int_storage;
> +struct wide_int_storage;
> +
> +/* An N-bit integer. Until we can use typedef templates, use this instead. */
> +#define FIXED_WIDE_INT(N) \
> + generic_wide_int < fixed_wide_int_storage <N> >
> +
> +typedef generic_wide_int <wide_int_storage> wide_int;
> +typedef FIXED_WIDE_INT (ADDR_MAX_PRECISION) addr_wide_int;
> +typedef FIXED_WIDE_INT (MAX_BITSIZE_MODE_ANY_INT) max_wide_int;
> +
> +struct wide_int_ref_storage;
> +typedef generic_wide_int <wide_int_ref_storage> wide_int_ref;
> +
> namespace wi
> {
> /* Classifies an integer based on its precision. */
> @@ -303,40 +343,70 @@ #define ADDR_MAX_PRECISION \
> a binary operation on two values of type T. */
> template <typename T>
> struct unary_traits : public binary_traits <T, T> {};
> -}
>
> -/* The type of result produced by a binary operation on types T1 and T2.
> - Defined purely for brevity. */
> -#define WI_BINARY_RESULT(T1, T2) \
> - typename wi::binary_traits <T1, T2>::result_type
> + /* Specify the result type for each supported combination of binary
> + inputs. Note that CONST_PRECISION and VAR_PRECISION cannot be
> + mixed, in order to give stronger type checking. When both inputs
> + are CONST_PRECISION, they must have the same precision. */
> + template <>
> + template <typename T1, typename T2>
> + struct binary_traits <T1, T2, FLEXIBLE_PRECISION, FLEXIBLE_PRECISION>
> + {
> + typedef max_wide_int result_type;
> + };
>
> -/* The type of result produced by a unary operation on type T. */
> -#define WI_UNARY_RESULT(T) \
> - typename wi::unary_traits <T>::result_type
> + template <>
> + template <typename T1, typename T2>
> + struct binary_traits <T1, T2, FLEXIBLE_PRECISION, VAR_PRECISION>
> + {
> + typedef wide_int result_type;
> + };
>
> -/* Define a variable RESULT to hold the result of a binary operation on
> - X and Y, which have types T1 and T2 respectively. Define VAR to
> - point to the blocks of RESULT. Once the user of the macro has
> - filled in VAR, it should call RESULT.set_len to set the number
> - of initialized blocks. */
> -#define WI_BINARY_RESULT_VAR(RESULT, VAL, T1, X, T2, Y) \
> - WI_BINARY_RESULT (T1, T2) RESULT = \
> - wi::int_traits <WI_BINARY_RESULT (T1, T2)>::get_binary_result (X, Y); \
> - HOST_WIDE_INT *VAL = RESULT.write_val ()
> + template <>
> + template <typename T1, typename T2>
> + struct binary_traits <T1, T2, FLEXIBLE_PRECISION, CONST_PRECISION>
> + {
> + /* Spelled out explicitly (rather than through FIXED_WIDE_INT)
> + so as not to confuse gengtype. */
> + typedef generic_wide_int < fixed_wide_int_storage
> + <int_traits <T2>::precision> > result_type;
> + };
>
> -/* Similar for the result of a unary operation on X, which has type T. */
> -#define WI_UNARY_RESULT_VAR(RESULT, VAL, T, X) \
> - WI_UNARY_RESULT (T) RESULT = \
> - wi::int_traits <WI_UNARY_RESULT (T)>::get_binary_result (X, X); \
> - HOST_WIDE_INT *VAL = RESULT.write_val ()
> + template <>
> + template <typename T1, typename T2>
> + struct binary_traits <T1, T2, VAR_PRECISION, FLEXIBLE_PRECISION>
> + {
> + typedef wide_int result_type;
> + };
>
> -template <typename T> struct generic_wide_int;
> + template <>
> + template <typename T1, typename T2>
> + struct binary_traits <T1, T2, CONST_PRECISION, FLEXIBLE_PRECISION>
> + {
> + /* Spelled out explicitly (rather than through FIXED_WIDE_INT)
> + so as not to confuse gengtype. */
> + typedef generic_wide_int < fixed_wide_int_storage
> + <int_traits <T1>::precision> > result_type;
> + };
>
> -struct wide_int_storage;
> -typedef generic_wide_int <wide_int_storage> wide_int;
> + template <>
> + template <typename T1, typename T2>
> + struct binary_traits <T1, T2, CONST_PRECISION, CONST_PRECISION>
> + {
> + /* Spelled out explicitly (rather than through FIXED_WIDE_INT)
> + so as not to confuse gengtype. */
> + STATIC_ASSERT (int_traits <T1>::precision == int_traits <T2>::precision);
> + typedef generic_wide_int < fixed_wide_int_storage
> + <int_traits <T1>::precision> > result_type;
> + };
>
> -struct wide_int_ref_storage;
> -typedef generic_wide_int <wide_int_ref_storage> wide_int_ref;
> + template <>
> + template <typename T1, typename T2>
> + struct binary_traits <T1, T2, VAR_PRECISION, VAR_PRECISION>
> + {
> + typedef wide_int result_type;
> + };
> +}
>
> /* Public functions for querying and operating on integers. */
> namespace wi
> @@ -572,38 +642,39 @@ #define BINARY_PREDICATE(OP, F) \
> bool OP (const T &c) const { return wi::F (*this, c); }
>
> #define UNARY_OPERATOR(OP, F) \
> - generic_wide_int OP () const { return wi::F (*this); }
> + WI_UNARY_RESULT (generic_wide_int) OP () const { return wi::F (*this); }
>
> #define BINARY_OPERATOR(OP, F) \
> template <typename T> \
> - generic_wide_int OP (const T &c) const { return wi::F (*this, c); }
> + WI_BINARY_RESULT (generic_wide_int, T) \
> + OP (const T &c) const { return wi::F (*this, c); }
>
> #define ASSIGNMENT_OPERATOR(OP, F) \
> template <typename T> \
> - generic_wide_int &OP (const T &c) { return (*this = wi::F (*this, c)); }
> + generic_wide_int &OP (const T &c) { return (*this = wi::F (*this, c)); }
>
> #define INCDEC_OPERATOR(OP, DELTA) \
> generic_wide_int &OP () { *this += DELTA; return *this; }
>
> - UNARY_OPERATOR (operator ~, bit_not) \
> - UNARY_OPERATOR (operator -, neg) \
> - BINARY_PREDICATE (operator ==, eq_p) \
> - BINARY_PREDICATE (operator !=, ne_p) \
> - BINARY_OPERATOR (operator &, bit_and) \
> - BINARY_OPERATOR (and_not, bit_and_not) \
> - BINARY_OPERATOR (operator |, bit_or) \
> - BINARY_OPERATOR (or_not, bit_or_not) \
> - BINARY_OPERATOR (operator ^, bit_xor) \
> - BINARY_OPERATOR (operator +, add) \
> - BINARY_OPERATOR (operator -, sub) \
> - BINARY_OPERATOR (operator *, mul) \
> - ASSIGNMENT_OPERATOR (operator &=, bit_and) \
> - ASSIGNMENT_OPERATOR (operator |=, bit_or) \
> - ASSIGNMENT_OPERATOR (operator ^=, bit_xor) \
> - ASSIGNMENT_OPERATOR (operator +=, add) \
> - ASSIGNMENT_OPERATOR (operator -=, sub) \
> - ASSIGNMENT_OPERATOR (operator *=, mul) \
> - INCDEC_OPERATOR (operator ++, 1) \
> + UNARY_OPERATOR (operator ~, bit_not)
> + UNARY_OPERATOR (operator -, neg)
> + BINARY_PREDICATE (operator ==, eq_p)
> + BINARY_PREDICATE (operator !=, ne_p)
> + BINARY_OPERATOR (operator &, bit_and)
> + BINARY_OPERATOR (and_not, bit_and_not)
> + BINARY_OPERATOR (operator |, bit_or)
> + BINARY_OPERATOR (or_not, bit_or_not)
> + BINARY_OPERATOR (operator ^, bit_xor)
> + BINARY_OPERATOR (operator +, add)
> + BINARY_OPERATOR (operator -, sub)
> + BINARY_OPERATOR (operator *, mul)
> + ASSIGNMENT_OPERATOR (operator &=, bit_and)
> + ASSIGNMENT_OPERATOR (operator |=, bit_or)
> + ASSIGNMENT_OPERATOR (operator ^=, bit_xor)
> + ASSIGNMENT_OPERATOR (operator +=, add)
> + ASSIGNMENT_OPERATOR (operator -=, sub)
> + ASSIGNMENT_OPERATOR (operator *=, mul)
> + INCDEC_OPERATOR (operator ++, 1)
> INCDEC_OPERATOR (operator --, -1)
>
> #undef BINARY_PREDICATE
> @@ -848,6 +919,19 @@ class GTY(()) wide_int_storage
> wide_int bswap () const;
> };
>
> +namespace wi
> +{
> + template <>
> + struct int_traits <wide_int_storage>
> + {
> + static const enum precision_type precision_type = VAR_PRECISION;
> + /* Guaranteed by a static assert in the wide_int_storage constructor. */
> + static const bool host_dependent_precision = false;
> + template <typename T1, typename T2>
> + static wide_int get_binary_result (const T1 &, const T2 &);
> + };
> +}
> +
> inline wide_int_storage::wide_int_storage () {}
>
> /* Initialize the storage from integer X, in its natural precision.
> @@ -933,19 +1017,6 @@ wide_int_storage::create (unsigned int p
> return x;
> }
>
> -namespace wi
> -{
> - template <>
> - struct int_traits <wide_int_storage>
> - {
> - static const enum precision_type precision_type = VAR_PRECISION;
> - /* Guaranteed by a static assert in the wide_int_storage constructor. */
> - static const bool host_dependent_precision = false;
> - template <typename T1, typename T2>
> - static wide_int get_binary_result (const T1 &, const T2 &);
> - };
> -}
> -
> template <typename T1, typename T2>
> inline wide_int
> wi::int_traits <wide_int_storage>::get_binary_result (const T1 &x, const T2 &y)
> @@ -959,10 +1030,6 @@ wi::int_traits <wide_int_storage>::get_b
> return wide_int::create (wi::get_precision (x));
> }
>
> -/* An N-bit integer. Until we can use typedef templates, use this instead. */
> -#define FIXED_WIDE_INT(N) \
> - generic_wide_int < fixed_wide_int_storage <N> >
> -
> /* The storage used by FIXED_WIDE_INT (N). */
> template <int N>
> class GTY(()) fixed_wide_int_storage
> @@ -988,8 +1055,19 @@ class GTY(()) fixed_wide_int_storage
> bool = true);
> };
>
> -typedef FIXED_WIDE_INT (ADDR_MAX_PRECISION) addr_wide_int;
> -typedef FIXED_WIDE_INT (MAX_BITSIZE_MODE_ANY_INT) max_wide_int;
> +namespace wi
> +{
> + template <>
> + template <int N>
> + struct int_traits < fixed_wide_int_storage <N> >
> + {
> + static const enum precision_type precision_type = CONST_PRECISION;
> + static const bool host_dependent_precision = false;
> + static const unsigned int precision = N;
> + template <typename T1, typename T2>
> + static FIXED_WIDE_INT (N) get_binary_result (const T1 &, const T2 &);
> + };
> +}
>
> template <int N>
> inline fixed_wide_int_storage <N>::fixed_wide_int_storage () {}
> @@ -1071,20 +1149,6 @@ fixed_wide_int_storage <N>::from_array (
> return result;
> }
>
> -namespace wi
> -{
> - template <>
> - template <int N>
> - struct int_traits < fixed_wide_int_storage <N> >
> - {
> - static const enum precision_type precision_type = CONST_PRECISION;
> - static const bool host_dependent_precision = false;
> - static const unsigned int precision = N;
> - template <typename T1, typename T2>
> - static FIXED_WIDE_INT (N) get_binary_result (const T1 &, const T2 &);
> - };
> -}
> -
> template <int N>
> template <typename T1, typename T2>
> inline FIXED_WIDE_INT (N)
> @@ -1094,72 +1158,6 @@ get_binary_result (const T1 &, const T2
> return FIXED_WIDE_INT (N) ();
> }
>
> -/* Specify the result type for each supported combination of binary
> - inputs. Note that CONST_PRECISION and VAR_PRECISION cannot be
> - mixed, in order to give stronger type checking. When both inputs
> - are CONST_PRECISION, they must have the same precision. */
> -namespace wi
> -{
> - template <>
> - template <typename T1, typename T2>
> - struct binary_traits <T1, T2, FLEXIBLE_PRECISION, FLEXIBLE_PRECISION>
> - {
> - typedef max_wide_int result_type;
> - };
> -
> - template <>
> - template <typename T1, typename T2>
> - struct binary_traits <T1, T2, FLEXIBLE_PRECISION, VAR_PRECISION>
> - {
> - typedef wide_int result_type;
> - };
> -
> - template <>
> - template <typename T1, typename T2>
> - struct binary_traits <T1, T2, FLEXIBLE_PRECISION, CONST_PRECISION>
> - {
> - /* Spelled out explicitly (rather than through FIXED_WIDE_INT)
> - so as not to confuse gengtype. */
> - typedef generic_wide_int < fixed_wide_int_storage
> - <int_traits <T2>::precision> > result_type;
> - };
> -
> - template <>
> - template <typename T1, typename T2>
> - struct binary_traits <T1, T2, VAR_PRECISION, FLEXIBLE_PRECISION>
> - {
> - typedef wide_int result_type;
> - };
> -
> - template <>
> - template <typename T1, typename T2>
> - struct binary_traits <T1, T2, CONST_PRECISION, FLEXIBLE_PRECISION>
> - {
> - /* Spelled out explicitly (rather than through FIXED_WIDE_INT)
> - so as not to confuse gengtype. */
> - typedef generic_wide_int < fixed_wide_int_storage
> - <int_traits <T1>::precision> > result_type;
> - };
> -
> - template <>
> - template <typename T1, typename T2>
> - struct binary_traits <T1, T2, CONST_PRECISION, CONST_PRECISION>
> - {
> - /* Spelled out explicitly (rather than through FIXED_WIDE_INT)
> - so as not to confuse gengtype. */
> - STATIC_ASSERT (int_traits <T1>::precision == int_traits <T2>::precision);
> - typedef generic_wide_int < fixed_wide_int_storage
> - <int_traits <T1>::precision> > result_type;
> - };
> -
> - template <>
> - template <typename T1, typename T2>
> - struct binary_traits <T1, T2, VAR_PRECISION, VAR_PRECISION>
> - {
> - typedef wide_int result_type;
> - };
> -}
> -
> namespace wi
> {
> /* Implementation of int_traits for primitive integer types like "int". */
> @@ -1288,9 +1286,7 @@ wi::two (unsigned int precision)
> template <>
> struct int_traits <wi::hwi_with_prec>
> {
> - /* Since we have a sign, we can extend or truncate the integer to
> - other precisions where necessary. */
> - static const enum precision_type precision_type = FLEXIBLE_PRECISION;
> + static const enum precision_type precision_type = VAR_PRECISION;
> /* hwi_with_prec has an explicitly-given precision, rather than the
> precision of HOST_WIDE_INT. */
> static const bool host_dependent_precision = false;
>
>
--
Richard Biener <rguenther@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend
More information about the Gcc-patches
mailing list