diff options
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/lra-assigns.c | 12 | ||||
-rw-r--r-- | gcc/lra-constraints.c | 5 | ||||
-rw-r--r-- | gcc/lra-eliminations.c | 11 | ||||
-rw-r--r-- | gcc/lra-int.h | 33 | ||||
-rw-r--r-- | gcc/lra.c | 3 |
6 files changed, 69 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a0b5ceb..f55df95 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2013-04-23 Shiva Chen <shiva0217@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_update_reg_val_offset to update register content offset. + * lra-int.h (struct lra_reg): Add offset member. + (lra_reg_val_equal_p): New static inline function. + (lra_update_reg_val_offset): 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-04-23 Catherine Moore <clm@codesourcery.com> * config/mips/mips.md (*movhi_internal, *movqi_internal): New 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 9e4924c..7cc7081 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 27a5d75..5aa0cb8 100644 --- a/gcc/lra-eliminations.c +++ b/gcc/lra-eliminations.c @@ -1124,8 +1124,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. */ + lra_update_reg_val_offset (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 5ec7fa1..3d7ecb3 100644 --- a/gcc/lra-int.h +++ b/gcc/lra-int.h @@ -118,6 +118,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 @@ -443,6 +445,37 @@ lra_get_insn_recog_data (rtx insn) return lra_set_insn_recog_data (insn); } +/* Update offset from pseudos with VAL by INCR. */ +static inline void +lra_update_reg_val_offset (int val, int incr) +{ + int i; + + for (i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++) + { + if (lra_reg_info[i].val == val) + lra_reg_info[i].offset += incr; + } +} + +/* Return true if register content is equal to VAL with OFFSET. */ +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 value of register FROM to TO. */ +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 @@ -194,7 +194,7 @@ 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_assign_reg_val (REGNO (original), REGNO (new_reg)); return new_reg; } @@ -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; } |