The following patch fixes the PR for new set of options.
The details of the problem can be found on
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60650
The patch affects a sensitive part for LRA. Therefore I bootstrapped
and tested it on x86-64, aarch64, arm, s390, and Ppc64. The results
look ok.
x86/x86-64 SPEC2000 testing shows no visible effect on performance
and code size.
Committed as rev. 209038.
2014-04-02 Vladimir Makarov <vmaka...@redhat.com>
PR rtl-optimization/60650
* lra-constraints.c (process_alt_operands): Decrease reject for
earlyclobber matching.
2014-04-02 Vladimir Makarov <vmaka...@redhat.com>
PR rtl-optimization/60650
* gcc.target/arm/pr60650-2.c: New.
Index: lra-constraints.c
===================================================================
--- lra-constraints.c (revision 208989)
+++ lra-constraints.c (working copy)
@@ -1747,12 +1747,27 @@ process_alt_operands (int only_alternati
[GET_MODE (*curr_id->operand_loc[m])]);
}
- /* We prefer no matching alternatives because
- it gives more freedom in RA. */
- if (operand_reg[nop] == NULL_RTX
- || (find_regno_note (curr_insn, REG_DEAD,
- REGNO (operand_reg[nop]))
- == NULL_RTX))
+ /* Prefer matching earlyclobber alternative as
+ it results in less hard regs required for
+ the insn than a non-matching earlyclobber
+ alternative. */
+ if (curr_static_id->operand[m].early_clobber)
+ {
+ if (lra_dump_file != NULL)
+ fprintf
+ (lra_dump_file,
+ " %d Matching earlyclobber alt:"
+ " reject--\n",
+ nop);
+ reject--;
+ }
+ /* Otherwise we prefer no matching
+ alternatives because it gives more freedom
+ in RA. */
+ else if (operand_reg[nop] == NULL_RTX
+ || (find_regno_note (curr_insn, REG_DEAD,
+ REGNO (operand_reg[nop]))
+ == NULL_RTX))
{
if (lra_dump_file != NULL)
fprintf
@@ -2143,7 +2158,7 @@ process_alt_operands (int only_alternati
}
/* If the operand is dying, has a matching constraint,
and satisfies constraints of the matched operand
- which failed to satisfy the own constraints, probably
+ which failed to satisfy the own constraints, most probably
the reload for this operand will be gone. */
if (this_alternative_matches >= 0
&& !curr_alt_win[this_alternative_matches]
Index: testsuite/gcc.target/arm/pr60650-2.c
===================================================================
--- testsuite/gcc.target/arm/pr60650-2.c (revision 0)
+++ testsuite/gcc.target/arm/pr60650-2.c (working copy)
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-omit-frame-pointer -march=armv7-a" } */
+
+int a, h, j;
+long long d, e, i;
+int f;
+fn1 (void *p1, int p2)
+{
+ switch (p2)
+ case 8:
+{
+ register b = *(long long *) p1, c asm ("r2");
+ asm ("%0": "=r" (a), "=r" (c):"r" (b), "r" (0));
+ *(long long *) p1 = c;
+ }
+}
+
+fn2 ()
+{
+ int k;
+ k = f;
+ while (1)
+ {
+ fn1 (&i, sizeof i);
+ e = d + k;
+ switch (d)
+ case 0:
+ (
+ {
+ register l asm ("r4");
+ register m asm ("r0");
+ asm (" .err .endif\n\t": "=r" (h), "=r" (j):"r" (m),
+ "r"
+ (l));;
+ });
+ }
+}