aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2022-01-10 14:47:07 +0000
committerRichard Sandiford <richard.sandiford@arm.com>2022-01-10 14:47:07 +0000
commitd54565d87ff79b882208dfb29af50232033c233d (patch)
tree47973cdb200c95c3e9ea7b34f3d9b981c37c55bd
parent909a4b4764c4f270f09ccb2a950c91b21ed7b33a (diff)
downloadgcc-d54565d87ff79b882208dfb29af50232033c233d.zip
gcc-d54565d87ff79b882208dfb29af50232033c233d.tar.gz
gcc-d54565d87ff79b882208dfb29af50232033c233d.tar.bz2
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.
-rw-r--r--gcc/ira-color.c21
-rw-r--r--gcc/ira-int.h28
2 files changed, 29 insertions, 20 deletions
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index e743331..ae0f08a 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 b32c80d..c5b1a13 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 */