summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authoramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2015-06-23 01:05:04 +0000
committeramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2015-06-23 01:05:04 +0000
commit0f6714c2c2bcacfc25d5e720d75d099f5ffd2473 (patch)
tree341df2ecb89793c16d2d555ad687094c7f9ded14 /gcc
parent1ec7c7d277c3f7d92c8956b6051effb9ff064488 (diff)
downloadgcc-0f6714c2c2bcacfc25d5e720d75d099f5ffd2473.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@224768 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/rtlanal.c9
-rw-r--r--gcc/simplify-rtx.c104
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 <amodra@gmail.com>
+
+ * 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 <derodat@adacore.com>
* 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