aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Vieira <andre.simoesdiasvieira@arm.com>2016-06-13 09:58:34 +0000
committerAndre Vieira <andre.simoesdiasvieira@arm.com>2016-06-13 09:58:34 +0000
commit33313f44a24da90879da7bb9e1d2469a6a0eed13 (patch)
tree665df48fe46c8d9ca2a9be874f92ed0805629041
parentf5b7e2f8784cac3d3238af8e316c9ad8da1c61a1 (diff)
Backport from Mainline
2015-09-01 Vladimir Makarov <vmakarov@redhat.com> PR target/61578 * lra-lives.c (process_bb_lives): Process move pseudos with the same value for copies and preferences * lra-constraints.c (match_reload): Create match reload pseudo with the same value from single dying input pseudo. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/ARM/embedded-5-branch@237369 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.arm11
-rw-r--r--gcc/lra-constraints.c18
-rw-r--r--gcc/lra-lives.c21
3 files changed, 36 insertions, 14 deletions
diff --git a/gcc/ChangeLog.arm b/gcc/ChangeLog.arm
index b141dc121cf..ba34cc3ae3e 100644
--- a/gcc/ChangeLog.arm
+++ b/gcc/ChangeLog.arm
@@ -1,3 +1,14 @@
+2016-06-13 Andre Vieira <andre.simoesdiasvieira@arm.com>
+
+ Backport from Mainline
+ 2015-09-01 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR target/61578
+ * lra-lives.c (process_bb_lives): Process move pseudos with the
+ same value for copies and preferences
+ * lra-constraints.c (match_reload): Create match reload pseudo
+ with the same value from single dying input pseudo.
+
2016-05-25 Thomas Preud'homme <thomas.preudhomme@arm.com>
* config/arm/t-baremetal (MULTILIB_MATCHES): Match ARMv8-M Mainline
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index f4cf6fbc845..b30f0c7c860 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -940,10 +940,12 @@ match_reload (signed char out, signed char *ins, enum reg_class goal_class,
they live in the same place. When we create a pseudo we
assign value of original pseudo (if any) from which we
created the new pseudo. If we create the pseudo from the
- input pseudo, the new pseudo will no conflict with the input
- pseudo which is wrong when the input pseudo lives after the
- insn and as the new pseudo value is changed by the insn
- output. Therefore we create the new pseudo from the output.
+ input pseudo, the new pseudo will have no conflict with the
+ input pseudo which is wrong when the input pseudo lives after
+ the insn and as the new pseudo value is changed by the insn
+ output. Therefore we create the new pseudo from the output
+ except the case when we have single matched dying input
+ pseudo.
We cannot reuse the current output register because we might
have a situation like "a <- a op b", where the constraints
@@ -952,8 +954,12 @@ match_reload (signed char out, signed char *ins, enum reg_class goal_class,
so that it doesn't clobber the current value of "a". */
new_in_reg = new_out_reg
- = lra_create_new_reg_with_unique_value (outmode, out_rtx,
- goal_class, "");
+ = (ins[1] < 0 && REG_P (in_rtx)
+ && (int) REGNO (in_rtx) < lra_new_regno_start
+ && find_regno_note (curr_insn, REG_DEAD, REGNO (in_rtx))
+ ? lra_create_new_reg (inmode, in_rtx, goal_class, "")
+ : lra_create_new_reg_with_unique_value (outmode, out_rtx,
+ goal_class, ""));
}
/* In operand can be got from transformations before processing insn
constraints. One example of such transformations is subreg
diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c
index fd9e29cce66..a6846dfc9a4 100644
--- a/gcc/lra-lives.c
+++ b/gcc/lra-lives.c
@@ -777,28 +777,33 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
lra_hard_reg_usage[reg->regno] += freq;
call_p = CALL_P (curr_insn);
+ src_regno = (set != NULL_RTX && REG_P (SET_SRC (set))
+ ? REGNO (SET_SRC (set)) : -1);
+ dst_regno = (set != NULL_RTX && REG_P (SET_DEST (set))
+ ? REGNO (SET_DEST (set)) : -1);
if (complete_info_p
- && set != NULL_RTX
- && REG_P (SET_DEST (set)) && REG_P (SET_SRC (set))
+ && src_regno >= 0 && dst_regno >= 0
/* Check that source regno does not conflict with
destination regno to exclude most impossible
preferences. */
- && ((((src_regno = REGNO (SET_SRC (set))) >= FIRST_PSEUDO_REGISTER
- && ! sparseset_bit_p (pseudos_live, src_regno))
+ && (((src_regno >= FIRST_PSEUDO_REGISTER
+ && (! sparseset_bit_p (pseudos_live, src_regno)
+ || (dst_regno >= FIRST_PSEUDO_REGISTER
+ && lra_reg_val_equal_p (src_regno,
+ lra_reg_info[dst_regno].val,
+ lra_reg_info[dst_regno].offset))))
|| (src_regno < FIRST_PSEUDO_REGISTER
&& ! TEST_HARD_REG_BIT (hard_regs_live, src_regno)))
/* It might be 'inheritance pseudo <- reload pseudo'. */
|| (src_regno >= lra_constraint_new_regno_start
- && ((int) REGNO (SET_DEST (set))
- >= lra_constraint_new_regno_start)
+ && dst_regno >= lra_constraint_new_regno_start
/* Remember to skip special cases where src/dest regnos are
the same, e.g. insn SET pattern has matching constraints
like =r,0. */
- && src_regno != (int) REGNO (SET_DEST (set)))))
+ && src_regno != dst_regno)))
{
int hard_regno = -1, regno = -1;
- dst_regno = REGNO (SET_DEST (set));
if (dst_regno >= lra_constraint_new_regno_start
&& src_regno >= lra_constraint_new_regno_start)
{