aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
authorLawrence Crowl <crowl@google.com>2012-09-24 18:22:31 +0000
committerLawrence Crowl <crowl@gcc.gnu.org>2012-09-24 18:22:31 +0000
commit9be0ac8c9e638bc1b52b83d34a98e8176af645e1 (patch)
tree023b0bf502c0f425e346dd501e463d522b3de28e /gcc/fold-const.c
parentee38ecd4066dc3af0b893f2f4cda42d7938fa951 (diff)
downloadgcc-9be0ac8c9e638bc1b52b83d34a98e8176af645e1.zip
gcc-9be0ac8c9e638bc1b52b83d34a98e8176af645e1.tar.gz
gcc-9be0ac8c9e638bc1b52b83d34a98e8176af645e1.tar.bz2
Finish conversion of uses of double_int to the new API.
Some old functionality required new interfaces, and these have been added to double-int.[hc]: double_int::from_pair - static constructor function wide_mul_with_sign - double-wide multiply instruction sub_with_overflow - subtraction with overlow testing neg_with_overflow - negation with overlow testing divmod_with_overflow - div and mod with overlow testing This patch corrects the bootstrap problem on HPPA, via the addition of sub_with_overflow. (The overflow properties of negation and addition are different from subtraction.) The prior two generations of the interface have been removed. Some of these old interfaces are still used as static implementation in double-int.c. The changed compiler appears 0.321% faster with 80% confidence of being faster. Tested on x86_64, HPPA, and SPARC. However, there are changes to the avr config files, and I have not tested those. Index: gcc/java/ChangeLog 2012-09-24 Lawrence Crowl <crowl@google.com> * decl.c (java_init_decl_processing): Change to new double_int API. * jcf-parse.c (get_constant): Likewise. * boehm.c (mark_reference_fields): Likewise. (get_boehm_type_descriptor): Likewise. Index: gcc/ChangeLog 2012-09-24 Lawrence Crowl <crowl@google.com> * double-int.h (double_int::from_pair): New. (double_int::wide_mul_with_sign): New. (double_int::sub_with_overflow): New. (double_int::neg_with_overflow): New. (double_int::divmod_with_overflow): New. (shwi_to_double_int): Remove. (uhwi_to_double_int): Remove. (double_int_to_shwi): Remove. (double_int_to_uhwi): Remove. (double_int_fits_in_uhwi_p): Remove. (double_int_fits_in_shwi_p): Remove. (double_int_fits_in_hwi_p): Remove. (double_int_mul): Remove. (double_int_mul_with_sign): Remove. (double_int_add): Remove. (double_int_sub): Remove. (double_int_neg): Remove. (double_int_div): Remove. (double_int_sdiv): Remove. (double_int_udiv): Remove. (double_int_mod): Remove. (double_int_smod): Remove. (double_int_umod): Remove. (double_int_divmod): Remove. (double_int_sdivmod): Remove. (double_int_udivmod): Remove. (double_int_multiple_of): Remove. (double_int_setbit): Remove. (double_int_ctz): Remove. (double_int_not): Remove. (double_int_ior): Remove. (double_int_and): Remove. (double_int_and_not): Remove. (double_int_xor): Remove. (double_int_lshift): Remove. (double_int_rshift): Remove. (double_int_lrotate): Remove. (double_int_rrotate): Remove. (double_int_negative_p): Remove. (double_int_cmp): Remove. (double_int_scmp): Remove. (double_int_ucmp): Remove. (double_int_max): Remove. (double_int_smax): Remove. (double_int_umax): Remove. (double_int_min): Remove. (double_int_smin): Remove. (double_int_umin): Remove. (double_int_ext): Remove. (double_int_sext): Remove. (double_int_zext): Remove. (double_int_mask): Remove. (double_int_max_value): Remove. (double_int_min_value): Remove. (double_int_zero_p): Remove. (double_int_one_p): Remove. (double_int_minus_one_p): Remove. (double_int_equal_p): Remove. (double_int_popcount): Remove. (extern add_double_with_sign): Remove. (#define add_double): Remove. (extern neg_double): Remove. (extern mul_double_with_sign): Remove. (extern mul_double_wide_with_sign): Remove. (#define mul_double): Remove. (extern lshift_double): Remove. (extern div_and_round_double): Remove. * double-int.c (add_double_with_sign): Make static. (#defined add_double): Localized from header. (neg_double): Make static. (mul_double_with_sign): Make static. (mul_double_wide_with_sign): Make static. (#defined mul_double): Localized from header. (lshift_double): Make static. (div_and_round_double): Make static. (double_int::wide_mul_with_sign): New. (double_int::sub_with_overflow): New. (double_int::neg_with_overflow): New. (double_int::divmod_with_overflow): New. * emit-rtl.c (init_emit_once): Change to new double_int API. * explow.c (plus_constant): Likewise. * expmed.c (choose_multiplier): Likewise. * fold-const.c (#define OVERFLOW_SUM_SIGN): Remove. (int_const_binop_1): Change to new double_int API. (fold_div_compare): Likewise. (maybe_canonicalize_comparison): Likewise. (pointer_may_wrap_p): Likewise. (fold_negate_const): Likewise. (fold_abs_const): Likewise. * simplify-rtx.c (simplify_const_unary_operation): Likewise. (simplify_const_binary_operation): Likewise. * tree-chrec.c (tree_fold_binomial): Likewise. * tree-vrp.c (extract_range_from_binary_expr_1): Likewise. * config/sparc/sparc.c (sparc_fold_builtin): Likewise. * config/avr/avr.c (avr_double_int_push_digit): Likewise. (avr_map): Likewise. (avr_map_decompose): Likewise. (avr_out_insert_bits): Likewise. Index: gcc/cp/ChangeLog 2012-09-24 Lawrence Crowl <crowl@google.com> * init.c (build_new_1): Change to new double_int API. * decl.c (build_enumerator): Likewise. * typeck2.c (process_init_constructor_array): Likewise. * mangle.c (write_array_type): Likewise. Index: gcc/fortran/ChangeLog 2012-09-24 Lawrence Crowl <crowl@google.com> * trans-expr.c (gfc_conv_cst_int_power): Change to new double_int API. * target-memory.c (gfc_interpret_logical): Likewise. From-SVN: r191675
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c81
1 files changed, 22 insertions, 59 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 223dc68..3197cef 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -165,17 +165,6 @@ protected_set_expr_location_unshare (tree x, location_t loc)
}
return x;
}
-
-
-/* We know that A1 + B1 = SUM1, using 2's complement arithmetic and ignoring
- overflow. Suppose A, B and SUM have the same respective signs as A1, B1,
- and SUM1. Then this yields nonzero if overflow occurred during the
- addition.
-
- Overflow occurs if A and B have the same sign, but A and SUM differ in
- sign. Use `^' to test whether signs differ, and `< 0' to isolate the
- sign. */
-#define OVERFLOW_SUM_SIGN(a, b, sum) ((~((a) ^ (b)) & ((a) ^ (sum))) < 0)
/* If ARG2 divides ARG1 with zero remainder, carries out the division
of type CODE and returns the quotient.
@@ -982,13 +971,7 @@ int_const_binop_1 (enum tree_code code, const_tree arg1, const_tree arg2,
break;
case MINUS_EXPR:
-/* FIXME(crowl) Remove this code if the replacment works.
- neg_double (op2.low, op2.high, &res.low, &res.high);
- add_double (op1.low, op1.high, res.low, res.high,
- &res.low, &res.high);
- overflow = OVERFLOW_SUM_SIGN (res.high, op2.high, op1.high);
-*/
- res = op1.add_with_sign (-op2, false, &overflow);
+ res = op1.sub_with_overflow (op2, &overflow);
break;
case MULT_EXPR:
@@ -1035,10 +1018,7 @@ int_const_binop_1 (enum tree_code code, const_tree arg1, const_tree arg2,
res = double_int_one;
break;
}
- overflow = div_and_round_double (code, uns,
- op1.low, op1.high, op2.low, op2.high,
- &res.low, &res.high,
- &tmp.low, &tmp.high);
+ res = op1.divmod_with_overflow (op2, uns, code, &tmp, &overflow);
break;
case TRUNC_MOD_EXPR:
@@ -1060,10 +1040,7 @@ int_const_binop_1 (enum tree_code code, const_tree arg1, const_tree arg2,
case ROUND_MOD_EXPR:
if (op2.is_zero ())
return NULL_TREE;
- overflow = div_and_round_double (code, uns,
- op1.low, op1.high, op2.low, op2.high,
- &tmp.low, &tmp.high,
- &res.low, &res.high);
+ tmp = op1.divmod_with_overflow (op2, uns, code, &res, &overflow);
break;
case MIN_EXPR:
@@ -6290,15 +6267,12 @@ fold_div_compare (location_t loc,
double_int val;
bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
bool neg_overflow;
- int overflow;
+ bool overflow;
/* We have to do this the hard way to detect unsigned overflow.
prod = int_const_binop (MULT_EXPR, arg01, arg1); */
- overflow = mul_double_with_sign (TREE_INT_CST_LOW (arg01),
- TREE_INT_CST_HIGH (arg01),
- TREE_INT_CST_LOW (arg1),
- TREE_INT_CST_HIGH (arg1),
- &val.low, &val.high, unsigned_p);
+ val = TREE_INT_CST (arg01)
+ .mul_with_sign (TREE_INT_CST (arg1), unsigned_p, &overflow);
prod = force_fit_type_double (TREE_TYPE (arg00), val, -1, overflow);
neg_overflow = false;
@@ -6309,11 +6283,8 @@ fold_div_compare (location_t loc,
lo = prod;
/* Likewise hi = int_const_binop (PLUS_EXPR, prod, tmp). */
- overflow = add_double_with_sign (TREE_INT_CST_LOW (prod),
- TREE_INT_CST_HIGH (prod),
- TREE_INT_CST_LOW (tmp),
- TREE_INT_CST_HIGH (tmp),
- &val.low, &val.high, unsigned_p);
+ val = TREE_INT_CST (prod)
+ .add_with_sign (TREE_INT_CST (tmp), unsigned_p, &overflow);
hi = force_fit_type_double (TREE_TYPE (arg00), val,
-1, overflow | TREE_OVERFLOW (prod));
}
@@ -8691,8 +8662,7 @@ maybe_canonicalize_comparison (location_t loc, enum tree_code code, tree type,
static bool
pointer_may_wrap_p (tree base, tree offset, HOST_WIDE_INT bitpos)
{
- unsigned HOST_WIDE_INT offset_low, total_low;
- HOST_WIDE_INT size, offset_high, total_high;
+ double_int di_offset, total;
if (!POINTER_TYPE_P (TREE_TYPE (base)))
return true;
@@ -8701,28 +8671,22 @@ pointer_may_wrap_p (tree base, tree offset, HOST_WIDE_INT bitpos)
return true;
if (offset == NULL_TREE)
- {
- offset_low = 0;
- offset_high = 0;
- }
+ di_offset = double_int_zero;
else if (TREE_CODE (offset) != INTEGER_CST || TREE_OVERFLOW (offset))
return true;
else
- {
- offset_low = TREE_INT_CST_LOW (offset);
- offset_high = TREE_INT_CST_HIGH (offset);
- }
+ di_offset = TREE_INT_CST (offset);
- if (add_double_with_sign (offset_low, offset_high,
- bitpos / BITS_PER_UNIT, 0,
- &total_low, &total_high,
- true))
+ bool overflow;
+ double_int units = double_int::from_uhwi (bitpos / BITS_PER_UNIT);
+ total = di_offset.add_with_sign (units, true, &overflow);
+ if (overflow)
return true;
- if (total_high != 0)
+ if (total.high != 0)
return true;
- size = int_size_in_bytes (TREE_TYPE (TREE_TYPE (base)));
+ HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (TREE_TYPE (base)));
if (size <= 0)
return true;
@@ -8737,7 +8701,7 @@ pointer_may_wrap_p (tree base, tree offset, HOST_WIDE_INT bitpos)
size = base_size;
}
- return total_low > (unsigned HOST_WIDE_INT) size;
+ return total.low > (unsigned HOST_WIDE_INT) size;
}
/* Subroutine of fold_binary. This routine performs all of the
@@ -15938,8 +15902,8 @@ fold_negate_const (tree arg0, tree type)
case INTEGER_CST:
{
double_int val = tree_to_double_int (arg0);
- int overflow = neg_double (val.low, val.high, &val.low, &val.high);
-
+ bool overflow;
+ val = val.neg_with_overflow (&overflow);
t = force_fit_type_double (type, val, 1,
(overflow | TREE_OVERFLOW (arg0))
&& !TYPE_UNSIGNED (type));
@@ -15996,9 +15960,8 @@ fold_abs_const (tree arg0, tree type)
its negation. */
else
{
- int overflow;
-
- overflow = neg_double (val.low, val.high, &val.low, &val.high);
+ bool overflow;
+ val = val.neg_with_overflow (&overflow);
t = force_fit_type_double (type, val, -1,
overflow | TREE_OVERFLOW (arg0));
}