summaryrefslogtreecommitdiff
path: root/gcc/double-int.h
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/double-int.h
parentee38ecd4066dc3af0b893f2f4cda42d7938fa951 (diff)
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/double-int.h')
-rw-r--r--gcc/double-int.h460
1 files changed, 18 insertions, 442 deletions
diff --git a/gcc/double-int.h b/gcc/double-int.h
index bc7aca1896a..f4eb6ab0a77 100644
--- a/gcc/double-int.h
+++ b/gcc/double-int.h
@@ -61,6 +61,7 @@ struct double_int
static double_int from_uhwi (unsigned HOST_WIDE_INT cst);
static double_int from_shwi (HOST_WIDE_INT cst);
+ static double_int from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low);
/* No copy assignment operator or destructor to keep the type a POD. */
@@ -105,9 +106,17 @@ struct double_int
/* Arithmetic operation functions. */
+ /* The following operations perform arithmetics modulo 2^precision, so you
+ do not need to call .ext between them, even if you are representing
+ numbers with precision less than HOST_BITS_PER_DOUBLE_INT bits. */
+
double_int set_bit (unsigned) const;
double_int mul_with_sign (double_int, bool unsigned_p, bool *overflow) const;
+ double_int wide_mul_with_sign (double_int, bool unsigned_p,
+ double_int *higher, bool *overflow) const;
double_int add_with_sign (double_int, bool unsigned_p, bool *overflow) const;
+ double_int sub_with_overflow (double_int, bool *overflow) const;
+ double_int neg_with_overflow (bool *overflow) const;
double_int operator * (double_int) const;
double_int operator + (double_int) const;
@@ -131,12 +140,15 @@ struct double_int
/* You must ensure that double_int::ext is called on the operands
of the following operations, if the precision of the numbers
is less than HOST_BITS_PER_DOUBLE_INT bits. */
+
double_int div (double_int, bool, unsigned) const;
double_int sdiv (double_int, unsigned) const;
double_int udiv (double_int, unsigned) const;
double_int mod (double_int, bool, unsigned) const;
double_int smod (double_int, unsigned) const;
double_int umod (double_int, unsigned) const;
+ double_int divmod_with_overflow (double_int, bool, unsigned,
+ double_int *, bool *) const;
double_int divmod (double_int, bool, unsigned, double_int *) const;
double_int sdivmod (double_int, unsigned, double_int *) const;
double_int udivmod (double_int, unsigned, double_int *) const;
@@ -199,13 +211,6 @@ double_int::from_shwi (HOST_WIDE_INT cst)
return r;
}
-/* FIXME(crowl): Remove after converting callers. */
-static inline double_int
-shwi_to_double_int (HOST_WIDE_INT cst)
-{
- return double_int::from_shwi (cst);
-}
-
/* Some useful constants. */
/* FIXME(crowl): Maybe remove after converting callers?
The problem is that a named constant would not be as optimizable,
@@ -229,11 +234,13 @@ double_int::from_uhwi (unsigned HOST_WIDE_INT cst)
return r;
}
-/* FIXME(crowl): Remove after converting callers. */
-static inline double_int
-uhwi_to_double_int (unsigned HOST_WIDE_INT cst)
+inline double_int
+double_int::from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low)
{
- return double_int::from_uhwi (cst);
+ double_int r;
+ r.low = low;
+ r.high = high;
+ return r;
}
inline double_int &
@@ -301,13 +308,6 @@ double_int::to_shwi () const
return (HOST_WIDE_INT) low;
}
-/* FIXME(crowl): Remove after converting callers. */
-static inline HOST_WIDE_INT
-double_int_to_shwi (double_int cst)
-{
- return cst.to_shwi ();
-}
-
/* Returns value of CST as an unsigned number. CST must satisfy
double_int::fits_unsigned. */
@@ -317,13 +317,6 @@ double_int::to_uhwi () const
return low;
}
-/* FIXME(crowl): Remove after converting callers. */
-static inline unsigned HOST_WIDE_INT
-double_int_to_uhwi (double_int cst)
-{
- return cst.to_uhwi ();
-}
-
/* Returns true if CST fits in unsigned HOST_WIDE_INT. */
inline bool
@@ -332,164 +325,6 @@ double_int::fits_uhwi () const
return high == 0;
}
-/* FIXME(crowl): Remove after converting callers. */
-static inline bool
-double_int_fits_in_uhwi_p (double_int cst)
-{
- return cst.fits_uhwi ();
-}
-
-/* Returns true if CST fits in signed HOST_WIDE_INT. */
-
-/* FIXME(crowl): Remove after converting callers. */
-inline bool
-double_int_fits_in_shwi_p (double_int cst)
-{
- return cst.fits_shwi ();
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline bool
-double_int_fits_in_hwi_p (double_int cst, bool uns)
-{
- return cst.fits_hwi (uns);
-}
-
-/* The following operations perform arithmetics modulo 2^precision,
- so you do not need to call double_int_ext between them, even if
- you are representing numbers with precision less than
- HOST_BITS_PER_DOUBLE_INT bits. */
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_mul (double_int a, double_int b)
-{
- return a * b;
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_mul_with_sign (double_int a, double_int b,
- bool unsigned_p, int *overflow)
-{
- bool ovf;
- return a.mul_with_sign (b, unsigned_p, &ovf);
- *overflow = ovf;
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_add (double_int a, double_int b)
-{
- return a + b;
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_sub (double_int a, double_int b)
-{
- return a - b;
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_neg (double_int a)
-{
- return -a;
-}
-
-/* You must ensure that double_int_ext is called on the operands
- of the following operations, if the precision of the numbers
- is less than HOST_BITS_PER_DOUBLE_INT bits. */
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_div (double_int a, double_int b, bool uns, unsigned code)
-{
- return a.div (b, uns, code);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_sdiv (double_int a, double_int b, unsigned code)
-{
- return a.sdiv (b, code);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_udiv (double_int a, double_int b, unsigned code)
-{
- return a.udiv (b, code);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_mod (double_int a, double_int b, bool uns, unsigned code)
-{
- return a.mod (b, uns, code);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_smod (double_int a, double_int b, unsigned code)
-{
- return a.smod (b, code);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_umod (double_int a, double_int b, unsigned code)
-{
- return a.umod (b, code);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_divmod (double_int a, double_int b, bool uns,
- unsigned code, double_int *mod)
-{
- return a.divmod (b, uns, code, mod);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_sdivmod (double_int a, double_int b, unsigned code, double_int *mod)
-{
- return a.sdivmod (b, code, mod);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_udivmod (double_int a, double_int b, unsigned code, double_int *mod)
-{
- return a.udivmod (b, code, mod);
-}
-
-/***/
-
-/* FIXME(crowl): Remove after converting callers. */
-inline bool
-double_int_multiple_of (double_int product, double_int factor,
- bool unsigned_p, double_int *multiple)
-{
- return product.multiple_of (factor, unsigned_p, multiple);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_setbit (double_int a, unsigned bitpos)
-{
- return a.set_bit (bitpos);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline int
-double_int_ctz (double_int a)
-{
- return a.trailing_zeros ();
-}
-
/* Logical operations. */
/* Returns ~A. */
@@ -503,13 +338,6 @@ double_int::operator ~ () const
return result;
}
-/* FIXME(crowl): Remove after converting callers. */
-static inline double_int
-double_int_not (double_int a)
-{
- return ~a;
-}
-
/* Returns A | B. */
inline double_int
@@ -521,13 +349,6 @@ double_int::operator | (double_int b) const
return result;
}
-/* FIXME(crowl): Remove after converting callers. */
-static inline double_int
-double_int_ior (double_int a, double_int b)
-{
- return a | b;
-}
-
/* Returns A & B. */
inline double_int
@@ -539,13 +360,6 @@ double_int::operator & (double_int b) const
return result;
}
-/* FIXME(crowl): Remove after converting callers. */
-static inline double_int
-double_int_and (double_int a, double_int b)
-{
- return a & b;
-}
-
/* Returns A & ~B. */
inline double_int
@@ -557,13 +371,6 @@ double_int::and_not (double_int b) const
return result;
}
-/* FIXME(crowl): Remove after converting callers. */
-static inline double_int
-double_int_and_not (double_int a, double_int b)
-{
- return a.and_not (b);
-}
-
/* Returns A ^ B. */
inline double_int
@@ -575,165 +382,8 @@ double_int::operator ^ (double_int b) const
return result;
}
-/* FIXME(crowl): Remove after converting callers. */
-static inline double_int
-double_int_xor (double_int a, double_int b)
-{
- return a ^ b;
-}
-
-
-/* Shift operations. */
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_lshift (double_int a, HOST_WIDE_INT count, unsigned int prec,
- bool arith)
-{
- return a.lshift (count, prec, arith);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_rshift (double_int a, HOST_WIDE_INT count, unsigned int prec,
- bool arith)
-{
- return a.rshift (count, prec, arith);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_lrotate (double_int a, HOST_WIDE_INT count, unsigned int prec)
-{
- return a.lrotate (count, prec);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_rrotate (double_int a, HOST_WIDE_INT count, unsigned int prec)
-{
- return a.rrotate (count, prec);
-}
-
-/* Returns true if CST is negative. Of course, CST is considered to
- be signed. */
-
-static inline bool
-double_int_negative_p (double_int cst)
-{
- return cst.high < 0;
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline int
-double_int_cmp (double_int a, double_int b, bool uns)
-{
- return a.cmp (b, uns);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline int
-double_int_scmp (double_int a, double_int b)
-{
- return a.scmp (b);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline int
-double_int_ucmp (double_int a, double_int b)
-{
- return a.ucmp (b);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_max (double_int a, double_int b, bool uns)
-{
- return a.max (b, uns);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_smax (double_int a, double_int b)
-{
- return a.smax (b);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_umax (double_int a, double_int b)
-{
- return a.umax (b);
-}
-
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_min (double_int a, double_int b, bool uns)
-{
- return a.min (b, uns);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_smin (double_int a, double_int b)
-{
- return a.smin (b);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_umin (double_int a, double_int b)
-{
- return a.umin (b);
-}
-
void dump_double_int (FILE *, double_int, bool);
-/* Zero and sign extension of numbers in smaller precisions. */
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_ext (double_int a, unsigned prec, bool uns)
-{
- return a.ext (prec, uns);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_sext (double_int a, unsigned prec)
-{
- return a.sext (prec);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_zext (double_int a, unsigned prec)
-{
- return a.zext (prec);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_mask (unsigned prec)
-{
- return double_int::mask (prec);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_max_value (unsigned int prec, bool uns)
-{
- return double_int::max_value (prec, uns);
-}
-
-/* FIXME(crowl): Remove after converting callers. */
-inline double_int
-double_int_min_value (unsigned int prec, bool uns)
-{
- return double_int::min_value (prec, uns);
-}
-
#define ALL_ONES (~((unsigned HOST_WIDE_INT) 0))
/* The operands of the following comparison functions must be processed
@@ -748,13 +398,6 @@ double_int::is_zero () const
return low == 0 && high == 0;
}
-/* FIXME(crowl): Remove after converting callers. */
-static inline bool
-double_int_zero_p (double_int cst)
-{
- return cst.is_zero ();
-}
-
/* Returns true if CST is one. */
inline bool
@@ -763,13 +406,6 @@ double_int::is_one () const
return low == 1 && high == 0;
}
-/* FIXME(crowl): Remove after converting callers. */
-static inline bool
-double_int_one_p (double_int cst)
-{
- return cst.is_one ();
-}
-
/* Returns true if CST is minus one. */
inline bool
@@ -778,13 +414,6 @@ double_int::is_minus_one () const
return low == ALL_ONES && high == -1;
}
-/* FIXME(crowl): Remove after converting callers. */
-static inline bool
-double_int_minus_one_p (double_int cst)
-{
- return cst.is_minus_one ();
-}
-
/* Returns true if CST is negative. */
inline bool
@@ -801,13 +430,6 @@ double_int::operator == (double_int cst2) const
return low == cst2.low && high == cst2.high;
}
-/* FIXME(crowl): Remove after converting callers. */
-static inline bool
-double_int_equal_p (double_int cst1, double_int cst2)
-{
- return cst1 == cst2;
-}
-
/* Returns true if CST1 != CST2. */
inline bool
@@ -824,52 +446,6 @@ double_int::popcount () const
return popcount_hwi (high) + popcount_hwi (low);
}
-/* FIXME(crowl): Remove after converting callers. */
-static inline int
-double_int_popcount (double_int cst)
-{
- return cst.popcount ();
-}
-
-
-/* Legacy interface with decomposed high/low parts. */
-
-/* FIXME(crowl): Remove after converting callers. */
-extern int add_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
- bool);
-/* FIXME(crowl): Remove after converting callers. */
-#define add_double(l1,h1,l2,h2,lv,hv) \
- add_double_with_sign (l1, h1, l2, h2, lv, hv, false)
-/* FIXME(crowl): Remove after converting callers. */
-extern int neg_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);
-/* FIXME(crowl): Remove after converting callers. */
-extern int mul_double_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
- bool);
-/* FIXME(crowl): Remove after converting callers. */
-extern int mul_double_wide_with_sign (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
- unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
- bool);
-/* FIXME(crowl): Remove after converting callers. */
-#define mul_double(l1,h1,l2,h2,lv,hv) \
- mul_double_with_sign (l1, h1, l2, h2, lv, hv, false)
-/* FIXME(crowl): Remove after converting callers. */
-extern void lshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- HOST_WIDE_INT, unsigned int,
- unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool);
-/* FIXME(crowl): Remove after converting callers. */
-extern int div_and_round_double (unsigned, int, unsigned HOST_WIDE_INT,
- HOST_WIDE_INT, unsigned HOST_WIDE_INT,
- HOST_WIDE_INT, unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *, unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *);
-
#ifndef GENERATOR_FILE
/* Conversion to and from GMP integer representations. */