re PR rtl-optimization/5263 (a & b & ~a & ~b not optimized)
PR optimization/5263 * simplify-rtx.c (associative_constant_p): Delete. (simplify_associative_operation): Rewrite to linearize terms, and attempt to simplify new term against both left and right subterms. (simplify_binary_operation): Call swap_commutative_operands_p on op0 and op1, not trueop0 and trueop1. Move the initialization of trueop0 and trueop1 down to where first needed. (simplify_relational_operation): Likewise. * rtlanal.c (commutative_operand_precedence): Also order constant operands using avoid_constant_pool_reference. From-SVN: r76179
This commit is contained in:
parent
0916f87331
commit
9ce79a7a5e
3 changed files with 68 additions and 59 deletions
|
@ -1,3 +1,16 @@
|
|||
2004-01-19 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
PR optimization/5263
|
||||
* simplify-rtx.c (associative_constant_p): Delete.
|
||||
(simplify_associative_operation): Rewrite to linearize terms, and
|
||||
attempt to simplify new term against both left and right subterms.
|
||||
(simplify_binary_operation): Call swap_commutative_operands_p on
|
||||
op0 and op1, not trueop0 and trueop1. Move the initialization of
|
||||
trueop0 and trueop1 down to where first needed.
|
||||
(simplify_relational_operation): Likewise.
|
||||
* rtlanal.c (commutative_operand_precedence): Also order constant
|
||||
operands using avoid_constant_pool_reference.
|
||||
|
||||
2004-01-19 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* config/alpha/alpha.c (aligned_memory_operand): Check MEM_ALIGN,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Analyze RTL for C-Compiler
|
||||
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
@ -3022,6 +3022,11 @@ int
|
|||
commutative_operand_precedence (rtx op)
|
||||
{
|
||||
/* Constants always come the second operand. Prefer "nice" constants. */
|
||||
if (GET_CODE (op) == CONST_INT)
|
||||
return -7;
|
||||
if (GET_CODE (op) == CONST_DOUBLE)
|
||||
return -6;
|
||||
op = avoid_constant_pool_reference (op);
|
||||
if (GET_CODE (op) == CONST_INT)
|
||||
return -5;
|
||||
if (GET_CODE (op) == CONST_DOUBLE)
|
||||
|
|
|
@ -55,7 +55,6 @@ static rtx simplify_plus_minus (enum rtx_code, enum machine_mode, rtx,
|
|||
rtx, int);
|
||||
static rtx simplify_immed_subreg (enum machine_mode, rtx, enum machine_mode,
|
||||
unsigned int);
|
||||
static bool associative_constant_p (rtx);
|
||||
static rtx simplify_associative_operation (enum rtx_code, enum machine_mode,
|
||||
rtx, rtx);
|
||||
|
||||
|
@ -1084,67 +1083,59 @@ 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 a commutative,
|
||||
associative binary operation CODE with result mode MODE, operating
|
||||
on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
|
||||
SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
|
||||
canonicalization is possible. */
|
||||
|
||||
/* 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)))
|
||||
/* Linearize the operator to the left. */
|
||||
if (GET_CODE (op1) == code)
|
||||
{
|
||||
tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
|
||||
if (! tem)
|
||||
return tem;
|
||||
return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
|
||||
/* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
|
||||
if (GET_CODE (op0) == code)
|
||||
{
|
||||
tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
|
||||
return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
|
||||
}
|
||||
|
||||
/* "a op (b op c)" becomes "(b op c) op a". */
|
||||
if (! swap_commutative_operands_p (op1, op0))
|
||||
return simplify_gen_binary (code, mode, op1, op0);
|
||||
|
||||
tem = op0;
|
||||
op0 = op1;
|
||||
op1 = 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)))
|
||||
if (GET_CODE (op0) == code)
|
||||
{
|
||||
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 (swap_commutative_operands_p (XEXP (op0, 1), op1))
|
||||
{
|
||||
tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
|
||||
return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
|
||||
}
|
||||
|
||||
/* 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));
|
||||
}
|
||||
/* Attempt to simplify "(a op b) op c" as "a op (b op c)". */
|
||||
tem = swap_commutative_operands_p (XEXP (op0, 1), op1)
|
||||
? simplify_binary_operation (code, mode, op1, XEXP (op0, 1))
|
||||
: simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
|
||||
if (tem != 0)
|
||||
return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
|
||||
|
||||
/* 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));
|
||||
/* Attempt to simplify "(a op b) op c" as "(a op c) op b". */
|
||||
tem = swap_commutative_operands_p (XEXP (op0, 0), op1)
|
||||
? simplify_binary_operation (code, mode, op1, XEXP (op0, 0))
|
||||
: simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
|
||||
if (tem != 0)
|
||||
return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1162,9 +1153,8 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
|
|||
HOST_WIDE_INT arg0, arg1, arg0s, arg1s;
|
||||
HOST_WIDE_INT val;
|
||||
unsigned int width = GET_MODE_BITSIZE (mode);
|
||||
rtx trueop0, trueop1;
|
||||
rtx tem;
|
||||
rtx trueop0 = avoid_constant_pool_reference (op0);
|
||||
rtx trueop1 = avoid_constant_pool_reference (op1);
|
||||
|
||||
/* Relational operations don't work here. We must know the mode
|
||||
of the operands in order to do the comparison correctly.
|
||||
|
@ -1176,12 +1166,14 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
|
|||
|
||||
/* Make sure the constant is second. */
|
||||
if (GET_RTX_CLASS (code) == 'c'
|
||||
&& swap_commutative_operands_p (trueop0, trueop1))
|
||||
&& swap_commutative_operands_p (op0, op1))
|
||||
{
|
||||
tem = op0, op0 = op1, op1 = tem;
|
||||
tem = trueop0, trueop0 = trueop1, trueop1 = tem;
|
||||
}
|
||||
|
||||
trueop0 = avoid_constant_pool_reference (op0);
|
||||
trueop1 = avoid_constant_pool_reference (op1);
|
||||
|
||||
if (VECTOR_MODE_P (mode)
|
||||
&& GET_CODE (trueop0) == CONST_VECTOR
|
||||
&& GET_CODE (trueop1) == CONST_VECTOR)
|
||||
|
@ -2509,22 +2501,21 @@ simplify_relational_operation (enum rtx_code code, enum machine_mode mode,
|
|||
if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
|
||||
op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);
|
||||
|
||||
trueop0 = avoid_constant_pool_reference (op0);
|
||||
trueop1 = avoid_constant_pool_reference (op1);
|
||||
|
||||
/* We can't simplify MODE_CC values since we don't know what the
|
||||
actual comparison is. */
|
||||
if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC || CC0_P (op0))
|
||||
return 0;
|
||||
|
||||
/* Make sure the constant is second. */
|
||||
if (swap_commutative_operands_p (trueop0, trueop1))
|
||||
if (swap_commutative_operands_p (op0, op1))
|
||||
{
|
||||
tem = op0, op0 = op1, op1 = tem;
|
||||
tem = trueop0, trueop0 = trueop1, trueop1 = tem;
|
||||
code = swap_condition (code);
|
||||
}
|
||||
|
||||
trueop0 = avoid_constant_pool_reference (op0);
|
||||
trueop1 = avoid_constant_pool_reference (op1);
|
||||
|
||||
/* For integer comparisons of A and B maybe we can simplify A - B and can
|
||||
then simplify a comparison of that with zero. If A and B are both either
|
||||
a register or a CONST_INT, this can't help; testing for these cases will
|
||||
|
|
Loading…
Add table
Reference in a new issue