	* lra-int.h (lra_constraint_insn_stack_bitmap,
	lra_constraint_insn_stack): Remove.
	(lra_pop_insn, lra_insn_stack_length): New prototypes.
	* lra.c (lra_constraint_insn_stack_bitmap): Make static sbitmap.
	(lra_constraint_insn_stack): Make static.
	(lra_push_insn_1): New function.
	(lra_push_insn): Rewrite using lra_push_insn_1.
	(lra_push_insn_and_update_insn_regno_info): Likewise.
	(lra_pop_insn, lra_insn_stack_length): New functions.
	* lra_constraints.c (lra_constraints): Use new interface to
	insns stack instead of manipulating in-place.
	* lra-eliminations.c (add_insn_bitmap_to_set): New function.
	(update_reg_eliminate): Make argument an sbitmap.  Return a bool
	telling whether the input sbitmap has changed.
	(lra_eliminate): Allocate and free the worklist set as an sbitmap.

	* lra-lives.c (curr_point): Make non-static in lra_create_live_ranges.
	(mark_pseudo_live): Take POINT argument.
	(mark_pseudo_dead): Likewise.
	(mark_regno_live): Likewise, and return a bool to indicate that
	someting changed in the dataflow sets.
	(mark_regno_dead): Likewise.
	(next_program_point): Renamed from incr_curr_point, and take the
	current program point as a by-reference argument.
	(process_bb_lives): Take the current program point as by-ref argument.
	Try to only do a program point increment if this is necessary.
	(remove_some_program_points_and_update_live_ranges): If no compression
	can be done, don't update the live ranges.
	(lra_create_live_ranges): Make curr_point local, and pass it around.
	Visit blocks in topological order of the reverse CFG.

	* lra-int.h (lra_assert): Define as duplicate of gcc_checking_assert.

Index: lra-int.h
===================================================================
--- lra-int.h	(revision 192183)
+++ lra-int.h	(working copy)
@@ -23,13 +23,7 @@ along with GCC; see the file COPYING3.	I
 #include "bitmap.h"
 #include "insn-attr.h"
 
-#ifdef ENABLE_CHECKING
-#define lra_assert(c) gcc_assert (c)
-#else
-/* Always define and include C, so that warnings for empty body in an
-  âifâ statement and unused variable do not occur.  */
-#define lra_assert(c) ((void)(0 && (c)))
-#endif
+#define lra_assert(c) gcc_checking_assert (c)
 
 /* The parameter used to prevent infinite reloading for an insn.  Each
    insn operands might require a reload and, if it is a memory, its
@@ -249,14 +243,13 @@ extern HARD_REG_SET lra_no_alloc_regs;
 extern int lra_insn_recog_data_len;
 extern lra_insn_recog_data_t *lra_insn_recog_data;
 
-extern bitmap_head lra_constraint_insn_stack_bitmap;
-extern VEC (rtx, heap) *lra_constraint_insn_stack;
-
 extern int lra_curr_reload_num;
 
 extern void lra_push_insn (rtx);
 extern void lra_push_insn_by_uid (unsigned int);
 extern void lra_push_insn_and_update_insn_regno_info (rtx);
+extern rtx lra_pop_insn (void);
+extern unsigned int lra_insn_stack_length (void);
 
 extern rtx lra_create_new_reg_with_unique_value (enum machine_mode, rtx,
 						 enum reg_class, const char *);
Index: lra.c
===================================================================
--- lra.c	(revision 192183)
+++ lra.c	(working copy)
@@ -1736,19 +1736,43 @@ lra_get_insn_regs (int uid)
    should be processed by the next constraint pass.  */
 
 /* Bitmap used to put an insn on the stack only in one exemplar.  */
-bitmap_head lra_constraint_insn_stack_bitmap;
+static sbitmap lra_constraint_insn_stack_bitmap;
 
 /* The stack itself.  */
 VEC (rtx, heap) *lra_constraint_insn_stack;
 
+/* Put INSN on the stack.  If ALWAYS_UPDATE is true, always update the reg
+   info for INSN, otherwise only update it if INSN is not already on the
+   stack.  */
+static inline void
+lra_push_insn_1 (rtx insn, bool always_update)
+{
+  unsigned int uid = INSN_UID (insn);
+  if (always_update)
+    lra_update_insn_regno_info (insn);
+  if (uid >= SBITMAP_SIZE (lra_constraint_insn_stack_bitmap))
+    lra_constraint_insn_stack_bitmap =
+      sbitmap_resize (lra_constraint_insn_stack_bitmap, 3 * uid / 2, 0);
+  if (TEST_BIT (lra_constraint_insn_stack_bitmap, uid))
+    return;
+  SET_BIT (lra_constraint_insn_stack_bitmap, uid);
+  if (! always_update)
+    lra_update_insn_regno_info (insn);
+  VEC_safe_push (rtx, heap, lra_constraint_insn_stack, insn);
+}
+
 /* Put INSN on the stack.  */
 void
 lra_push_insn (rtx insn)
 {
-  if (! bitmap_set_bit (&lra_constraint_insn_stack_bitmap, INSN_UID (insn)))
-    return;
-  lra_update_insn_regno_info (insn);
-  VEC_safe_push (rtx, heap, lra_constraint_insn_stack, insn);
+  lra_push_insn_1 (insn, false);
+}
+
+/* Put INSN on the stack and update its reg info.  */
+void
+lra_push_insn_and_update_insn_regno_info (rtx insn)
+{
+  lra_push_insn_1 (insn, true);
 }
 
 /* Put insn with UID on the stack.  */
@@ -1758,14 +1782,20 @@ lra_push_insn_by_uid (unsigned int uid)
   lra_push_insn (lra_insn_recog_data[uid]->insn);
 }
 
-/* Put INSN on the stack and update its reg info.  */
-void
-lra_push_insn_and_update_insn_regno_info (rtx insn)
+/* Take the last-inserted insns off the stack and return it.  */
+rtx
+lra_pop_insn (void)
 {
-  lra_update_insn_regno_info (insn);
-  if (! bitmap_set_bit (&lra_constraint_insn_stack_bitmap, INSN_UID (insn)))
-    return;
-  VEC_safe_push (rtx, heap, lra_constraint_insn_stack, insn);
+  rtx insn = VEC_pop (rtx, lra_constraint_insn_stack);
+  RESET_BIT (lra_constraint_insn_stack_bitmap, INSN_UID (insn));
+  return insn;
+}
+
+/* Return the current size of the insn stack.  */
+unsigned int
+lra_insn_stack_length (void)
+{
+  return VEC_length (rtx, lra_constraint_insn_stack);
 }
 
 /* Push insns FROM to TO (excluding it) going in reverse order.	 */
@@ -2240,7 +2270,8 @@ lra (FILE *f)
      expensive when a lot of RTL changes are made.  */
   df_set_flags (DF_NO_INSN_RESCAN);
   lra_constraint_insn_stack = VEC_alloc (rtx, heap, get_max_uid ());
-  bitmap_initialize (&lra_constraint_insn_stack_bitmap, &reg_obstack);
+  lra_constraint_insn_stack_bitmap = sbitmap_alloc (get_max_uid ());
+  sbitmap_zero (lra_constraint_insn_stack_bitmap);
   lra_live_ranges_init ();
   lra_contraints_init ();
   lra_curr_reload_num = 0;
@@ -2322,7 +2353,7 @@ lra (FILE *f)
   lra_live_ranges_finish ();
   lra_contraints_finish ();
   finish_reg_info ();
-  bitmap_clear (&lra_constraint_insn_stack_bitmap);
+  sbitmap_free (lra_constraint_insn_stack_bitmap);
   VEC_free (rtx, heap, lra_constraint_insn_stack);
   finish_insn_recog_data ();
   regstat_free_n_sets_and_refs ();
Index: lra-constraints.c
===================================================================
--- lra-constraints.c	(revision 192183)
+++ lra-constraints.c	(working copy)
@@ -851,7 +851,7 @@ operands_match_p (rtx x, rtx y, int y_ha
   return true;
 }
 
-/* Reload pseudos created for input and output(or early clobber)
+/* Reload pseudos created for input and output (or early clobber)
    reloads which should have the same hard register.  Such pseudos as
    input operands should be not inherited because the output rewrite
    the value in any away.  */
@@ -3674,7 +3674,7 @@ lra_constraints (bool first_p)
 {
   bool changed_p;
   int i, hard_regno, new_insns_num;
-  unsigned int min_len;
+  unsigned int min_len, new_min_len;
   rtx set, x, dest_reg;
   basic_block last_bb;
 
@@ -3738,24 +3738,23 @@ lra_constraints (bool first_p)
 	  }
       }
   lra_eliminate (false);
-  min_len = VEC_length (rtx, lra_constraint_insn_stack);
+  min_len = lra_insn_stack_length ();
   new_insns_num = 0;
   last_bb = NULL;
   changed_p = false;
-  for (;VEC_length (rtx, lra_constraint_insn_stack) != 0;)
+  while ((new_min_len = lra_insn_stack_length ()) != 0)
     {
-      curr_insn = VEC_pop (rtx, lra_constraint_insn_stack);
-      bitmap_clear_bit (&lra_constraint_insn_stack_bitmap,
-			INSN_UID (curr_insn));
+      curr_insn = lra_pop_insn ();
+      --new_min_len;
       curr_bb = BLOCK_FOR_INSN (curr_insn); 
       if (curr_bb != last_bb)
 	{
 	  last_bb = curr_bb;
 	  bb_reload_num = lra_curr_reload_num;
 	}
-      if (min_len > VEC_length (rtx, lra_constraint_insn_stack))
+      if (min_len > new_min_len)
 	{
-	  min_len = VEC_length (rtx, lra_constraint_insn_stack);
+	  min_len = new_min_len;
 	  new_insns_num = 0;
 	}
       if (new_insns_num > MAX_RELOAD_INSNS_NUMBER)
Index: lra-eliminations.c
===================================================================
--- lra-eliminations.c	(revision 192183)
+++ lra-eliminations.c	(working copy)
@@ -1085,17 +1085,44 @@ spill_pseudos (HARD_REG_SET set)
   bitmap_clear (&to_process);
 }
 
+/* Add the insns from INSN_BITMAP to INSNS_WITH_CHANGED_OFFSETS,
+   and return true if something changed.  */
+static bool
+add_insn_bitmap_to_set (sbitmap insns_with_changed_offsets,
+			bitmap insn_bitmap)
+{
+  bitmap_iterator bi;
+  unsigned int ix;
+  unsigned int size = SBITMAP_SIZE (insns_with_changed_offsets);
+
+  if (bitmap_empty_p (insn_bitmap))
+    return false;
+  EXECUTE_IF_SET_IN_BITMAP (insn_bitmap, 0, ix, bi)
+    {
+      if (ix >= size)
+	{
+	  size = 3 * ix / 2;
+	  insns_with_changed_offsets = 
+	    sbitmap_resize (insns_with_changed_offsets, size, 0);
+	}
+      SET_BIT (insns_with_changed_offsets, ix);
+    }
+  return true;
+}
+
 /* Update all offsets and possibility for elimination on eliminable
    registers.  Spill pseudos assigned to registers which became
    uneliminable, update LRA_NO_ALLOC_REGS and ELIMINABLE_REG_SET.  Add
    insns to INSNS_WITH_CHANGED_OFFSETS containing eliminable hard
-   registers whose offsets should be changed.  */
-static void
-update_reg_eliminate (bitmap insns_with_changed_offsets)
+   registers whose offsets should be changed.
+   Return true if INSNS_WITH_CHANGED_OFFSETS was changed.  */
+static bool
+update_reg_eliminate (sbitmap insns_with_changed_offsets)
 {
   bool prev;
   struct elim_table *ep, *ep1;
   HARD_REG_SET temp_hard_reg_set;
+  bool changed = false;
 
   /* Clear self elimination offsets.  */
   for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
@@ -1154,8 +1181,8 @@ update_reg_eliminate (bitmap insns_with_
 	      self_elim_offsets[ep->from] = -ep->offset;
 	      SET_HARD_REG_BIT (temp_hard_reg_set, ep->from);
 	      if (ep->offset != 0)
-		bitmap_ior_into (insns_with_changed_offsets,
-				 &lra_reg_info[ep->from].insn_bitmap);
+		changed |= add_insn_bitmap_to_set (insns_with_changed_offsets,
+						   &lra_reg_info[ep->from].insn_bitmap);
 	    }
 	}
 
@@ -1171,8 +1198,9 @@ update_reg_eliminate (bitmap insns_with_
   setup_elimination_map ();
   for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
     if (elimination_map[ep->from] == ep && ep->previous_offset != ep->offset)
-      bitmap_ior_into (insns_with_changed_offsets,
-		       &lra_reg_info[ep->from].insn_bitmap);
+      changed |= add_insn_bitmap_to_set (insns_with_changed_offsets,
+					 &lra_reg_info[ep->from].insn_bitmap);
+  return changed;
 }
 
 /* Initialize the table of hard registers to eliminate.
@@ -1293,18 +1321,19 @@ lra_eliminate (bool final_p)
   int i;
   basic_block bb;
   rtx insn, temp, mem_loc, invariant;
-  bitmap_head insns_with_changed_offsets;
+  sbitmap insns_with_changed_offsets;
   struct elim_table *ep;
   int regs_num = max_reg_num ();
 
   timevar_push (TV_LRA_ELIMINATE);
 
-  bitmap_initialize (&insns_with_changed_offsets, &reg_obstack);
+  insns_with_changed_offsets = sbitmap_alloc (get_max_uid ());
+  sbitmap_zero (insns_with_changed_offsets);
+
   if (final_p)
     {
 #ifdef ENABLE_CHECKING
-      update_reg_eliminate (&insns_with_changed_offsets);
-      if (! bitmap_empty_p (&insns_with_changed_offsets))
+      if (update_reg_eliminate (insns_with_changed_offsets))
 	gcc_unreachable ();
 #endif
       /* We change eliminable hard registers in insns so we should do
@@ -1312,13 +1341,12 @@ lra_eliminate (bool final_p)
 	 register.  */
       for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
 	if (elimination_map[ep->from] != NULL)
-	  bitmap_ior_into (&insns_with_changed_offsets,
-			   &lra_reg_info[ep->from].insn_bitmap);
+	  add_insn_bitmap_to_set (insns_with_changed_offsets,
+				  &lra_reg_info[ep->from].insn_bitmap);
     }
   else
     {
-      update_reg_eliminate (&insns_with_changed_offsets);
-      if (bitmap_empty_p (&insns_with_changed_offsets))
+      if (! update_reg_eliminate (insns_with_changed_offsets))
 	goto lra_eliminate_done;
     }
   if (lra_dump_file != NULL)
@@ -1347,11 +1375,13 @@ lra_eliminate (bool final_p)
   FOR_EACH_BB (bb)
     FOR_BB_INSNS_SAFE (bb, insn, temp)
       {
-	if (bitmap_bit_p (&insns_with_changed_offsets, INSN_UID (insn)))
+        unsigned int uid = INSN_UID (insn);
+	if (SBITMAP_SIZE (insns_with_changed_offsets) > uid
+	    && TEST_BIT (insns_with_changed_offsets, uid))
 	  process_insn_for_elimination (insn, final_p);
       }
-  bitmap_clear (&insns_with_changed_offsets);
 
 lra_eliminate_done:
+  sbitmap_free (insns_with_changed_offsets);
   timevar_pop (TV_LRA_ELIMINATE);
 }
Index: lra-lives.c
===================================================================
--- lra-lives.c	(revision 192183)
+++ lra-lives.c	(working copy)
@@ -66,9 +66,6 @@ int lra_hard_reg_usage[FIRST_PSEUDO_REGI
    coalescing and spill passes.	 */
 static bool complete_info_p;
 
-/* Number of the current program point.	 */
-static int curr_point;
-
 /* Pseudos live at current point in the RTL scan.  */
 static sparseset pseudos_live;
 
@@ -313,11 +310,11 @@ make_hard_regno_dead (int regno)
   CLEAR_HARD_REG_BIT (hard_regs_live, regno);
 }
 
-/* Mark pseudo REGNO as currently living, update conflicting hard
-   registers of the pseudo and START_LIVING, and start a new live
+/* Mark pseudo REGNO as living at program point POINT, update conflicting
+   hard registers of the pseudo and START_LIVING, and start a new live
    range for the pseudo corresponding to REGNO if it is necessary.  */
 static void
-mark_pseudo_live (int regno)
+mark_pseudo_live (int regno, int point)
 {
   lra_live_range_t p;
 
@@ -325,20 +322,21 @@ mark_pseudo_live (int regno)
   lra_assert (! sparseset_bit_p (pseudos_live, regno));
   sparseset_set_bit (pseudos_live, regno);
   IOR_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs, hard_regs_live);
-  
+
   if ((complete_info_p || lra_get_regno_hard_regno (regno) < 0)
       && ((p = lra_reg_info[regno].live_ranges) == NULL
-	  || (p->finish != curr_point && p->finish + 1 != curr_point)))
-    lra_reg_info[regno].live_ranges
-      = create_live_range (regno, curr_point, -1, p);
+	  || (p->finish != point && p->finish + 1 != point)))
+     lra_reg_info[regno].live_ranges
+       = create_live_range (regno, point, -1, p);
   sparseset_set_bit (start_living, regno);
 }
 
-/* Mark pseudo REGNO as currently not living and update START_DYING.
+/* Mark pseudo REGNO as not living at program point POINT and update
+   START_DYING.
    This finishes the current live range for the pseudo corresponding
    to REGNO.  */
 static void
-mark_pseudo_dead (int regno)
+mark_pseudo_dead (int regno, int point)
 {
   lra_live_range_t p;
 
@@ -350,15 +348,19 @@ mark_pseudo_dead (int regno)
     {
       p = lra_reg_info[regno].live_ranges;
       lra_assert (p != NULL);
-      p->finish = curr_point;
+      p->finish = point;
     }
 }
 
-/* Mark register REGNO (pseudo or hard register) in MODE as live.  */
-static void
-mark_regno_live (int regno, enum machine_mode mode)
+/* Mark register REGNO (pseudo or hard register) in MODE as live
+   at program point POINT.
+   Return TRUE if the liveness tracking sets were modified,
+   or FALSE if nothing changed.  */
+static bool
+mark_regno_live (int regno, enum machine_mode mode, int point)
 {
   int last;
+  bool changed = false;
 
   if (regno < FIRST_PSEUDO_REGISTER)
     {
@@ -368,15 +370,22 @@ mark_regno_live (int regno, enum machine
 	make_hard_regno_born (regno);
     }
   else if (! sparseset_bit_p (pseudos_live, regno))
-    mark_pseudo_live (regno);
+    {
+      mark_pseudo_live (regno, point);
+      changed = true;
+    }
+  return changed;
 }
 
 
-/* Mark register REGNO in MODE as dead.	 */
-static void
-mark_regno_dead (int regno, enum machine_mode mode)
+/* Mark register REGNO in MODE as dead at program point POINT.
+   Return TRUE if the liveness tracking sets were modified,
+   or FALSE if nothing changed.  */
+static bool
+mark_regno_dead (int regno, enum machine_mode mode, int point)
 {
   int last;
+  bool changed = false;
 
   if (regno < FIRST_PSEUDO_REGISTER)
     {
@@ -386,7 +395,11 @@ mark_regno_dead (int regno, enum machine
 	make_hard_regno_dead (regno);
     }
   else if (sparseset_bit_p (pseudos_live, regno))
-    mark_pseudo_dead (regno);
+    {
+      mark_pseudo_dead (regno, point);
+      changed = true;
+    }
+  return changed;
 }
 
 /* Insn currently scanned.  */
@@ -403,7 +416,7 @@ bb_has_abnormal_call_pred (basic_block b
 {
   edge e;
   edge_iterator ei;
-  
+
   FOR_EACH_EDGE (e, ei, bb->preds)
     {
       if (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))
@@ -418,14 +431,14 @@ static VEC(int,heap) *point_freq_vec;
 /* The start of the above vector elements.  */
 int *lra_point_freq;
 
-/* Increment the current program point to the next point which has
+/* Increment the current program point POINT to the next point which has
    execution frequency FREQ.  */
 static void
-incr_curr_point (int freq)
+next_program_point (int &point, int freq)
 {
   VEC_safe_push (int, heap, point_freq_vec, freq);
   lra_point_freq = VEC_address (int, point_freq_vec);
-  curr_point++;
+  point++;
 }
 
 /* Update the preference of HARD_REGNO for pseudo REGNO by PROFIT.  */
@@ -507,9 +520,11 @@ check_pseudos_live_through_calls (int re
 
 /* Process insns of the basic block BB to update pseudo live ranges,
    pseudo hard register conflicts, and insn notes.  We do it on
-   backward scan of BB insns.  */
+   backward scan of BB insns.  CURR_POINT is the program point where
+   BB ends.  The function updates this counter and returns in
+   CURR_POINT the program point where BB starts.  */
 static void
-process_bb_lives (basic_block bb)
+process_bb_lives (basic_block bb, int &curr_point)
 {
   int i, regno, freq;
   unsigned int j;
@@ -517,6 +532,7 @@ process_bb_lives (basic_block bb)
   bitmap reg_live_out;
   unsigned int px;
   rtx link, *link_loc;
+  bool need_curr_point_incr;
 
   reg_live_out = DF_LR_OUT (bb);
   sparseset_clear (pseudos_live);
@@ -526,7 +542,7 @@ process_bb_lives (basic_block bb)
   AND_COMPL_HARD_REG_SET (hard_regs_live, eliminable_regset);
   AND_COMPL_HARD_REG_SET (hard_regs_live, lra_no_alloc_regs);
   EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi)
-    mark_pseudo_live (j);
+    mark_pseudo_live (j, curr_point);
       
   freq = REG_FREQ_FROM_BB (bb);
 
@@ -551,7 +567,7 @@ process_bb_lives (basic_block bb)
 
       if (!NONDEBUG_INSN_P (curr_insn))
 	continue;
-      
+
       curr_id = lra_get_insn_recog_data (curr_insn);
       curr_static_id = curr_id->insn_static_data;
       if (lra_dump_file != NULL)
@@ -607,13 +623,22 @@ process_bb_lives (basic_block bb)
 	}
 
       sparseset_clear (start_living);
+
+      /* Try to avoid unnecessary program point increments, this saves
+	 a lot of time in remove_some_program_points_and_update_live_ranges.
+	 We only need an increment if something becomes live or dies at this
+	 program point.  */
+      need_curr_point_incr = false;
+
       /* Mark each defined value as live.  We need to do this for
 	 unused values because they still conflict with quantities
 	 that are live at the time of the definition.  */
       for (reg = curr_id->regs; reg != NULL; reg = reg->next)
 	if (reg->type != OP_IN)
 	  {
-	    mark_regno_live (reg->regno, reg->biggest_mode);
+	    need_curr_point_incr |= mark_regno_live (reg->regno,
+						     reg->biggest_mode,
+						     curr_point);
 	    check_pseudos_live_through_calls (reg->regno);
 	  }
 
@@ -622,7 +647,7 @@ process_bb_lives (basic_block bb)
 	  make_hard_regno_born (reg->regno);
 
       sparseset_copy (unused_set, start_living);
-      
+
       sparseset_clear (start_dying);
 
       /* See which defined values die here.  */
@@ -630,7 +655,9 @@ process_bb_lives (basic_block bb)
 	if (reg->type == OP_OUT && ! reg->early_clobber
 	    && (! reg->subreg_p
 		|| bitmap_bit_p (&lra_bound_pseudos, reg->regno)))
-	  mark_regno_dead (reg->regno, reg->biggest_mode);
+	  need_curr_point_incr |= mark_regno_dead (reg->regno,
+						   reg->biggest_mode,
+						   curr_point);
 
       for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
 	if (reg->type == OP_OUT && ! reg->early_clobber
@@ -648,16 +675,22 @@ process_bb_lives (basic_block bb)
 	    sparseset_ior (pseudos_live_through_setjumps,
 			   pseudos_live_through_setjumps, pseudos_live);
 	}
-      
-      incr_curr_point (freq);
-      
+
+      /* Increment the current program point if we must.  */
+      if (need_curr_point_incr)
+	next_program_point (curr_point, freq);
+
       sparseset_clear (start_living);
 
+      need_curr_point_incr = false;
+
       /* Mark each used value as live.	*/
       for (reg = curr_id->regs; reg != NULL; reg = reg->next)
 	if (reg->type == OP_IN)
 	  {
-	    mark_regno_live (reg->regno, reg->biggest_mode);
+	    need_curr_point_incr |= mark_regno_live (reg->regno,
+						     reg->biggest_mode,
+						     curr_point);
 	    check_pseudos_live_through_calls (reg->regno);
 	  }
 
@@ -671,17 +704,20 @@ process_bb_lives (basic_block bb)
 	  make_hard_regno_born (regno);
 
       sparseset_and_compl (dead_set, start_living, start_dying);
-      
+
       /* Mark early clobber outputs dead.  */
       for (reg = curr_id->regs; reg != NULL; reg = reg->next)
 	if (reg->type == OP_OUT && reg->early_clobber && ! reg->subreg_p)
-	  mark_regno_dead (reg->regno, reg->biggest_mode);
+	  need_curr_point_incr = mark_regno_dead (reg->regno,
+						  reg->biggest_mode,
+						  curr_point);
 
       for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
 	if (reg->type == OP_OUT && reg->early_clobber && ! reg->subreg_p)
 	  make_hard_regno_dead (reg->regno);
 
-      incr_curr_point (freq);
+      if (need_curr_point_incr)
+	next_program_point (curr_point, freq);
 
       /* Update notes.	*/
       for (link_loc = &REG_NOTES (curr_insn); (link = *link_loc) != NULL_RTX;)
@@ -705,14 +741,14 @@ process_bb_lives (basic_block bb)
 	      else if (REG_NOTE_KIND (link) == REG_UNUSED)
 		sparseset_clear_bit (unused_set, regno);
 	    }
-	  link_loc = &XEXP (link, 1);  
+	  link_loc = &XEXP (link, 1);
 	}
       EXECUTE_IF_SET_IN_SPARSESET (dead_set, j)
 	add_reg_note (curr_insn, REG_DEAD, regno_reg_rtx[j]);
       EXECUTE_IF_SET_IN_SPARSESET (unused_set, j)
 	add_reg_note (curr_insn, REG_UNUSED, regno_reg_rtx[j]);
     }
-  
+
 #ifdef EH_RETURN_DATA_REGNO
   if (bb_has_eh_pred (bb))
     for (j = 0; ; ++j)
@@ -724,7 +760,7 @@ process_bb_lives (basic_block bb)
 	make_hard_regno_born (regno);
       }
 #endif
-  
+
   /* Pseudos can't go in stack regs at the start of a basic block that
      is reached by an abnormal edge. Likewise for call clobbered regs,
      because caller-save, fixup_abnormal_edges and possibly the table
@@ -746,15 +782,25 @@ process_bb_lives (basic_block bb)
 	  if (call_used_regs[px])
 	    make_hard_regno_born (px);
     }
-  
+
+  /* See if we'll need an increment at the end of this basic block.
+     An increment is needed if the PSEUDOS_LIVE set is not empty,
+     to make sure the finish points are set up correctly.  */
+  need_curr_point_incr = (sparseset_cardinality (pseudos_live) > 0);
+
   EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, i)
-    mark_pseudo_dead (i);
+    mark_pseudo_dead (i, curr_point);
 
   EXECUTE_IF_SET_IN_BITMAP (DF_LR_IN (bb), FIRST_PSEUDO_REGISTER, j, bi)
-    if (sparseset_bit_p (pseudos_live_through_calls, j))
-      check_pseudos_live_through_calls (j);
+    {
+      if (sparseset_cardinality (pseudos_live_through_calls) == 0)
+	break;
+      if (sparseset_bit_p (pseudos_live_through_calls, j))
+	check_pseudos_live_through_calls (j);
+    }
-  
-  incr_curr_point (freq);
+
+  if (need_curr_point_incr)
+    next_program_point (curr_point, freq);
 }
 
 /* Compress pseudo live ranges by removing program points where
@@ -771,7 +817,7 @@ remove_some_program_points_and_update_li
   sbitmap born_or_dead, born, dead;
   sbitmap_iterator sbi;
   bool born_p, dead_p, prev_born_p, prev_dead_p;
-  
+
   born = sbitmap_alloc (lra_live_max_point);
   dead = sbitmap_alloc (lra_live_max_point);
   sbitmap_zero (born);
@@ -816,24 +862,27 @@ remove_some_program_points_and_update_li
   if (lra_dump_file != NULL)
     fprintf (lra_dump_file, "Compressing live ranges: from %d to %d - %d%%\n",
 	     lra_live_max_point, n, 100 * n / lra_live_max_point);
-  lra_live_max_point = n;
-  for (i = FIRST_PSEUDO_REGISTER; i < (unsigned) max_regno; i++)
-    {
-      for (prev_r = NULL, r = lra_reg_info[i].live_ranges;
-	   r != NULL;
-	   r = next_r)
-	{
-	  next_r = r->next;
-	  r->start = map[r->start];
-	  r->finish = map[r->finish];
-	  if (prev_r == NULL || prev_r->start > r->finish + 1)
-	    {
-	      prev_r = r;
-	      continue;
-	    }
-	  prev_r->start = r->start;
-	  prev_r->next = next_r;
-	  free_live_range (r);
+  if (n < lra_live_max_point)
+    {
+      lra_live_max_point = n;
+      for (i = FIRST_PSEUDO_REGISTER; i < (unsigned) max_regno; i++)
+	{
+	  for (prev_r = NULL, r = lra_reg_info[i].live_ranges;
+	       r != NULL;
+	       r = next_r)
+	    {
+	      next_r = r->next;
+	      r->start = map[r->start];
+	      r->finish = map[r->finish];
+	      if (prev_r == NULL || prev_r->start > r->finish + 1)
+		{
+		  prev_r = r;
+		  continue;
+		}
+	      prev_r->start = r->start;
+	      prev_r->next = next_r;
+	      free_live_range (r);
+	    }
 	}
     }
   free (map);
@@ -913,6 +962,8 @@ lra_create_live_ranges (bool all_p)
 {
   basic_block bb;
   int i, hard_regno, max_regno = max_reg_num ();
+  int curr_point;
+
   timevar_push (TV_LRA_CREATE_LIVE_RANGES);
 
   complete_info_p = all_p;
@@ -954,8 +1005,17 @@ lra_create_live_ranges (bool all_p)
   curr_point = 0;
   point_freq_vec = VEC_alloc (int, heap, get_max_uid () * 2);
   lra_point_freq = VEC_address (int, point_freq_vec);
-  FOR_EACH_BB (bb)
-    process_bb_lives (bb);
+  int *post_order_rev_cfg = XNEWVEC (int, last_basic_block);
+  int n_blocks_inverted = inverted_post_order_compute (post_order_rev_cfg);
+  lra_assert (n_blocks_inverted == n_basic_blocks);
+  for (i = n_blocks_inverted - 1; i >= 0; --i)
+    {
+      bb = BASIC_BLOCK (post_order_rev_cfg[i]);
+      if (bb == EXIT_BLOCK_PTR || bb == ENTRY_BLOCK_PTR)
+	continue;
+      process_bb_lives (bb, curr_point);
+    }
+  free (post_order_rev_cfg);
   lra_live_max_point = curr_point;
   if (lra_dump_file != NULL)
     print_live_ranges (lra_dump_file);
