alpha.c (alpha_gimplify_va_arg_1): Use build_va_arg_indirect_ref.
[official-gcc.git] / gcc / loop-init.c
blob375b2bf23a5e310b13a31a400e5a0e8455909e18
1 /* Loop optimizer initialization routines.
2 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "rtl.h"
26 #include "hard-reg-set.h"
27 #include "obstack.h"
28 #include "basic-block.h"
29 #include "cfgloop.h"
30 #include "cfglayout.h"
31 #include "tree-pass.h"
32 #include "timevar.h"
33 #include "flags.h"
35 /* Initialize loop optimizer. */
37 struct loops *
38 loop_optimizer_init (FILE *dumpfile)
40 struct loops *loops = xcalloc (1, sizeof (struct loops));
41 edge e;
42 edge_iterator ei;
43 static bool first_time = true;
45 if (first_time)
47 first_time = false;
48 init_set_costs ();
51 /* Avoid annoying special cases of edges going to exit
52 block. */
54 for (ei = ei_start (EXIT_BLOCK_PTR->preds); (e = ei_safe_edge (ei)); )
55 if ((e->flags & EDGE_FALLTHRU) && !single_succ_p (e->src))
56 split_edge (e);
57 else
58 ei_next (&ei);
60 /* Find the loops. */
62 if (flow_loops_find (loops) <= 1)
64 /* No loops. */
65 flow_loops_free (loops);
66 free (loops);
68 return NULL;
71 /* Not going to update these. */
72 free (loops->cfg.rc_order);
73 loops->cfg.rc_order = NULL;
74 free (loops->cfg.dfs_order);
75 loops->cfg.dfs_order = NULL;
77 /* Create pre-headers. */
78 create_preheaders (loops, CP_SIMPLE_PREHEADERS);
80 /* Force all latches to have only single successor. */
81 force_single_succ_latches (loops);
83 /* Mark irreducible loops. */
84 mark_irreducible_loops (loops);
86 /* Dump loops. */
87 flow_loops_dump (loops, dumpfile, NULL, 1);
89 #ifdef ENABLE_CHECKING
90 verify_dominators (CDI_DOMINATORS);
91 verify_loop_structure (loops);
92 #endif
94 return loops;
97 /* Finalize loop optimizer. */
98 void
99 loop_optimizer_finalize (struct loops *loops, FILE *dumpfile)
101 unsigned i;
103 if (!loops)
104 return;
106 for (i = 1; i < loops->num; i++)
107 if (loops->parray[i])
108 free_simple_loop_desc (loops->parray[i]);
110 /* Another dump. */
111 flow_loops_dump (loops, dumpfile, NULL, 1);
113 /* Clean up. */
114 flow_loops_free (loops);
115 free (loops);
117 /* Checking. */
118 #ifdef ENABLE_CHECKING
119 verify_flow_info ();
120 #endif
123 static bool
124 gate_handle_loop2 (void)
126 return (optimize > 0 && flag_loop_optimize2
127 && (flag_move_loop_invariants
128 || flag_unswitch_loops
129 || flag_peel_loops
130 || flag_unroll_loops
131 || flag_branch_on_count_reg));
134 /* Perform loop optimizations. It might be better to do them a bit
135 sooner, but we want the profile feedback to work more
136 efficiently. */
137 static void
138 rest_of_handle_loop2 (void)
140 struct loops *loops;
141 basic_block bb;
143 if (dump_file)
144 dump_flow_info (dump_file);
146 /* Initialize structures for layout changes. */
147 cfg_layout_initialize (0);
149 loops = loop_optimizer_init (dump_file);
151 if (loops)
153 /* The optimizations: */
154 if (flag_move_loop_invariants)
155 move_loop_invariants (loops);
157 if (flag_unswitch_loops)
158 unswitch_loops (loops);
160 if (flag_peel_loops || flag_unroll_loops)
161 unroll_and_peel_loops (loops,
162 (flag_peel_loops ? UAP_PEEL : 0) |
163 (flag_unroll_loops ? UAP_UNROLL : 0) |
164 (flag_unroll_all_loops ? UAP_UNROLL_ALL : 0));
166 #ifdef HAVE_doloop_end
167 if (flag_branch_on_count_reg && HAVE_doloop_end)
168 doloop_optimize_loops (loops);
169 #endif /* HAVE_doloop_end */
171 loop_optimizer_finalize (loops, dump_file);
174 free_dominance_info (CDI_DOMINATORS);
176 /* Finalize layout changes. */
177 FOR_EACH_BB (bb)
178 if (bb->next_bb != EXIT_BLOCK_PTR)
179 bb->aux = bb->next_bb;
180 cfg_layout_finalize ();
182 cleanup_cfg (CLEANUP_EXPENSIVE);
183 delete_trivially_dead_insns (get_insns (), max_reg_num ());
184 reg_scan (get_insns (), max_reg_num ());
185 if (dump_file)
186 dump_flow_info (dump_file);
189 struct tree_opt_pass pass_loop2 =
191 "loop2", /* name */
192 gate_handle_loop2, /* gate */
193 rest_of_handle_loop2, /* execute */
194 NULL, /* sub */
195 NULL, /* next */
196 0, /* static_pass_number */
197 TV_LOOP, /* tv_id */
198 0, /* properties_required */
199 0, /* properties_provided */
200 0, /* properties_destroyed */
201 0, /* todo_flags_start */
202 TODO_dump_func |
203 TODO_ggc_collect, /* todo_flags_finish */
204 'L' /* letter */