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
This commit is contained in:
Peter Bergner 2018-09-30 20:03:14 +00:00 committed by Peter Bergner
parent a086078b8f
commit 0df92803a9
3 changed files with 99 additions and 68 deletions

View File

@ -1,3 +1,34 @@
2018-09-30 Peter Bergner <bergner@linux.ibm.com>
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.
2018-09-29 H.J. Lu <hongjiu.lu@intel.com>
PR target/87370

View File

@ -84,14 +84,19 @@ static int *allocno_saved_at_call;
supplemental to recog_data. */
static alternative_mask preferred_alternatives;
/* Record the birth of hard register REGNO, updating hard_regs_live and
hard reg conflict information for living allocnos. */
/* Record hard register REGNO as now being live. */
static void
make_hard_regno_born (int regno)
make_hard_regno_live (int regno)
{
SET_HARD_REG_BIT (hard_regs_live, regno);
}
/* Process the definition of hard register REGNO. This updates
hard_regs_live and hard reg conflict information for living allocnos. */
static void
make_hard_regno_dead (int regno)
{
unsigned int i;
SET_HARD_REG_BIT (hard_regs_live, regno);
EXECUTE_IF_SET_IN_SPARSESET (objects_live, i)
{
ira_object_t obj = ira_object_id_map[i];
@ -99,28 +104,17 @@ make_hard_regno_born (int regno)
SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), regno);
SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), regno);
}
}
/* Process the death of hard register REGNO. This updates
hard_regs_live. */
static void
make_hard_regno_dead (int regno)
{
CLEAR_HARD_REG_BIT (hard_regs_live, regno);
}
/* Record the birth of object OBJ. Set a bit for it in objects_live,
start a new live range for it if necessary and update hard register
conflicts. */
/* Record object OBJ as now being live. Set a bit for it in objects_live,
and start a new live range for it if necessary. */
static void
make_object_born (ira_object_t obj)
make_object_live (ira_object_t obj)
{
live_range_t lr = OBJECT_LIVE_RANGES (obj);
sparseset_set_bit (objects_live, OBJECT_CONFLICT_ID (obj));
IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), hard_regs_live);
IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), hard_regs_live);
live_range_t lr = OBJECT_LIVE_RANGES (obj);
if (lr == NULL
|| (lr->finish != curr_point && lr->finish + 1 != curr_point))
ira_add_live_range_to_object (obj, curr_point, -1);
@ -154,14 +148,18 @@ update_allocno_pressure_excess_length (ira_object_t obj)
}
}
/* Process the death of object OBJ, which is associated with allocno
A. This finishes the current live range for it. */
/* Process the definition of object OBJ, which is associated with allocno A.
This finishes the current live range for it. */
static void
make_object_dead (ira_object_t obj)
{
live_range_t lr;
sparseset_clear_bit (objects_live, OBJECT_CONFLICT_ID (obj));
IOR_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj), hard_regs_live);
IOR_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), hard_regs_live);
lr = OBJECT_LIVE_RANGES (obj);
ira_assert (lr != NULL);
lr->finish = curr_point;
@ -290,7 +288,7 @@ mark_pseudo_regno_live (int regno)
continue;
inc_register_pressure (pclass, nregs);
make_object_born (obj);
make_object_live (obj);
}
}
@ -327,7 +325,7 @@ mark_pseudo_regno_subword_live (int regno, int subword)
return;
inc_register_pressure (pclass, 1);
make_object_born (obj);
make_object_live (obj);
}
/* Mark the register REG as live. Store a 1 in hard_regs_live for
@ -351,7 +349,7 @@ mark_hard_reg_live (rtx reg)
aclass = ira_hard_regno_allocno_class[regno];
pclass = ira_pressure_class_translate[aclass];
inc_register_pressure (pclass, 1);
make_hard_regno_born (regno);
make_hard_regno_live (regno);
}
regno++;
}
@ -457,8 +455,8 @@ mark_pseudo_regno_subword_dead (int regno, int subword)
make_object_dead (obj);
}
/* Mark the hard register REG as dead. Store a 0 in hard_regs_live for the
register. */
/* Process the definition of hard register REG. This updates hard_regs_live
and hard reg conflict information for living allocnos. */
static void
mark_hard_reg_dead (rtx reg)
{
@ -1298,7 +1296,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
unsigned int regno = EH_RETURN_DATA_REGNO (j);
if (regno == INVALID_REGNUM)
break;
make_hard_regno_born (regno);
make_hard_regno_live (regno);
}
/* Allocnos can't go in stack regs at the start of a basic block
@ -1317,7 +1315,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
ALLOCNO_TOTAL_NO_STACK_REG_P (a) = true;
}
for (px = FIRST_STACK_REG; px <= LAST_STACK_REG; px++)
make_hard_regno_born (px);
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
@ -1340,7 +1338,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
&& REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER)
#endif
)
make_hard_regno_born (px);
make_hard_regno_live (px);
}
EXECUTE_IF_SET_IN_SPARSESET (objects_live, i)

View File

@ -223,21 +223,33 @@ 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);
if (fixed_regs[regno] || TEST_HARD_REG_BIT (hard_regs_spilled_into, regno))
bitmap_set_bit (bb_gen_pseudos, regno);
}
/* 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, 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
@ -246,19 +258,6 @@ make_hard_regno_born (int regno, bool check_pic_pseudo_p ATTRIBUTE_UNUSED)
|| 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. */
static void
make_hard_regno_dead (int regno)
{
lra_assert (regno < FIRST_PSEUDO_REGISTER);
if (! TEST_HARD_REG_BIT (hard_regs_live, regno))
return;
sparseset_set_bit (start_dying, 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;