diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 178b736c9f7..46efc5ddf3c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2007-08-01 Zdenek Dvorak + + * tree-ssa-threadupdate.c (thread_through_all_blocks): Record that + the loop structures may need fixing. + * tree-cfgcleanup.c (cleanup_tree_cfg_noloop, repair_loop_structures): + New functions. + (cleanup_tree_cfg_loop): Removed. + (cleanup_tree_cfg): If loops need fixing, call repair_loop_structures. + * tree-predcom.c (tree_predictive_commoning): Return TODO_cleanup_cfg + instead of running cleanup_tree_cfg_loop. + * cfgloop.h (LOOPS_NEED_FIXUP): New constant. + * tree-flow.h (cleanup_tree_cfg_loop): Declaration removed. + (tree_predictive_commoning): Declaration changed. + * passes.c (execute_function_todo): Do not use cleanup_tree_cfg_loop. + 2007-08-01 Zdenek Dvorak * doc/invoke.texi (l1-cache-size): Update documentation. diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index b1ec4b52141..903672dfcf9 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -170,7 +170,8 @@ enum LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS = 4, LOOPS_HAVE_RECORDED_EXITS = 8, LOOPS_MAY_HAVE_MULTIPLE_LATCHES = 16, - LOOP_CLOSED_SSA = 32 + LOOP_CLOSED_SSA = 32, + LOOPS_NEED_FIXUP = 64 }; #define LOOPS_NORMAL (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES \ diff --git a/gcc/passes.c b/gcc/passes.c index 9ec254f3808..51517063d8f 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -891,12 +891,7 @@ execute_function_todo (void *data) /* Always cleanup the CFG before trying to update SSA. */ if (flags & TODO_cleanup_cfg) { - bool cleanup; - - if (current_loops) - cleanup = cleanup_tree_cfg_loop (); - else - cleanup = cleanup_tree_cfg (); + bool cleanup = cleanup_tree_cfg (); if (cleanup && (cfun->curr_properties & PROP_ssa)) flags |= TODO_remove_unused_locals; diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index 00fed83b544..c35001c33e7 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -596,8 +596,8 @@ cleanup_tree_cfg_1 (void) /* Remove unreachable blocks and other miscellaneous clean up work. Return true if the flowgraph was modified, false otherwise. */ -bool -cleanup_tree_cfg (void) +static bool +cleanup_tree_cfg_noloop (void) { bool changed; @@ -632,34 +632,47 @@ cleanup_tree_cfg (void) timevar_pop (TV_TREE_CLEANUP_CFG); + if (changed && current_loops) + current_loops->state |= LOOPS_NEED_FIXUP; + return changed; } +/* Repairs loop structures. */ + +static void +repair_loop_structures (void) +{ + bitmap changed_bbs = BITMAP_ALLOC (NULL); + fix_loop_structure (changed_bbs); + + /* This usually does nothing. But sometimes parts of cfg that originally + were inside a loop get out of it due to edge removal (since they + become unreachable by back edges from latch). */ + if ((current_loops->state & LOOP_CLOSED_SSA) != 0) + rewrite_into_loop_closed_ssa (changed_bbs, TODO_update_ssa); + + BITMAP_FREE (changed_bbs); + +#ifdef ENABLE_CHECKING + verify_loop_structure (); +#endif + scev_reset (); + + current_loops->state &= ~LOOPS_NEED_FIXUP; +} + /* Cleanup cfg and repair loop structures. */ bool -cleanup_tree_cfg_loop (void) +cleanup_tree_cfg (void) { - bool changed = cleanup_tree_cfg (); + bool changed = cleanup_tree_cfg_noloop (); - if (changed && current_loops != NULL) - { - bitmap changed_bbs = BITMAP_ALLOC (NULL); - fix_loop_structure (changed_bbs); + if (current_loops != NULL + && (current_loops->state & LOOPS_NEED_FIXUP)) + repair_loop_structures (); - /* This usually does nothing. But sometimes parts of cfg that originally - were inside a loop get out of it due to edge removal (since they - become unreachable by back edges from latch). */ - if ((current_loops->state & LOOP_CLOSED_SSA) != 0) - rewrite_into_loop_closed_ssa (changed_bbs, TODO_update_ssa); - - BITMAP_FREE (changed_bbs); - -#ifdef ENABLE_CHECKING - verify_loop_structure (); -#endif - scev_reset (); - } return changed; } diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index e3895d19fbf..55bec44c27b 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -783,7 +783,6 @@ void remove_edge_and_dominated_blocks (edge); /* In tree-cfgcleanup.c */ extern bitmap cfgcleanup_altered_bbs; extern bool cleanup_tree_cfg (void); -extern bool cleanup_tree_cfg_loop (void); /* In tree-pretty-print.c. */ extern void dump_generic_bb (FILE *, basic_block, int, int); @@ -975,7 +974,7 @@ unsigned int tree_unroll_loops_completely (bool); unsigned int tree_ssa_prefetch_arrays (void); unsigned int remove_empty_loops (void); void tree_ssa_iv_optimize (void); -void tree_predictive_commoning (void); +unsigned tree_predictive_commoning (void); bool number_of_iterations_exit (struct loop *, edge, struct tree_niter_desc *niter, bool); diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c index caf0501af04..fcf42911d28 100644 --- a/gcc/tree-predcom.c +++ b/gcc/tree-predcom.c @@ -2582,12 +2582,13 @@ end: ; /* Runs predictive commoning. */ -void +unsigned tree_predictive_commoning (void) { bool unrolled = false; struct loop *loop; loop_iterator li; + unsigned ret = 0; initialize_original_copy_tables (); FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST) @@ -2598,7 +2599,9 @@ tree_predictive_commoning (void) if (unrolled) { scev_reset (); - cleanup_tree_cfg_loop (); + ret = TODO_cleanup_cfg; } free_original_copy_tables (); + + return ret; } diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index dfe1829a110..a626cdd7648 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -1076,6 +1076,9 @@ thread_through_all_blocks (bool may_peel_loop_headers) VEC_free (edge, heap, threaded_edges); threaded_edges = NULL; + if (retval) + current_loops->state |= LOOPS_NEED_FIXUP; + return retval; }