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.
---
gcc/ira-color.c | 21 +
gcc/ira-int.h | 28
2 files changed, 29 insertions(+), 20 deletions(-)
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index e7433312675..ae0f08af4b3 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -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))
{
diff --git a/gcc/ira-int.h b/gcc/ira-int.h
index b32c80d4c9e..c5b1a131abd 100644
--- a/gcc/ira-int.h
+++ b/gcc/ira-int.h
@@ -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 */
--
2.25.1