summaryrefslogtreecommitdiff
path: root/gcc/explow.c
diff options
context:
space:
mode:
authorcrowl <crowl@138bc75d-0d04-0410-961f-82ee72b054a4>2012-09-24 18:22:31 +0000
committercrowl <crowl@138bc75d-0d04-0410-961f-82ee72b054a4>2012-09-24 18:22:31 +0000
commitd67b711955a845f469a37437ab471a3a5985b787 (patch)
tree023b0bf502c0f425e346dd501e463d522b3de28e /gcc/explow.c
parenta2dc95ebfe0e8f59dc5b1ab46be92c1399bb5584 (diff)
downloadgcc-d67b711955a845f469a37437ab471a3a5985b787.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@191675 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/explow.c')
-rw-r--r--gcc/explow.c33
1 files changed, 15 insertions, 18 deletions
diff --git a/gcc/explow.c b/gcc/explow.c
index 0563a231d68..61098324aae 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -100,36 +100,33 @@ plus_constant (enum machine_mode mode, rtx x, HOST_WIDE_INT c)
case CONST_INT:
if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
{
- unsigned HOST_WIDE_INT l1 = INTVAL (x);
- HOST_WIDE_INT h1 = (l1 >> (HOST_BITS_PER_WIDE_INT - 1)) ? -1 : 0;
- unsigned HOST_WIDE_INT l2 = c;
- HOST_WIDE_INT h2 = c < 0 ? -1 : 0;
- unsigned HOST_WIDE_INT lv;
- HOST_WIDE_INT hv;
-
- if (add_double_with_sign (l1, h1, l2, h2, &lv, &hv, false))
+ double_int di_x = double_int::from_shwi (INTVAL (x));
+ double_int di_c = double_int::from_shwi (c);
+
+ bool overflow;
+ double_int v = di_x.add_with_sign (di_c, false, &overflow);
+ if (overflow)
gcc_unreachable ();
- return immed_double_const (lv, hv, VOIDmode);
+ return immed_double_int_const (v, VOIDmode);
}
return GEN_INT (INTVAL (x) + c);
case CONST_DOUBLE:
{
- unsigned HOST_WIDE_INT l1 = CONST_DOUBLE_LOW (x);
- HOST_WIDE_INT h1 = CONST_DOUBLE_HIGH (x);
- unsigned HOST_WIDE_INT l2 = c;
- HOST_WIDE_INT h2 = c < 0 ? -1 : 0;
- unsigned HOST_WIDE_INT lv;
- HOST_WIDE_INT hv;
-
- if (add_double_with_sign (l1, h1, l2, h2, &lv, &hv, false))
+ double_int di_x = double_int::from_pair (CONST_DOUBLE_HIGH (x),
+ CONST_DOUBLE_LOW (x));
+ double_int di_c = double_int::from_shwi (c);
+
+ bool overflow;
+ double_int v = di_x.add_with_sign (di_c, false, &overflow);
+ if (overflow)
/* Sorry, we have no way to represent overflows this wide.
To fix, add constant support wider than CONST_DOUBLE. */
gcc_assert (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_DOUBLE_INT);
- return immed_double_const (lv, hv, VOIDmode);
+ return immed_double_int_const (v, VOIDmode);
}
case MEM: