From 9fa264571da0247ed1b0d0d0e64897f7b3731c50 Mon Sep 17 00:00:00 2001 From: Steven Bosscher Date: Tue, 19 Jul 2005 00:44:45 +0000 Subject: [PATCH] loop-init.c (rest_of_handle_loop2): Remove. * loop-init.c (rest_of_handle_loop2): Remove. (rtl_loop_init, rtl_loop_done, rtl_move_loop_invariants, rtl_unswitch, rtl_unroll_and_peel_loops, rtl_doloop): New functions. (pass_rtl_loop_init, pass_rtl_loop_done, pass_rtl_move_loop_invariants, pass_rtl_unswitch, pass_rtl_unroll_and_peel_loops, pass_rtl_doloop): New passes. * tree-ssa-loop.c (pass_loop, pass_loop_init, pass_loop_done, pass_unswitch): Rename to pass_tree_loop, pass_tree_loop_init, pass_tree_loop_done, and pass_tree_unswitch. (gate_loop): Rename to gate_tree_loop. * passes.c (init_optimization_passes): Update for renamed tree loop passes. Add the new loop2 passes as subpasses of loop2. * tree-pass.h: Add extern declarations for the new loop2 subpasses. Update for the renamed tree loop passes. From-SVN: r102149 --- gcc/ChangeLog | 17 ++++ gcc/loop-init.c | 217 ++++++++++++++++++++++++++++++++++++-------- gcc/passes.c | 22 ++++- gcc/tree-pass.h | 16 +++- gcc/tree-ssa-loop.c | 12 +-- 5 files changed, 233 insertions(+), 51 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9cd5cffac63d..f599f04e594a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2005-07-19 Steven Bosscher + + * loop-init.c (rest_of_handle_loop2): Remove. + (rtl_loop_init, rtl_loop_done, rtl_move_loop_invariants, + rtl_unswitch, rtl_unroll_and_peel_loops, rtl_doloop): New functions. + (pass_rtl_loop_init, pass_rtl_loop_done, + pass_rtl_move_loop_invariants, pass_rtl_unswitch, + pass_rtl_unroll_and_peel_loops, pass_rtl_doloop): New passes. + * tree-ssa-loop.c (pass_loop, pass_loop_init, pass_loop_done, + pass_unswitch): Rename to pass_tree_loop, pass_tree_loop_init, + pass_tree_loop_done, and pass_tree_unswitch. + (gate_loop): Rename to gate_tree_loop. + * passes.c (init_optimization_passes): Update for renamed tree + loop passes. Add the new loop2 passes as subpasses of loop2. + * tree-pass.h: Add extern declarations for the new loop2 subpasses. + Update for the renamed tree loop passes. + 2005-07-18 Ian Lance Taylor PR middle-end/22057 diff --git a/gcc/loop-init.c b/gcc/loop-init.c index 375b2bf23a5e..0e0b0cf4c88f 100644 --- a/gcc/loop-init.c +++ b/gcc/loop-init.c @@ -1,4 +1,4 @@ -/* Loop optimizer initialization routines. +/* Loop optimizer initialization routines and RTL loop optimization passes. Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GCC. @@ -32,7 +32,9 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "timevar.h" #include "flags.h" -/* Initialize loop optimizer. */ + +/* Initialize loop optimizer. This is used by the tree and RTL loop + optimizers. */ struct loops * loop_optimizer_init (FILE *dumpfile) @@ -119,7 +121,11 @@ loop_optimizer_finalize (struct loops *loops, FILE *dumpfile) verify_flow_info (); #endif } + +/* Gate for the RTL loop superpass. The actual passes are subpasses. + See passes.c for more on that. */ + static bool gate_handle_loop2 (void) { @@ -131,45 +137,64 @@ gate_handle_loop2 (void) || flag_branch_on_count_reg)); } -/* Perform loop optimizations. It might be better to do them a bit - sooner, but we want the profile feedback to work more - efficiently. */ -static void -rest_of_handle_loop2 (void) +struct tree_opt_pass pass_loop2 = { - struct loops *loops; - basic_block bb; + "loop2", /* name */ + gate_handle_loop2, /* gate */ + NULL, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_LOOP, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'L' /* letter */ +}; + +/* Initialization of the RTL loop passes. */ +static void +rtl_loop_init (void) +{ if (dump_file) dump_flow_info (dump_file); /* Initialize structures for layout changes. */ cfg_layout_initialize (0); - loops = loop_optimizer_init (dump_file); + current_loops = loop_optimizer_init (dump_file); +} - if (loops) - { - /* The optimizations: */ - if (flag_move_loop_invariants) - move_loop_invariants (loops); +struct tree_opt_pass pass_rtl_loop_init = +{ + "loopinit", /* name */ + NULL, /* gate */ + rtl_loop_init, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_LOOP, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 'L' /* letter */ +}; - if (flag_unswitch_loops) - unswitch_loops (loops); + +/* Finalization of the RTL loop passes. */ +static void +rtl_loop_done (void) +{ + basic_block bb; - if (flag_peel_loops || flag_unroll_loops) - unroll_and_peel_loops (loops, - (flag_peel_loops ? UAP_PEEL : 0) | - (flag_unroll_loops ? UAP_UNROLL : 0) | - (flag_unroll_all_loops ? UAP_UNROLL_ALL : 0)); - -#ifdef HAVE_doloop_end - if (flag_branch_on_count_reg && HAVE_doloop_end) - doloop_optimize_loops (loops); -#endif /* HAVE_doloop_end */ - - loop_optimizer_finalize (loops, dump_file); - } + if (current_loops) + loop_optimizer_finalize (current_loops, dump_file); free_dominance_info (CDI_DOMINATORS); @@ -184,13 +209,15 @@ rest_of_handle_loop2 (void) reg_scan (get_insns (), max_reg_num ()); if (dump_file) dump_flow_info (dump_file); + + current_loops = NULL; } -struct tree_opt_pass pass_loop2 = +struct tree_opt_pass pass_rtl_loop_done = { - "loop2", /* name */ - gate_handle_loop2, /* gate */ - rest_of_handle_loop2, /* execute */ + "loopdone", /* name */ + NULL, /* gate */ + rtl_loop_done, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ @@ -199,8 +226,126 @@ struct tree_opt_pass pass_loop2 = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | - TODO_ggc_collect, /* todo_flags_finish */ + TODO_dump_func, /* todo_flags_finish */ + 'L' /* letter */ +}; + + +/* Loop invariant code motion. */ +static void +rtl_move_loop_invariants (void) +{ + if (current_loops && flag_move_loop_invariants) + move_loop_invariants (current_loops); +} + +struct tree_opt_pass pass_rtl_move_loop_invariants = +{ + "loop_invariant", /* name */ + NULL, /* gate */ + rtl_move_loop_invariants, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_LOOP, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 'L' /* letter */ +}; + + +/* Loop unswitching for RTL. */ +static void +rtl_unswitch (void) +{ + if (current_loops && flag_unswitch_loops) + unswitch_loops (current_loops); +} + +struct tree_opt_pass pass_rtl_unswitch = +{ + "loop_unswitch", /* name */ + NULL, /* gate */ + rtl_unswitch, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_LOOP, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 'L' /* letter */ +}; + + +/* Loop unswitching for RTL. */ +static void +rtl_unroll_and_peel_loops (void) +{ + if (current_loops + && (flag_peel_loops || flag_unroll_loops || flag_unroll_all_loops)) + { + int flags = 0; + + if (flag_peel_loops) + flags |= UAP_PEEL; + if (flag_unroll_loops) + flags |= UAP_UNROLL; + if (flag_unroll_all_loops) + flags |= UAP_UNROLL_ALL; + + unroll_and_peel_loops (current_loops, flags); + } +} + +struct tree_opt_pass pass_rtl_unroll_and_peel_loops = +{ + "loop_unroll", /* name */ + NULL, /* gate */ + rtl_unroll_and_peel_loops, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_LOOP, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 'L' /* letter */ +}; + + +/* The doloop optimization. */ +static void +rtl_doloop (void) +{ +#ifdef HAVE_doloop_end + if (current_loops + && (flag_branch_on_count_reg && HAVE_doloop_end)) + doloop_optimize_loops (current_loops); +#endif +} + +struct tree_opt_pass pass_rtl_doloop = +{ + "loop_doloop", /* name */ + NULL, /* gate */ + rtl_doloop, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_LOOP, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ 'L' /* letter */ }; diff --git a/gcc/passes.c b/gcc/passes.c index edc75f1e672a..efe3e5b94217 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -525,7 +525,7 @@ init_optimization_passes (void) NEXT_PASS (pass_reassoc); NEXT_PASS (pass_pre); NEXT_PASS (pass_sink_code); - NEXT_PASS (pass_loop); + NEXT_PASS (pass_tree_loop); NEXT_PASS (pass_dominator); NEXT_PASS (pass_copy_prop); NEXT_PASS (pass_cd_dce); @@ -553,11 +553,11 @@ init_optimization_passes (void) NEXT_PASS (pass_cleanup_cfg_post_optimizing); *p = NULL; - p = &pass_loop.sub; - NEXT_PASS (pass_loop_init); + p = &pass_tree_loop.sub; + NEXT_PASS (pass_tree_loop_init); NEXT_PASS (pass_copy_prop); NEXT_PASS (pass_lim); - NEXT_PASS (pass_unswitch); + NEXT_PASS (pass_tree_unswitch); NEXT_PASS (pass_scev_cprop); NEXT_PASS (pass_empty_loop); NEXT_PASS (pass_record_bounds); @@ -571,9 +571,18 @@ init_optimization_passes (void) NEXT_PASS (pass_lower_vector_ssa); NEXT_PASS (pass_complete_unroll); NEXT_PASS (pass_iv_optimize); - NEXT_PASS (pass_loop_done); + NEXT_PASS (pass_tree_loop_done); *p = NULL; + p = &pass_loop2.sub; + NEXT_PASS (pass_rtl_loop_init); + NEXT_PASS (pass_rtl_move_loop_invariants); + NEXT_PASS (pass_rtl_unswitch); + NEXT_PASS (pass_rtl_unroll_and_peel_loops); + NEXT_PASS (pass_rtl_doloop); + NEXT_PASS (pass_rtl_loop_done); + *p = NULL; + p = &pass_rest_of_compilation.sub; NEXT_PASS (pass_remove_unnecessary_notes); NEXT_PASS (pass_init_function); @@ -592,6 +601,9 @@ init_optimization_passes (void) NEXT_PASS (pass_profiling); NEXT_PASS (pass_rtl_ifcvt); NEXT_PASS (pass_tracer); + /* Perform loop optimizations. It might be better to do them a bit + sooner, but we want the profile feedback to work more + efficiently. */ NEXT_PASS (pass_loop2); NEXT_PASS (pass_web); NEXT_PASS (pass_cse2); diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 7db3751952fa..e5056377f924 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -222,10 +222,10 @@ extern struct tree_opt_pass pass_referenced_vars; extern struct tree_opt_pass pass_sra; extern struct tree_opt_pass pass_tail_recursion; extern struct tree_opt_pass pass_tail_calls; -extern struct tree_opt_pass pass_loop; -extern struct tree_opt_pass pass_loop_init; +extern struct tree_opt_pass pass_tree_loop; +extern struct tree_opt_pass pass_tree_loop_init; extern struct tree_opt_pass pass_lim; -extern struct tree_opt_pass pass_unswitch; +extern struct tree_opt_pass pass_tree_unswitch; extern struct tree_opt_pass pass_iv_canon; extern struct tree_opt_pass pass_scev_cprop; extern struct tree_opt_pass pass_empty_loop; @@ -234,7 +234,7 @@ extern struct tree_opt_pass pass_if_conversion; extern struct tree_opt_pass pass_vectorize; extern struct tree_opt_pass pass_complete_unroll; extern struct tree_opt_pass pass_iv_optimize; -extern struct tree_opt_pass pass_loop_done; +extern struct tree_opt_pass pass_tree_loop_done; extern struct tree_opt_pass pass_ch; extern struct tree_opt_pass pass_ccp; extern struct tree_opt_pass pass_build_ssa; @@ -316,7 +316,15 @@ extern struct tree_opt_pass pass_cfg; extern struct tree_opt_pass pass_profiling; extern struct tree_opt_pass pass_rtl_ifcvt; extern struct tree_opt_pass pass_tracer; + extern struct tree_opt_pass pass_loop2; +extern struct tree_opt_pass pass_rtl_loop_init; +extern struct tree_opt_pass pass_rtl_move_loop_invariants; +extern struct tree_opt_pass pass_rtl_unswitch; +extern struct tree_opt_pass pass_rtl_unroll_and_peel_loops; +extern struct tree_opt_pass pass_rtl_doloop; +extern struct tree_opt_pass pass_rtl_loop_done; + extern struct tree_opt_pass pass_web; extern struct tree_opt_pass pass_cse2; extern struct tree_opt_pass pass_life; diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c index 1e7d73b8885a..abfcf15bc763 100644 --- a/gcc/tree-ssa-loop.c +++ b/gcc/tree-ssa-loop.c @@ -61,15 +61,15 @@ tree_loop_optimizer_init (FILE *dump) /* The loop superpass. */ static bool -gate_loop (void) +gate_tree_loop (void) { return flag_tree_loop_optimize != 0; } -struct tree_opt_pass pass_loop = +struct tree_opt_pass pass_tree_loop = { "loop", /* name */ - gate_loop, /* gate */ + gate_tree_loop, /* gate */ NULL, /* execute */ NULL, /* sub */ NULL, /* next */ @@ -98,7 +98,7 @@ tree_ssa_loop_init (void) scev_initialize (current_loops); } -struct tree_opt_pass pass_loop_init = +struct tree_opt_pass pass_tree_loop_init = { "loopinit", /* name */ NULL, /* gate */ @@ -166,7 +166,7 @@ gate_tree_ssa_loop_unswitch (void) return flag_unswitch_loops != 0; } -struct tree_opt_pass pass_unswitch = +struct tree_opt_pass pass_tree_unswitch = { "unswitch", /* name */ gate_tree_ssa_loop_unswitch, /* gate */ @@ -454,7 +454,7 @@ tree_ssa_loop_done (void) current_loops = NULL; } -struct tree_opt_pass pass_loop_done = +struct tree_opt_pass pass_tree_loop_done = { "loopdone", /* name */ NULL, /* gate */