2012-08-15 Janus Weil <janus@gcc.gnu.org>
[official-gcc.git] / gcc / loop-init.c
blob438c66e0400b95e12f79666dd3b633b68cac97b6
1 /* Loop optimizer initialization routines and RTL loop optimization passes.
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
3 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "rtl.h"
26 #include "regs.h"
27 #include "obstack.h"
28 #include "basic-block.h"
29 #include "cfgloop.h"
30 #include "tree-pass.h"
31 #include "flags.h"
32 #include "df.h"
33 #include "ggc.h"
36 /* Initialize loop structures. This is used by the tree and RTL loop
37 optimizers. FLAGS specify what properties to compute and/or ensure for
38 loops. */
40 void
41 loop_optimizer_init (unsigned flags)
43 timevar_push (TV_LOOP_INIT);
44 if (!current_loops)
46 struct loops *loops = ggc_alloc_cleared_loops ();
48 gcc_assert (!(cfun->curr_properties & PROP_loops));
50 /* Find the loops. */
52 flow_loops_find (loops);
53 current_loops = loops;
55 else
57 gcc_assert (cfun->curr_properties & PROP_loops);
59 /* Ensure that the dominators are computed, like flow_loops_find does. */
60 calculate_dominance_info (CDI_DOMINATORS);
62 #ifdef ENABLE_CHECKING
63 verify_loop_structure ();
64 #endif
67 if (flags & LOOPS_MAY_HAVE_MULTIPLE_LATCHES)
69 /* If the loops may have multiple latches, we cannot canonicalize
70 them further (and most of the loop manipulation functions will
71 not work). However, we avoid modifying cfg, which some
72 passes may want. */
73 gcc_assert ((flags & ~(LOOPS_MAY_HAVE_MULTIPLE_LATCHES
74 | LOOPS_HAVE_RECORDED_EXITS)) == 0);
75 loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
77 else
78 disambiguate_loops_with_multiple_latches ();
80 /* Create pre-headers. */
81 if (flags & LOOPS_HAVE_PREHEADERS)
83 int cp_flags = CP_SIMPLE_PREHEADERS;
85 if (flags & LOOPS_HAVE_FALLTHRU_PREHEADERS)
86 cp_flags |= CP_FALLTHRU_PREHEADERS;
88 create_preheaders (cp_flags);
91 /* Force all latches to have only single successor. */
92 if (flags & LOOPS_HAVE_SIMPLE_LATCHES)
93 force_single_succ_latches ();
95 /* Mark irreducible loops. */
96 if (flags & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
97 mark_irreducible_loops ();
99 if (flags & LOOPS_HAVE_RECORDED_EXITS)
100 record_loop_exits ();
102 /* Dump loops. */
103 flow_loops_dump (dump_file, NULL, 1);
105 #ifdef ENABLE_CHECKING
106 verify_loop_structure ();
107 #endif
109 timevar_pop (TV_LOOP_INIT);
112 /* Finalize loop structures. */
114 void
115 loop_optimizer_finalize (void)
117 loop_iterator li;
118 struct loop *loop;
119 basic_block bb;
121 timevar_push (TV_LOOP_FINI);
123 if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
124 release_recorded_exits ();
126 /* If we should preserve loop structure, do not free it but clear
127 flags that advanced properties are there as we are not preserving
128 that in full. */
129 if (cfun->curr_properties & PROP_loops)
131 loops_state_clear (LOOP_CLOSED_SSA
132 | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS
133 | LOOPS_HAVE_PREHEADERS
134 | LOOPS_HAVE_SIMPLE_LATCHES
135 | LOOPS_HAVE_FALLTHRU_PREHEADERS);
136 goto loop_fini_done;
139 gcc_assert (current_loops != NULL);
141 FOR_EACH_LOOP (li, loop, 0)
143 free_simple_loop_desc (loop);
146 /* Clean up. */
147 flow_loops_free (current_loops);
148 ggc_free (current_loops);
149 current_loops = NULL;
151 FOR_ALL_BB (bb)
153 bb->loop_father = NULL;
156 loop_fini_done:
157 timevar_pop (TV_LOOP_FINI);
161 /* Gate for the RTL loop superpass. The actual passes are subpasses.
162 See passes.c for more on that. */
164 static bool
165 gate_handle_loop2 (void)
167 if (optimize > 0
168 && (flag_move_loop_invariants
169 || flag_unswitch_loops
170 || flag_peel_loops
171 || flag_unroll_loops
172 #ifdef HAVE_doloop_end
173 || (flag_branch_on_count_reg && HAVE_doloop_end)
174 #endif
176 return true;
177 else
179 /* No longer preserve loops, remove them now. */
180 cfun->curr_properties &= ~PROP_loops;
181 if (current_loops)
182 loop_optimizer_finalize ();
183 return false;
187 struct rtl_opt_pass pass_loop2 =
190 RTL_PASS,
191 "loop2", /* name */
192 gate_handle_loop2, /* gate */
193 NULL, /* 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_ggc_collect /* todo_flags_finish */
207 /* Initialization of the RTL loop passes. */
208 static unsigned int
209 rtl_loop_init (void)
211 gcc_assert (current_ir_type () == IR_RTL_CFGLAYOUT);
213 if (dump_file)
215 dump_reg_info (dump_file);
216 dump_flow_info (dump_file, dump_flags);
219 loop_optimizer_init (LOOPS_NORMAL);
220 return 0;
223 struct rtl_opt_pass pass_rtl_loop_init =
226 RTL_PASS,
227 "loop2_init", /* name */
228 NULL, /* gate */
229 rtl_loop_init, /* execute */
230 NULL, /* sub */
231 NULL, /* next */
232 0, /* static_pass_number */
233 TV_LOOP, /* tv_id */
234 0, /* properties_required */
235 0, /* properties_provided */
236 0, /* properties_destroyed */
237 0, /* todo_flags_start */
238 TODO_verify_rtl_sharing /* todo_flags_finish */
243 /* Finalization of the RTL loop passes. */
245 static unsigned int
246 rtl_loop_done (void)
248 /* No longer preserve loops, remove them now. */
249 cfun->curr_properties &= ~PROP_loops;
250 loop_optimizer_finalize ();
251 free_dominance_info (CDI_DOMINATORS);
253 cleanup_cfg (0);
254 if (dump_file)
256 dump_reg_info (dump_file);
257 dump_flow_info (dump_file, dump_flags);
260 return 0;
263 struct rtl_opt_pass pass_rtl_loop_done =
266 RTL_PASS,
267 "loop2_done", /* name */
268 NULL, /* gate */
269 rtl_loop_done, /* execute */
270 NULL, /* sub */
271 NULL, /* next */
272 0, /* static_pass_number */
273 TV_LOOP, /* tv_id */
274 0, /* properties_required */
275 0, /* properties_provided */
276 PROP_loops, /* properties_destroyed */
277 0, /* todo_flags_start */
278 TODO_verify_flow
279 | TODO_verify_rtl_sharing /* todo_flags_finish */
284 /* Loop invariant code motion. */
285 static bool
286 gate_rtl_move_loop_invariants (void)
288 return flag_move_loop_invariants;
291 static unsigned int
292 rtl_move_loop_invariants (void)
294 if (number_of_loops () > 1)
295 move_loop_invariants ();
296 return 0;
299 struct rtl_opt_pass pass_rtl_move_loop_invariants =
302 RTL_PASS,
303 "loop2_invariant", /* name */
304 gate_rtl_move_loop_invariants, /* gate */
305 rtl_move_loop_invariants, /* execute */
306 NULL, /* sub */
307 NULL, /* next */
308 0, /* static_pass_number */
309 TV_LOOP_MOVE_INVARIANTS, /* tv_id */
310 0, /* properties_required */
311 0, /* properties_provided */
312 0, /* properties_destroyed */
313 0, /* todo_flags_start */
314 TODO_df_verify |
315 TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */
320 /* Loop unswitching for RTL. */
321 static bool
322 gate_rtl_unswitch (void)
324 return flag_unswitch_loops;
327 static unsigned int
328 rtl_unswitch (void)
330 if (number_of_loops () > 1)
331 unswitch_loops ();
332 return 0;
335 struct rtl_opt_pass pass_rtl_unswitch =
338 RTL_PASS,
339 "loop2_unswitch", /* name */
340 gate_rtl_unswitch, /* gate */
341 rtl_unswitch, /* execute */
342 NULL, /* sub */
343 NULL, /* next */
344 0, /* static_pass_number */
345 TV_LOOP_UNSWITCH, /* tv_id */
346 0, /* properties_required */
347 0, /* properties_provided */
348 0, /* properties_destroyed */
349 0, /* todo_flags_start */
350 TODO_verify_rtl_sharing, /* todo_flags_finish */
355 /* Loop unswitching for RTL. */
356 static bool
357 gate_rtl_unroll_and_peel_loops (void)
359 return (flag_peel_loops || flag_unroll_loops || flag_unroll_all_loops);
362 static unsigned int
363 rtl_unroll_and_peel_loops (void)
365 if (number_of_loops () > 1)
367 int flags = 0;
368 if (dump_file)
369 df_dump (dump_file);
371 if (flag_peel_loops)
372 flags |= UAP_PEEL;
373 if (flag_unroll_loops)
374 flags |= UAP_UNROLL;
375 if (flag_unroll_all_loops)
376 flags |= UAP_UNROLL_ALL;
378 unroll_and_peel_loops (flags);
380 return 0;
383 struct rtl_opt_pass pass_rtl_unroll_and_peel_loops =
386 RTL_PASS,
387 "loop2_unroll", /* name */
388 gate_rtl_unroll_and_peel_loops, /* gate */
389 rtl_unroll_and_peel_loops, /* execute */
390 NULL, /* sub */
391 NULL, /* next */
392 0, /* static_pass_number */
393 TV_LOOP_UNROLL, /* tv_id */
394 0, /* properties_required */
395 0, /* properties_provided */
396 0, /* properties_destroyed */
397 0, /* todo_flags_start */
398 TODO_verify_rtl_sharing, /* todo_flags_finish */
403 /* The doloop optimization. */
404 static bool
405 gate_rtl_doloop (void)
407 #ifdef HAVE_doloop_end
408 return (flag_branch_on_count_reg && HAVE_doloop_end);
409 #else
410 return 0;
411 #endif
414 static unsigned int
415 rtl_doloop (void)
417 #ifdef HAVE_doloop_end
418 if (number_of_loops () > 1)
419 doloop_optimize_loops ();
420 #endif
421 return 0;
424 struct rtl_opt_pass pass_rtl_doloop =
427 RTL_PASS,
428 "loop2_doloop", /* name */
429 gate_rtl_doloop, /* gate */
430 rtl_doloop, /* execute */
431 NULL, /* sub */
432 NULL, /* next */
433 0, /* static_pass_number */
434 TV_LOOP_DOLOOP, /* tv_id */
435 0, /* properties_required */
436 0, /* properties_provided */
437 0, /* properties_destroyed */
438 0, /* todo_flags_start */
439 TODO_verify_rtl_sharing /* todo_flags_finish */