simplify-rtx.c (associative_constant_p): New function to test whether an RTX expression is an immediate constant.
* simplify-rtx.c (associative_constant_p): New function to test whether an RTX expression is an immediate constant. (simplify_associative_operation): New function to perform some reassociation optimizations of associative binary expressions. (simplify_binary_operation): Use simplify_associative_operation to simplify PLUS, MULT, AND, IOR, XOR, SMIN, SMAX, UMIN and UMAX. Floating point expressions are only reassociated when unsafe math optimizations are permitted. From-SVN: r70521
This commit is contained in:
parent
fde46628fa
commit
dd61aa98ca
@ -1,3 +1,14 @@
|
|||||||
|
2003-08-17 Roger Sayle <roger@eyesopen.com>
|
||||||
|
|
||||||
|
* simplify-rtx.c (associative_constant_p): New function to test
|
||||||
|
whether an RTX expression is an immediate constant.
|
||||||
|
(simplify_associative_operation): New function to perform some
|
||||||
|
reassociation optimizations of associative binary expressions.
|
||||||
|
(simplify_binary_operation): Use simplify_associative_operation
|
||||||
|
to simplify PLUS, MULT, AND, IOR, XOR, SMIN, SMAX, UMIN and UMAX.
|
||||||
|
Floating point expressions are only reassociated when unsafe
|
||||||
|
math optimizations are permitted.
|
||||||
|
|
||||||
2003-08-17 Andreas Jaeger <aj@suse.de>
|
2003-08-17 Andreas Jaeger <aj@suse.de>
|
||||||
|
|
||||||
* config/alpha/alpha.md: Remove usage of PARAMS.
|
* config/alpha/alpha.md: Remove usage of PARAMS.
|
||||||
|
@ -53,6 +53,9 @@ static rtx neg_const_int (enum machine_mode, rtx);
|
|||||||
static int simplify_plus_minus_op_data_cmp (const void *, const void *);
|
static int simplify_plus_minus_op_data_cmp (const void *, const void *);
|
||||||
static rtx simplify_plus_minus (enum rtx_code, enum machine_mode, rtx,
|
static rtx simplify_plus_minus (enum rtx_code, enum machine_mode, rtx,
|
||||||
rtx, int);
|
rtx, int);
|
||||||
|
static bool associative_constant_p (rtx);
|
||||||
|
static rtx simplify_associative_operation (enum rtx_code, enum machine_mode,
|
||||||
|
rtx, rtx);
|
||||||
|
|
||||||
/* Negate a CONST_INT rtx, truncating (because a conversion from a
|
/* Negate a CONST_INT rtx, truncating (because a conversion from a
|
||||||
maximally negative number can overflow). */
|
maximally negative number can overflow). */
|
||||||
@ -854,6 +857,72 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Subroutine of simplify_associative_operation. Return true if rtx OP
|
||||||
|
is a suitable integer or floating point immediate constant. */
|
||||||
|
static bool
|
||||||
|
associative_constant_p (rtx op)
|
||||||
|
{
|
||||||
|
if (GET_CODE (op) == CONST_INT
|
||||||
|
|| GET_CODE (op) == CONST_DOUBLE)
|
||||||
|
return true;
|
||||||
|
op = avoid_constant_pool_reference (op);
|
||||||
|
return GET_CODE (op) == CONST_INT
|
||||||
|
|| GET_CODE (op) == CONST_DOUBLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Subroutine of simplify_binary_operation to simplify an associative
|
||||||
|
binary operation CODE with result mode MODE, operating on OP0 and OP1.
|
||||||
|
Return 0 if no simplification is possible. */
|
||||||
|
static rtx
|
||||||
|
simplify_associative_operation (enum rtx_code code, enum machine_mode mode,
|
||||||
|
rtx op0, rtx op1)
|
||||||
|
{
|
||||||
|
rtx tem;
|
||||||
|
|
||||||
|
/* Simplify (x op c1) op c2 as x op (c1 op c2). */
|
||||||
|
if (GET_CODE (op0) == code
|
||||||
|
&& associative_constant_p (op1)
|
||||||
|
&& associative_constant_p (XEXP (op0, 1)))
|
||||||
|
{
|
||||||
|
tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
|
||||||
|
if (! tem)
|
||||||
|
return tem;
|
||||||
|
return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Simplify (x op c1) op (y op c2) as (x op y) op (c1 op c2). */
|
||||||
|
if (GET_CODE (op0) == code
|
||||||
|
&& GET_CODE (op1) == code
|
||||||
|
&& associative_constant_p (XEXP (op0, 1))
|
||||||
|
&& associative_constant_p (XEXP (op1, 1)))
|
||||||
|
{
|
||||||
|
rtx c = simplify_binary_operation (code, mode,
|
||||||
|
XEXP (op0, 1), XEXP (op1, 1));
|
||||||
|
if (! c)
|
||||||
|
return 0;
|
||||||
|
tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
|
||||||
|
return simplify_gen_binary (code, mode, tem, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Canonicalize (x op c) op y as (x op y) op c. */
|
||||||
|
if (GET_CODE (op0) == code
|
||||||
|
&& associative_constant_p (XEXP (op0, 1)))
|
||||||
|
{
|
||||||
|
tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
|
||||||
|
return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Canonicalize x op (y op c) as (x op y) op c. */
|
||||||
|
if (GET_CODE (op1) == code
|
||||||
|
&& associative_constant_p (XEXP (op1, 1)))
|
||||||
|
{
|
||||||
|
tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
|
||||||
|
return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Simplify a binary operation CODE with result mode MODE, operating on OP0
|
/* Simplify a binary operation CODE with result mode MODE, operating on OP0
|
||||||
and OP1. Return 0 if no simplification is possible.
|
and OP1. Return 0 if no simplification is possible.
|
||||||
|
|
||||||
@ -1179,6 +1248,16 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
|
|||||||
&& GET_CODE (XEXP (op1, 0)) == PLUS))
|
&& GET_CODE (XEXP (op1, 0)) == PLUS))
|
||||||
&& (tem = simplify_plus_minus (code, mode, op0, op1, 0)) != 0)
|
&& (tem = simplify_plus_minus (code, mode, op0, op1, 0)) != 0)
|
||||||
return tem;
|
return tem;
|
||||||
|
|
||||||
|
/* Reassociate floating point addition only when the user
|
||||||
|
specifies unsafe math optimizations. */
|
||||||
|
if (FLOAT_MODE_P (mode)
|
||||||
|
&& flag_unsafe_math_optimizations)
|
||||||
|
{
|
||||||
|
tem = simplify_associative_operation (code, mode, op0, op1);
|
||||||
|
if (tem)
|
||||||
|
return tem;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COMPARE:
|
case COMPARE:
|
||||||
@ -1388,6 +1467,16 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
|
|||||||
if (REAL_VALUES_EQUAL (d, dconstm1))
|
if (REAL_VALUES_EQUAL (d, dconstm1))
|
||||||
return simplify_gen_unary (NEG, mode, op0, mode);
|
return simplify_gen_unary (NEG, mode, op0, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reassociate multiplication, but for floating point MULTs
|
||||||
|
only when the user specifies unsafe math optimizations. */
|
||||||
|
if (! FLOAT_MODE_P (mode)
|
||||||
|
|| flag_unsafe_math_optimizations)
|
||||||
|
{
|
||||||
|
tem = simplify_associative_operation (code, mode, op0, op1);
|
||||||
|
if (tem)
|
||||||
|
return tem;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOR:
|
case IOR:
|
||||||
@ -1405,6 +1494,9 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
|
|||||||
&& ! side_effects_p (op0)
|
&& ! side_effects_p (op0)
|
||||||
&& GET_MODE_CLASS (mode) != MODE_CC)
|
&& GET_MODE_CLASS (mode) != MODE_CC)
|
||||||
return constm1_rtx;
|
return constm1_rtx;
|
||||||
|
tem = simplify_associative_operation (code, mode, op0, op1);
|
||||||
|
if (tem)
|
||||||
|
return tem;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XOR:
|
case XOR:
|
||||||
@ -1417,6 +1509,9 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
|
|||||||
if (trueop0 == trueop1 && ! side_effects_p (op0)
|
if (trueop0 == trueop1 && ! side_effects_p (op0)
|
||||||
&& GET_MODE_CLASS (mode) != MODE_CC)
|
&& GET_MODE_CLASS (mode) != MODE_CC)
|
||||||
return const0_rtx;
|
return const0_rtx;
|
||||||
|
tem = simplify_associative_operation (code, mode, op0, op1);
|
||||||
|
if (tem)
|
||||||
|
return tem;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AND:
|
case AND:
|
||||||
@ -1435,6 +1530,9 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
|
|||||||
&& ! side_effects_p (op0)
|
&& ! side_effects_p (op0)
|
||||||
&& GET_MODE_CLASS (mode) != MODE_CC)
|
&& GET_MODE_CLASS (mode) != MODE_CC)
|
||||||
return const0_rtx;
|
return const0_rtx;
|
||||||
|
tem = simplify_associative_operation (code, mode, op0, op1);
|
||||||
|
if (tem)
|
||||||
|
return tem;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UDIV:
|
case UDIV:
|
||||||
@ -1524,36 +1622,50 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SMIN:
|
case SMIN:
|
||||||
if (width <= HOST_BITS_PER_WIDE_INT && GET_CODE (trueop1) == CONST_INT
|
if (width <= HOST_BITS_PER_WIDE_INT
|
||||||
|
&& GET_CODE (trueop1) == CONST_INT
|
||||||
&& INTVAL (trueop1) == (HOST_WIDE_INT) 1 << (width -1)
|
&& INTVAL (trueop1) == (HOST_WIDE_INT) 1 << (width -1)
|
||||||
&& ! side_effects_p (op0))
|
&& ! side_effects_p (op0))
|
||||||
return op1;
|
return op1;
|
||||||
else if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
|
if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
|
||||||
return op0;
|
return op0;
|
||||||
|
tem = simplify_associative_operation (code, mode, op0, op1);
|
||||||
|
if (tem)
|
||||||
|
return tem;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SMAX:
|
case SMAX:
|
||||||
if (width <= HOST_BITS_PER_WIDE_INT && GET_CODE (trueop1) == CONST_INT
|
if (width <= HOST_BITS_PER_WIDE_INT
|
||||||
|
&& GET_CODE (trueop1) == CONST_INT
|
||||||
&& ((unsigned HOST_WIDE_INT) INTVAL (trueop1)
|
&& ((unsigned HOST_WIDE_INT) INTVAL (trueop1)
|
||||||
== (unsigned HOST_WIDE_INT) GET_MODE_MASK (mode) >> 1)
|
== (unsigned HOST_WIDE_INT) GET_MODE_MASK (mode) >> 1)
|
||||||
&& ! side_effects_p (op0))
|
&& ! side_effects_p (op0))
|
||||||
return op1;
|
return op1;
|
||||||
else if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
|
if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
|
||||||
return op0;
|
return op0;
|
||||||
|
tem = simplify_associative_operation (code, mode, op0, op1);
|
||||||
|
if (tem)
|
||||||
|
return tem;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UMIN:
|
case UMIN:
|
||||||
if (trueop1 == const0_rtx && ! side_effects_p (op0))
|
if (trueop1 == const0_rtx && ! side_effects_p (op0))
|
||||||
return op1;
|
return op1;
|
||||||
else if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
|
if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
|
||||||
return op0;
|
return op0;
|
||||||
|
tem = simplify_associative_operation (code, mode, op0, op1);
|
||||||
|
if (tem)
|
||||||
|
return tem;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UMAX:
|
case UMAX:
|
||||||
if (trueop1 == constm1_rtx && ! side_effects_p (op0))
|
if (trueop1 == constm1_rtx && ! side_effects_p (op0))
|
||||||
return op1;
|
return op1;
|
||||||
else if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
|
if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
|
||||||
return op0;
|
return op0;
|
||||||
|
tem = simplify_associative_operation (code, mode, op0, op1);
|
||||||
|
if (tem)
|
||||||
|
return tem;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SS_PLUS:
|
case SS_PLUS:
|
||||||
|
Loading…
Reference in New Issue
Block a user