ira: Add ira_subloop_allocnos_can_differ_p
authorRichard Sandiford <richard.sandiford@arm.com>
Mon, 10 Jan 2022 14:47:07 +0000 (14:47 +0000)
committerRichard Sandiford <richard.sandiford@arm.com>
Mon, 10 Jan 2022 14:47:07 +0000 (14:47 +0000)
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
gcc/ira-int.h

index e743331..ae0f08a 100644 (file)
@@ -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))
                {
index b32c80d..c5b1a13 100644 (file)
@@ -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 */