diff options
author | Andre Vieira <andre.simoesdiasvieira@arm.com> | 2016-06-13 09:58:34 +0000 |
---|---|---|
committer | Andre Vieira <andre.simoesdiasvieira@arm.com> | 2016-06-13 09:58:34 +0000 |
commit | 33313f44a24da90879da7bb9e1d2469a6a0eed13 (patch) | |
tree | 665df48fe46c8d9ca2a9be874f92ed0805629041 | |
parent | f5b7e2f8784cac3d3238af8e316c9ad8da1c61a1 (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.arm | 11 | ||||
-rw-r--r-- | gcc/lra-constraints.c | 18 | ||||
-rw-r--r-- | gcc/lra-lives.c | 21 |
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) { |