aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2013-02-22 16:30:22 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2013-02-22 16:30:22 +0000
commit2194f7a28116dcfe999681c7e80de06f2aac614e (patch)
treec3727cc3a0c7096bab4eb9f71f6ed67e16e2ed59
parent7d61373544eb18698bd9015f73940048aeb4324e (diff)
downloadgcc-2194f7a28116dcfe999681c7e80de06f2aac614e.zip
gcc-2194f7a28116dcfe999681c7e80de06f2aac614e.tar.gz
gcc-2194f7a28116dcfe999681c7e80de06f2aac614e.tar.bz2
re PR inline-asm/56148 (inline asm matching constraint with different mode)
2013-02-22 Vladimir Makarov <vmakarov@redhat.com> PR inline-asm/56148 * lra-constraints.c (process_alt_operands): Reload operand conflicting with earlier clobber only if no more other conflicting operands. From-SVN: r196223
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/lra-constraints.c22
2 files changed, 22 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e7cd749..2b2180c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2013-02-22 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR inline-asm/56148
+ * lra-constraints.c (process_alt_operands): Reload operand
+ conflicting with earlier clobber only if no more other conflicting
+ operands.
+
2013-02-22 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/56393
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index d3f4420..e3b4add 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -2052,7 +2052,7 @@ process_alt_operands (int only_alternative)
curr_alt_dont_inherit_ops_num = 0;
for (nop = 0; nop < early_clobbered_regs_num; nop++)
{
- int i, j, clobbered_hard_regno;
+ int i, j, clobbered_hard_regno, first_conflict_j, last_conflict_j;
HARD_REG_SET temp_set;
i = early_clobbered_nops[nop];
@@ -2063,6 +2063,7 @@ process_alt_operands (int only_alternative)
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);
+ first_conflict_j = last_conflict_j = -1;
for (j = 0; j < n_operands; j++)
if (j == i
/* We don't want process insides of match_operator and
@@ -2077,19 +2078,26 @@ process_alt_operands (int only_alternative)
/* 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)
+ {
+ if (first_conflict_j < 0)
+ first_conflict_j = j;
+ last_conflict_j = j;
+ }
+ if (last_conflict_j < 0)
continue;
/* 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]))
+ if (first_conflict_j == last_conflict_j
+ && operand_reg[last_conflict_j]
+ != NULL_RTX && ! curr_alt_match_win[last_conflict_j]
+ && REGNO (operand_reg[i]) == REGNO (operand_reg[last_conflict_j]))
{
- curr_alt_win[j] = false;
- curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++] = j;
+ curr_alt_win[last_conflict_j] = false;
+ curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++]
+ = last_conflict_j;
losers++;
overall += LRA_LOSER_COST_FACTOR;
}