Index: emit-rtl.c
===================================================================
--- emit-rtl.c	(revision 191858)
+++ emit-rtl.c	(working copy)
@@ -923,6 +923,75 @@ gen_reg_rtx (enum machine_mode mode)
   return val;
 }
 
+extern void compact_regno_reg_rtx (void);
+
+static int
+mark_used_regs (rtx *cur_rtx, void *arg)
+{
+  sbitmap used_regnos = (sbitmap) arg;
+  if (*cur_rtx && REG_P (*cur_rtx)
+      && REGNO (*cur_rtx) > LAST_VIRTUAL_REGISTER)
+    SET_BIT (used_regnos, REGNO (*cur_rtx));
+  return 0;
+}
+
+void
+compact_regno_reg_rtx (void)
+{
+  basic_block bb;
+  rtx insn;
+  unsigned max_regno = reg_rtx_no;
+  unsigned n_used_regnos = 0;
+  sbitmap used_regnos = sbitmap_alloc (reg_rtx_no);
+  sbitmap_zero (used_regnos);
+  FOR_EACH_BB (bb)
+    {
+      FOR_BB_INSNS (bb, insn)
+	{ 
+	  if (! INSN_P (insn))
+	    continue;
+	  for_each_rtx (&PATTERN (insn), mark_used_regs, used_regnos);
+	  for_each_rtx (&REG_NOTES (insn), mark_used_regs, used_regnos);
+	}
+    }
+  n_used_regnos = (unsigned) sbitmap_popcount (used_regnos, reg_rtx_no);
+  fprintf (stderr, "%32s: %u\t%u\n",
+	   "just_counting", n_used_regnos, max_regno - LAST_VIRTUAL_REGISTER);
+  if (n_used_regnos == max_regno - LAST_VIRTUAL_REGISTER)
+    return;
+
+  unsigned int regno, next_regno;
+  for (regno = next_regno = LAST_VIRTUAL_REGISTER + 1;
+       regno < max_regno; regno++)
+    {
+      rtx reg = regno_reg_rtx[regno];
+      if (TEST_BIT (used_regnos, regno))
+	{
+	  gcc_assert (reg);
+	  if (regno > next_regno)
+	    {
+	      gcc_assert (regno == ORIGINAL_REGNO (reg));
+	      gcc_assert (regno_reg_rtx[next_regno] == NULL);
+	      SET_REGNO_RAW (reg, next_regno);
+	      ORIGINAL_REGNO (reg) = next_regno;
+	      regno_reg_rtx[next_regno] = reg;
+	      regno_reg_rtx[regno] = NULL;
+	    }
+	  next_regno++;
+	}
+      else if (reg)
+        {
+	  gcc_assert (REG_P (reg));
+	  SET_REGNO_RAW (reg, INVALID_REGNUM);
+	  ORIGINAL_REGNO (reg) = INVALID_REGNUM;
+	  PUT_MODE (reg, VOIDmode);
+	  regno_reg_rtx[regno] = NULL;
+	}
+    }
+  gcc_assert (n_used_regnos == next_regno - LAST_VIRTUAL_REGISTER - 1);
+  reg_rtx_no = next_regno;
+}
+
 /* Update NEW with the same attributes as REG, but with OFFSET added
    to the REG_OFFSET.  */
 
Index: df-core.c
===================================================================
--- df-core.c	(revision 191858)
+++ df-core.c	(working copy)
@@ -700,6 +700,7 @@ df_finish_pass (bool verify ATTRIBUTE_UN
 
 
 /* Set up the dataflow instance for the entire back end.  */
+extern void compact_regno_reg_rtx (void);
 
 static unsigned int
 rest_of_handle_df_initialize (void)
@@ -708,6 +709,7 @@ rest_of_handle_df_initialize (void)
   df = XCNEW (struct df_d);
   df->changeable_flags = 0;
 
+  compact_regno_reg_rtx ();
   bitmap_obstack_initialize (&df_bitmap_obstack);
 
   /* Set this to a conservative value.  Stack_ptr_mod will compute it
