aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2013-02-12 17:44:47 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2013-02-12 17:44:47 +0000
commit1c86bd80a3fc159b7b8b56b531790d87ff2556c9 (patch)
treefc606b44c9939a7cad6385d98896b6cc5edfbf75 /gcc
parent1f8aec0030448f6a432414ebde4d610ab73b19db (diff)
downloadgcc-1c86bd80a3fc159b7b8b56b531790d87ff2556c9.zip
gcc-1c86bd80a3fc159b7b8b56b531790d87ff2556c9.tar.gz
gcc-1c86bd80a3fc159b7b8b56b531790d87ff2556c9.tar.bz2
re PR inline-asm/56148 (inline asm matching constraint with different mode)
2013-02-12 Vladimir Makarov <vmakarov@redhat.com> PR inline-asm/56148 * lra-constraints.c (process_alt_operands): Match early clobber operand with itself. Check conflicts with earlyclobner only if the operand is not reloaded. Prefer to reload conflicting operand if earlyclobber and matching operands are the same. 2013-02-12 Vladimir Makarov <vmakarov@redhat.com> PR inline-asm/56148 * gcc.target/i386/pr56148.c: New test. From-SVN: r195988
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/lra-constraints.c60
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr56148.c12
4 files changed, 65 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4308b5b..2e7171f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2013-02-12 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR inline-asm/56148
+ * lra-constraints.c (process_alt_operands): Match early clobber
+ operand with itself. Check conflicts with earlyclobner only if
+ the operand is not reloaded. Prefer to reload conflicting operand
+ if earlyclobber and matching operands are the same.
+
2013-02-12 Richard Biener <rguenther@suse.de>
PR lto/56297
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 49c9723..d3f4420 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -1533,8 +1533,8 @@ process_alt_operands (int only_alternative)
if (! curr_static_id->operand[m].early_clobber
|| operand_reg[nop] == NULL_RTX
|| (find_regno_note (curr_insn, REG_DEAD,
- REGNO (operand_reg[nop]))
- != NULL_RTX))
+ REGNO (op))
+ || REGNO (op) == REGNO (operand_reg[m])))
match_p = true;
}
if (match_p)
@@ -2059,6 +2059,7 @@ process_alt_operands (int only_alternative)
if ((! curr_alt_win[i] && ! curr_alt_match_win[i])
|| hard_regno[i] < 0)
continue;
+ lra_assert (operand_reg[i] != NULL_RTX);
clobbered_hard_regno = hard_regno[i];
CLEAR_HARD_REG_SET (temp_set);
add_to_hard_reg_set (&temp_set, biggest_mode[i], clobbered_hard_regno);
@@ -2073,30 +2074,49 @@ process_alt_operands (int only_alternative)
else if ((curr_alt_matches[j] == i && curr_alt_match_win[j])
|| (curr_alt_matches[i] == j && curr_alt_match_win[i]))
continue;
- else if (uses_hard_regs_p (*curr_id->operand_loc[j], temp_set))
+ /* If we don't reload j-th operand, check conflicts. */
+ else if ((curr_alt_win[j] || curr_alt_match_win[j])
+ && uses_hard_regs_p (*curr_id->operand_loc[j], temp_set))
break;
if (j >= n_operands)
continue;
- /* We need to reload early clobbered register. */
- for (j = 0; j < n_operands; j++)
- if (curr_alt_matches[j] == i)
- {
- curr_alt_match_win[j] = false;
- losers++;
- overall += LRA_LOSER_COST_FACTOR;
- }
- if (! curr_alt_match_win[i])
- curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++] = i;
+ /* If earlyclobber operand conflicts with another
+ non-matching operand which is actually the same register
+ as the earlyclobber operand, it is better to reload the
+ another operand as an operand matching the earlyclobber
+ operand can be also the same. */
+ if (operand_reg[j] != NULL_RTX && ! curr_alt_match_win[j]
+ && REGNO (operand_reg[i]) == REGNO (operand_reg[j]))
+ {
+ curr_alt_win[j] = false;
+ curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++] = j;
+ losers++;
+ overall += LRA_LOSER_COST_FACTOR;
+ }
else
{
- /* Remember pseudos used for match reloads are never
- inherited. */
- lra_assert (curr_alt_matches[i] >= 0);
- curr_alt_win[curr_alt_matches[i]] = false;
+ /* We need to reload early clobbered register and the
+ matched registers. */
+ for (j = 0; j < n_operands; j++)
+ if (curr_alt_matches[j] == i)
+ {
+ curr_alt_match_win[j] = false;
+ losers++;
+ overall += LRA_LOSER_COST_FACTOR;
+ }
+ if (! curr_alt_match_win[i])
+ curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++] = i;
+ else
+ {
+ /* Remember pseudos used for match reloads are never
+ inherited. */
+ lra_assert (curr_alt_matches[i] >= 0);
+ curr_alt_win[curr_alt_matches[i]] = false;
+ }
+ curr_alt_win[i] = curr_alt_match_win[i] = false;
+ losers++;
+ overall += LRA_LOSER_COST_FACTOR;
}
- curr_alt_win[i] = curr_alt_match_win[i] = false;
- losers++;
- overall += LRA_LOSER_COST_FACTOR;
}
small_class_operands_num = 0;
for (nop = 0; nop < n_operands; nop++)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ab009a5..7d07c20 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-02-12 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR inline-asm/56148
+ * gcc.target/i386/pr56148.c: New test.
+
2013-02-12 Dominique d'Humieres <dominiq@lps.ens.fr>
Tobias Burnus <burnus@net-b.de>
diff --git a/gcc/testsuite/gcc.target/i386/pr56148.c b/gcc/testsuite/gcc.target/i386/pr56148.c
new file mode 100644
index 0000000..78d2efb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr56148.c
@@ -0,0 +1,12 @@
+/* PR inline-asm/56148 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void
+foo (void)
+{
+ unsigned char e[16];
+ unsigned long a, b, c, d;
+ __asm__ __volatile__ ("" : "=d" (a), "=&c" (c), "=&D" (d), "=&a" (b)
+ : "0" (-1U), "mr" (e), "1" (128 >> 5), "2" (e), "3" (-1U));
+}