diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fa3c54d57284b0ee92338ed1fc56f75668991907..804d74053d6ffd75a37fde2d01403a7758c42402 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2012-10-13  Steven Bosscher  <steven@gcc.gnu.org>
+
+	* ira.c (ira): Set current_loops to &ira_loops before recording
+	loop exits.  Release recorded exits and loops early.
+
 2012-10-13  Chung-Lin Tang  <cltang@codesourcery.com>
 
 	* builtins.c (expand_builtin_set_thread_pointer): Use
diff --git a/gcc/ira.c b/gcc/ira.c
index 4a7dcb52043d93a5eb0550b617a9c5ee5368789b..9a93297b0d4b7ec220ec06d6839d341a4f1a3d6d 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -4233,8 +4233,8 @@ ira (FILE *f)
   if (flag_ira_region == IRA_REGION_ALL || flag_ira_region == IRA_REGION_MIXED)
     {
       flow_loops_find (&ira_loops);
-      record_loop_exits ();
       current_loops = &ira_loops;
+      record_loop_exits ();
     }
 
   if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
@@ -4277,9 +4277,14 @@ ira (FILE *f)
 	     info.  */
 	  df_analyze ();
 
+	  /* ??? Rebuild the loop tree, but why?  Does the loop tree
+	     change if new insns were generated?  Can that be handled
+	     by updating the loop tree incrementally?  */
+	  release_recorded_exits ();
+	  flow_loops_free (&ira_loops);
 	  flow_loops_find (&ira_loops);
-	  record_loop_exits ();
 	  current_loops = &ira_loops;
+	  record_loop_exits ();
 
 	  setup_allocno_assignment_flags ();
 	  ira_initiate_assign ();
@@ -4363,6 +4368,7 @@ do_reload (void)
 
   if (current_loops != NULL)
     {
+      release_recorded_exits ();
       flow_loops_free (&ira_loops);
       free_dominance_info (CDI_DOMINATORS);
     }