|
|
dadd0b |
2020-01-28 Vladimir Makarov <vmakarov@redhat.com>
|
|
|
dadd0b |
|
|
|
dadd0b |
PR rtl-optimization/93272
|
|
|
dadd0b |
* ira-lives.c (process_out_of_region_eh_regs): New function.
|
|
|
dadd0b |
(process_bb_node_lives): Call it.
|
|
|
dadd0b |
|
|
|
dadd0b |
--- gcc/ira-lives.c
|
|
|
dadd0b |
+++ gcc/ira-lives.c
|
|
|
dadd0b |
@@ -1116,6 +1116,50 @@
|
|
|
dadd0b |
return cheap_reg;
|
|
|
dadd0b |
}
|
|
|
dadd0b |
|
|
|
dadd0b |
+#ifdef EH_RETURN_DATA_REGNO
|
|
|
dadd0b |
+
|
|
|
dadd0b |
+/* Add EH return hard registers as conflict hard registers to allocnos
|
|
|
dadd0b |
+ living at end of BB. For most allocnos it is already done in
|
|
|
dadd0b |
+ process_bb_node_lives when we processing input edges but it does
|
|
|
dadd0b |
+ not work when and EH edge is edge out of the current region. This
|
|
|
dadd0b |
+ function covers such out of region edges. */
|
|
|
dadd0b |
+static void
|
|
|
dadd0b |
+process_out_of_region_eh_regs (basic_block bb)
|
|
|
dadd0b |
+{
|
|
|
dadd0b |
+ edge e;
|
|
|
dadd0b |
+ edge_iterator ei;
|
|
|
dadd0b |
+ unsigned int i;
|
|
|
dadd0b |
+ bitmap_iterator bi;
|
|
|
dadd0b |
+ bool eh_p = false;
|
|
|
dadd0b |
+
|
|
|
dadd0b |
+ FOR_EACH_EDGE (e, ei, bb->succs)
|
|
|
dadd0b |
+ if ((e->flags & EDGE_EH)
|
|
|
dadd0b |
+ && IRA_BB_NODE (e->dest)->parent != IRA_BB_NODE (bb)->parent)
|
|
|
dadd0b |
+ eh_p = true;
|
|
|
dadd0b |
+
|
|
|
dadd0b |
+ if (! eh_p)
|
|
|
dadd0b |
+ return;
|
|
|
dadd0b |
+
|
|
|
dadd0b |
+ EXECUTE_IF_SET_IN_BITMAP (df_get_live_out (bb), FIRST_PSEUDO_REGISTER, i, bi)
|
|
|
dadd0b |
+ {
|
|
|
dadd0b |
+ ira_allocno_t a = ira_curr_regno_allocno_map[i];
|
|
|
dadd0b |
+ for (int n = ALLOCNO_NUM_OBJECTS (a) - 1; n >= 0; n--)
|
|
|
dadd0b |
+ {
|
|
|
dadd0b |
+ ira_object_t obj = ALLOCNO_OBJECT (a, n);
|
|
|
dadd0b |
+ for (int k = 0; ; k++)
|
|
|
dadd0b |
+ {
|
|
|
dadd0b |
+ unsigned int regno = EH_RETURN_DATA_REGNO (k);
|
|
|
dadd0b |
+ if (regno == INVALID_REGNUM)
|
|
|
dadd0b |
+ break;
|
|
|
dadd0b |
+ SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), regno);
|
|
|
dadd0b |
+ SET_HARD_REG_BIT (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj), regno);
|
|
|
dadd0b |
+ }
|
|
|
dadd0b |
+ }
|
|
|
dadd0b |
+ }
|
|
|
dadd0b |
+}
|
|
|
dadd0b |
+
|
|
|
dadd0b |
+#endif
|
|
|
dadd0b |
+
|
|
|
dadd0b |
/* Process insns of the basic block given by its LOOP_TREE_NODE to
|
|
|
dadd0b |
update allocno live ranges, allocno hard register conflicts,
|
|
|
dadd0b |
intersected calls, and register pressure info for allocnos for the
|
|
|
dadd0b |
@@ -1170,6 +1214,10 @@
|
|
|
dadd0b |
EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi)
|
|
|
dadd0b |
mark_pseudo_regno_live (j);
|
|
|
dadd0b |
|
|
|
dadd0b |
+#ifdef EH_RETURN_DATA_REGNO
|
|
|
dadd0b |
+ process_out_of_region_eh_regs (bb);
|
|
|
dadd0b |
+#endif
|
|
|
dadd0b |
+
|
|
|
dadd0b |
freq = REG_FREQ_FROM_BB (bb);
|
|
|
dadd0b |
if (freq == 0)
|
|
|
dadd0b |
freq = 1;
|