Commit 9ce79a7a by Roger Sayle Committed by Roger Sayle

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
parent 0916f873
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> 2004-01-19 Richard Henderson <rth@redhat.com>
* config/alpha/alpha.c (aligned_memory_operand): Check MEM_ALIGN, * config/alpha/alpha.c (aligned_memory_operand): Check MEM_ALIGN,
......
/* Analyze RTL for C-Compiler /* Analyze RTL for C-Compiler
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 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. This file is part of GCC.
...@@ -3023,6 +3023,11 @@ commutative_operand_precedence (rtx op) ...@@ -3023,6 +3023,11 @@ commutative_operand_precedence (rtx op)
{ {
/* Constants always come the second operand. Prefer "nice" constants. */ /* Constants always come the second operand. Prefer "nice" constants. */
if (GET_CODE (op) == CONST_INT) 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; return -5;
if (GET_CODE (op) == CONST_DOUBLE) if (GET_CODE (op) == CONST_DOUBLE)
return -4; return -4;
......
...@@ -55,7 +55,6 @@ static rtx simplify_plus_minus (enum rtx_code, enum machine_mode, rtx, ...@@ -55,7 +55,6 @@ static rtx simplify_plus_minus (enum rtx_code, enum machine_mode, rtx,
rtx, int); rtx, int);
static rtx simplify_immed_subreg (enum machine_mode, rtx, enum machine_mode, static rtx simplify_immed_subreg (enum machine_mode, rtx, enum machine_mode,
unsigned int); unsigned int);
static bool associative_constant_p (rtx);
static rtx simplify_associative_operation (enum rtx_code, enum machine_mode, static rtx simplify_associative_operation (enum rtx_code, enum machine_mode,
rtx, rtx); rtx, rtx);
...@@ -1084,67 +1083,59 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode, ...@@ -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 /* Subroutine of simplify_binary_operation to simplify a commutative,
is a suitable integer or floating point immediate constant. */ associative binary operation CODE with result mode MODE, operating
static bool on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
associative_constant_p (rtx op) SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
{ canonicalization is possible. */
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 static rtx
simplify_associative_operation (enum rtx_code code, enum machine_mode mode, simplify_associative_operation (enum rtx_code code, enum machine_mode mode,
rtx op0, rtx op1) rtx op0, rtx op1)
{ {
rtx tem; rtx tem;
/* Simplify (x op c1) op c2 as x op (c1 op c2). */ /* Linearize the operator to the left. */
if (GET_CODE (op0) == code if (GET_CODE (op1) == code)
&& associative_constant_p (op1)
&& associative_constant_p (XEXP (op0, 1)))
{ {
tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1); /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
if (! tem) if (GET_CODE (op0) == code)
return tem; {
return simplify_gen_binary (code, mode, XEXP (op0, 0), tem); tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
} return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
}
/* Simplify (x op c1) op (y op c2) as (x op y) op (c1 op c2). */ /* "a op (b op c)" becomes "(b op c) op a". */
if (GET_CODE (op0) == code if (! swap_commutative_operands_p (op1, op0))
&& GET_CODE (op1) == code return simplify_gen_binary (code, mode, op1, op0);
&& 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. */ tem = op0;
if (GET_CODE (op0) == code op0 = op1;
&& associative_constant_p (XEXP (op0, 1))) op1 = tem;
{
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 (op0) == code)
if (GET_CODE (op1) == code
&& associative_constant_p (XEXP (op1, 1)))
{ {
tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0)); /* Canonicalize "(x op c) op y" as "(x op y) op c". */
return simplify_gen_binary (code, mode, tem, XEXP (op1, 1)); 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));
}
/* 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);
/* 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; return 0;
...@@ -1162,9 +1153,8 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode, ...@@ -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 arg0, arg1, arg0s, arg1s;
HOST_WIDE_INT val; HOST_WIDE_INT val;
unsigned int width = GET_MODE_BITSIZE (mode); unsigned int width = GET_MODE_BITSIZE (mode);
rtx trueop0, trueop1;
rtx tem; 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 /* Relational operations don't work here. We must know the mode
of the operands in order to do the comparison correctly. 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, ...@@ -1176,12 +1166,14 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
/* Make sure the constant is second. */ /* Make sure the constant is second. */
if (GET_RTX_CLASS (code) == 'c' 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 = 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) if (VECTOR_MODE_P (mode)
&& GET_CODE (trueop0) == CONST_VECTOR && GET_CODE (trueop0) == CONST_VECTOR
&& GET_CODE (trueop1) == CONST_VECTOR) && GET_CODE (trueop1) == CONST_VECTOR)
...@@ -2509,22 +2501,21 @@ simplify_relational_operation (enum rtx_code code, enum machine_mode mode, ...@@ -2509,22 +2501,21 @@ simplify_relational_operation (enum rtx_code code, enum machine_mode mode,
if (GET_CODE (op0) == COMPARE && op1 == const0_rtx) if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
op1 = XEXP (op0, 1), op0 = XEXP (op0, 0); 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 /* We can't simplify MODE_CC values since we don't know what the
actual comparison is. */ actual comparison is. */
if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC || CC0_P (op0)) if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC || CC0_P (op0))
return 0; return 0;
/* Make sure the constant is second. */ /* 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 = op0, op0 = op1, op1 = tem;
tem = trueop0, trueop0 = trueop1, trueop1 = tem;
code = swap_condition (code); 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 /* 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 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 a register or a CONST_INT, this can't help; testing for these cases will
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment