From 350911e65183b142018003691fd8d2eee479e175 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 23 Jun 2015 10:35:04 +0930 Subject: [PATCH] rtlanal.c (commutative_operand_precedence): Correct comments. * rtlanal.c (commutative_operand_precedence): Correct comments. * simplify-rtx.c (simplify_plus_minus_op_data_cmp): Delete forward declaration. Return an int. Distinguish REG,REG return from others. (struct simplify_plus_minus_op_data): Make local to function. (simplify_plus_minus): Don't set canonicalized if merely sorting registers. Avoid packing ops if nothing changes. White space fixes. From-SVN: r224768 --- gcc/ChangeLog | 10 +++++ gcc/rtlanal.c | 9 ++-- gcc/simplify-rtx.c | 104 +++++++++++++++++++++++++++------------------ 3 files changed, 77 insertions(+), 46 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e5a5764404b..540685bc376 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2015-06-23 Alan Modra + + * rtlanal.c (commutative_operand_precedence): Correct comments. + * simplify-rtx.c (simplify_plus_minus_op_data_cmp): Delete forward + declaration. Return an int. Distinguish REG,REG return from + others. + (struct simplify_plus_minus_op_data): Make local to function. + (simplify_plus_minus): Don't set canonicalized if merely sorting + registers. Avoid packing ops if nothing changes. White space fixes. + 2015-06-22 Pierre-Marie de Rodat * gcc.c (default_compilers): Pass "-o %g.s" to cc1 for headers even if diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index d4a9eda2629..86b3b622f89 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -3132,17 +3132,16 @@ regno_use_in (unsigned int regno, rtx x) } /* Return a value indicating whether OP, an operand of a commutative - operation, is preferred as the first or second operand. The higher - the value, the stronger the preference for being the first operand. - We use negative values to indicate a preference for the first operand - and positive values for the second operand. */ + operation, is preferred as the first or second operand. The more + positive the value, the stronger the preference for being the first + operand. */ int commutative_operand_precedence (rtx op) { enum rtx_code code = GET_CODE (op); - /* Constants always come the second operand. Prefer "nice" constants. */ + /* Constants always become the second operand. Prefer "nice" constants. */ if (code == CONST_INT) return -8; if (code == CONST_WIDE_INT) diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 521fecf566e..ca8310d1556 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -59,7 +59,6 @@ along with GCC; see the file COPYING3. If not see static rtx neg_const_int (machine_mode, const_rtx); static bool plus_minus_operand_p (const_rtx); -static bool simplify_plus_minus_op_data_cmp (rtx, rtx); static rtx simplify_plus_minus (enum rtx_code, machine_mode, rtx, rtx); static rtx simplify_immed_subreg (machine_mode, rtx, machine_mode, unsigned int); @@ -4049,20 +4048,10 @@ simplify_const_binary_operation (enum rtx_code code, machine_mode mode, -/* Simplify a PLUS or MINUS, at least one of whose operands may be another - PLUS or MINUS. +/* Return a positive integer if X should sort after Y. The value + returned is 1 if and only if X and Y are both regs. */ - Rather than test for specific case, we do this by a brute-force method - and do all possible simplifications until no more changes occur. Then - we rebuild the operation. */ - -struct simplify_plus_minus_op_data -{ - rtx op; - short neg; -}; - -static bool +static int simplify_plus_minus_op_data_cmp (rtx x, rtx y) { int result; @@ -4070,20 +4059,33 @@ simplify_plus_minus_op_data_cmp (rtx x, rtx y) result = (commutative_operand_precedence (y) - commutative_operand_precedence (x)); if (result) - return result > 0; + return result + result; /* Group together equal REGs to do more simplification. */ if (REG_P (x) && REG_P (y)) return REGNO (x) > REGNO (y); - else - return false; + + return 0; } +/* Simplify and canonicalize a PLUS or MINUS, at least one of whose + operands may be another PLUS or MINUS. + + Rather than test for specific case, we do this by a brute-force method + and do all possible simplifications until no more changes occur. Then + we rebuild the operation. + + May return NULL_RTX when no changes were made. */ + static rtx simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0, rtx op1) { - struct simplify_plus_minus_op_data ops[16]; + struct simplify_plus_minus_op_data + { + rtx op; + short neg; + } ops[16]; rtx result, tem; int n_ops = 2; int changed, n_constants, canonicalized = 0; @@ -4124,7 +4126,18 @@ simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0, ops[i].op = XEXP (this_op, 0); changed = 1; - canonicalized |= this_neg || i != n_ops - 2; + /* If this operand was negated then we will potentially + canonicalize the expression. Similarly if we don't + place the operands adjacent we're re-ordering the + expression and thus might be performing a + canonicalization. Ignore register re-ordering. + ??? It might be better to shuffle the ops array here, + but then (plus (plus (A, B), plus (C, D))) wouldn't + be seen as non-canonical. */ + if (this_neg + || (i != n_ops - 2 + && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op)))) + canonicalized = 1; break; case NEG: @@ -4145,7 +4158,7 @@ simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0, ops[n_ops].neg = this_neg; n_ops++; changed = 1; - canonicalized = 1; + canonicalized = 1; } break; @@ -4158,7 +4171,7 @@ simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0, ops[i].op = XEXP (this_op, 0); ops[i].neg = !this_neg; changed = 1; - canonicalized = 1; + canonicalized = 1; } break; @@ -4169,7 +4182,7 @@ simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0, ops[i].op = neg_const_int (mode, this_op); ops[i].neg = 0; changed = 1; - canonicalized = 1; + canonicalized = 1; } break; @@ -4213,23 +4226,29 @@ simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0, } /* Now simplify each pair of operands until nothing changes. */ - do + while (1) { /* Insertion sort is good enough for a small array. */ for (i = 1; i < n_ops; i++) - { - struct simplify_plus_minus_op_data save; - j = i - 1; - if (!simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op)) + { + struct simplify_plus_minus_op_data save; + int cmp; + + j = i - 1; + cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op); + if (cmp <= 0) continue; + /* Just swapping registers doesn't count as canonicalization. */ + if (cmp != 1) + canonicalized = 1; - canonicalized = 1; - save = ops[i]; - do + save = ops[i]; + do ops[j + 1] = ops[j]; - while (j-- && simplify_plus_minus_op_data_cmp (ops[j].op, save.op)); - ops[j + 1] = save; - } + while (j-- + && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0); + ops[j + 1] = save; + } changed = 0; for (i = n_ops - 1; i > 0; i--) @@ -4258,7 +4277,8 @@ simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0, tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs; tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs; - tem = simplify_binary_operation (ncode, mode, tem_lhs, tem_rhs); + tem = simplify_binary_operation (ncode, mode, tem_lhs, + tem_rhs); if (tem && !CONSTANT_P (tem)) tem = gen_rtx_CONST (GET_MODE (tem), tem); @@ -4296,20 +4316,22 @@ simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0, } } - /* If nothing changed, fail. */ - if (!canonicalized) - return NULL_RTX; + if (!changed) + break; /* Pack all the operands to the lower-numbered entries. */ for (i = 0, j = 0; j < n_ops; j++) - if (ops[j].op) - { + if (ops[j].op) + { ops[i] = ops[j]; i++; - } + } n_ops = i; } - while (changed); + + /* If nothing changed, fail. */ + if (!canonicalized) + return NULL_RTX; /* Create (minus -C X) instead of (neg (const (plus X C))). */ if (n_ops == 2 -- 2.30.2