Hello, IRA uses record_loop_exits() to cache the loop exit edges, but due to a code ordering bug the edges are not actually recorded. record_loop_exits() starts with:
if (!current_loops) return; So ira.c should set current_loops before calling record_loop_exits. With the current order, the exists are not actually recorded. Also, ira.c should release recorded exits and loops, this releases a considerable amount of GC memory that can be re-used in the next IRA iteration. It's not clear to me why IRA has to re-compute the cfgloop tree from scratch, though, so I've added a "???" comment for that. Bootstrapped&tested (with and without checking) on powerpc64-unknown-linux-gnu. OK for trunk? Ciao! Steven * ira.c (ira): Set current_loops to &ira_loops before recording loop exits. Release recorded exits and loops early. Index: ira.c =================================================================== --- ira.c (revision 192377) +++ ira.c (working copy) @@ -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); + current_loops = &ira_loops; record_loop_exits (); - current_loops = &ira_loops; } 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); + current_loops = &ira_loops; record_loop_exits (); - current_loops = &ira_loops; 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); }