Blame SOURCES/gcc48-pr93272.patch

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