Hi, Vladimir I add the code and the patch has passed bootstrap/regression test on i686-pc-linux-gnu with current main trunk.
However, I don't have svn write access yet. Could you please help to commit this patch? Thanks for your comment and your help. I really appreciate it. A plaintext gcc/ChangeLog is as below: 2013-04-23 Shiva Chen <shiva0...@gmail.com> * lra-assigns.c (find_hard_regno_for): Use lra_reg_val_equal_p to check the register content is equal or not. * lra-constraints.c (match_reload): Use lra_assign_reg_val to assign register content record. * lra-eliminations.c (update_reg_eliminate): Use lra_set_up_reg_val to update register content offset. * lra-int.h (struct lra_reg): Add offset member. (lra_reg_val_equal_p): New static inline function. (lra_set_up_reg_val): New static inline function. (lra_assign_reg_val): New static inline function. * lra.c (lra_create_new_reg): Use lra_assign_reg_val to assign register content record. (initialize_lra_reg_info_element): Initial offset to zero 2013/4/23 Vladimir Makarov <vmaka...@redhat.com>: > 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; >> } >> >> >
lra-reg-content-fix.patch
Description: Binary data