aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeoffrey Keating <geoffk@gcc.gnu.org>2004-02-17 05:15:05 +0000
committerGeoffrey Keating <geoffk@gcc.gnu.org>2004-02-17 05:15:05 +0000
commite3d6e7405227b25651958b6e5a6b06ed45048943 (patch)
tree6dfb44863c0022501e008c5e034fc8b9d78d044f
parentef2a223fbdeea1853e00c0cbf98f3d812e054924 (diff)
downloadgcc-e3d6e7405227b25651958b6e5a6b06ed45048943.zip
gcc-e3d6e7405227b25651958b6e5a6b06ed45048943.tar.gz
gcc-e3d6e7405227b25651958b6e5a6b06ed45048943.tar.bz2
Index: ChangeLog
2004-02-16 Geoffrey Keating <geoffk@apple.com> * doc/md.texi (Insn Canonicalizations): Document left-chaining in associative operators. * rtlanal.c (commutative_operand_precedence): Create some new variables. Prefer a commutative operand on the left, then binary expressions, then NEG and NOT. Index: testsuite/ChangeLog 2004-02-16 Geoffrey Keating <geoffk@apple.com> * gcc.c-torture/compile/20040216-1.c: New. From-SVN: r77945
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/doc/md.texi9
-rw-r--r--gcc/rtlanal.c37
-rw-r--r--gcc/testsuite/ChangeLog14
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040216-1.c4
5 files changed, 55 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 62ead89..c4f3ec6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2004-02-16 Geoffrey Keating <geoffk@apple.com>
+
+ * doc/md.texi (Insn Canonicalizations): Document left-chaining
+ in associative operators.
+ * rtlanal.c (commutative_operand_precedence): Create some new
+ variables. Prefer a commutative operand on the left, then
+ binary expressions, then NEG and NOT.
+
2004-02-16 Matthias Klose <doko@debian.org>
* config/t-slibgcc-elf-ver: Define SHLIB_NAME and SHLIB_SONAME
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index f8bf54e..b3cb5df 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -3835,6 +3835,15 @@ second operand. If a machine only supports a constant as the second
operand, only patterns that match a constant in the second operand need
be supplied.
+@item
+For associative operators, a sequence of operators will always chain
+to the left; for instance, only the left operand of an integer @code{plus}
+can itself be a @code{plus}. @code{and}, @code{ior}, @code{xor},
+@code{plus}, @code{mult}, @code{smin}, @code{smax}, @code{umin}, and
+@code{umax} are associative when applied to integers, and sometimes to
+floating-point.
+
+@item
@cindex @code{neg}, canonicalization of
@cindex @code{not}, canonicalization of
@cindex @code{mult}, canonicalization of
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 994d389..82a112c 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -3029,35 +3029,48 @@ regno_use_in (unsigned int regno, rtx x)
int
commutative_operand_precedence (rtx op)
{
+ enum rtx_code code = GET_CODE (op);
+ char class;
+
/* Constants always come the second operand. Prefer "nice" constants. */
- if (GET_CODE (op) == CONST_INT)
+ if (code == CONST_INT)
return -7;
- if (GET_CODE (op) == CONST_DOUBLE)
+ if (code == CONST_DOUBLE)
return -6;
op = avoid_constant_pool_reference (op);
- if (GET_CODE (op) == CONST_INT)
+ if (code == CONST_INT)
return -5;
- if (GET_CODE (op) == CONST_DOUBLE)
+ if (code == CONST_DOUBLE)
return -4;
if (CONSTANT_P (op))
return -3;
/* SUBREGs of objects should come second. */
- if (GET_CODE (op) == SUBREG
+ if (code == SUBREG
&& GET_RTX_CLASS (GET_CODE (SUBREG_REG (op))) == 'o')
return -2;
- /* If only one operand is a `neg', `not',
- `mult', `plus', or `minus' expression, it will be the first
- operand. */
- if (GET_CODE (op) == NEG || GET_CODE (op) == NOT
- || GET_CODE (op) == MULT || GET_CODE (op) == PLUS
- || GET_CODE (op) == MINUS)
+ class = GET_RTX_CLASS (code);
+
+ /* Prefer operands that are themselves commutative to be first.
+ This helps to make things linear. In particular,
+ (and (and (reg) (reg)) (not (reg))) is canonical. */
+ if (class == 'c')
+ return 4;
+
+ /* If only one operand is a binary expression, it will be the first
+ operand. In particular, (plus (minus (reg) (reg)) (neg (reg)))
+ is canonical, although it will usually be further simplified. */
+ if (class == '2')
return 2;
+
+ /* Then prefer NEG and NOT. */
+ if (code == NEG || code == NOT)
+ return 1;
/* Complex expressions should be the first, so decrease priority
of objects. */
- if (GET_RTX_CLASS (GET_CODE (op)) == 'o')
+ if (GET_RTX_CLASS (code) == 'o')
return -1;
return 0;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 35b9eb8..90b5678 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,10 +1,14 @@
+2004-02-16 Geoffrey Keating <geoffk@apple.com>
+
+ * gcc.c-torture/compile/20040216-1.c: New.
+
2004-02-16 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- * g++.dg/tc1/dr101.C, g++.dg/tc1/dr135.C, g++.dg/tc1/dr142.C,
- g++.dg/tc1/dr152.C, g++.dg/tc1/dr159.C, g++.dg/tc1/dr161.C,
- g++.dg/tc1/dr166.C, g++.dg/tc1/dr176.C, g++.dg/tc1/dr188.C,
- g++.dg/tc1/dr193.C, g++.dg/tc1/dr194.C, g++.dg/tc1/dr217.C,
- g++.dg/tc1/dr48.C, g++.dg/tc1/dr56.C, g++.dg/tc1/dr68.C,
+ * g++.dg/tc1/dr101.C, g++.dg/tc1/dr135.C, g++.dg/tc1/dr142.C,
+ g++.dg/tc1/dr152.C, g++.dg/tc1/dr159.C, g++.dg/tc1/dr161.C,
+ g++.dg/tc1/dr166.C, g++.dg/tc1/dr176.C, g++.dg/tc1/dr188.C,
+ g++.dg/tc1/dr193.C, g++.dg/tc1/dr194.C, g++.dg/tc1/dr217.C,
+ g++.dg/tc1/dr48.C, g++.dg/tc1/dr56.C, g++.dg/tc1/dr68.C,
g++.dg/tc1/dr76.C, g++.dg/tc1/dr80.C, g++.dg/tc1/dr94.C: New tests.
2004-02-16 Eric Botcazou <ebotcazou@libertysurf.fr>
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040216-1.c b/gcc/testsuite/gcc.c-torture/compile/20040216-1.c
new file mode 100644
index 0000000..12d5e5e
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040216-1.c
@@ -0,0 +1,4 @@
+int foo (int a, int b, int c, int d)
+{
+ return ~a & ~b & ~c & ~d;
+}