LRA assign same hard register with live range overlapped pseduos
Vladimir Makarov
vmakarov@redhat.com
Tue Apr 23 00:05:00 GMT 2013
On 13-04-22 2:26 AM, Shiva Chen wrote:
> Hi, Vladimir
>
> I write the new patch as your suggestion.
> Could you help me to check is there something missing ?
I think there is one more place to use lra_assign_reg_val:
lra.c::lra_create_new_reg
Please add the code and right changelog entry for the patch and you can
commit the patch into trunk.
Thanks, Shiva.
> Thanks, Shiva
>
> gcc/lra-assigns.c | 12 +++++++-----
> gcc/lra-constraints.c | 5 ++---
> gcc/lra-eliminations.c | 10 ++++++++--
> gcc/lra-int.h | 33 +++++++++++++++++++++++++++++++++
> gcc/lra.c | 1 +
> 5 files changed, 51 insertions(+), 10 deletions(-)
>
> diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c
> index b204513..3f8a899 100644
> --- a/gcc/lra-assigns.c
> +++ b/gcc/lra-assigns.c
> @@ -448,7 +448,7 @@ find_hard_regno_for (int regno, int *cost, int
> try_only_hard_regno)
> int hr, conflict_hr, nregs;
> enum machine_mode biggest_mode;
> unsigned int k, conflict_regno;
> - int val, biggest_nregs, nregs_diff;
> + int offset, val, biggest_nregs, nregs_diff;
> enum reg_class rclass;
> bitmap_iterator bi;
> bool *rclass_intersect_p;
> @@ -508,9 +508,10 @@ find_hard_regno_for (int regno, int *cost, int
> try_only_hard_regno)
> #endif
> sparseset_clear_bit (conflict_reload_and_inheritance_pseudos, regno);
> val = lra_reg_info[regno].val;
> + offset = lra_reg_info[regno].offset;
> CLEAR_HARD_REG_SET (impossible_start_hard_regs);
> EXECUTE_IF_SET_IN_SPARSESET (live_range_hard_reg_pseudos, conflict_regno)
> - if (val == lra_reg_info[conflict_regno].val)
> + if (lra_reg_val_equal_p (conflict_regno, val, offset))
> {
> conflict_hr = live_pseudos_reg_renumber[conflict_regno];
> nregs = (hard_regno_nregs[conflict_hr]
> @@ -538,7 +539,7 @@ find_hard_regno_for (int regno, int *cost, int
> try_only_hard_regno)
> }
> EXECUTE_IF_SET_IN_SPARSESET (conflict_reload_and_inheritance_pseudos,
> conflict_regno)
> - if (val != lra_reg_info[conflict_regno].val)
> + if (!lra_reg_val_equal_p (conflict_regno, val, offset))
> {
> lra_assert (live_pseudos_reg_renumber[conflict_regno] < 0);
> if ((hard_regno
> @@ -1007,7 +1008,7 @@
> setup_live_pseudos_and_spill_after_risky_transforms (bitmap
> {
> int p, i, j, n, regno, hard_regno;
> unsigned int k, conflict_regno;
> - int val;
> + int val, offset;
> HARD_REG_SET conflict_set;
> enum machine_mode mode;
> lra_live_range_t r;
> @@ -1050,8 +1051,9 @@
> setup_live_pseudos_and_spill_after_risky_transforms (bitmap
> COPY_HARD_REG_SET (conflict_set, lra_no_alloc_regs);
> IOR_HARD_REG_SET (conflict_set, lra_reg_info[regno].conflict_hard_regs);
> val = lra_reg_info[regno].val;
> + offset = lra_reg_info[regno].offset;
> EXECUTE_IF_SET_IN_SPARSESET (live_range_hard_reg_pseudos, conflict_regno)
> - if (val != lra_reg_info[conflict_regno].val
> + if (!lra_reg_val_equal_p (conflict_regno, val, offset)
> /* If it is multi-register pseudos they should start on
> the same hard register. */
> || hard_regno != reg_renumber[conflict_regno])
> diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
> index e3b4add..2a72aef 100644
> --- a/gcc/lra-constraints.c
> +++ b/gcc/lra-constraints.c
> @@ -704,7 +704,7 @@ match_reload (signed char out, signed char *ins,
> enum reg_class goal_class,
> pseudos still live where reload pseudos dies. */
> if (REG_P (in_rtx) && (int) REGNO (in_rtx) < lra_new_regno_start
> && find_regno_note (curr_insn, REG_DEAD, REGNO (in_rtx)))
> - lra_reg_info[REGNO (reg)].val = lra_reg_info[REGNO (in_rtx)].val;
> + lra_assign_reg_val (REGNO (in_rtx), REGNO (reg));
> }
> else
> {
> @@ -733,8 +733,7 @@ match_reload (signed char out, signed char *ins,
> enum reg_class goal_class,
> && GET_MODE (subreg_reg) == outmode
> && SUBREG_BYTE (in_rtx) == SUBREG_BYTE (new_in_reg)
> && find_regno_note (curr_insn, REG_DEAD, REGNO (subreg_reg)))
> - lra_reg_info[REGNO (reg)].val
> - = lra_reg_info[REGNO (subreg_reg)].val;
> + lra_assign_reg_val (REGNO (subreg_reg), REGNO (reg));
> }
> }
> }
> diff --git a/gcc/lra-eliminations.c b/gcc/lra-eliminations.c
> index 9df0bae..0e75cc2 100644
> --- a/gcc/lra-eliminations.c
> +++ b/gcc/lra-eliminations.c
> @@ -1124,8 +1124,14 @@ update_reg_eliminate (bitmap insns_with_changed_offsets)
> setup_elimination_map ();
> for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
> if (elimination_map[ep->from] == ep && ep->previous_offset != ep->offset)
> - bitmap_ior_into (insns_with_changed_offsets,
> - &lra_reg_info[ep->from].insn_bitmap);
> + {
> + bitmap_ior_into (insns_with_changed_offsets,
> + &lra_reg_info[ep->from].insn_bitmap);
> +
> + /* Update offset when the eliminate offset have been changed. */
> + lra_set_up_reg_val (lra_reg_info[ep->from].val,
> + ep->offset - ep->previous_offset);
> + }
> }
>
> /* Initialize the table of hard registers to eliminate.
> diff --git a/gcc/lra-int.h b/gcc/lra-int.h
> index 98f2ff7..69f8f8a 100644
> --- a/gcc/lra-int.h
> +++ b/gcc/lra-int.h
> @@ -116,6 +116,8 @@ struct lra_reg
> /* Value holding by register. If the pseudos have the same value
> they do not conflict. */
> int val;
> + /* Offset from relative eliminate register to pesudo reg. */
> + int offset;
> /* These members are set up in lra-lives.c and updated in
> lra-coalesce.c. */
> /* The biggest size mode in which each pseudo reg is referred in
> @@ -439,6 +441,37 @@ lra_get_insn_recog_data (rtx insn)
> return lra_set_insn_recog_data (insn);
> }
> +/* Update offset from eliminate register to pseduo i. */
> +static inline void
> +lra_set_up_reg_val (int val, int offset)
> +{
> + int i;
> +
> + for (i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++)
> + {
> + if (lra_reg_info[i].val == val)
> + lra_reg_info[i].offset += offset;
> + }
> +}
> +
> +/* Return true if register content are equal. */
> +static inline bool
> +lra_reg_val_equal_p (int regno, int val, int offset)
> +{
> + if (lra_reg_info[regno].val == val
> + && lra_reg_info[regno].offset == offset)
> + return true;
> +
> + return false;
> +}
> +
> +/* Assign register content record. */
> +static inline void
> +lra_assign_reg_val (int from, int to)
> +{
> + lra_reg_info[to].val = lra_reg_info[from].val;
> + lra_reg_info[to].offset = lra_reg_info[from].offset;
> +}
> struct target_lra_int
> diff --git a/gcc/lra.c b/gcc/lra.c
> index 9df24b5..4c06a0c 100644
> --- a/gcc/lra.c
> +++ b/gcc/lra.c
> @@ -1392,6 +1392,7 @@ initialize_lra_reg_info_element (int i)
> lra_reg_info[i].last_reload = 0;
> lra_reg_info[i].restore_regno = -1;
> lra_reg_info[i].val = get_new_reg_value ();
> + lra_reg_info[i].offset = 0;
> lra_reg_info[i].copies = NULL;
> }
>
>
More information about the Gcc
mailing list