Message ID | 87txg9cvzc.fsf@sandifor-thinkpad.stglab.manchester.uk.ibm.com |
---|---|
State | New |
Headers | show |
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> writes: >> 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)? offset_int, max_int, wi::to_offset and wi::to_max sound OK to me. Kenny? Mike? >> 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 is native_encode_int rather than native_interpret_int though. AIUI it's used for VIEW_CONVERT_EXPRs, so I thought the upper bits might get used. Thanks, Richard
On Wed, 23 Oct 2013, Richard Sandiford wrote: > Richard Biener <rguenther@suse.de> writes: > >> 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)? > > offset_int, max_int, wi::to_offset and wi::to_max sound OK to me. > Kenny? Mike? > > >> 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 is native_encode_int rather than native_interpret_int though. Yes, I was looking at the matched interpret variant though to see what we do. > AIUI it's used for VIEW_CONVERT_EXPRs, so I thought the upper bits > might get used. Yeah, that might happen, but still relying on the upper bits in any way would be brittle here. Richard.
On 10/23/2013 08:13 AM, Richard Biener wrote: > On Wed, 23 Oct 2013, Richard Sandiford wrote: > >> Richard Biener <rguenther@suse.de> writes: >>>> 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)? >> offset_int, max_int, wi::to_offset and wi::to_max sound OK to me. >> Kenny? Mike? >> >>>> 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 is native_encode_int rather than native_interpret_int though. > Yes, I was looking at the matched interpret variant though to see > what we do. > the wide_int_to_tree really needs to canonicalize the value before making it into a tree. the calls to tree_fits*_p (the successor to host_integer_p) depend on this being clean. Otherwise, these functions will have to clean the short integers and they get called all over the place. >> AIUI it's used for VIEW_CONVERT_EXPRs, so I thought the upper bits >> might get used. > Yeah, that might happen, but still relying on the upper bits in any > way would be brittle here. > > Richard.
On Oct 23, 2013, at 2:09 AM, Richard Biener <rguenther@suse.de> wrote: > 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 The idea was to have one type to rule them all… everything address related... bit offsets, byte offsets… Bit offset is the wrong name, as that would be a wrong type to use for a byte offset. Someone that has a bit offset type, would naturally want to /8 to get a byte offset. If one wanted a bit offset, then it should be split into two, bit offset and byte offset.
On Oct 23, 2013, at 5:00 AM, Richard Sandiford <rsandifo@linux.vnet.ibm.com> wrote: > offset_int, max_int, wi::to_offset and wi::to_max sound OK to me. > Kenny? Mike? Those two names seem reasonable. to_offset should document that these are for address offsets (and address constants) exclusively.
Mike Stump <mikestump@comcast.net> writes: > On Oct 23, 2013, at 5:00 AM, Richard Sandiford > <rsandifo@linux.vnet.ibm.com> wrote: >> offset_int, max_int, wi::to_offset and wi::to_max sound OK to me. >> Kenny? Mike? > > Those two names seem reasonable. to_offset should document that these > are for address offsets (and address constants) exclusively. Reading this back, I realise "max_int" might sound too similar to INT_MAX. Maybe we could follow the current HOST_* stuff and use: offset_int, widest_int, wi::to_offset and wi::to_widest. Bah. I'm no good at naming stuff... Richard
On Wed, 23 Oct 2013, Richard Sandiford wrote: > Mike Stump <mikestump@comcast.net> writes: > > On Oct 23, 2013, at 5:00 AM, Richard Sandiford > > <rsandifo@linux.vnet.ibm.com> wrote: > >> offset_int, max_int, wi::to_offset and wi::to_max sound OK to me. > >> Kenny? Mike? > > > > Those two names seem reasonable. to_offset should document that these > > are for address offsets (and address constants) exclusively. > > Reading this back, I realise "max_int" might sound too similar to INT_MAX. > Maybe we could follow the current HOST_* stuff and use: offset_int, widest_int, > wi::to_offset and wi::to_widest. > > Bah. I'm no good at naming stuff... Nobody is ... but yes, offset_int and widest_int and wi::to_offset and wi::to_widest sounds good to me - both short and descriptive. 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;