ira: Add ira_subloop_allocnos_can_differ_p
color_pass has two instances of the same code for propagating non-cap assignments from parent loops to subloops. This patch adds a helper function for testing when such propagations are required for correctness and uses it to remove the duplicated code. A later patch will use this in ira-build.c too, which is why the function is exported to ira-int.h. No functional change intended. gcc/ PR rtl-optimization/98782 * ira-int.h (ira_subloop_allocnos_can_differ_p): New function, extracted from... * ira-color.c (color_pass): ...here.
This commit is contained in:
parent
909a4b4764
commit
d54565d87f
2 changed files with 29 additions and 20 deletions
|
@ -3446,26 +3446,7 @@ color_pass (ira_loop_tree_node_t loop_tree_node)
|
|||
if ((flag_ira_region == IRA_REGION_MIXED
|
||||
&& (loop_tree_node->reg_pressure[pclass]
|
||||
<= ira_class_hard_regs_num[pclass]))
|
||||
|| (pic_offset_table_rtx != NULL
|
||||
&& regno == (int) REGNO (pic_offset_table_rtx))
|
||||
/* Avoid overlapped multi-registers. Moves between them
|
||||
might result in wrong code generation. */
|
||||
|| (hard_regno >= 0
|
||||
&& ira_reg_class_max_nregs[pclass][mode] > 1))
|
||||
{
|
||||
if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
|
||||
{
|
||||
ALLOCNO_HARD_REGNO (subloop_allocno) = hard_regno;
|
||||
ALLOCNO_ASSIGNED_P (subloop_allocno) = true;
|
||||
if (hard_regno >= 0)
|
||||
update_costs_from_copies (subloop_allocno, true, true);
|
||||
/* We don't need updated costs anymore. */
|
||||
ira_free_allocno_updated_costs (subloop_allocno);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
ira_assert (regno < ira_reg_equiv_len);
|
||||
if (ira_equiv_no_lvalue_p (regno))
|
||||
|| !ira_subloop_allocnos_can_differ_p (a, hard_regno >= 0))
|
||||
{
|
||||
if (! ALLOCNO_ASSIGNED_P (subloop_allocno))
|
||||
{
|
||||
|
|
|
@ -1595,4 +1595,32 @@ ira_loop_border_costs::move_between_loops_cost () const
|
|||
return move_cost * (m_entry_freq + m_exit_freq);
|
||||
}
|
||||
|
||||
/* Return true if subloops that contain allocnos for A's register can
|
||||
use a different assignment from A. ALLOCATED_P is true for the case
|
||||
in which allocation succeeded for A. */
|
||||
inline bool
|
||||
ira_subloop_allocnos_can_differ_p (ira_allocno_t a, bool allocated_p = true)
|
||||
{
|
||||
auto regno = ALLOCNO_REGNO (a);
|
||||
|
||||
if (pic_offset_table_rtx != NULL
|
||||
&& regno == (int) REGNO (pic_offset_table_rtx))
|
||||
return false;
|
||||
|
||||
ira_assert (regno < ira_reg_equiv_len);
|
||||
if (ira_equiv_no_lvalue_p (regno))
|
||||
return false;
|
||||
|
||||
/* Avoid overlapping multi-registers. Moves between them might result
|
||||
in wrong code generation. */
|
||||
if (allocated_p)
|
||||
{
|
||||
auto pclass = ira_pressure_class_translate[ALLOCNO_CLASS (a)];
|
||||
if (ira_reg_class_max_nregs[pclass][ALLOCNO_MODE (a)] > 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* GCC_IRA_INT_H */
|
||||
|
|
Loading…
Add table
Reference in a new issue