Hi, Vladimir I write the new patch as your suggestion. Could you help me to check is there something missing ?
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; } 2013/4/20 Vladimir Makarov <vmaka...@redhat.com>: > On 13-04-17 11:11 PM, Shiva Chen wrote: >> >> Hi, Vladimir >> >> Overlapped live range RTL is from line 7577 to 7597 in test2.c.209r.reload >> >> Previous patch probably not completed. >> The new patch will record lra_reg_info[i].offset as the offset from >> eliminate register to the pseudo i >> and keep updating when the stack has been changed. >> Therefore, lra-assign could get the latest offset to identify the >> pseudo content is equal or not. >> >> gcc/lra-assigns.c | 6 ++++-- >> gcc/lra-eliminations.c | 12 ++++++++++-- >> gcc/lra-int.h | 2 ++ >> gcc/lra.c | 5 ++++- >> 4 files changed, 20 insertions(+), 5 deletions(-) >> >> diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c >> index b204513..daf0aa9 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,11 @@ 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 ((val == lra_reg_info[conflict_regno].val) >> + && (offset == lra_reg_info[conflict_regno].offset)) >> { >> conflict_hr = live_pseudos_reg_renumber[conflict_regno]; >> nregs = (hard_regno_nregs[conflict_hr] >> diff --git a/gcc/lra-eliminations.c b/gcc/lra-eliminations.c >> index 9df0bae..2d34b51 100644 >> --- a/gcc/lra-eliminations.c >> +++ b/gcc/lra-eliminations.c >> @@ -1046,6 +1046,7 @@ spill_pseudos (HARD_REG_SET set) >> static void >> update_reg_eliminate (bitmap insns_with_changed_offsets) >> { >> + int i; >> bool prev; >> struct elim_table *ep, *ep1; >> HARD_REG_SET temp_hard_reg_set; >> @@ -1124,8 +1125,15 @@ 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. */ >> + for (i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++) >> + if (lra_reg_info[i].val - 1 == ep->from) > > I guess, -1 here is typo. > >> + lra_reg_info[i].offset += (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..944cad1 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 >> diff --git a/gcc/lra.c b/gcc/lra.c >> index 9df24b5..7a60281 100644 >> --- a/gcc/lra.c >> +++ b/gcc/lra.c >> @@ -194,7 +194,10 @@ lra_create_new_reg (enum machine_mode md_mode, >> rtx original, >> new_reg >> = lra_create_new_reg_with_unique_value (md_mode, original, rclass, >> title); >> if (original != NULL_RTX && REG_P (original)) >> - lra_reg_info[REGNO (new_reg)].val = lra_reg_info[REGNO >> (original)].val; >> + { >> + lra_reg_info[REGNO (new_reg)].val = lra_reg_info[REGNO >> (original)].val; >> + lra_reg_info[REGNO (new_reg)].offset = 0; >> + } >> return new_reg; >> } >> >> >> > Thanks for the dump files. They help me to understand better the situation. > The patch is better but it is still incomplete. There are more places where > the values are used (more places in lra-assigns.c, a few places in > lra-constraints.c). > > As there are many places it would be nice to have helper functions (I'd make > them static inline and put them in lra-int.h): > > static inline void > lra_set_up_reg_val (int regno, int val, int offset) > > and > > static inline bool > lra_reg_val_equal_p (int regno, int val, int offset) > > and use them wherever it is possible. > > So could you check all the places where .val is used, define the helper > functions, and use them wherever it is possible and send me the new version > of the patch. I'll approve it after some checking. > > Thanks for working on this problem. I really appreciate it. >