aboutsummaryrefslogtreecommitdiff
path: root/gcc/lra-lives.c
diff options
context:
space:
mode:
authorPeter Bergner <bergner@linux.ibm.com>2018-09-30 20:03:14 +0000
committerPeter Bergner <bergner@gcc.gnu.org>2018-09-30 15:03:14 -0500
commit0df92803a9f297fd8af6f23b224f15e1cf12f12a (patch)
treeb6dae223a430f5e7fecd8cf91c5602da541d0401 /gcc/lra-lives.c
parenta086078b8f7ee2580e55afc03026acf63bfb9605 (diff)
downloadgcc-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.c74
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;