This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Clean up int_const_binop and simplify_const_binary_operation function


2010/6/16 Anatoly Sokolov <aesok@post.ru>:
> ?Hi.
>
> ?This patch clean up int_const_binop and simplify_const_binary_operation
> function ?by using double_int_* utility function.
>
> ?Also this patch add double_int_xor, double_int_lrotate, double_int_rrotate
> and double_int_min/max function in the GCC and remove unnecessary
> lrotate_double and rrotate_double function.
>
> ?Bootstrapped/regtested on x86_64-unknown-linux-gnu and
> hppa2.0-unknown-linux-gnu for c, c++ and ada.
>
> ?OK for mainline?

Ok with ...

> ? ? ? ?* double-int.h (double_int_to_shwi, double_int_to_uhwi,
> ? ? ? ?double_int_fits_in_uhwi_p): Implement as static inline.
> ? ? ? ?(): New inline function.
> ? ? ? ?(double_int_lrotate, double_int_rrotate, double_int_max,
> ? ? ? ?double_int_umax, double_int_smax, double_int_min, double_int_umin,
> ? ? ? ?double_int_smin): Declare.
> ? ? ? ?(lrotate_double, rrotate_double): Remove declaration.
> ? ? ? ?* double-int.c (double_int_fits_in_uhwi_p, double_int_to_shwi,
> ? ? ? ?double_int_to_uhwi, lrotate_double, rrotate_double): Remove function.
> ? ? ? ?(double_int_lrotate, double_int_rrotate, double_int_max,
> ? ? ? ?double_int_umax, double_int_smax, double_int_min, double_int_umin,
> ? ? ? ?double_int_smin): New function.
> ? ? ? ?* fold-const.c (int_const_binop): Clean up, use double_int_*
> ? ? ? ?functions.
> ? ? ? ?* simplify-rtx.c (simplify_const_binary_operation): Clean up, use
> ? ? ? ?double_int_* and immed_double_int_const functions.
>
>
> Index: gcc/double-int.c
> ===================================================================
> --- gcc/double-int.c ? ?(revision 160850)
> +++ gcc/double-int.c ? ?(working copy)
> @@ -432,51 +432,6 @@
> ? ? }
> ?}
>
> -/* Rotate the doubleword integer in L1, H1 left by COUNT places
> - ? keeping only PREC bits of result.
> - ? Rotate right if COUNT is negative.
> - ? Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV. ?*/
> -
> -void
> -lrotate_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
> - ? ? ? ? ? ? ? HOST_WIDE_INT count, unsigned int prec,
> - ? ? ? ? ? ? ? unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
> -{
> - ?unsigned HOST_WIDE_INT s1l, s2l;
> - ?HOST_WIDE_INT s1h, s2h;
> -
> - ?count %= prec;
> - ?if (count < 0)
> - ? ?count += prec;
> -
> - ?lshift_double (l1, h1, count, prec, &s1l, &s1h, 0);
> - ?rshift_double (l1, h1, prec - count, prec, &s2l, &s2h, 0);
> - ?*lv = s1l | s2l;
> - ?*hv = s1h | s2h;
> -}
> -
> -/* Rotate the doubleword integer in L1, H1 left by COUNT places
> - ? keeping only PREC bits of result. ?COUNT must be positive.
> - ? Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV. ?*/
> -
> -void
> -rrotate_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
> - ? ? ? ? ? ? ? HOST_WIDE_INT count, unsigned int prec,
> - ? ? ? ? ? ? ? unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
> -{
> - ?unsigned HOST_WIDE_INT s1l, s2l;
> - ?HOST_WIDE_INT s1h, s2h;
> -
> - ?count %= prec;
> - ?if (count < 0)
> - ? ?count += prec;
> -
> - ?rshift_double (l1, h1, count, prec, &s1l, &s1h, 0);
> - ?lshift_double (l1, h1, prec - count, prec, &s2l, &s2h, 0);
> - ?*lv = s1l | s2l;
> - ?*hv = s1h | s2h;
> -}
> -
> ?/* Divide doubleword integer LNUM, HNUM by doubleword integer LDEN, HDEN
> ? ?for a quotient (stored in *LQUO, *HQUO) and remainder (in *LREM, *HREM).
> ? ?CODE is a tree code for a kind of division, one of
> @@ -842,14 +797,6 @@
> ? return r;
> ?}
>
> -/* Returns true if CST fits in unsigned HOST_WIDE_INT. ?*/
> -
> -bool
> -double_int_fits_in_uhwi_p (double_int cst)
> -{
> - ?return cst.high == 0;
> -}
> -
> ?/* Returns true if CST fits in signed HOST_WIDE_INT. ?*/
>
> ?bool
> @@ -875,24 +822,6 @@
> ? ? return double_int_fits_in_shwi_p (cst);
> ?}
>
> -/* Returns value of CST as a signed number. ?CST must satisfy
> - ? double_int_fits_in_shwi_p. ?*/
> -
> -HOST_WIDE_INT
> -double_int_to_shwi (double_int cst)
> -{
> - ?return (HOST_WIDE_INT) cst.low;
> -}
> -
> -/* Returns value of CST as an unsigned number. ?CST must satisfy
> - ? double_int_fits_in_uhwi_p. ?*/
> -
> -unsigned HOST_WIDE_INT
> -double_int_to_uhwi (double_int cst)
> -{
> - ?return cst.low;
> -}
> -
> ?/* Returns A * B. ?*/
>
> ?double_int
> @@ -1049,6 +978,42 @@
> ? return ret;
> ?}
>
> +/* Rotate ?A left by COUNT places keeping only PREC bits of result.
> + ? Rotate right if COUNT is negative. ?*/
> +
> +double_int
> +double_int_lrotate (double_int a, HOST_WIDE_INT count, unsigned int prec)
> +{
> + ?double_int t1, t2;
> +
> + ?count %= prec;
> + ?if (count < 0)
> + ? ?count += prec;
> +
> + ?t1 = double_int_lshift (a, count, prec, false);
> + ?t2 = double_int_rshift (a, prec - count, prec, false);
> +
> + ?return double_int_ior (t1, t2);
> +}
> +
> +/* Rotate A rigth by COUNT places keeping only PREC bits of result.
> + ? Rotate right if COUNT is negative. ?*/
> +
> +double_int
> +double_int_rrotate (double_int a, HOST_WIDE_INT count, unsigned int prec)
> +{
> + ?double_int t1, t2;
> +
> + ?count %= prec;
> + ?if (count < 0)
> + ? ?count += prec;
> +
> + ?t1 = double_int_rshift (a, count, prec, false);
> + ?t2 = double_int_lshift (a, prec - count, prec, false);
> +
> + ?return double_int_ior (t1, t2);
> +}
> +
> ?/* Returns -1 if A < B, 0 if A == B and 1 if A > B. ?Signedness of the
> ? ?comparison is given by UNS. ?*/
>
> @@ -1097,6 +1062,51 @@
> ? return 0;
> ?}
>
> +/* Compares two values A and B. ?Returns max value. ?Signedness of the
> + ? comparison is given by UNS. ?*/
> +
> +double_int
> +double_int_max (double_int a, double_int b, bool uns)
> +{
> + ?return (double_int_cmp (a, b, uns) == 1) ? a : b;
> +}
> +
> +/* Compares two signed values A and B. ?Returns max value. ?*/
> +
> +double_int double_int_smax (double_int a, double_int b)
> +{
> + ?return (double_int_scmp (a, b) == 1) ? a : b;
> +}
> +
> +/* Compares two unsigned values A and B. ?Returns max value. ?*/
> +
> +double_int double_int_umax (double_int a, double_int b)
> +{
> + ?return (double_int_ucmp (a, b) == 1) ? a : b;
> +}
> +
> +/* Compares two values A and B. ?Returns mix value. ?Signedness of the
> + ? comparison is given by UNS. ?*/
> +
> +double_int double_int_min (double_int a, double_int b, bool uns)
> +{
> + ?return (double_int_cmp (a, b, uns) == -1) ? a : b;
> +}
> +
> +/* Compares two signed values A and B. ?Returns min value. ?*/
> +
> +double_int double_int_smin (double_int a, double_int b)
> +{
> + ?return (double_int_scmp (a, b) == -1) ? a : b;
> +}
> +
> +/* Compares two unsigned values A and B. ?Returns min value. ?*/
> +
> +double_int double_int_umin (double_int a, double_int b)
> +{
> + ?return (double_int_ucmp (a, b) == -1) ? a : b;
> +}
> +
> ?/* Splits last digit of *CST (taken as unsigned) in BASE and returns it. ?*/
>
> ?static unsigned
> Index: gcc/double-int.h
> ===================================================================
> --- gcc/double-int.h ? ?(revision 160850)
> +++ gcc/double-int.h ? ?(working copy)
> @@ -97,6 +97,35 @@
> ? return r;
> ?}
>
> +/* Returns value of CST as a signed number. ?CST must satisfy
> + ? double_int_fits_in_shwi_p. ?*/
> +
> +static inline HOST_WIDE_INT
> +double_int_to_shwi (double_int cst)
> +{
> + ?return (HOST_WIDE_INT) cst.low;
> +}
> +
> +/* Returns value of CST as an unsigned number. ?CST must satisfy
> + ? double_int_fits_in_uhwi_p. ?*/
> +
> +static inline unsigned HOST_WIDE_INT
> +double_int_to_uhwi (double_int cst)
> +{
> + ?return cst.low;
> +}
> +
> +bool double_int_fits_in_hwi_p (double_int, bool);
> +bool double_int_fits_in_shwi_p (double_int);
> +
> +/* Returns true if CST fits in unsigned HOST_WIDE_INT. ?*/
> +
> +static inline bool
> +double_int_fits_in_uhwi_p (double_int cst)
> +{
> + ?return cst.high == 0;
> +}
> +
> ?/* 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
> @@ -109,11 +138,6 @@
> ?/* 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 2 * HOST_BITS_PER_WIDE_INT bits. ?*/
> -bool double_int_fits_in_hwi_p (double_int, bool);
> -bool double_int_fits_in_shwi_p (double_int);
> -bool double_int_fits_in_uhwi_p (double_int);
> -HOST_WIDE_INT double_int_to_shwi (double_int);
> -unsigned HOST_WIDE_INT double_int_to_uhwi (double_int);
> ?double_int double_int_div (double_int, double_int, bool, unsigned);
> ?double_int double_int_sdiv (double_int, double_int, unsigned);
> ?double_int double_int_udiv (double_int, double_int, unsigned);
> @@ -157,9 +181,22 @@
> ? return a;
> ?}
>
> +/* Returns A ^ B. ?*/
> +
> +static inline double_int
> +double_int_xor (double_int a, double_int b)
> +{
> + ?a.low ^= b.low;
> + ?a.high ^= b.high;
> + ?return a;
> +}
> +
> +
> ?/* Shift operations. ?*/
> ?double_int double_int_lshift (double_int, HOST_WIDE_INT, unsigned int, bool);
> ?double_int double_int_rshift (double_int, HOST_WIDE_INT, unsigned int, bool);
> +double_int double_int_lrotate (double_int, HOST_WIDE_INT, unsigned int);
> +double_int double_int_rrotate (double_int, HOST_WIDE_INT, unsigned int);
>
> ?/* Returns true if CST is negative. ?Of course, CST is considered to
> ? ?be signed. ?*/
> @@ -173,6 +210,15 @@
> ?int double_int_cmp (double_int, double_int, bool);
> ?int double_int_scmp (double_int, double_int);
> ?int double_int_ucmp (double_int, double_int);
> +
> +double_int double_int_max (double_int, double_int, bool);
> +double_int double_int_smax (double_int, double_int);
> +double_int double_int_umax (double_int, double_int);
> +
> +double_int double_int_min (double_int, double_int, bool);
> +double_int double_int_smin (double_int, double_int);
> +double_int double_int_umin (double_int, double_int);
> +
> ?void dump_double_int (FILE *, double_int, bool);
>
> ?/* Zero and sign extension of numbers in smaller precisions. ?*/
> @@ -248,12 +294,6 @@
> ?extern void rshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
> ? ? ? ? ? ? ? ? ? ? ? ? ? HOST_WIDE_INT, unsigned int,
> ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, bool);
> -extern void lrotate_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? HOST_WIDE_INT, unsigned int,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);
> -extern void rrotate_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? HOST_WIDE_INT, unsigned int,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);
> ?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 *,
> Index: gcc/fold-const.c
> ===================================================================
> --- gcc/fold-const.c ? ?(revision 160850)
> +++ gcc/fold-const.c ? ?(working copy)
> @@ -924,145 +924,140 @@
> ?tree
> ?int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2, int notrunc)
> ?{
> - ?unsigned HOST_WIDE_INT int1l, int2l;
> - ?HOST_WIDE_INT int1h, int2h;
> - ?unsigned HOST_WIDE_INT low;
> - ?HOST_WIDE_INT hi;
> - ?unsigned HOST_WIDE_INT garbagel;
> - ?HOST_WIDE_INT garbageh;
> + ?double_int op1, op2, res, tmp;
> ? tree t;
> ? tree type = TREE_TYPE (arg1);
> - ?int uns = TYPE_UNSIGNED (type);
> - ?int is_sizetype
> + ?bool uns = TYPE_UNSIGNED (type);
> + ?bool is_sizetype
> ? ? = (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type));
> - ?int overflow = 0;
> + ?bool overflow = false;
>
> - ?int1l = TREE_INT_CST_LOW (arg1);
> - ?int1h = TREE_INT_CST_HIGH (arg1);
> - ?int2l = TREE_INT_CST_LOW (arg2);
> - ?int2h = TREE_INT_CST_HIGH (arg2);
> + ?op1 = tree_to_double_int (arg1);
> + ?op2 = tree_to_double_int (arg2);
>
> ? switch (code)
> ? ? {
> ? ? case BIT_IOR_EXPR:
> - ? ? ?low = int1l | int2l, hi = int1h | int2h;
> + ? ? ?res = double_int_ior (op1, op2);
> ? ? ? break;
>
> ? ? case BIT_XOR_EXPR:
> - ? ? ?low = int1l ^ int2l, hi = int1h ^ int2h;
> + ? ? ?res = double_int_xor (op1, op2);
> ? ? ? break;
>
> ? ? case BIT_AND_EXPR:
> - ? ? ?low = int1l & int2l, hi = int1h & int2h;
> + ? ? ?res = double_int_and (op1, op2);
> ? ? ? break;
>
> ? ? case RSHIFT_EXPR:
> - ? ? ?int2l = -int2l;
> + ? ? ?res = double_int_rshift (op1, double_int_to_shwi (op2),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?TYPE_PRECISION (type), !uns);
> + ? ? ?break;
> +
> ? ? case LSHIFT_EXPR:
> ? ? ? /* It's unclear from the C standard whether shifts can overflow.
> ? ? ? ? The following code ignores overflow; perhaps a C standard
> ? ? ? ? interpretation ruling is needed. ?*/
> - ? ? ?lshift_double (int1l, int1h, int2l, TYPE_PRECISION (type),
> - ? ? ? ? ? ? ? ? ? ?&low, &hi, !uns);
> + ? ? ?res = double_int_lshift (op1, double_int_to_shwi (op2),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?TYPE_PRECISION (type), !uns);
> ? ? ? break;
>
> ? ? case RROTATE_EXPR:
> - ? ? ?int2l = - int2l;
> + ? ? ?res = double_int_rrotate (op1, double_int_to_shwi (op2),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TYPE_PRECISION (type));
> + ? ? ?break;
> +
> ? ? case LROTATE_EXPR:
> - ? ? ?lrotate_double (int1l, int1h, int2l, TYPE_PRECISION (type),
> - ? ? ? ? ? ? ? ? ? ? &low, &hi);
> + ? ? ?res = double_int_lrotate (op1, double_int_to_shwi (op2),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TYPE_PRECISION (type));
> ? ? ? break;
>
> ? ? case PLUS_EXPR:
> - ? ? ?overflow = add_double (int1l, int1h, int2l, int2h, &low, &hi);
> + ? ? ?overflow = add_double (op1.low, op1.high, op2.low, op2.high,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?&res.low, &res.high);
> ? ? ? break;
>
> ? ? case MINUS_EXPR:
> - ? ? ?neg_double (int2l, int2h, &low, &hi);
> - ? ? ?add_double (int1l, int1h, low, hi, &low, &hi);
> - ? ? ?overflow = OVERFLOW_SUM_SIGN (hi, int2h, int1h);
> + ? ? ?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);
> ? ? ? break;
>
> ? ? case MULT_EXPR:
> - ? ? ?overflow = mul_double (int1l, int1h, int2l, int2h, &low, &hi);
> + ? ? ?overflow = mul_double (op1.low, op1.high, op2.low, op2.high,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?&res.low, &res.high);
> ? ? ? break;
>
> ? ? case TRUNC_DIV_EXPR:
> ? ? case FLOOR_DIV_EXPR: case CEIL_DIV_EXPR:
> ? ? case EXACT_DIV_EXPR:
> ? ? ? /* This is a shortcut for a common special case. ?*/
> - ? ? ?if (int2h == 0 && (HOST_WIDE_INT) int2l > 0
> + ? ? ?if (op2.high == 0 && (HOST_WIDE_INT) op2.low > 0
> ? ? ? ? ?&& !TREE_OVERFLOW (arg1)
> ? ? ? ? ?&& !TREE_OVERFLOW (arg2)
> - ? ? ? ? && int1h == 0 && (HOST_WIDE_INT) int1l >= 0)
> + ? ? ? ? && op1.high == 0 && (HOST_WIDE_INT) op1.low >= 0)
> ? ? ? ?{
> ? ? ? ? ?if (code == CEIL_DIV_EXPR)
> - ? ? ? ? ? int1l += int2l - 1;
> + ? ? ? ? ? op1.low += op2.low - 1;
>
> - ? ? ? ? low = int1l / int2l, hi = 0;
> + ? ? ? ? res.low = op1.low / op2.low, res.high = 0;
> ? ? ? ? ?break;
> ? ? ? ?}
>
> ? ? ? /* ... fall through ... ?*/
>
> ? ? case ROUND_DIV_EXPR:
> - ? ? ?if (int2h == 0 && int2l == 0)
> + ? ? ?if (double_int_zero_p (op2))
> ? ? ? ?return NULL_TREE;
> - ? ? ?if (int2h == 0 && int2l == 1)
> + ? ? ?if (double_int_one_p (op2))
> ? ? ? ?{
> - ? ? ? ? low = int1l, hi = int1h;
> + ? ? ? ? res = op1;
> ? ? ? ? ?break;
> ? ? ? ?}
> - ? ? ?if (int1l == int2l && int1h == int2h
> - ? ? ? ? && ! (int1l == 0 && int1h == 0))
> + ? ? ?if (double_int_equal_p (op1, op2)
> + ? ? ? ? && ! double_int_zero_p (op1))
> ? ? ? ?{
> - ? ? ? ? low = 1, hi = 0;
> + ? ? ? ? res = double_int_one;
> ? ? ? ? ?break;
> ? ? ? ?}
> - ? ? ?overflow = div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?&low, &hi, &garbagel, &garbageh);
> + ? ? ?overflow = div_and_round_double (code, uns,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?op1.low, op1.high, op2.low, op2.high,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?&res.low, &res.high,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?&tmp.low, &tmp.high);
> ? ? ? break;
>
> ? ? case TRUNC_MOD_EXPR:
> ? ? case FLOOR_MOD_EXPR: case CEIL_MOD_EXPR:
> ? ? ? /* This is a shortcut for a common special case. ?*/
> - ? ? ?if (int2h == 0 && (HOST_WIDE_INT) int2l > 0
> + ? ? ?if (op2.high == 0 && (HOST_WIDE_INT) op2.low > 0
> ? ? ? ? ?&& !TREE_OVERFLOW (arg1)
> ? ? ? ? ?&& !TREE_OVERFLOW (arg2)
> - ? ? ? ? && int1h == 0 && (HOST_WIDE_INT) int1l >= 0)
> + ? ? ? ? && op1.high == 0 && (HOST_WIDE_INT) op1.low >= 0)
> ? ? ? ?{
> ? ? ? ? ?if (code == CEIL_MOD_EXPR)
> - ? ? ? ? ? int1l += int2l - 1;
> - ? ? ? ? low = int1l % int2l, hi = 0;
> + ? ? ? ? ? op1.low += op2.low - 1;
> + ? ? ? ? res.low = op1.low % op2.low, res.high = 0;
> ? ? ? ? ?break;
> ? ? ? ?}
>
> ? ? ? /* ... fall through ... ?*/
>
> ? ? case ROUND_MOD_EXPR:
> - ? ? ?if (int2h == 0 && int2l == 0)
> + ? ? ?if (double_int_zero_p (op2))
> ? ? ? ?return NULL_TREE;
> ? ? ? overflow = div_and_round_double (code, uns,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int1l, int1h, int2l, int2h,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?&garbagel, &garbageh, &low, &hi);
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?op1.low, op1.high, op2.low, op2.high,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?&tmp.low, &tmp.high,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?&res.low, &res.high);
> ? ? ? break;
>
> ? ? case MIN_EXPR:
> - ? ?case MAX_EXPR:
> - ? ? ?if (uns)
> - ? ? ? low = (((unsigned HOST_WIDE_INT) int1h
> - ? ? ? ? ? ? ? < (unsigned HOST_WIDE_INT) int2h)
> - ? ? ? ? ? ? ?|| (((unsigned HOST_WIDE_INT) int1h
> - ? ? ? ? ? ? ? ? ? == (unsigned HOST_WIDE_INT) int2h)
> - ? ? ? ? ? ? ? ? ?&& int1l < int2l));
> - ? ? ?else
> - ? ? ? low = (int1h < int2h
> - ? ? ? ? ? ? ?|| (int1h == int2h && int1l < int2l));
> + ? ? ?res = double_int_min (op1, op2, uns);
> + ? ? ?break;
>
> - ? ? ?if (low == (code == MIN_EXPR))
> - ? ? ? low = int1l, hi = int1h;
> - ? ? ?else
> - ? ? ? low = int2l, hi = int2h;
> + ? ?case MAX_EXPR:
> + ? ? ?res = double_int_max (op1, op2, uns);
> ? ? ? break;
>
> ? ? default:
> @@ -1071,7 +1066,7 @@
>
> ? if (notrunc)
> ? ? {
> - ? ? ?t = build_int_cst_wide (TREE_TYPE (arg1), low, hi);
> + ? ? ?t = build_int_cst_wide (TREE_TYPE (arg1), res.low, res.high);
>
> ? ? ? /* Propagate overflow flags ourselves. ?*/
> ? ? ? if (((!uns || is_sizetype) && overflow)
> @@ -1082,7 +1077,7 @@
> ? ? ? ?}
> ? ? }
> ? else
> - ? ?t = force_fit_type_double (TREE_TYPE (arg1), low, hi, 1,
> + ? ?t = force_fit_type_double (TREE_TYPE (arg1), res.low, res.high, 1,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ((!uns || is_sizetype) && overflow)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2));
>
> Index: gcc/simplify-rtx.c
> ===================================================================
> --- gcc/simplify-rtx.c ?(revision 160850)
> +++ gcc/simplify-rtx.c ?(working copy)
> @@ -3268,141 +3268,121 @@
>
> ? /* We can fold some multi-word operations. ?*/
> ? if (GET_MODE_CLASS (mode) == MODE_INT
> - ? ? ?&& width == HOST_BITS_PER_WIDE_INT * 2
> - ? ? ?&& (GET_CODE (op0) == CONST_DOUBLE || CONST_INT_P (op0))
> - ? ? ?&& (GET_CODE (op1) == CONST_DOUBLE || CONST_INT_P (op1)))
> + ? ? ?&& width == HOST_BITS_PER_DOUBLE_INT
> + ? ? ?&& (CONST_DOUBLE_P (op0) || CONST_INT_P (op0))
> + ? ? ?&& (CONST_DOUBLE_P (op1) || CONST_INT_P (op1)))
> ? ? {
> - ? ? ?unsigned HOST_WIDE_INT l1, l2, lv, lt;
> - ? ? ?HOST_WIDE_INT h1, h2, hv, ht;
> + ? ? ?double_int o0, o1, res, tmp;
>
> - ? ? ?if (GET_CODE (op0) == CONST_DOUBLE)
> - ? ? ? l1 = CONST_DOUBLE_LOW (op0), h1 = CONST_DOUBLE_HIGH (op0);
> - ? ? ?else
> - ? ? ? l1 = INTVAL (op0), h1 = HWI_SIGN_EXTEND (l1);
> + ? ? ?o0 = rtx_to_double_int (op0);
> + ? ? ?o1 = rtx_to_double_int (op1);
>
> - ? ? ?if (GET_CODE (op1) == CONST_DOUBLE)
> - ? ? ? l2 = CONST_DOUBLE_LOW (op1), h2 = CONST_DOUBLE_HIGH (op1);
> - ? ? ?else
> - ? ? ? l2 = INTVAL (op1), h2 = HWI_SIGN_EXTEND (l2);
> -
> ? ? ? switch (code)
> ? ? ? ?{
> ? ? ? ?case MINUS:
> ? ? ? ? ?/* A - B == A + (-B). ?*/
> - ? ? ? ? neg_double (l2, h2, &lv, &hv);
> - ? ? ? ? l2 = lv, h2 = hv;
> + ? ? ? ? o1 = double_int_neg (o1);
>
> ? ? ? ? ?/* Fall through.... ?*/
>
> ? ? ? ?case PLUS:
> - ? ? ? ? add_double (l1, h1, l2, h2, &lv, &hv);
> + ? ? ? ? res = double_int_add (o0, o1);
> ? ? ? ? ?break;
>
> ? ? ? ?case MULT:
> - ? ? ? ? mul_double (l1, h1, l2, h2, &lv, &hv);
> + ? ? ? ? res = double_int_mul (o0, o1);
> ? ? ? ? ?break;
>
> ? ? ? ?case DIV:
> - ? ? ? ? if (div_and_round_double (TRUNC_DIV_EXPR, 0, l1, h1, l2, h2,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &lv, &hv, &lt, &ht))
> + ? ? ? ? if (div_and_round_double (TRUNC_DIV_EXPR, 0,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? o0.low, o0.high, o1.low, o1.high,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &res.low, &res.high,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &tmp.low, &tmp.high))
> ? ? ? ? ? ?return 0;
> ? ? ? ? ?break;
>
> ? ? ? ?case MOD:
> - ? ? ? ? if (div_and_round_double (TRUNC_DIV_EXPR, 0, l1, h1, l2, h2,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &lt, &ht, &lv, &hv))
> + ? ? ? ? if (div_and_round_double (TRUNC_DIV_EXPR, 0,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? o0.low, o0.high, o1.low, o1.high,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &tmp.low, &tmp.high,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &res.low, &res.high))
> ? ? ? ? ? ?return 0;
> ? ? ? ? ?break;
>
> ? ? ? ?case UDIV:
> - ? ? ? ? if (div_and_round_double (TRUNC_DIV_EXPR, 1, l1, h1, l2, h2,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &lv, &hv, &lt, &ht))
> + ? ? ? ? if (div_and_round_double (TRUNC_DIV_EXPR, 1,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? o0.low, o0.high, o1.low, o1.high,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &res.low, &res.high,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &tmp.low, &tmp.high))
> ? ? ? ? ? ?return 0;
> ? ? ? ? ?break;
>
> ? ? ? ?case UMOD:
> - ? ? ? ? if (div_and_round_double (TRUNC_DIV_EXPR, 1, l1, h1, l2, h2,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &lt, &ht, &lv, &hv))
> + ? ? ? ? if (div_and_round_double (TRUNC_DIV_EXPR, 1,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? o0.low, o0.high, o1.low, o1.high,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &tmp.low, &tmp.high,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &res.low, &res.high))
> ? ? ? ? ? ?return 0;
> ? ? ? ? ?break;
>
> ? ? ? ?case AND:
> - ? ? ? ? lv = l1 & l2, hv = h1 & h2;
> + ? ? ? ? res = double_int_and (o0, o1);
> ? ? ? ? ?break;
>
> ? ? ? ?case IOR:
> - ? ? ? ? lv = l1 | l2, hv = h1 | h2;
> + ? ? ? ? res = double_int_ior (o0, o1);
> ? ? ? ? ?break;
>
> ? ? ? ?case XOR:
> - ? ? ? ? lv = l1 ^ l2, hv = h1 ^ h2;
> + ? ? ? ? res = double_int_xor (o0, o1);
> ? ? ? ? ?break;
>
> ? ? ? ?case SMIN:
> - ? ? ? ? if (h1 < h2
> - ? ? ? ? ? ? || (h1 == h2
> - ? ? ? ? ? ? ? ? && ((unsigned HOST_WIDE_INT) l1
> - ? ? ? ? ? ? ? ? ? ? < (unsigned HOST_WIDE_INT) l2)))
> - ? ? ? ? ? lv = l1, hv = h1;
> - ? ? ? ? else
> - ? ? ? ? ? lv = l2, hv = h2;
> + ? ? ? ? res = double_int_smin (o0, o1);
> ? ? ? ? ?break;
>
> ? ? ? ?case SMAX:
> - ? ? ? ? if (h1 > h2
> - ? ? ? ? ? ? || (h1 == h2
> - ? ? ? ? ? ? ? ? && ((unsigned HOST_WIDE_INT) l1
> - ? ? ? ? ? ? ? ? ? ? > (unsigned HOST_WIDE_INT) l2)))
> - ? ? ? ? ? lv = l1, hv = h1;
> - ? ? ? ? else
> - ? ? ? ? ? lv = l2, hv = h2;
> + ? ? ? ? res = double_int_smax (o0, o1);
> ? ? ? ? ?break;
>
> ? ? ? ?case UMIN:
> - ? ? ? ? if ((unsigned HOST_WIDE_INT) h1 < (unsigned HOST_WIDE_INT) h2
> - ? ? ? ? ? ? || (h1 == h2
> - ? ? ? ? ? ? ? ? && ((unsigned HOST_WIDE_INT) l1
> - ? ? ? ? ? ? ? ? ? ? < (unsigned HOST_WIDE_INT) l2)))
> - ? ? ? ? ? lv = l1, hv = h1;
> - ? ? ? ? else
> - ? ? ? ? ? lv = l2, hv = h2;
> + ? ? ? ? res = double_int_umin (o0, o1);
> ? ? ? ? ?break;
>
> ? ? ? ?case UMAX:
> - ? ? ? ? if ((unsigned HOST_WIDE_INT) h1 > (unsigned HOST_WIDE_INT) h2
> - ? ? ? ? ? ? || (h1 == h2
> - ? ? ? ? ? ? ? ? && ((unsigned HOST_WIDE_INT) l1
> - ? ? ? ? ? ? ? ? ? ? > (unsigned HOST_WIDE_INT) l2)))
> - ? ? ? ? ? lv = l1, hv = h1;
> - ? ? ? ? else
> - ? ? ? ? ? lv = l2, hv = h2;
> + ? ? ? ? res = double_int_umax (o0, o1);
> ? ? ? ? ?break;
>
> ? ? ? ?case LSHIFTRT: ? case ASHIFTRT:
> ? ? ? ?case ASHIFT:
> ? ? ? ?case ROTATE: ? ? case ROTATERT:
> ? ? ? ? ?if (SHIFT_COUNT_TRUNCATED)
> - ? ? ? ? ? l2 &= (GET_MODE_BITSIZE (mode) - 1), h2 = 0;
> + ? ? ? ? ? o1 = double_int_zext (o1, GET_MODE_BITSIZE (mode));
>
> - ? ? ? ? if (h2 != 0 || l2 >= GET_MODE_BITSIZE (mode))
> + ? ? ? ? if (!double_int_fits_in_uhwi_p (o1)
> + ? ? ? ? ? ? || double_int_to_uhwi (o1) >= GET_MODE_BITSIZE (mode))
> ? ? ? ? ? ?return 0;

Can you compute the shift amount (double_int_to_uhwi (o1)) into
a temporary and re-use that in the following if-cascade to make
the code more readable?

Ok with that change.

If you don't have enough stuff on your list, something that I have
noticed again is the notrunc parameter to int_const_binop.  It
ought to go and we should always truncate - I believe nearly
all callers call int_const_binop with zero, others might choose
to either pass one 1) for speed reasons 2) because they
really do not want to truncate.  I suspect all callers are of kind 1),
but that needs auditing.  Callers of kind 2) should be converted
to not build a tree result at all but instead use double_ints - if
such callers exist.

Thanks,
Richard.

> ? ? ? ? ?if (code == LSHIFTRT || code == ASHIFTRT)
> - ? ? ? ? ? rshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv,
> - ? ? ? ? ? ? ? ? ? ? ? ? ?code == ASHIFTRT);
> + ? ? ? ? ? res = double_int_rshift (o0, double_int_to_uhwi (o1),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?GET_MODE_BITSIZE (mode),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?code == ASHIFTRT);
> ? ? ? ? ?else if (code == ASHIFT)
> - ? ? ? ? ? lshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv, 1);
> + ? ? ? ? ? res = double_int_lshift (o0, double_int_to_uhwi (o1),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?GET_MODE_BITSIZE (mode), true);
> ? ? ? ? ?else if (code == ROTATE)
> - ? ? ? ? ? lrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv);
> + ? ? ? ? ? res = double_int_lrotate (o0, double_int_to_uhwi (o1),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? GET_MODE_BITSIZE (mode));
> ? ? ? ? ?else /* code == ROTATERT */
> - ? ? ? ? ? rrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv);
> + ? ? ? ? ? res = double_int_rrotate (o0, double_int_to_uhwi (o1),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? GET_MODE_BITSIZE (mode));
> ? ? ? ? ?break;
>
> ? ? ? ?default:
> ? ? ? ? ?return 0;
> ? ? ? ?}
>
> - ? ? ?return immed_double_const (lv, hv, mode);
> + ? ? ?return immed_double_int_const (res, mode);
> ? ? }
>
> ? if (CONST_INT_P (op0) && CONST_INT_P (op1)
>
>
> Anatoly.
>
>
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]