This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: patch for 37790


The following patch solves PR37790. The problem is described on

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37790

The patch switches stack slot coalescing from usage of bitmaps to usage of live ranges. It dramatically decreases compilation speed and memory usage for this test. The patch also prohibits stack slot sharing and processing pseudos spilled by IRA in reload pass when the register pressure is too high (more than 10K) to guarantee IRA decent behavior in extreme cases. The patch was successfully bootstrapped on x86/x86_64, ppc64, and itanium.

Ok to submit?

2008-11-15 Vladimir Makarov <vmakarov@redhat.com>

PR bootstrap/37790
* ira-int.h (ira_copy_allocno_live_range_list,
ira_merge_allocno_live_ranges,
ira_allocno_live_ranges_intersect_p,
ira_finish_allocno_live_range_list): New prototypes.
(ira_allocno_live_ranges_intersect_p,
ira_pseudo_live_ranges_intersect_p): Remove.
* ira-conflicts.c (ira_allocno_live_ranges_intersect_p,
ira_pseudo_live_ranges_intersect_p): Rename to
allocnos_have_intersected_live_ranges_p and
pseudos_have_intersected_live_ranges_p. Move them from here to
...


   * ira-color.c: ... here
   (coalesced_allocno_conflict_p): Use
   allocnos_have_intersected_live_ranges_p.
   (coalesced_allocnos_living_at_program_points,
   coalesced_allocnos_live_at_points_p,
   set_coalesced_allocnos_live_points): Remove.
   (slot_coalesced_allocnos_live_ranges,
   slot_coalesced_allocno_live_ranges_intersect_p,
   setup_slot_coalesced_allocno_live_ranges): New.
   (coalesce_spill_slots): Use ranges of coalesced allocnos.
   (ira_sort_regnos_for_alter_reg): Use
   allocnos_have_intersected_live_ranges_p.
   (ira_reuse_stack_slot): Use
   pseudos_have_intersected_live_ranges_p.

   * global.c (pseudo_for_reload_consideration_p): Check
   flag_ira_share_spill_slots too.

* ira-build.c (copy_allocno_live_range_list): Rename to
ira_copy_allocno_live_range_list. Make it external.
(merge_ranges): Rename to ira_merge_allocno_live_ranges. Make it
external.
(ira_allocno_live_ranges_intersect_p): New.
(ira_finish_allocno_live_range_list): New.
(finish_allocno): Use it.
(remove_unnecessary_allocnos): Use ira_merge_allocno_live_ranges.
(copy_info_to_removed_store_destinations): Ditto. Use
ira_copy_allocno_live_range_list.
(ira_flattening): Use ira_merge_allocno_live_ranges.
* ira.c (too_high_register_pressure_p): New function.
(ira): Switch off sharing spill slots if the pressure is too high.



Index: ira-conflicts.c
===================================================================
--- ira-conflicts.c	(revision 141823)
+++ ira-conflicts.c	(working copy)
@@ -532,52 +532,6 @@ propagate_copies (void)
     }
 }
 
-/* Return TRUE if live ranges of allocnos A1 and A2 intersect.  It is
-   used to find a conflict for new allocnos or allocnos with the
-   different cover classes.  */
-bool
-ira_allocno_live_ranges_intersect_p (ira_allocno_t a1, ira_allocno_t a2)
-{
-  allocno_live_range_t r1, r2;
-
-  if (a1 == a2)
-    return false;
-  if (ALLOCNO_REG (a1) != NULL && ALLOCNO_REG (a2) != NULL
-      && (ORIGINAL_REGNO (ALLOCNO_REG (a1))
-	  == ORIGINAL_REGNO (ALLOCNO_REG (a2))))
-    return false;
-  /* Remember the ranges are always kept ordered.  */
-  for (r1 = ALLOCNO_LIVE_RANGES (a1), r2 = ALLOCNO_LIVE_RANGES (a2);
-       r1 != NULL && r2 != NULL;)
-    {
-      if (r1->start > r2->finish)
-	r1 = r1->next;
-      else if (r2->start > r1->finish)
-	r2 = r2->next;
-      else
-	return true;
-    }
-  return false;
-}
-
-/* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
-   intersect.  This should be used when there is only one region.
-   Currently this is used during reload.  */
-bool
-ira_pseudo_live_ranges_intersect_p (int regno1, int regno2)
-{
-  ira_allocno_t a1, a2;
-
-  ira_assert (regno1 >= FIRST_PSEUDO_REGISTER
-	      && regno2 >= FIRST_PSEUDO_REGISTER);
-  /* Reg info caclulated by dataflow infrastructure can be different
-     from one calculated by regclass.  */
-  if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL
-      || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL)
-    return false;
-  return ira_allocno_live_ranges_intersect_p (a1, a2);
-}
-
 /* Array used to collect all conflict allocnos for given allocno.  */
 static ira_allocno_t *collected_conflict_allocnos;
 
Index: ira-int.h
===================================================================
--- ira-int.h	(revision 141823)
+++ ira-int.h	(working copy)
@@ -857,7 +857,14 @@ extern void ira_add_allocno_conflict (ir
 extern void ira_print_expanded_allocno (ira_allocno_t);
 extern allocno_live_range_t ira_create_allocno_live_range
 	                    (ira_allocno_t, int, int, allocno_live_range_t);
+extern allocno_live_range_t ira_copy_allocno_live_range_list
+                            (allocno_live_range_t);
+extern allocno_live_range_t ira_merge_allocno_live_ranges
+                            (allocno_live_range_t, allocno_live_range_t);
+extern bool ira_allocno_live_ranges_intersect_p (allocno_live_range_t,
+						 allocno_live_range_t);
 extern void ira_finish_allocno_live_range (allocno_live_range_t);
+extern void ira_finish_allocno_live_range_list (allocno_live_range_t);
 extern void ira_free_allocno_updated_costs (ira_allocno_t);
 extern ira_copy_t ira_create_copy (ira_allocno_t, ira_allocno_t,
 				   int, bool, rtx, ira_loop_tree_node_t);
@@ -893,8 +900,6 @@ extern void ira_compress_allocno_live_ra
 extern void ira_finish_allocno_live_ranges (void);
 
 /* ira-conflicts.c */
-extern bool ira_allocno_live_ranges_intersect_p (ira_allocno_t, ira_allocno_t);
-extern bool ira_pseudo_live_ranges_intersect_p (int, int);
 extern void ira_debug_conflicts (bool);
 extern void ira_build_conflicts (void);
 
Index: ira-color.c
===================================================================
--- ira-color.c	(revision 141823)
+++ ira-color.c	(working copy)
@@ -84,6 +84,45 @@ static VEC(ira_allocno_t,heap) *removed_
 
 
 
+/* This page contains functions used to find conflicts using allocno
+   live ranges.  */
+
+/* Return TRUE if live ranges of allocnos A1 and A2 intersect.  It is
+   used to find a conflict for new allocnos or allocnos with the
+   different cover classes.  */
+static bool
+allocnos_have_intersected_live_ranges_p (ira_allocno_t a1, ira_allocno_t a2)
+{
+  if (a1 == a2)
+    return false;
+  if (ALLOCNO_REG (a1) != NULL && ALLOCNO_REG (a2) != NULL
+      && (ORIGINAL_REGNO (ALLOCNO_REG (a1))
+	  == ORIGINAL_REGNO (ALLOCNO_REG (a2))))
+    return false;
+  return ira_allocno_live_ranges_intersect_p (ALLOCNO_LIVE_RANGES (a1),
+					      ALLOCNO_LIVE_RANGES (a2));
+}
+
+/* Return TRUE if live ranges of pseudo-registers REGNO1 and REGNO2
+   intersect.  This should be used when there is only one region.
+   Currently this is used during reload.  */
+static bool
+pseudos_have_intersected_live_ranges_p (int regno1, int regno2)
+{
+  ira_allocno_t a1, a2;
+
+  ira_assert (regno1 >= FIRST_PSEUDO_REGISTER
+	      && regno2 >= FIRST_PSEUDO_REGISTER);
+  /* Reg info caclulated by dataflow infrastructure can be different
+     from one calculated by regclass.  */
+  if ((a1 = ira_loop_tree_root->regno_allocno_map[regno1]) == NULL
+      || (a2 = ira_loop_tree_root->regno_allocno_map[regno2]) == NULL)
+    return false;
+  return allocnos_have_intersected_live_ranges_p (a1, a2);
+}
+
+
+
 /* This page contains functions used to choose hard registers for
    allocnos.  */
 
@@ -1486,7 +1525,8 @@ coalesced_allocno_conflict_p (ira_allocn
 	       conflict_allocno
 		 = ALLOCNO_NEXT_COALESCED_ALLOCNO (conflict_allocno))
 	    {
-	      if (ira_allocno_live_ranges_intersect_p (a, conflict_allocno))
+	      if (allocnos_have_intersected_live_ranges_p (a,
+							   conflict_allocno))
 		return true;
 	      if (conflict_allocno == a1)
 		break;
@@ -2316,38 +2356,37 @@ collect_spilled_coalesced_allocnos (int 
   return num;
 }
 
-/* Array of bitmaps of size IRA_MAX_POINT.  Bitmap for given point
-   contains numbers of coalesced allocnos living at this point.  */
-static regset_head *coalesced_allocnos_living_at_program_points;
-
-/* Return TRUE if coalesced allocnos represented by ALLOCNO live at
-   program points of coalesced allocnos with number N.  */
+/* Array of live ranges of size IRA_ALLOCNOS_NUM.  Live range for
+   given slot contains live ranges of coalesced allocnos assigned to
+   given slot.  */
+static allocno_live_range_t *slot_coalesced_allocnos_live_ranges;
+
+/* Return TRUE if coalesced allocnos represented by ALLOCNO has live
+   ranges intersected with live ranges of coalesced allocnos assigned
+   to slot with number N.  */
 static bool
-coalesced_allocnos_live_at_points_p (ira_allocno_t allocno, int n)
+slot_coalesced_allocno_live_ranges_intersect_p (ira_allocno_t allocno, int n)
 {
-  int i;
   ira_allocno_t a;
-  allocno_live_range_t r;
 
   for (a = ALLOCNO_NEXT_COALESCED_ALLOCNO (allocno);;
        a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
     {
-      for (r = ALLOCNO_LIVE_RANGES (a); r != NULL; r = r->next)
-	for (i = r->start; i <= r->finish; i++)
-	  if (bitmap_bit_p (&coalesced_allocnos_living_at_program_points[i], n))
-	      return true;
+      if (ira_allocno_live_ranges_intersect_p
+	  (slot_coalesced_allocnos_live_ranges[n], ALLOCNO_LIVE_RANGES (a)))
+	return true;
       if (a == allocno)
 	break;
     }
   return false;
 }
 
-/* Mark program points where coalesced allocnos represented by ALLOCNO
-   live.  */
+/* Update live ranges of slot to which coalesced allocnos represented
+   by ALLOCNO were assigned.  */
 static void
-set_coalesced_allocnos_live_points (ira_allocno_t allocno)
+setup_slot_coalesced_allocno_live_ranges (ira_allocno_t allocno)
 {
-  int i, n;
+  int n;
   ira_allocno_t a;
   allocno_live_range_t r;
 
@@ -2355,9 +2394,10 @@ set_coalesced_allocnos_live_points (ira_
   for (a = ALLOCNO_NEXT_COALESCED_ALLOCNO (allocno);;
        a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
     {
-      for (r = ALLOCNO_LIVE_RANGES (a); r != NULL; r = r->next)
-	for (i = r->start; i <= r->finish; i++)
-	  bitmap_set_bit (&coalesced_allocnos_living_at_program_points[i], n);
+      r = ira_copy_allocno_live_range_list (ALLOCNO_LIVE_RANGES (a));
+      slot_coalesced_allocnos_live_ranges[n]
+	= ira_merge_allocno_live_ranges
+	  (slot_coalesced_allocnos_live_ranges[n], r);
       if (a == allocno)
 	break;
     }
@@ -2371,14 +2411,15 @@ set_coalesced_allocnos_live_points (ira_
 static bool
 coalesce_spill_slots (ira_allocno_t *spilled_coalesced_allocnos, int num)
 {
-  int i, j, last_coalesced_allocno_num;
+  int i, j, n, last_coalesced_allocno_num;
   ira_allocno_t allocno, a;
   bool merged_p = false;
 
-  coalesced_allocnos_living_at_program_points
-    = (regset_head *) ira_allocate (sizeof (regset_head) * ira_max_point);
-  for (i = 0; i < ira_max_point; i++)
-    INIT_REG_SET (&coalesced_allocnos_living_at_program_points[i]);
+  slot_coalesced_allocnos_live_ranges
+    = (allocno_live_range_t *) ira_allocate (sizeof (allocno_live_range_t)
+					     * ira_allocnos_num);
+  memset (slot_coalesced_allocnos_live_ranges, 0,
+	  sizeof (allocno_live_range_t) * ira_allocnos_num);
   last_coalesced_allocno_num = 0;
   /* Coalesce non-conflicting spilled allocnos preferring most
      frequently used.  */
@@ -2387,18 +2428,18 @@ coalesce_spill_slots (ira_allocno_t *spi
       allocno = spilled_coalesced_allocnos[i];
       if (ALLOCNO_FIRST_COALESCED_ALLOCNO (allocno) != allocno
 	  || (ALLOCNO_REGNO (allocno) < ira_reg_equiv_len
-	      && (ira_reg_equiv_invariant_p[ALLOCNO_REGNO (allocno)]
-		  || ira_reg_equiv_const[ALLOCNO_REGNO (allocno)] != NULL_RTX)))
+	      && (ira_reg_equiv_const[ALLOCNO_REGNO (allocno)] != NULL_RTX
+		  || ira_reg_equiv_invariant_p[ALLOCNO_REGNO (allocno)])))
 	continue;
       for (j = 0; j < i; j++)
 	{
 	  a = spilled_coalesced_allocnos[j];
+	  n = ALLOCNO_TEMP (a);
 	  if (ALLOCNO_FIRST_COALESCED_ALLOCNO (a) == a
 	      && (ALLOCNO_REGNO (a) >= ira_reg_equiv_len
 		  || (! ira_reg_equiv_invariant_p[ALLOCNO_REGNO (a)]
 		      && ira_reg_equiv_const[ALLOCNO_REGNO (a)] == NULL_RTX))
-	      && ! coalesced_allocnos_live_at_points_p (allocno,
-							ALLOCNO_TEMP (a)))
+	      && ! slot_coalesced_allocno_live_ranges_intersect_p (allocno, n))
 	    break;
 	}
       if (j >= i)
@@ -2406,7 +2447,7 @@ coalesce_spill_slots (ira_allocno_t *spi
 	  /* No coalescing: set up number for coalesced allocnos
 	     represented by ALLOCNO.  */
 	  ALLOCNO_TEMP (allocno) = last_coalesced_allocno_num++;
-	  set_coalesced_allocnos_live_points (allocno);
+	  setup_slot_coalesced_allocno_live_ranges (allocno);
 	}
       else
 	{
@@ -2418,14 +2459,15 @@ coalesce_spill_slots (ira_allocno_t *spi
 		     ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno),
 		     ALLOCNO_NUM (a), ALLOCNO_REGNO (a));
 	  ALLOCNO_TEMP (allocno) = ALLOCNO_TEMP (a);
-	  set_coalesced_allocnos_live_points (allocno);
+	  setup_slot_coalesced_allocno_live_ranges (allocno);
 	  merge_allocnos (a, allocno);
 	  ira_assert (ALLOCNO_FIRST_COALESCED_ALLOCNO (a) == a);
 	}
     }
-  for (i = 0; i < ira_max_point; i++)
-    CLEAR_REG_SET (&coalesced_allocnos_living_at_program_points[i]);
-  ira_free (coalesced_allocnos_living_at_program_points);
+  for (i = 0; i < ira_allocnos_num; i++)
+    ira_finish_allocno_live_range_list
+      (slot_coalesced_allocnos_live_ranges[i]);
+  ira_free (slot_coalesced_allocnos_live_ranges);
   return merged_p;
 }
 
@@ -2496,8 +2538,8 @@ ira_sort_regnos_for_alter_reg (int *pseu
       if (ALLOCNO_FIRST_COALESCED_ALLOCNO (allocno) != allocno
 	  || ALLOCNO_HARD_REGNO (allocno) >= 0
 	  || (ALLOCNO_REGNO (allocno) < ira_reg_equiv_len
-	      && (ira_reg_equiv_invariant_p[ALLOCNO_REGNO (allocno)]
-		  || ira_reg_equiv_const[ALLOCNO_REGNO (allocno)] != NULL_RTX)))
+	      && (ira_reg_equiv_const[ALLOCNO_REGNO (allocno)] != NULL_RTX
+		  || ira_reg_equiv_invariant_p[ALLOCNO_REGNO (allocno)])))
 	continue;
       if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
 	fprintf (ira_dump_file, "      Slot %d (freq,size):", slot_num);
@@ -2826,8 +2868,8 @@ ira_reuse_stack_slot (int regno, unsigne
 				    FIRST_PSEUDO_REGISTER, i, bi)
 	    {
 	      another_allocno = ira_regno_allocno_map[i];
-	      if (ira_allocno_live_ranges_intersect_p (allocno,
-						       another_allocno))
+	      if (allocnos_have_intersected_live_ranges_p (allocno,
+							   another_allocno))
 		goto cont;
 	    }
 	  for (cost = 0, cp = ALLOCNO_COPIES (allocno);
@@ -2875,7 +2917,7 @@ ira_reuse_stack_slot (int regno, unsigne
       EXECUTE_IF_SET_IN_BITMAP (&slot->spilled_regs,
 				FIRST_PSEUDO_REGISTER, i, bi)
 	{
-	  ira_assert (! ira_pseudo_live_ranges_intersect_p (regno, i));
+	  ira_assert (! pseudos_have_intersected_live_ranges_p (regno, i));
 	}
       SET_REGNO_REG_SET (&slot->spilled_regs, regno);
       if (internal_flag_ira_verbose > 3 && ira_dump_file)
Index: global.c
===================================================================
--- global.c	(revision 141823)
+++ global.c	(working copy)
@@ -1393,7 +1393,8 @@ pseudo_for_reload_consideration_p (int r
 {
   /* Consider spilled pseudos too for IRA because they still have a
      chance to get hard-registers in the reload when IRA is used.  */
-  return reg_renumber[regno] >= 0 || (flag_ira && optimize);
+  return (reg_renumber[regno] >= 0
+	  || (flag_ira && optimize && flag_ira_share_spill_slots));
 }
 
 /* Walk the insns of the current function and build reload_insn_chain,
Index: ira-build.c
===================================================================
--- ira-build.c	(revision 141823)
+++ ira-build.c	(working copy)
@@ -824,8 +824,8 @@ copy_allocno_live_range (allocno_live_ra
 
 /* Copy allocno live range list given by its head R and return the
    result.  */
-static allocno_live_range_t
-copy_allocno_live_range_list (allocno_live_range_t r)
+allocno_live_range_t
+ira_copy_allocno_live_range_list (allocno_live_range_t r)
 {
   allocno_live_range_t p, first, last;
 
@@ -843,6 +843,103 @@ copy_allocno_live_range_list (allocno_li
   return first;
 }
 
+/* Merge ranges R1 and R2 and returns the result.  The function
+   maintains the order of ranges and tries to minimize number of the
+   result ranges.  */
+allocno_live_range_t 
+ira_merge_allocno_live_ranges (allocno_live_range_t r1,
+			       allocno_live_range_t r2)
+{
+  allocno_live_range_t first, last, temp;
+
+  if (r1 == NULL)
+    return r2;
+  if (r2 == NULL)
+    return r1;
+  for (first = last = NULL; r1 != NULL && r2 != NULL;)
+    {
+      if (r1->start < r2->start)
+	{
+	  temp = r1;
+	  r1 = r2;
+	  r2 = temp;
+	}
+      if (r1->start <= r2->finish + 1)
+	{
+	  /* Intersected ranges: merge r1 and r2 into r1.  */
+	  r1->start = r2->start;
+	  if (r1->finish < r2->finish)
+	    r1->finish = r2->finish;
+	  temp = r2;
+	  r2 = r2->next;
+	  ira_finish_allocno_live_range (temp);
+	  if (r2 == NULL)
+	    {
+	      /* To try to merge with subsequent ranges in r1.  */
+	      r2 = r1->next;
+	      r1->next = NULL;
+	    }
+	}
+      else
+	{
+	  /* Add r1 to the result.  */
+	  if (first == NULL)
+	    first = last = r1;
+	  else
+	    {
+	      last->next = r1;
+	      last = r1;
+	    }
+	  r1 = r1->next;
+	  if (r1 == NULL)
+	    {
+	      /* To try to merge with subsequent ranges in r2.  */
+	      r1 = r2->next;
+	      r2->next = NULL;
+	    }
+	}
+    }
+  if (r1 != NULL)
+    {
+      if (first == NULL)
+	first = r1;
+      else
+	last->next = r1;
+      ira_assert (r1->next == NULL);
+    }
+  else if (r2 != NULL)
+    {
+      if (first == NULL)
+	first = r2;
+      else
+	last->next = r2;
+      ira_assert (r2->next == NULL);
+    }
+  else
+    {
+      ira_assert (last->next == NULL);
+    }
+  return first;
+}
+
+/* Return TRUE if live ranges R1 and R2 intersect.  */
+bool
+ira_allocno_live_ranges_intersect_p (allocno_live_range_t r1,
+				     allocno_live_range_t r2)
+{
+  /* Remember the live ranges are always kept ordered.  */
+  while (r1 != NULL && r2 != NULL)
+    {
+      if (r1->start > r2->finish)
+	r1 = r1->next;
+      else if (r2->start > r1->finish)
+	r2 = r2->next;
+      else
+	return true;
+    }
+  return false;
+}
+
 /* Free allocno live range R.  */
 void
 ira_finish_allocno_live_range (allocno_live_range_t r)
@@ -850,6 +947,19 @@ ira_finish_allocno_live_range (allocno_l
   pool_free (allocno_live_range_pool, r);
 }
 
+/* Free list of allocno live ranges starting with R.  */
+void
+ira_finish_allocno_live_range_list (allocno_live_range_t r)
+{
+  allocno_live_range_t next_r;
+
+  for (; r != NULL; r = next_r)
+    {
+      next_r = r->next;
+      ira_finish_allocno_live_range (r);
+    }
+}
+
 /* Free updated register costs of allocno A.  */
 void
 ira_free_allocno_updated_costs (ira_allocno_t a)
@@ -870,7 +980,6 @@ ira_free_allocno_updated_costs (ira_allo
 static void
 finish_allocno (ira_allocno_t a)
 {
-  allocno_live_range_t r, next_r;
   enum reg_class cover_class = ALLOCNO_COVER_CLASS (a);
 
   ira_allocnos[ALLOCNO_NUM (a)] = NULL;
@@ -886,11 +995,7 @@ finish_allocno (ira_allocno_t a)
   if (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) != NULL)
     ira_free_cost_vector (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a),
 			  cover_class);
-  for (r = ALLOCNO_LIVE_RANGES (a); r != NULL; r = next_r)
-    {
-      next_r = r->next;
-      ira_finish_allocno_live_range (r);
-    }
+  ira_finish_allocno_live_range_list (ALLOCNO_LIVE_RANGES (a));
   pool_free (allocno_pool, a);
 }
 
@@ -1539,84 +1644,6 @@ create_allocnos (void)
    will hardly improve the result.  As a result we speed up regional
    register allocation.  */
 
-/* Merge ranges R1 and R2 and returns the result.  The function
-   maintains the order of ranges and tries to minimize number of the
-   result ranges.  */
-static allocno_live_range_t 
-merge_ranges (allocno_live_range_t r1, allocno_live_range_t r2)
-{
-  allocno_live_range_t first, last, temp;
-
-  if (r1 == NULL)
-    return r2;
-  if (r2 == NULL)
-    return r1;
-  for (first = last = NULL; r1 != NULL && r2 != NULL;)
-    {
-      if (r1->start < r2->start)
-	{
-	  temp = r1;
-	  r1 = r2;
-	  r2 = temp;
-	}
-      if (r1->start <= r2->finish + 1)
-	{
-	  /* Intersected ranges: merge r1 and r2 into r1.  */
-	  r1->start = r2->start;
-	  if (r1->finish < r2->finish)
-	    r1->finish = r2->finish;
-	  temp = r2;
-	  r2 = r2->next;
-	  ira_finish_allocno_live_range (temp);
-	  if (r2 == NULL)
-	    {
-	      /* To try to merge with subsequent ranges in r1.  */
-	      r2 = r1->next;
-	      r1->next = NULL;
-	    }
-	}
-      else
-	{
-	  /* Add r1 to the result.  */
-	  if (first == NULL)
-	    first = last = r1;
-	  else
-	    {
-	      last->next = r1;
-	      last = r1;
-	    }
-	  r1 = r1->next;
-	  if (r1 == NULL)
-	    {
-	      /* To try to merge with subsequent ranges in r2.  */
-	      r1 = r2->next;
-	      r2->next = NULL;
-	    }
-	}
-    }
-  if (r1 != NULL)
-    {
-      if (first == NULL)
-	first = r1;
-      else
-	last->next = r1;
-      ira_assert (r1->next == NULL);
-    }
-  else if (r2 != NULL)
-    {
-      if (first == NULL)
-	first = r2;
-      else
-	last->next = r2;
-      ira_assert (r2->next == NULL);
-    }
-  else
-    {
-      ira_assert (last->next == NULL);
-    }
-  return first;
-}
-
 /* The function changes allocno in range list given by R onto A.  */
 static void
 change_allocno_in_range_list (allocno_live_range_t r, ira_allocno_t a)
@@ -1758,7 +1785,8 @@ remove_unnecessary_allocnos (void)
 		r = ALLOCNO_LIVE_RANGES (a);
 		change_allocno_in_range_list (r, parent_a);
 		ALLOCNO_LIVE_RANGES (parent_a)
-		  = merge_ranges (r, ALLOCNO_LIVE_RANGES (parent_a));
+		  = ira_merge_allocno_live_ranges
+		    (r, ALLOCNO_LIVE_RANGES (parent_a));
 		merged_p = true;
 		ALLOCNO_LIVE_RANGES (a) = NULL;
 		IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (parent_a),
@@ -2086,10 +2114,10 @@ copy_info_to_removed_store_destinations 
 	  ira_print_live_range_list (ira_dump_file,
 				     ALLOCNO_LIVE_RANGES (a));
 	}
-      r = copy_allocno_live_range_list (ALLOCNO_LIVE_RANGES (a));
+      r = ira_copy_allocno_live_range_list (ALLOCNO_LIVE_RANGES (a));
       change_allocno_in_range_list (r, parent_a);
       ALLOCNO_LIVE_RANGES (parent_a)
-	= merge_ranges (r, ALLOCNO_LIVE_RANGES (parent_a));
+	= ira_merge_allocno_live_ranges (r, ALLOCNO_LIVE_RANGES (parent_a));
       IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (parent_a),
 			ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
 #ifdef STACK_REGS
@@ -2186,8 +2214,8 @@ ira_flattening (int max_regno_before_emi
 		}
 	      change_allocno_in_range_list (ALLOCNO_LIVE_RANGES (a), parent_a);
 	      ALLOCNO_LIVE_RANGES (parent_a)
-		= merge_ranges (ALLOCNO_LIVE_RANGES (a),
-				ALLOCNO_LIVE_RANGES (parent_a));
+		= ira_merge_allocno_live_ranges
+		  (ALLOCNO_LIVE_RANGES (a), ALLOCNO_LIVE_RANGES (parent_a));
 	      merged_p = true;
 	      ALLOCNO_LIVE_RANGES (a) = NULL;
 	      ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a)
Index: ira.c
===================================================================
--- ira.c	(revision 141823)
+++ ira.c	(working copy)
@@ -1695,6 +1695,23 @@ expand_reg_info (int old_size)
     }
 }
 
+/* Return TRUE if there is too high register pressure in the function.
+   It is used to decide when stack slot sharing is worth to do.  */
+static bool
+too_high_register_pressure_p (void)
+{
+  int i;
+  enum reg_class cover_class;
+  
+  for (i = 0; i < ira_reg_class_cover_size; i++)
+    {
+      cover_class = ira_reg_class_cover[i];
+      if (ira_loop_tree_root->reg_pressure[cover_class] > 10000)
+	return true;
+    }
+  return false;
+}
+
 
 
 /* All natural loops.  */
@@ -1709,6 +1726,7 @@ ira (FILE *f)
   int max_regno_before_ira, ira_max_point_before_emit;
   int rebuild_p;
   int saved_flag_ira_algorithm;
+  int saved_flag_ira_share_spill_slots;
   basic_block bb;
 
   timevar_push (TV_IRA);
@@ -1792,6 +1810,13 @@ ira (FILE *f)
   loops_p = ira_build (optimize
 		       && (flag_ira_algorithm == IRA_ALGORITHM_REGIONAL
 			   || flag_ira_algorithm == IRA_ALGORITHM_MIXED));
+
+  saved_flag_ira_share_spill_slots = flag_ira_share_spill_slots;
+  if (too_high_register_pressure_p ())
+    /* It is just wasting compiler's time to pack spilled pseudos into
+       stack slots in this case -- prohibit it.  */ 
+    flag_ira_share_spill_slots = FALSE;
+
   ira_color ();
       
   ira_max_point_before_emit = ira_max_point;
@@ -1902,6 +1927,8 @@ ira (FILE *f)
     fprintf (ira_dump_file, "+++Overall after reload %d\n", ira_overall_cost);
   ira_destroy ();
   
+  flag_ira_share_spill_slots = saved_flag_ira_share_spill_slots;
+
   flow_loops_free (&ira_loops);
   free_dominance_info (CDI_DOMINATORS);
   FOR_ALL_BB (bb)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]