X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Floop-init.c;h=9184a148c40aa721a507381bcf1a08aba3ee62d7;hb=be7e6d8e385789443cc5fa56379fcb60d34c8076;hp=3e6d3428b897cb2c4c06f5631c443444113722a3;hpb=4a6f9e197c022b9b9efb396b6f13a2c2dbc2234f;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/loop-init.c b/gcc/loop-init.c index 3e6d3428b89..9184a148c40 100644 --- a/gcc/loop-init.c +++ b/gcc/loop-init.c @@ -1,11 +1,12 @@ /* Loop optimizer initialization routines and RTL loop optimization passes. - Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 + Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later +Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY @@ -14,9 +15,8 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. */ +along with GCC; see the file COPYING3. If not see +. */ #include "config.h" #include "system.h" @@ -31,6 +31,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "tree-pass.h" #include "timevar.h" #include "flags.h" +#include "df.h" +#include "ggc.h" /* Initialize loop structures. This is used by the tree and RTL loop @@ -43,21 +45,13 @@ loop_optimizer_init (unsigned flags) struct loops *loops; gcc_assert (!current_loops); - loops = XCNEW (struct loops); + loops = ggc_alloc_cleared_loops (); /* Find the loops. */ flow_loops_find (loops); current_loops = loops; - if (number_of_loops () <= 1) - { - /* No loops (the 1 returned by number_of_loops corresponds to the fake - loop that we put as a root of the loop tree). */ - loop_optimizer_finalize (); - return; - } - if (flags & LOOPS_MAY_HAVE_MULTIPLE_LATCHES) { /* If the loops may have multiple latches, we cannot canonicalize @@ -66,14 +60,21 @@ loop_optimizer_init (unsigned flags) passes may want. */ gcc_assert ((flags & ~(LOOPS_MAY_HAVE_MULTIPLE_LATCHES | LOOPS_HAVE_RECORDED_EXITS)) == 0); - current_loops->state = LOOPS_MAY_HAVE_MULTIPLE_LATCHES; + loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES); } else disambiguate_loops_with_multiple_latches (); /* Create pre-headers. */ if (flags & LOOPS_HAVE_PREHEADERS) - create_preheaders (CP_SIMPLE_PREHEADERS); + { + int cp_flags = CP_SIMPLE_PREHEADERS; + + if (flags & LOOPS_HAVE_FALLTHRU_PREHEADERS) + cp_flags |= CP_FALLTHRU_PREHEADERS; + + create_preheaders (cp_flags); + } /* Force all latches to have only single successor. */ if (flags & LOOPS_HAVE_SIMPLE_LATCHES) @@ -104,8 +105,7 @@ loop_optimizer_finalize (void) struct loop *loop; basic_block bb; - if (!current_loops) - return; + gcc_assert (current_loops != NULL); FOR_EACH_LOOP (li, loop, 0) { @@ -113,21 +113,16 @@ loop_optimizer_finalize (void) } /* Clean up. */ - if (current_loops->state & LOOPS_HAVE_RECORDED_EXITS) + if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS)) release_recorded_exits (); flow_loops_free (current_loops); - free (current_loops); + ggc_free (current_loops); current_loops = NULL; FOR_ALL_BB (bb) { bb->loop_father = NULL; } - - /* Checking. */ -#ifdef ENABLE_CHECKING - verify_flow_info (); -#endif } @@ -148,8 +143,10 @@ gate_handle_loop2 (void) )); } -struct tree_opt_pass pass_loop2 = +struct rtl_opt_pass pass_loop2 = { + { + RTL_PASS, "loop2", /* name */ gate_handle_loop2, /* gate */ NULL, /* execute */ @@ -161,9 +158,8 @@ 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 */ - 'L' /* letter */ + TODO_ggc_collect /* todo_flags_finish */ + } }; @@ -171,18 +167,19 @@ struct tree_opt_pass pass_loop2 = static unsigned int rtl_loop_init (void) { + gcc_assert (current_ir_type () == IR_RTL_CFGLAYOUT); + if (dump_file) dump_flow_info (dump_file, dump_flags); - /* Initialize structures for layout changes. */ - cfg_layout_initialize (0); - loop_optimizer_init (LOOPS_NORMAL); return 0; } -struct tree_opt_pass pass_rtl_loop_init = +struct rtl_opt_pass pass_rtl_loop_init = { + { + RTL_PASS, "loop2_init", /* name */ NULL, /* gate */ rtl_loop_init, /* execute */ @@ -194,8 +191,8 @@ struct tree_opt_pass pass_rtl_loop_init = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func, /* todo_flags_finish */ - 'L' /* letter */ + TODO_verify_rtl_sharing /* todo_flags_finish */ + } }; @@ -204,28 +201,20 @@ struct tree_opt_pass pass_rtl_loop_init = static unsigned int rtl_loop_done (void) { - basic_block bb; - loop_optimizer_finalize (); 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 ()); + cleanup_cfg (0); if (dump_file) dump_flow_info (dump_file, dump_flags); return 0; } -struct tree_opt_pass pass_rtl_loop_done = +struct rtl_opt_pass pass_rtl_loop_done = { + { + RTL_PASS, "loop2_done", /* name */ NULL, /* gate */ rtl_loop_done, /* execute */ @@ -237,8 +226,9 @@ struct tree_opt_pass pass_rtl_loop_done = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func, /* todo_flags_finish */ - 'L' /* letter */ + TODO_verify_flow + | TODO_verify_rtl_sharing /* todo_flags_finish */ + } }; @@ -252,26 +242,29 @@ gate_rtl_move_loop_invariants (void) static unsigned int rtl_move_loop_invariants (void) { - if (current_loops) + if (number_of_loops () > 1) move_loop_invariants (); return 0; } -struct tree_opt_pass pass_rtl_move_loop_invariants = +struct rtl_opt_pass pass_rtl_move_loop_invariants = { - "loop2_invariant", /* name */ + { + RTL_PASS, + "loop2_invariant", /* name */ gate_rtl_move_loop_invariants, /* gate */ rtl_move_loop_invariants, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ - TV_LOOP, /* tv_id */ + TV_LOOP_MOVE_INVARIANTS, /* tv_id */ 0, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func, /* todo_flags_finish */ - 'L' /* letter */ + TODO_df_verify | + TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */ + } }; @@ -285,26 +278,28 @@ gate_rtl_unswitch (void) static unsigned int rtl_unswitch (void) { - if (current_loops) + if (number_of_loops () > 1) unswitch_loops (); return 0; } -struct tree_opt_pass pass_rtl_unswitch = +struct rtl_opt_pass pass_rtl_unswitch = { + { + RTL_PASS, "loop2_unswitch", /* name */ gate_rtl_unswitch, /* gate */ rtl_unswitch, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ - TV_LOOP, /* tv_id */ + TV_LOOP_UNSWITCH, /* tv_id */ 0, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func, /* todo_flags_finish */ - 'L' /* letter */ + TODO_verify_rtl_sharing, /* todo_flags_finish */ + } }; @@ -318,9 +313,11 @@ gate_rtl_unroll_and_peel_loops (void) static unsigned int rtl_unroll_and_peel_loops (void) { - if (current_loops) + if (number_of_loops () > 1) { int flags = 0; + if (dump_file) + df_dump (dump_file); if (flag_peel_loops) flags |= UAP_PEEL; @@ -334,21 +331,23 @@ rtl_unroll_and_peel_loops (void) return 0; } -struct tree_opt_pass pass_rtl_unroll_and_peel_loops = +struct rtl_opt_pass pass_rtl_unroll_and_peel_loops = { + { + RTL_PASS, "loop2_unroll", /* name */ gate_rtl_unroll_and_peel_loops, /* gate */ rtl_unroll_and_peel_loops, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ - TV_LOOP, /* tv_id */ + TV_LOOP_UNROLL, /* tv_id */ 0, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func, /* todo_flags_finish */ - 'L' /* letter */ + TODO_verify_rtl_sharing, /* todo_flags_finish */ + } }; @@ -367,26 +366,27 @@ static unsigned int rtl_doloop (void) { #ifdef HAVE_doloop_end - if (current_loops) + if (number_of_loops () > 1) doloop_optimize_loops (); #endif return 0; } -struct tree_opt_pass pass_rtl_doloop = +struct rtl_opt_pass pass_rtl_doloop = { + { + RTL_PASS, "loop2_doloop", /* name */ gate_rtl_doloop, /* gate */ rtl_doloop, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ - TV_LOOP, /* tv_id */ + TV_LOOP_DOLOOP, /* tv_id */ 0, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func, /* todo_flags_finish */ - 'L' /* letter */ + TODO_verify_rtl_sharing /* todo_flags_finish */ + } }; -