diff options
author | Peter Bergner <bergner@linux.ibm.com> | 2018-09-30 20:03:14 +0000 |
---|---|---|
committer | Peter Bergner <bergner@gcc.gnu.org> | 2018-09-30 15:03:14 -0500 |
commit | 0df92803a9f297fd8af6f23b224f15e1cf12f12a (patch) | |
tree | b6dae223a430f5e7fecd8cf91c5602da541d0401 /gcc/lra-lives.c | |
parent | a086078b8f7ee2580e55afc03026acf63bfb9605 (diff) | |
download | gcc-0df92803a9f297fd8af6f23b224f15e1cf12f12a.zip gcc-0df92803a9f297fd8af6f23b224f15e1cf12f12a.tar.gz gcc-0df92803a9f297fd8af6f23b224f15e1cf12f12a.tar.bz2 |
re PR rtl-optimization/86939 (IRA incorrectly creates an interference between a pseudo register and a hard register)
gcc/
PR rtl-optimization/86939
* ira-lives.c (make_hard_regno_born): Rename from this...
(make_hard_regno_live): ... to this. Remove update to conflict
information. Update function comment.
(make_hard_regno_dead): Add conflict information update. Update
function comment.
(make_object_born): Rename from this...
(make_object_live): ... to this. Remove update to conflict information.
Update function comment.
(make_object_dead): Add conflict information update. Update function
comment.
(mark_pseudo_regno_live): Call make_object_live.
(mark_pseudo_regno_subword_live): Likewise.
(mark_hard_reg_dead): Update function comment.
(mark_hard_reg_live): Call make_hard_regno_live.
(process_bb_node_lives): Likewise.
* lra-lives.c (make_hard_regno_born): Rename from this...
(make_hard_regno_live): ... to this. Remove update to conflict
information. Remove now uneeded check_pic_pseudo_p argument.
Update function comment.
(make_hard_regno_dead): Add check_pic_pseudo_p argument and add update
to conflict information. Update function comment.
(mark_pseudo_live): Remove update to conflict information. Update
function comment.
(mark_pseudo_dead): Add conflict information update.
(mark_regno_live): Call make_hard_regno_live.
(mark_regno_dead): Call make_hard_regno_dead with new arguement.
(process_bb_lives): Call make_hard_regno_live and make_hard_regno_dead.
From-SVN: r264726
Diffstat (limited to 'gcc/lra-lives.c')
-rw-r--r-- | gcc/lra-lives.c | 74 |
1 files changed, 38 insertions, 36 deletions
diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index 565c68b..b41df60 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -223,42 +223,41 @@ lra_intersected_live_ranges_p (lra_live_range_t r1, lra_live_range_t r2) /* The corresponding bitmaps of BB currently being processed. */ static bitmap bb_killed_pseudos, bb_gen_pseudos; -/* The function processing birth of hard register REGNO. It updates - living hard regs, START_LIVING, and conflict hard regs for living - pseudos. Conflict hard regs for the pic pseudo is not updated if - REGNO is REAL_PIC_OFFSET_TABLE_REGNUM and CHECK_PIC_PSEUDO_P is - true. */ +/* Record hard register REGNO as now being live. It updates + living hard regs and START_LIVING. */ static void -make_hard_regno_born (int regno, bool check_pic_pseudo_p ATTRIBUTE_UNUSED) +make_hard_regno_live (int regno) { - unsigned int i; - lra_assert (regno < FIRST_PSEUDO_REGISTER); if (TEST_HARD_REG_BIT (hard_regs_live, regno)) return; SET_HARD_REG_BIT (hard_regs_live, regno); sparseset_set_bit (start_living, regno); - EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, i) -#ifdef REAL_PIC_OFFSET_TABLE_REGNUM - if (! check_pic_pseudo_p - || regno != REAL_PIC_OFFSET_TABLE_REGNUM - || pic_offset_table_rtx == NULL - || i != REGNO (pic_offset_table_rtx)) -#endif - SET_HARD_REG_BIT (lra_reg_info[i].conflict_hard_regs, regno); if (fixed_regs[regno] || TEST_HARD_REG_BIT (hard_regs_spilled_into, regno)) bitmap_set_bit (bb_gen_pseudos, regno); } -/* Process the death of hard register REGNO. This updates - hard_regs_live and START_DYING. */ +/* Process the definition of hard register REGNO. This updates + hard_regs_live, START_DYING and conflict hard regs for living + pseudos. Conflict hard regs for the pic pseudo is not updated if + REGNO is REAL_PIC_OFFSET_TABLE_REGNUM and CHECK_PIC_PSEUDO_P is + true. */ static void -make_hard_regno_dead (int regno) +make_hard_regno_dead (int regno, bool check_pic_pseudo_p ATTRIBUTE_UNUSED) { lra_assert (regno < FIRST_PSEUDO_REGISTER); if (! TEST_HARD_REG_BIT (hard_regs_live, regno)) return; sparseset_set_bit (start_dying, regno); + unsigned int i; + EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, i) +#ifdef REAL_PIC_OFFSET_TABLE_REGNUM + if (! check_pic_pseudo_p + || regno != REAL_PIC_OFFSET_TABLE_REGNUM + || pic_offset_table_rtx == NULL + || i != REGNO (pic_offset_table_rtx)) +#endif + SET_HARD_REG_BIT (lra_reg_info[i].conflict_hard_regs, regno); CLEAR_HARD_REG_BIT (hard_regs_live, regno); if (fixed_regs[regno] || TEST_HARD_REG_BIT (hard_regs_spilled_into, regno)) { @@ -267,9 +266,9 @@ make_hard_regno_dead (int regno) } } -/* Mark pseudo REGNO as living at program point POINT, update conflicting - hard registers of the pseudo and START_LIVING, and start a new live - range for the pseudo corresponding to REGNO if it is necessary. */ +/* Mark pseudo REGNO as living at program point POINT, update START_LIVING + and start a new live range for the pseudo corresponding to REGNO if it + is necessary. */ static void mark_pseudo_live (int regno, int point) { @@ -278,7 +277,6 @@ mark_pseudo_live (int regno, int point) lra_assert (regno >= FIRST_PSEUDO_REGISTER); lra_assert (! sparseset_bit_p (pseudos_live, regno)); sparseset_set_bit (pseudos_live, regno); - IOR_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs, hard_regs_live); if ((complete_info_p || lra_get_regno_hard_regno (regno) < 0) && ((p = lra_reg_info[regno].live_ranges) == NULL @@ -301,6 +299,9 @@ mark_pseudo_dead (int regno, int point) lra_assert (sparseset_bit_p (pseudos_live, regno)); sparseset_clear_bit (pseudos_live, regno); sparseset_set_bit (start_dying, regno); + + IOR_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs, hard_regs_live); + if (complete_info_p || lra_get_regno_hard_regno (regno) < 0) { p = lra_reg_info[regno].live_ranges; @@ -322,7 +323,7 @@ mark_regno_live (int regno, machine_mode mode, int point) if (regno < FIRST_PSEUDO_REGISTER) { for (last = end_hard_regno (mode, regno); regno < last; regno++) - make_hard_regno_born (regno, false); + make_hard_regno_live (regno); } else { @@ -349,7 +350,7 @@ mark_regno_dead (int regno, machine_mode mode, int point) if (regno < FIRST_PSEUDO_REGISTER) { for (last = end_hard_regno (mode, regno); regno < last; regno++) - make_hard_regno_dead (regno); + make_hard_regno_dead (regno, false); } else { @@ -834,13 +835,13 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) if (reg->type != OP_IN) - make_hard_regno_born (reg->regno, false); + make_hard_regno_live (reg->regno); if (curr_id->arg_hard_regs != NULL) for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) if (regno >= FIRST_PSEUDO_REGISTER) /* It is a clobber. */ - make_hard_regno_born (regno - FIRST_PSEUDO_REGISTER, false); + make_hard_regno_live (regno - FIRST_PSEUDO_REGISTER); sparseset_copy (unused_set, start_living); @@ -857,13 +858,14 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) if (reg->type == OP_OUT && ! reg_early_clobber_p (reg, n_alt) && ! reg->subreg_p) - make_hard_regno_dead (reg->regno); + make_hard_regno_dead (reg->regno, false); if (curr_id->arg_hard_regs != NULL) for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) if (regno >= FIRST_PSEUDO_REGISTER) - /* It is a clobber. */ - make_hard_regno_dead (regno - FIRST_PSEUDO_REGISTER); + /* It is a clobber. Don't create conflict of used + REAL_PIC_OFFSET_TABLE_REGNUM and the pic pseudo. */ + make_hard_regno_dead (regno - FIRST_PSEUDO_REGISTER, true); if (call_p) { @@ -920,14 +922,14 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) if (reg->type == OP_IN) - make_hard_regno_born (reg->regno, false); + make_hard_regno_live (reg->regno); if (curr_id->arg_hard_regs != NULL) /* Make argument hard registers live. Don't create conflict of used REAL_PIC_OFFSET_TABLE_REGNUM and the pic pseudo. */ for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) if (regno < FIRST_PSEUDO_REGISTER) - make_hard_regno_born (regno, true); + make_hard_regno_live (regno); sparseset_and_compl (dead_set, start_living, start_dying); @@ -952,7 +954,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) if (reg2->type != OP_OUT && reg2->regno == reg->regno) break; if (reg2 == NULL) - make_hard_regno_dead (reg->regno); + make_hard_regno_dead (reg->regno, false); } if (need_curr_point_incr) @@ -995,7 +997,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) if (regno == INVALID_REGNUM) break; - make_hard_regno_born (regno, false); + make_hard_regno_live (regno); } /* Pseudos can't go in stack regs at the start of a basic block that @@ -1009,7 +1011,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, px) lra_reg_info[px].no_stack_p = true; for (px = FIRST_STACK_REG; px <= LAST_STACK_REG; px++) - make_hard_regno_born (px, false); + make_hard_regno_live (px); #endif /* No need to record conflicts for call clobbered regs if we have nonlocal labels around, as we don't ever try to @@ -1029,7 +1031,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER) #endif ) - make_hard_regno_born (px, false); + make_hard_regno_live (px); } bool live_change_p = false; |