From e3d6e7405227b25651958b6e5a6b06ed45048943 Mon Sep 17 00:00:00 2001 From: Geoffrey Keating Date: Tue, 17 Feb 2004 05:15:05 +0000 Subject: Index: ChangeLog 2004-02-16 Geoffrey Keating * 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 * gcc.c-torture/compile/20040216-1.c: New. From-SVN: r77945 --- gcc/rtlanal.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'gcc/rtlanal.c') 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; } -- cgit v1.1