===================================================================
--- gcc.orig/ira-build.c
+++ gcc/ira-build.c
@@ -504,6 +504,25 @@ ira_set_allocno_cover_class (ira_allocno
 			  reg_class_contents[cover_class]);
 }
 
+/* Merge hard register conflicts from allocno FROM into allocno TO.  If
+   TOTAL_ONLY is true, we ignore ALLOCNO_CONFLICT_HARD_REGS.  */
+static void
+merge_hard_reg_conflicts (ira_allocno_t from, ira_allocno_t to,
+			  bool total_only)
+{
+  if (!total_only)
+    IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (to),
+		      ALLOCNO_CONFLICT_HARD_REGS (from));
+  IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (to),
+		    ALLOCNO_TOTAL_CONFLICT_HARD_REGS (from));
+#ifdef STACK_REGS
+  if (!total_only && ALLOCNO_NO_STACK_REG_P (from))
+    ALLOCNO_NO_STACK_REG_P (to) = true;
+  if (ALLOCNO_TOTAL_NO_STACK_REG_P (from))
+    ALLOCNO_TOTAL_NO_STACK_REG_P (to) = true;
+#endif
+}
+
 /* Return TRUE if the conflict vector with NUM elements is more
    profitable than conflict bit vector for A.  */
 bool
@@ -781,15 +800,8 @@ create_cap_allocno (ira_allocno_t a)
   ALLOCNO_NREFS (cap) = ALLOCNO_NREFS (a);
   ALLOCNO_FREQ (cap) = ALLOCNO_FREQ (a);
   ALLOCNO_CALL_FREQ (cap) = ALLOCNO_CALL_FREQ (a);
-  IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (cap),
-		    ALLOCNO_CONFLICT_HARD_REGS (a));
-  IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (cap),
-		    ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
+  merge_hard_reg_conflicts (a, cap, false);
   ALLOCNO_CALLS_CROSSED_NUM (cap) = ALLOCNO_CALLS_CROSSED_NUM (a);
-#ifdef STACK_REGS
-  ALLOCNO_NO_STACK_REG_P (cap) = ALLOCNO_NO_STACK_REG_P (a);
-  ALLOCNO_TOTAL_NO_STACK_REG_P (cap) = ALLOCNO_TOTAL_NO_STACK_REG_P (a);
-#endif
   if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
     {
       fprintf (ira_dump_file, "    Creating cap ");
@@ -1603,12 +1615,7 @@ propagate_allocno_info (void)
 	  ALLOCNO_NREFS (parent_a) += ALLOCNO_NREFS (a);
 	  ALLOCNO_FREQ (parent_a) += ALLOCNO_FREQ (a);
 	  ALLOCNO_CALL_FREQ (parent_a) += ALLOCNO_CALL_FREQ (a);
-#ifdef STACK_REGS
-	  if (ALLOCNO_TOTAL_NO_STACK_REG_P (a))
-	    ALLOCNO_TOTAL_NO_STACK_REG_P (parent_a) = true;
-#endif
-	  IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (parent_a),
-			    ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
+	  merge_hard_reg_conflicts (a, parent_a, true);
 	  ALLOCNO_CALLS_CROSSED_NUM (parent_a)
 	    += ALLOCNO_CALLS_CROSSED_NUM (a);
 	  ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a)
@@ -1657,6 +1664,46 @@ change_allocno_in_range_list (allocno_li
     r->allocno = a;
 }
 
+/* Move all live ranges associated with allocno A to allocno OTHER_A.  */
+static void
+move_allocno_live_ranges (ira_allocno_t from, ira_allocno_t to)
+{
+  allocno_live_range_t lr = ALLOCNO_LIVE_RANGES (from);
+
+  if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
+    {
+      fprintf (ira_dump_file,
+	       "      Moving ranges of a%dr%d to a%dr%d: ",
+	       ALLOCNO_NUM (from), ALLOCNO_REGNO (from),
+	       ALLOCNO_NUM (to), ALLOCNO_REGNO (to));
+      ira_print_live_range_list (ira_dump_file, lr);
+    }
+  change_allocno_in_range_list (lr, to);
+  ALLOCNO_LIVE_RANGES (to)
+    = ira_merge_allocno_live_ranges (lr, ALLOCNO_LIVE_RANGES (to));
+  ALLOCNO_LIVE_RANGES (from) = NULL;
+}
+
+/* Copy all live ranges associated with allocno A to allocno OTHER_A.  */
+static void
+copy_allocno_live_ranges (ira_allocno_t from, ira_allocno_t to)
+{
+  allocno_live_range_t lr = ALLOCNO_LIVE_RANGES (from);
+
+  if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
+    {
+      fprintf (ira_dump_file,
+	       "      Copying ranges of a%dr%d to a%dr%d: ",
+	       ALLOCNO_NUM (from), ALLOCNO_REGNO (from),
+	       ALLOCNO_NUM (to), ALLOCNO_REGNO (to));
+      ira_print_live_range_list (ira_dump_file, lr);
+    }
+  lr = ira_copy_allocno_live_range_list (lr);
+  change_allocno_in_range_list (lr, to);
+  ALLOCNO_LIVE_RANGES (to)
+    = ira_merge_allocno_live_ranges (lr, ALLOCNO_LIVE_RANGES (to));
+}
+
 /* Return TRUE if NODE represents a loop with low register
    pressure.  */
 static bool
@@ -1890,26 +1937,15 @@ propagate_some_info_from_allocno (ira_al
 {
   enum reg_class cover_class;
 
-  IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
-		    ALLOCNO_CONFLICT_HARD_REGS (from_a));
-#ifdef STACK_REGS
-  if (ALLOCNO_NO_STACK_REG_P (from_a))
-    ALLOCNO_NO_STACK_REG_P (a) = true;
-#endif
+  merge_hard_reg_conflicts (from_a, a, false);
   ALLOCNO_NREFS (a) += ALLOCNO_NREFS (from_a);
   ALLOCNO_FREQ (a) += ALLOCNO_FREQ (from_a);
   ALLOCNO_CALL_FREQ (a) += ALLOCNO_CALL_FREQ (from_a);
-  IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
-		    ALLOCNO_TOTAL_CONFLICT_HARD_REGS (from_a));
   ALLOCNO_CALLS_CROSSED_NUM (a) += ALLOCNO_CALLS_CROSSED_NUM (from_a);
   ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a)
     += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (from_a);
   if (! ALLOCNO_BAD_SPILL_P (from_a))
     ALLOCNO_BAD_SPILL_P (a) = false;
-#ifdef STACK_REGS
-  if (ALLOCNO_TOTAL_NO_STACK_REG_P (from_a))
-    ALLOCNO_TOTAL_NO_STACK_REG_P (a) = true;
-#endif
   cover_class = ALLOCNO_COVER_CLASS (from_a);
   ira_assert (cover_class == ALLOCNO_COVER_CLASS (a));
   ira_allocate_and_accumulate_costs (&ALLOCNO_HARD_REG_COSTS (a), cover_class,
@@ -1930,7 +1966,6 @@ remove_unnecessary_allocnos (void)
   bool merged_p, rebuild_p;
   ira_allocno_t a, prev_a, next_a, parent_a;
   ira_loop_tree_node_t a_node, parent;
-  allocno_live_range_t r;
 
   merged_p = false;
   regno_allocnos = NULL;
@@ -1971,13 +2006,8 @@ remove_unnecessary_allocnos (void)
 		    ira_regno_allocno_map[regno] = next_a;
 		  else
 		    ALLOCNO_NEXT_REGNO_ALLOCNO (prev_a) = next_a;
-		  r = ALLOCNO_LIVE_RANGES (a);
-		  change_allocno_in_range_list (r, parent_a);
-		  ALLOCNO_LIVE_RANGES (parent_a)
-		    = ira_merge_allocno_live_ranges
-		      (r, ALLOCNO_LIVE_RANGES (parent_a));
+		  move_allocno_live_ranges (a, parent_a);
 		  merged_p = true;
-		  ALLOCNO_LIVE_RANGES (a) = NULL;
 		  propagate_some_info_from_allocno (parent_a, a);
 		  /* Remove it from the corresponding regno allocno
 		     map to avoid info propagation of subsequent
@@ -2011,7 +2041,6 @@ remove_low_level_allocnos (void)
   bool merged_p, propagate_p;
   ira_allocno_t a, top_a;
   ira_loop_tree_node_t a_node, parent;
-  allocno_live_range_t r;
   ira_allocno_iterator ai;
 
   merged_p = false;
@@ -2030,12 +2059,8 @@ remove_low_level_allocnos (void)
       propagate_p = a_node->parent->regno_allocno_map[regno] == NULL;
       /* Remove the allocno and update info of allocno in the upper
 	 region.  */
-      r = ALLOCNO_LIVE_RANGES (a);
-      change_allocno_in_range_list (r, top_a);
-      ALLOCNO_LIVE_RANGES (top_a)
-	= ira_merge_allocno_live_ranges (r, ALLOCNO_LIVE_RANGES (top_a));
+      move_allocno_live_ranges (a, top_a);
       merged_p = true;
-      ALLOCNO_LIVE_RANGES (a) = NULL;
       if (propagate_p)
 	propagate_some_info_from_allocno (top_a, a);
     }
@@ -2402,7 +2427,6 @@ copy_info_to_removed_store_destinations 
   ira_allocno_t a;
   ira_allocno_t parent_a = NULL;
   ira_loop_tree_node_t parent;
-  allocno_live_range_t r;
   bool merged_p;
 
   merged_p = false;
@@ -2425,26 +2449,8 @@ copy_info_to_removed_store_destinations 
 	  break;
       if (parent == NULL || parent_a == NULL)
 	continue;
-      if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
-	{
-	  fprintf
-	    (ira_dump_file,
-	     "      Coping ranges of a%dr%d to a%dr%d: ",
-	     ALLOCNO_NUM (a), REGNO (ALLOCNO_REG (a)),
-	     ALLOCNO_NUM (parent_a), REGNO (ALLOCNO_REG (parent_a)));
-	  ira_print_live_range_list (ira_dump_file,
-				     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)
-	= 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
-      if (ALLOCNO_TOTAL_NO_STACK_REG_P (a))
-	ALLOCNO_TOTAL_NO_STACK_REG_P (parent_a) = true;
-#endif
+      copy_allocno_live_ranges (a, parent_a);
+      merge_hard_reg_conflicts (a, parent_a, true);
       ALLOCNO_CALL_FREQ (parent_a) += ALLOCNO_CALL_FREQ (a);
       ALLOCNO_CALLS_CROSSED_NUM (parent_a)
 	+= ALLOCNO_CALLS_CROSSED_NUM (a);
@@ -2522,28 +2528,9 @@ ira_flattening (int max_regno_before_emi
 	    mem_dest_p = true;
 	  if (REGNO (ALLOCNO_REG (a)) == REGNO (ALLOCNO_REG (parent_a)))
 	    {
-	      IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (parent_a),
-				ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
-#ifdef STACK_REGS
-	      if (ALLOCNO_TOTAL_NO_STACK_REG_P (a))
-		ALLOCNO_TOTAL_NO_STACK_REG_P (parent_a) = true;
-#endif
-	      if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
-		{
-		  fprintf (ira_dump_file,
-			   "      Moving ranges of a%dr%d to a%dr%d: ",
-			   ALLOCNO_NUM (a), REGNO (ALLOCNO_REG (a)),
-			   ALLOCNO_NUM (parent_a),
-			   REGNO (ALLOCNO_REG (parent_a)));
-		  ira_print_live_range_list (ira_dump_file,
-					     ALLOCNO_LIVE_RANGES (a));
-		}
-	      change_allocno_in_range_list (ALLOCNO_LIVE_RANGES (a), parent_a);
-	      ALLOCNO_LIVE_RANGES (parent_a)
-		= ira_merge_allocno_live_ranges
-		  (ALLOCNO_LIVE_RANGES (a), ALLOCNO_LIVE_RANGES (parent_a));
+	      merge_hard_reg_conflicts (a, parent_a, true);
+	      move_allocno_live_ranges (a, parent_a);
 	      merged_p = true;
-	      ALLOCNO_LIVE_RANGES (a) = NULL;
 	      ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a)
 		= (ALLOCNO_MEM_OPTIMIZED_DEST_P (parent_a)
 		   || ALLOCNO_MEM_OPTIMIZED_DEST_P (a));
Index: gcc/ira-lives.c
===================================================================
--- gcc.orig/ira-lives.c
+++ gcc/ira-lives.c
@@ -81,33 +81,44 @@ static int last_call_num;
 /* The number of last call at which given allocno was saved.  */
 static int *allocno_saved_at_call;
 
-/* The function processing birth of register REGNO.  It updates living
-   hard regs and conflict hard regs for living allocnos or starts a
-   new live range for the allocno corresponding to REGNO if it is
-   necessary.  */
+/* Record the birth of hard register REGNO, updating hard_regs_live
+   and hard reg conflict information for living allocno.  */
 static void
-make_regno_born (int regno)
+make_hard_regno_born (int regno)
 {
   unsigned int i;
-  ira_allocno_t a;
-  allocno_live_range_t p;
 
-  if (regno < FIRST_PSEUDO_REGISTER)
+  SET_HARD_REG_BIT (hard_regs_live, regno);
+  EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i)
     {
-      SET_HARD_REG_BIT (hard_regs_live, regno);
-      EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i)
-        {
-	  SET_HARD_REG_BIT (ALLOCNO_CONFLICT_HARD_REGS (ira_allocnos[i]),
-			    regno);
-	  SET_HARD_REG_BIT (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (ira_allocnos[i]),
-			    regno);
-	}
-      return;
+      SET_HARD_REG_BIT (ALLOCNO_CONFLICT_HARD_REGS (ira_allocnos[i]),
+			regno);
+      SET_HARD_REG_BIT (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (ira_allocnos[i]),
+			regno);
     }
-  a = ira_curr_regno_allocno_map[regno];
-  if (a == NULL)
-    return;
-  if ((p = ALLOCNO_LIVE_RANGES (a)) == NULL
+}
+
+/* Process the death of hard register REGNO.  This updates
+   hard_regs_live.  */
+static void
+make_hard_regno_dead (int regno)
+{
+  CLEAR_HARD_REG_BIT (hard_regs_live, regno);
+}
+
+/* Record the birth of allocno A, starting a new live range for
+   it if necessary, and updating hard reg conflict information.  We also
+   record it in allocnos_live.  */
+static void
+make_allocno_born (ira_allocno_t a)
+{
+  allocno_live_range_t p = ALLOCNO_LIVE_RANGES (a);
+
+  sparseset_set_bit (allocnos_live, ALLOCNO_NUM (a));
+  IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a), hard_regs_live);
+  IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), hard_regs_live);
+
+  if (p == NULL
       || (p->finish != curr_point && p->finish + 1 != curr_point))
     ALLOCNO_LIVE_RANGES (a)
       = ira_create_allocno_live_range (a, curr_point, -1,
@@ -137,56 +148,39 @@ update_allocno_pressure_excess_length (i
     }
 }
 
-/* Process the death of register REGNO.  This updates hard_regs_live
-   or finishes the current live range for the allocno corresponding to
-   REGNO.  */
+/* Process the death of allocno A.  This finishes the current live
+   range for it.  */
 static void
-make_regno_dead (int regno)
+make_allocno_dead (ira_allocno_t a)
 {
-  ira_allocno_t a;
   allocno_live_range_t p;
 
-  if (regno < FIRST_PSEUDO_REGISTER)
-    {
-      CLEAR_HARD_REG_BIT (hard_regs_live, regno);
-      return;
-    }
-  a = ira_curr_regno_allocno_map[regno];
-  if (a == NULL)
-    return;
   p = ALLOCNO_LIVE_RANGES (a);
   ira_assert (p != NULL);
   p->finish = curr_point;
   update_allocno_pressure_excess_length (a);
+  sparseset_clear_bit (allocnos_live, ALLOCNO_NUM (a));
 }
 
 /* The current register pressures for each cover class for the current
    basic block.  */
 static int curr_reg_pressure[N_REG_CLASSES];
 
-/* Mark allocno A as currently living and update current register
-   pressure, maximal register pressure for the current BB, start point
-   of the register pressure excess, and conflicting hard registers of
-   A.  */
+/* Record that register pressure for COVER_CLASS increased by N
+   registers.  Update the current register pressure, maximal register
+   pressure for the current BB and the start point of the register
+   pressure excess.  */
 static void
-set_allocno_live (ira_allocno_t a)
+inc_register_pressure (enum reg_class cover_class, int n)
 {
   int i;
-  enum reg_class cover_class, cl;
+  enum reg_class cl;
 
-  /* Invalidate because it is referenced.  */
-  allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
-  if (sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
-    return;
-  sparseset_set_bit (allocnos_live, ALLOCNO_NUM (a));
-  IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a), hard_regs_live);
-  IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a), hard_regs_live);
-  cover_class = ALLOCNO_COVER_CLASS (a);
   for (i = 0;
        (cl = ira_reg_class_super_classes[cover_class][i]) != LIM_REG_CLASSES;
        i++)
     {
-      curr_reg_pressure[cl] += ira_reg_class_nregs[cl][ALLOCNO_MODE (a)];
+      curr_reg_pressure[cl] += n;
       if (high_pressure_start_point[cl] < 0
 	  && (curr_reg_pressure[cl] > ira_available_class_regs[cl]))
 	high_pressure_start_point[cl] = curr_point;
@@ -195,110 +189,87 @@ set_allocno_live (ira_allocno_t a)
     }
 }
 
-/* Mark allocno A as currently not living and update current register
-   pressure, start point of the register pressure excess, and register
-   pressure excess length for living allocnos.  */
+/* Record that register pressure for COVER_CLASS has decreased by
+   NREGS registers; update current register pressure, start point of
+   the register pressure excess, and register pressure excess length
+   for living allocnos.  */
+
 static void
-clear_allocno_live (ira_allocno_t a)
+dec_register_pressure (enum reg_class cover_class, int nregs)
 {
   int i;
   unsigned int j;
-  enum reg_class cover_class, cl;
-  bool set_p;
+  enum reg_class cl;
+  bool set_p = false;
 
-  /* Invalidate because it is referenced.  */
-  allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
-  if (sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
+  for (i = 0;
+       (cl = ira_reg_class_super_classes[cover_class][i]) != LIM_REG_CLASSES;
+       i++)
     {
-      cover_class = ALLOCNO_COVER_CLASS (a);
-      set_p = false;
+      curr_reg_pressure[cl] -= nregs;
+      ira_assert (curr_reg_pressure[cl] >= 0);
+      if (high_pressure_start_point[cl] >= 0
+	  && curr_reg_pressure[cl] <= ira_available_class_regs[cl])
+	set_p = true;
+    }
+  if (set_p)
+    {
+      EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, j)
+	update_allocno_pressure_excess_length (ira_allocnos[j]);
       for (i = 0;
 	   (cl = ira_reg_class_super_classes[cover_class][i])
 	     != LIM_REG_CLASSES;
 	   i++)
-	{
-	  curr_reg_pressure[cl] -= ira_reg_class_nregs[cl][ALLOCNO_MODE (a)];
-	  ira_assert (curr_reg_pressure[cl] >= 0);
-	  if (high_pressure_start_point[cl] >= 0
-	      && curr_reg_pressure[cl] <= ira_available_class_regs[cl])
-	    set_p = true;
-	}
-      if (set_p)
-	{
-	  EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, j)
-	    update_allocno_pressure_excess_length (ira_allocnos[j]);
-	  for (i = 0;
-	       (cl = ira_reg_class_super_classes[cover_class][i])
-		 != LIM_REG_CLASSES;
-	       i++)
-	    if (high_pressure_start_point[cl] >= 0
-		&& curr_reg_pressure[cl] <= ira_available_class_regs[cl])
-	      high_pressure_start_point[cl] = -1;
-
-	}
+	if (high_pressure_start_point[cl] >= 0
+	    && curr_reg_pressure[cl] <= ira_available_class_regs[cl])
+	  high_pressure_start_point[cl] = -1;
     }
-  sparseset_clear_bit (allocnos_live, ALLOCNO_NUM (a));
 }
 
-/* Mark the register REG as live.  Store a 1 in hard_regs_live or
-   allocnos_live for this register or the corresponding allocno,
-   record how many consecutive hardware registers it actually
-   needs.  */
+/* Mark the pseudo register REGNO as live.  Update all information about
+   live ranges and register pressure.  */
 static void
-mark_reg_live (rtx reg)
+mark_pseudo_regno_live (int regno)
 {
-  int i, regno;
+  ira_allocno_t a = ira_curr_regno_allocno_map[regno];
+  enum reg_class cl;
+  int nregs;
 
-  gcc_assert (REG_P (reg));
-  regno = REGNO (reg);
+  if (a == NULL)
+    return;
 
-  if (regno >= FIRST_PSEUDO_REGISTER)
-    {
-      ira_allocno_t a = ira_curr_regno_allocno_map[regno];
+  /* Invalidate because it is referenced.  */
+  allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
 
-      if (a != NULL)
-	{
-	  if (sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
-	    {
-	      /* Invalidate because it is referenced.  */
-	      allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
-	      return;
-	    }
-	  set_allocno_live (a);
-	}
-      make_regno_born (regno);
-    }
-  else if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
+  if (sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
+    return;
+
+  cl = ALLOCNO_COVER_CLASS (a);
+  nregs = ira_reg_class_nregs[cl][ALLOCNO_MODE (a)];
+  inc_register_pressure (cl, nregs);
+  make_allocno_born (a);
+}
+
+/* Mark the hard register REG as live.  Store a 1 in hard_regs_live
+   for this register, record how many consecutive hardware registers
+   it actually needs.  */
+static void
+mark_hard_reg_live (rtx reg)
+{
+  int regno = REGNO (reg);
+
+  if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
     {
       int last = regno + hard_regno_nregs[regno][GET_MODE (reg)];
-      enum reg_class cover_class, cl;
 
       while (regno < last)
 	{
 	  if (! TEST_HARD_REG_BIT (hard_regs_live, regno)
 	      && ! TEST_HARD_REG_BIT (eliminable_regset, regno))
 	    {
-	      cover_class = ira_hard_regno_cover_class[regno];
-	      for (i = 0;
-		   (cl = ira_reg_class_super_classes[cover_class][i])
-		     != LIM_REG_CLASSES;
-		   i++)
-		{
-		  curr_reg_pressure[cl]++;
-		  if (high_pressure_start_point[cl] < 0
-		      && (curr_reg_pressure[cl]
-			  > ira_available_class_regs[cl]))
-		    high_pressure_start_point[cl] = curr_point;
-		}
-	      make_regno_born (regno);
-	      for (i = 0;
-		   (cl = ira_reg_class_super_classes[cover_class][i])
-		     != LIM_REG_CLASSES;
-		   i++)
-		{
-		  if (curr_bb_node->reg_pressure[cl] < curr_reg_pressure[cl])
-		    curr_bb_node->reg_pressure[cl] = curr_reg_pressure[cl];
-		}
+	      enum reg_class cover_class = ira_hard_regno_cover_class[regno];
+	      inc_register_pressure (cover_class, 1);
+	      make_hard_regno_born (regno);
 	    }
 	  regno++;
 	}
@@ -314,74 +285,55 @@ mark_ref_live (df_ref ref)
   reg = DF_REF_REG (ref);
   if (GET_CODE (reg) == SUBREG)
     reg = SUBREG_REG (reg);
-  mark_reg_live (reg);
+  if (REGNO (reg) >= FIRST_PSEUDO_REGISTER)
+    mark_pseudo_regno_live (REGNO (reg));
+  else
+    mark_hard_reg_live (reg);
 }
 
-/* Mark the register REG as dead.  Store a 0 in hard_regs_live or
-   allocnos_live for the register.  */
+/* Mark the pseudo register REGNO as dead.  Update all information about
+   live ranges and register pressure.  */
 static void
-mark_reg_dead (rtx reg)
+mark_pseudo_regno_dead (int regno)
 {
-  int regno;
+  ira_allocno_t a = ira_curr_regno_allocno_map[regno];
+  enum reg_class cl;
+  int nregs;
 
-  gcc_assert (REG_P (reg));
-  regno = REGNO (reg);
+  if (a == NULL)
+    return;
 
-  if (regno >= FIRST_PSEUDO_REGISTER)
-    {
-      ira_allocno_t a = ira_curr_regno_allocno_map[regno];
+  /* Invalidate because it is referenced.  */
+  allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
 
-      if (a != NULL)
-	{
-	  if (! sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
-	    {
-	      /* Invalidate because it is referenced.  */
-	      allocno_saved_at_call[ALLOCNO_NUM (a)] = 0;
-	      return;
-	    }
-	  clear_allocno_live (a);
-	}
-      make_regno_dead (regno);
-    }
-  else if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
+  if (! sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)))
+    return;
+
+  cl = ALLOCNO_COVER_CLASS (a);
+  nregs = ira_reg_class_nregs[cl][ALLOCNO_MODE (a)];
+  dec_register_pressure (cl, nregs);
+
+  make_allocno_dead (a);
+}
+
+/* Mark the hard register REG as dead.  Store a 0 in hard_regs_live
+   for the register.  */
+static void
+mark_hard_reg_dead (rtx reg)
+{
+  int regno = REGNO (reg);
+
+  if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
     {
-      int i;
-      unsigned int j;
       int last = regno + hard_regno_nregs[regno][GET_MODE (reg)];
-      enum reg_class cover_class, cl;
-      bool set_p;
 
       while (regno < last)
 	{
 	  if (TEST_HARD_REG_BIT (hard_regs_live, regno))
 	    {
-	      set_p = false;
-	      cover_class = ira_hard_regno_cover_class[regno];
-	      for (i = 0;
-		   (cl = ira_reg_class_super_classes[cover_class][i])
-		     != LIM_REG_CLASSES;
-		   i++)
-  		{
-		  curr_reg_pressure[cl]--;
-		  if (high_pressure_start_point[cl] >= 0
-		      && curr_reg_pressure[cl] <= ira_available_class_regs[cl])
-		    set_p = true;
-		  ira_assert (curr_reg_pressure[cl] >= 0);
-		}
-	      if (set_p)
-		{
-		  EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, j)
-		    update_allocno_pressure_excess_length (ira_allocnos[j]);
-		  for (i = 0;
-		       (cl = ira_reg_class_super_classes[cover_class][i])
-			 != LIM_REG_CLASSES;
-		       i++)
-		    if (high_pressure_start_point[cl] >= 0
-			&& (curr_reg_pressure[cl]
-			    <= ira_available_class_regs[cl]))
-		      high_pressure_start_point[cl] = -1;
-		}
-	      make_regno_dead (regno);
+	      enum reg_class cover_class = ira_hard_regno_cover_class[regno];
+	      dec_register_pressure (cover_class, 1);
+	      make_hard_regno_dead (regno);
 	    }
 	  regno++;
 	}
@@ -402,7 +354,10 @@ mark_ref_dead (df_ref def)
   reg = DF_REF_REG (def);
   if (GET_CODE (reg) == SUBREG)
     reg = SUBREG_REG (reg);
-  mark_reg_dead (reg);
+  if (REGNO (reg) >= FIRST_PSEUDO_REGISTER)
+    mark_pseudo_regno_dead (REGNO (reg));
+  else
+    mark_hard_reg_dead (reg);
 }
 
 /* Make pseudo REG conflicting with pseudo DREG, if the 1st pseudo
@@ -427,10 +382,10 @@ make_pseudo_conflict (rtx reg, enum reg_
   if (advance_p)
     curr_point++;
 
-  mark_reg_live (reg);
-  mark_reg_live (dreg);
-  mark_reg_dead (reg);
-  mark_reg_dead (dreg);
+  mark_pseudo_regno_live (REGNO (reg));
+  mark_pseudo_regno_live (REGNO (dreg));
+  mark_pseudo_regno_dead (REGNO (reg));
+  mark_pseudo_regno_dead (REGNO (dreg));
 
   return false;
 }
@@ -961,15 +916,7 @@ process_bb_node_lives (ira_loop_tree_nod
 	      }
 	  }
       EXECUTE_IF_SET_IN_BITMAP (reg_live_out, FIRST_PSEUDO_REGISTER, j, bi)
-	{
-	  ira_allocno_t a = ira_curr_regno_allocno_map[j];
-
-	  if (a == NULL)
-	    continue;
-	  ira_assert (! sparseset_bit_p (allocnos_live, ALLOCNO_NUM (a)));
-	  set_allocno_live (a);
-	  make_regno_born (j);
-	}
+	mark_pseudo_regno_live (j);
 
       freq = REG_FREQ_FROM_BB (bb);
       if (freq == 0)
@@ -1137,7 +1084,7 @@ process_bb_node_lives (ira_loop_tree_nod
 	    unsigned int regno = EH_RETURN_DATA_REGNO (j);
 	    if (regno == INVALID_REGNUM)
 	      break;
-	    make_regno_born (regno);
+	    make_hard_regno_born (regno);
 	  }
 #endif
 
@@ -1155,7 +1102,7 @@ process_bb_node_lives (ira_loop_tree_nod
 	      ALLOCNO_TOTAL_NO_STACK_REG_P (ira_allocnos[px]) = true;
 	    }
 	  for (px = FIRST_STACK_REG; px <= LAST_STACK_REG; px++)
-	    make_regno_born (px);
+	    make_hard_regno_born (px);
 #endif
 	  /* No need to record conflicts for call clobbered regs if we
 	     have nonlocal labels around, as we don't ever try to
@@ -1163,13 +1110,11 @@ process_bb_node_lives (ira_loop_tree_nod
 	  if (!cfun->has_nonlocal_label && bb_has_abnormal_call_pred (bb))
 	    for (px = 0; px < FIRST_PSEUDO_REGISTER; px++)
 	      if (call_used_regs[px])
-		make_regno_born (px);
+		make_hard_regno_born (px);
 	}
 
       EXECUTE_IF_SET_IN_SPARSESET (allocnos_live, i)
-	{
-	  make_regno_dead (ALLOCNO_REGNO (ira_allocnos[i]));
-	}
+	make_allocno_dead (ira_allocnos[i]);
 
       curr_point++;
 
