diff options
Diffstat (limited to 'gcc/loop-init.c')
-rw-r--r-- | gcc/loop-init.c | 247 |
1 files changed, 109 insertions, 138 deletions
diff --git a/gcc/loop-init.c b/gcc/loop-init.c index 2c2c269b83a..90453f67eca 100644 --- a/gcc/loop-init.c +++ b/gcc/loop-init.c @@ -287,31 +287,8 @@ fix_loop_structure (bitmap changed_bbs) return number_of_loops (cfun) - old_nloops; } -/* Gate for the RTL loop superpass. The actual passes are subpasses. - See passes.c for more on that. */ - -static bool -gate_handle_loop2 (void) -{ - if (optimize > 0 - && (flag_move_loop_invariants - || flag_unswitch_loops - || flag_peel_loops - || flag_unroll_loops -#ifdef HAVE_doloop_end - || (flag_branch_on_count_reg && HAVE_doloop_end) -#endif - )) - return true; - else - { - /* No longer preserve loops, remove them now. */ - cfun->curr_properties &= ~PROP_loops; - if (current_loops) - loop_optimizer_finalize (); - return false; - } -} +/* The RTL loop superpass. The actual passes are subpasses. See passes.c for + more on that. */ namespace { @@ -320,7 +297,6 @@ const pass_data pass_data_loop2 = RTL_PASS, /* type */ "loop2", /* name */ OPTGROUP_LOOP, /* optinfo_flags */ - true, /* has_gate */ false, /* has_execute */ TV_LOOP, /* tv_id */ 0, /* properties_required */ @@ -338,10 +314,33 @@ public: {} /* opt_pass methods: */ - bool gate () { return gate_handle_loop2 (); } + virtual bool gate (function *); }; // class pass_loop2 +bool +pass_loop2::gate (function *fun) +{ + if (optimize > 0 + && (flag_move_loop_invariants + || flag_unswitch_loops + || flag_peel_loops + || flag_unroll_loops +#ifdef HAVE_doloop_end + || (flag_branch_on_count_reg && HAVE_doloop_end) +#endif + )) + return true; + else + { + /* No longer preserve loops, remove them now. */ + fun->curr_properties &= ~PROP_loops; + if (current_loops) + loop_optimizer_finalize (); + return false; + } +} + } // anon namespace rtl_opt_pass * @@ -374,7 +373,6 @@ const pass_data pass_data_rtl_loop_init = RTL_PASS, /* type */ "loop2_init", /* name */ OPTGROUP_LOOP, /* optinfo_flags */ - false, /* has_gate */ true, /* has_execute */ TV_LOOP, /* tv_id */ 0, /* properties_required */ @@ -392,7 +390,7 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return rtl_loop_init (); } + virtual unsigned int execute (function *) { return rtl_loop_init (); } }; // class pass_rtl_loop_init @@ -407,24 +405,6 @@ make_pass_rtl_loop_init (gcc::context *ctxt) /* Finalization of the RTL loop passes. */ -static unsigned int -rtl_loop_done (void) -{ - /* No longer preserve loops, remove them now. */ - cfun->curr_properties &= ~PROP_loops; - loop_optimizer_finalize (); - free_dominance_info (CDI_DOMINATORS); - - cleanup_cfg (0); - if (dump_file) - { - dump_reg_info (dump_file); - dump_flow_info (dump_file, dump_flags); - } - - return 0; -} - namespace { const pass_data pass_data_rtl_loop_done = @@ -432,7 +412,6 @@ const pass_data pass_data_rtl_loop_done = RTL_PASS, /* type */ "loop2_done", /* name */ OPTGROUP_LOOP, /* optinfo_flags */ - false, /* has_gate */ true, /* has_execute */ TV_LOOP, /* tv_id */ 0, /* properties_required */ @@ -450,10 +429,28 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return rtl_loop_done (); } + virtual unsigned int execute (function *); }; // class pass_rtl_loop_done +unsigned int +pass_rtl_loop_done::execute (function *fun) +{ + /* No longer preserve loops, remove them now. */ + fun->curr_properties &= ~PROP_loops; + loop_optimizer_finalize (); + free_dominance_info (CDI_DOMINATORS); + + cleanup_cfg (0); + if (dump_file) + { + dump_reg_info (dump_file); + dump_flow_info (dump_file, dump_flags); + } + + return 0; +} + } // anon namespace rtl_opt_pass * @@ -464,19 +461,6 @@ make_pass_rtl_loop_done (gcc::context *ctxt) /* Loop invariant code motion. */ -static bool -gate_rtl_move_loop_invariants (void) -{ - return flag_move_loop_invariants; -} - -static unsigned int -rtl_move_loop_invariants (void) -{ - if (number_of_loops (cfun) > 1) - move_loop_invariants (); - return 0; -} namespace { @@ -485,7 +469,6 @@ const pass_data pass_data_rtl_move_loop_invariants = RTL_PASS, /* type */ "loop2_invariant", /* name */ OPTGROUP_LOOP, /* optinfo_flags */ - true, /* has_gate */ true, /* has_execute */ TV_LOOP_MOVE_INVARIANTS, /* tv_id */ 0, /* properties_required */ @@ -504,8 +487,13 @@ public: {} /* opt_pass methods: */ - bool gate () { return gate_rtl_move_loop_invariants (); } - unsigned int execute () { return rtl_move_loop_invariants (); } + virtual bool gate (function *) { return flag_move_loop_invariants; } + virtual unsigned int execute (function *fun) + { + if (number_of_loops (fun) > 1) + move_loop_invariants (); + return 0; + } }; // class pass_rtl_move_loop_invariants @@ -518,21 +506,6 @@ make_pass_rtl_move_loop_invariants (gcc::context *ctxt) } -/* Loop unswitching for RTL. */ -static bool -gate_rtl_unswitch (void) -{ - return flag_unswitch_loops; -} - -static unsigned int -rtl_unswitch (void) -{ - if (number_of_loops (cfun) > 1) - unswitch_loops (); - return 0; -} - namespace { const pass_data pass_data_rtl_unswitch = @@ -540,7 +513,6 @@ const pass_data pass_data_rtl_unswitch = RTL_PASS, /* type */ "loop2_unswitch", /* name */ OPTGROUP_LOOP, /* optinfo_flags */ - true, /* has_gate */ true, /* has_execute */ TV_LOOP_UNSWITCH, /* tv_id */ 0, /* properties_required */ @@ -558,8 +530,13 @@ public: {} /* opt_pass methods: */ - bool gate () { return gate_rtl_unswitch (); } - unsigned int execute () { return rtl_unswitch (); } + virtual bool gate (function *) { return flag_unswitch_loops; } + virtual unsigned int execute (function *fun) + { + if (number_of_loops (fun) > 1) + unswitch_loops (); + return 0; + } }; // class pass_rtl_unswitch @@ -572,34 +549,6 @@ make_pass_rtl_unswitch (gcc::context *ctxt) } -/* Loop unswitching for RTL. */ -static bool -gate_rtl_unroll_and_peel_loops (void) -{ - return (flag_peel_loops || flag_unroll_loops || flag_unroll_all_loops); -} - -static unsigned int -rtl_unroll_and_peel_loops (void) -{ - if (number_of_loops (cfun) > 1) - { - int flags = 0; - if (dump_file) - df_dump (dump_file); - - 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 (flags); - } - return 0; -} - namespace { const pass_data pass_data_rtl_unroll_and_peel_loops = @@ -607,7 +556,6 @@ const pass_data pass_data_rtl_unroll_and_peel_loops = RTL_PASS, /* type */ "loop2_unroll", /* name */ OPTGROUP_LOOP, /* optinfo_flags */ - true, /* has_gate */ true, /* has_execute */ TV_LOOP_UNROLL, /* tv_id */ 0, /* properties_required */ @@ -625,11 +573,36 @@ public: {} /* opt_pass methods: */ - bool gate () { return gate_rtl_unroll_and_peel_loops (); } - unsigned int execute () { return rtl_unroll_and_peel_loops (); } + virtual bool gate (function *) + { + return (flag_peel_loops || flag_unroll_loops || flag_unroll_all_loops); + } + + virtual unsigned int execute (function *); }; // class pass_rtl_unroll_and_peel_loops +unsigned int +pass_rtl_unroll_and_peel_loops::execute (function *fun) +{ + if (number_of_loops (fun) > 1) + { + int flags = 0; + if (dump_file) + df_dump (dump_file); + + 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 (flags); + } + return 0; +} + } // anon namespace rtl_opt_pass * @@ -639,27 +612,6 @@ make_pass_rtl_unroll_and_peel_loops (gcc::context *ctxt) } -/* The doloop optimization. */ -static bool -gate_rtl_doloop (void) -{ -#ifdef HAVE_doloop_end - return (flag_branch_on_count_reg && HAVE_doloop_end); -#else - return 0; -#endif -} - -static unsigned int -rtl_doloop (void) -{ -#ifdef HAVE_doloop_end - if (number_of_loops (cfun) > 1) - doloop_optimize_loops (); -#endif - return 0; -} - namespace { const pass_data pass_data_rtl_doloop = @@ -667,7 +619,6 @@ const pass_data pass_data_rtl_doloop = RTL_PASS, /* type */ "loop2_doloop", /* name */ OPTGROUP_LOOP, /* optinfo_flags */ - true, /* has_gate */ true, /* has_execute */ TV_LOOP_DOLOOP, /* tv_id */ 0, /* properties_required */ @@ -685,11 +636,31 @@ public: {} /* opt_pass methods: */ - bool gate () { return gate_rtl_doloop (); } - unsigned int execute () { return rtl_doloop (); } + virtual bool gate (function *); + virtual unsigned int execute (function *); }; // class pass_rtl_doloop +bool +pass_rtl_doloop::gate (function *) +{ +#ifdef HAVE_doloop_end + return (flag_branch_on_count_reg && HAVE_doloop_end); +#else + return false; +#endif +} + +unsigned int +pass_rtl_doloop::execute (function *fun ATTRIBUTE_UNUSED) +{ +#ifdef HAVE_doloop_end + if (number_of_loops (fun) > 1) + doloop_optimize_loops (); +#endif + return 0; +} + } // anon namespace rtl_opt_pass * |