diff options
Diffstat (limited to 'gcc/loop-init.c')
-rw-r--r-- | gcc/loop-init.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/gcc/loop-init.c b/gcc/loop-init.c index 4702789..375b2bf 100644 --- a/gcc/loop-init.c +++ b/gcc/loop-init.c @@ -28,6 +28,9 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "basic-block.h" #include "cfgloop.h" #include "cfglayout.h" +#include "tree-pass.h" +#include "timevar.h" +#include "flags.h" /* Initialize loop optimizer. */ @@ -116,3 +119,88 @@ loop_optimizer_finalize (struct loops *loops, FILE *dumpfile) verify_flow_info (); #endif } + +static bool +gate_handle_loop2 (void) +{ + return (optimize > 0 && flag_loop_optimize2 + && (flag_move_loop_invariants + || flag_unswitch_loops + || flag_peel_loops + || flag_unroll_loops + || 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 loops *loops; + basic_block bb; + + if (dump_file) + dump_flow_info (dump_file); + + /* Initialize structures for layout changes. */ + cfg_layout_initialize (0); + + loops = loop_optimizer_init (dump_file); + + if (loops) + { + /* The optimizations: */ + if (flag_move_loop_invariants) + move_loop_invariants (loops); + + if (flag_unswitch_loops) + unswitch_loops (loops); + + 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); + } + + free_dominance_info (CDI_DOMINATORS); + + /* Finalize layout changes. */ + FOR_EACH_BB (bb) + if (bb->next_bb != EXIT_BLOCK_PTR) + bb->aux = bb->next_bb; + cfg_layout_finalize (); + + cleanup_cfg (CLEANUP_EXPENSIVE); + delete_trivially_dead_insns (get_insns (), max_reg_num ()); + reg_scan (get_insns (), max_reg_num ()); + if (dump_file) + dump_flow_info (dump_file); +} + +struct tree_opt_pass pass_loop2 = +{ + "loop2", /* name */ + gate_handle_loop2, /* gate */ + rest_of_handle_loop2, /* 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 */ +}; + |