1 /* Loop optimizer initialization routines and RTL loop optimization passes.
2 Copyright (C) 2002-2013 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 3, or (at your option) any later
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
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
28 #include "basic-block.h"
30 #include "tree-pass.h"
35 #include "tree-ssa-loop-niter.h"
38 /* Apply FLAGS to the loop state. */
41 apply_loop_flags (unsigned flags
)
43 if (flags
& LOOPS_MAY_HAVE_MULTIPLE_LATCHES
)
45 /* If the loops may have multiple latches, we cannot canonicalize
46 them further (and most of the loop manipulation functions will
47 not work). However, we avoid modifying cfg, which some
49 gcc_assert ((flags
& ~(LOOPS_MAY_HAVE_MULTIPLE_LATCHES
50 | LOOPS_HAVE_RECORDED_EXITS
)) == 0);
51 loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES
);
54 disambiguate_loops_with_multiple_latches ();
56 /* Create pre-headers. */
57 if (flags
& LOOPS_HAVE_PREHEADERS
)
59 int cp_flags
= CP_SIMPLE_PREHEADERS
;
61 if (flags
& LOOPS_HAVE_FALLTHRU_PREHEADERS
)
62 cp_flags
|= CP_FALLTHRU_PREHEADERS
;
64 create_preheaders (cp_flags
);
67 /* Force all latches to have only single successor. */
68 if (flags
& LOOPS_HAVE_SIMPLE_LATCHES
)
69 force_single_succ_latches ();
71 /* Mark irreducible loops. */
72 if (flags
& LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS
)
73 mark_irreducible_loops ();
75 if (flags
& LOOPS_HAVE_RECORDED_EXITS
)
79 /* Initialize loop structures. This is used by the tree and RTL loop
80 optimizers. FLAGS specify what properties to compute and/or ensure for
84 loop_optimizer_init (unsigned flags
)
86 timevar_push (TV_LOOP_INIT
);
90 gcc_assert (!(cfun
->curr_properties
& PROP_loops
));
93 current_loops
= flow_loops_find (NULL
);
97 bool recorded_exits
= loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS
);
99 gcc_assert (cfun
->curr_properties
& PROP_loops
);
101 /* Ensure that the dominators are computed, like flow_loops_find does. */
102 calculate_dominance_info (CDI_DOMINATORS
);
104 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP
))
106 loops_state_clear (~0U);
107 fix_loop_structure (NULL
);
110 #ifdef ENABLE_CHECKING
112 verify_loop_structure ();
115 /* Clear all flags. */
117 release_recorded_exits ();
118 loops_state_clear (~0U);
121 /* Apply flags to loops. */
122 apply_loop_flags (flags
);
125 flow_loops_dump (dump_file
, NULL
, 1);
127 #ifdef ENABLE_CHECKING
128 verify_loop_structure ();
131 timevar_pop (TV_LOOP_INIT
);
134 /* Finalize loop structures. */
137 loop_optimizer_finalize (void)
143 timevar_push (TV_LOOP_FINI
);
145 if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS
))
146 release_recorded_exits ();
148 free_numbers_of_iterations_estimates ();
150 /* If we should preserve loop structure, do not free it but clear
151 flags that advanced properties are there as we are not preserving
153 if (cfun
->curr_properties
& PROP_loops
)
155 loops_state_clear (LOOP_CLOSED_SSA
156 | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS
157 | LOOPS_HAVE_PREHEADERS
158 | LOOPS_HAVE_SIMPLE_LATCHES
159 | LOOPS_HAVE_FALLTHRU_PREHEADERS
);
160 loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES
);
164 gcc_assert (current_loops
!= NULL
);
166 FOR_EACH_LOOP (li
, loop
, 0)
168 free_simple_loop_desc (loop
);
172 flow_loops_free (current_loops
);
173 ggc_free (current_loops
);
174 current_loops
= NULL
;
178 bb
->loop_father
= NULL
;
182 timevar_pop (TV_LOOP_FINI
);
185 /* The structure of loops might have changed. Some loops might get removed
186 (and their headers and latches were set to NULL), loop exists might get
187 removed (thus the loop nesting may be wrong), and some blocks and edges
188 were changed (so the information about bb --> loop mapping does not have
189 to be correct). But still for the remaining loops the header dominates
190 the latch, and loops did not get new subloops (new loops might possibly
191 get created, but we are not interested in them). Fix up the mess.
193 If CHANGED_BBS is not NULL, basic blocks whose loop depth has changed are
196 Returns the number of new discovered loops. */
199 fix_loop_structure (bitmap changed_bbs
)
202 int record_exits
= 0;
205 unsigned old_nloops
, i
;
207 timevar_push (TV_LOOP_INIT
);
209 /* We need exact and fast dominance info to be available. */
210 gcc_assert (dom_info_state (CDI_DOMINATORS
) == DOM_OK
);
212 if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS
))
214 release_recorded_exits ();
215 record_exits
= LOOPS_HAVE_RECORDED_EXITS
;
218 /* Remember the depth of the blocks in the loop hierarchy, so that we can
219 recognize blocks whose loop nesting relationship has changed. */
222 bb
->aux
= (void *) (size_t) loop_depth (bb
->loop_father
);
224 /* Remove the dead loops from structures. We start from the innermost
225 loops, so that when we remove the loops, we know that the loops inside
226 are preserved, and do not waste time relinking loops that will be
228 FOR_EACH_LOOP (li
, loop
, LI_FROM_INNERMOST
)
230 /* Detect the case that the loop is no longer present even though
231 it wasn't marked for removal.
232 ??? If we do that we can get away with not marking loops for
233 removal at all. And possibly avoid some spurious removals. */
235 && bb_loop_header_p (loop
->header
))
238 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
239 fprintf (dump_file
, "fix_loop_structure: removing loop %d\n",
244 struct loop
*ploop
= loop
->inner
;
245 flow_loop_tree_node_remove (ploop
);
246 flow_loop_tree_node_add (loop_outer (loop
), ploop
);
249 /* Remove the loop. */
251 flow_loop_tree_node_remove (loop
);
254 /* Remember the number of loops so we can return how many new loops
255 flow_loops_find discovered. */
256 old_nloops
= number_of_loops (cfun
);
258 /* Re-compute loop structure in-place. */
259 flow_loops_find (current_loops
);
261 /* Mark the blocks whose loop has changed. */
266 if ((void *) (size_t) loop_depth (bb
->loop_father
) != bb
->aux
)
267 bitmap_set_bit (changed_bbs
, bb
->index
);
273 /* Finally free deleted loops. */
274 FOR_EACH_VEC_ELT (*get_loops (cfun
), i
, loop
)
275 if (loop
&& loop
->header
== NULL
)
277 (*get_loops (cfun
))[i
] = NULL
;
278 flow_loop_free (loop
);
281 loops_state_clear (LOOPS_NEED_FIXUP
);
283 /* Apply flags to loops. */
284 apply_loop_flags (current_loops
->state
| record_exits
);
286 #ifdef ENABLE_CHECKING
287 verify_loop_structure ();
290 timevar_pop (TV_LOOP_INIT
);
292 return number_of_loops (cfun
) - old_nloops
;
295 /* Gate for the RTL loop superpass. The actual passes are subpasses.
296 See passes.c for more on that. */
299 gate_handle_loop2 (void)
302 && (flag_move_loop_invariants
303 || flag_unswitch_loops
306 #ifdef HAVE_doloop_end
307 || (flag_branch_on_count_reg
&& HAVE_doloop_end
)
313 /* No longer preserve loops, remove them now. */
314 cfun
->curr_properties
&= ~PROP_loops
;
316 loop_optimizer_finalize ();
323 const pass_data pass_data_loop2
=
327 OPTGROUP_LOOP
, /* optinfo_flags */
329 false, /* has_execute */
331 0, /* properties_required */
332 0, /* properties_provided */
333 0, /* properties_destroyed */
334 0, /* todo_flags_start */
335 0, /* todo_flags_finish */
338 class pass_loop2
: public rtl_opt_pass
341 pass_loop2 (gcc::context
*ctxt
)
342 : rtl_opt_pass (pass_data_loop2
, ctxt
)
345 /* opt_pass methods: */
346 bool gate () { return gate_handle_loop2 (); }
348 }; // class pass_loop2
353 make_pass_loop2 (gcc::context
*ctxt
)
355 return new pass_loop2 (ctxt
);
359 /* Initialization of the RTL loop passes. */
363 gcc_assert (current_ir_type () == IR_RTL_CFGLAYOUT
);
367 dump_reg_info (dump_file
);
368 dump_flow_info (dump_file
, dump_flags
);
371 loop_optimizer_init (LOOPS_NORMAL
);
377 const pass_data pass_data_rtl_loop_init
=
380 "loop2_init", /* name */
381 OPTGROUP_LOOP
, /* optinfo_flags */
382 false, /* has_gate */
383 true, /* has_execute */
385 0, /* properties_required */
386 0, /* properties_provided */
387 0, /* properties_destroyed */
388 0, /* todo_flags_start */
389 TODO_verify_rtl_sharing
, /* todo_flags_finish */
392 class pass_rtl_loop_init
: public rtl_opt_pass
395 pass_rtl_loop_init (gcc::context
*ctxt
)
396 : rtl_opt_pass (pass_data_rtl_loop_init
, ctxt
)
399 /* opt_pass methods: */
400 unsigned int execute () { return rtl_loop_init (); }
402 }; // class pass_rtl_loop_init
407 make_pass_rtl_loop_init (gcc::context
*ctxt
)
409 return new pass_rtl_loop_init (ctxt
);
413 /* Finalization of the RTL loop passes. */
418 /* No longer preserve loops, remove them now. */
419 cfun
->curr_properties
&= ~PROP_loops
;
420 loop_optimizer_finalize ();
421 free_dominance_info (CDI_DOMINATORS
);
426 dump_reg_info (dump_file
);
427 dump_flow_info (dump_file
, dump_flags
);
435 const pass_data pass_data_rtl_loop_done
=
438 "loop2_done", /* name */
439 OPTGROUP_LOOP
, /* optinfo_flags */
440 false, /* has_gate */
441 true, /* has_execute */
443 0, /* properties_required */
444 0, /* properties_provided */
445 PROP_loops
, /* properties_destroyed */
446 0, /* todo_flags_start */
447 ( TODO_verify_flow
| TODO_verify_rtl_sharing
), /* todo_flags_finish */
450 class pass_rtl_loop_done
: public rtl_opt_pass
453 pass_rtl_loop_done (gcc::context
*ctxt
)
454 : rtl_opt_pass (pass_data_rtl_loop_done
, ctxt
)
457 /* opt_pass methods: */
458 unsigned int execute () { return rtl_loop_done (); }
460 }; // class pass_rtl_loop_done
465 make_pass_rtl_loop_done (gcc::context
*ctxt
)
467 return new pass_rtl_loop_done (ctxt
);
471 /* Loop invariant code motion. */
473 gate_rtl_move_loop_invariants (void)
475 return flag_move_loop_invariants
;
479 rtl_move_loop_invariants (void)
481 if (number_of_loops (cfun
) > 1)
482 move_loop_invariants ();
488 const pass_data pass_data_rtl_move_loop_invariants
=
491 "loop2_invariant", /* name */
492 OPTGROUP_LOOP
, /* optinfo_flags */
494 true, /* has_execute */
495 TV_LOOP_MOVE_INVARIANTS
, /* tv_id */
496 0, /* properties_required */
497 0, /* properties_provided */
498 0, /* properties_destroyed */
499 0, /* todo_flags_start */
500 ( TODO_df_verify
| TODO_df_finish
501 | TODO_verify_rtl_sharing
), /* todo_flags_finish */
504 class pass_rtl_move_loop_invariants
: public rtl_opt_pass
507 pass_rtl_move_loop_invariants (gcc::context
*ctxt
)
508 : rtl_opt_pass (pass_data_rtl_move_loop_invariants
, ctxt
)
511 /* opt_pass methods: */
512 bool gate () { return gate_rtl_move_loop_invariants (); }
513 unsigned int execute () { return rtl_move_loop_invariants (); }
515 }; // class pass_rtl_move_loop_invariants
520 make_pass_rtl_move_loop_invariants (gcc::context
*ctxt
)
522 return new pass_rtl_move_loop_invariants (ctxt
);
526 /* Loop unswitching for RTL. */
528 gate_rtl_unswitch (void)
530 return flag_unswitch_loops
;
536 if (number_of_loops (cfun
) > 1)
543 const pass_data pass_data_rtl_unswitch
=
546 "loop2_unswitch", /* name */
547 OPTGROUP_LOOP
, /* optinfo_flags */
549 true, /* has_execute */
550 TV_LOOP_UNSWITCH
, /* tv_id */
551 0, /* properties_required */
552 0, /* properties_provided */
553 0, /* properties_destroyed */
554 0, /* todo_flags_start */
555 TODO_verify_rtl_sharing
, /* todo_flags_finish */
558 class pass_rtl_unswitch
: public rtl_opt_pass
561 pass_rtl_unswitch (gcc::context
*ctxt
)
562 : rtl_opt_pass (pass_data_rtl_unswitch
, ctxt
)
565 /* opt_pass methods: */
566 bool gate () { return gate_rtl_unswitch (); }
567 unsigned int execute () { return rtl_unswitch (); }
569 }; // class pass_rtl_unswitch
574 make_pass_rtl_unswitch (gcc::context
*ctxt
)
576 return new pass_rtl_unswitch (ctxt
);
580 /* Loop unswitching for RTL. */
582 gate_rtl_unroll_and_peel_loops (void)
584 return (flag_peel_loops
|| flag_unroll_loops
|| flag_unroll_all_loops
);
588 rtl_unroll_and_peel_loops (void)
590 if (number_of_loops (cfun
) > 1)
598 if (flag_unroll_loops
)
600 if (flag_unroll_all_loops
)
601 flags
|= UAP_UNROLL_ALL
;
603 unroll_and_peel_loops (flags
);
610 const pass_data pass_data_rtl_unroll_and_peel_loops
=
613 "loop2_unroll", /* name */
614 OPTGROUP_LOOP
, /* optinfo_flags */
616 true, /* has_execute */
617 TV_LOOP_UNROLL
, /* tv_id */
618 0, /* properties_required */
619 0, /* properties_provided */
620 0, /* properties_destroyed */
621 0, /* todo_flags_start */
622 TODO_verify_rtl_sharing
, /* todo_flags_finish */
625 class pass_rtl_unroll_and_peel_loops
: public rtl_opt_pass
628 pass_rtl_unroll_and_peel_loops (gcc::context
*ctxt
)
629 : rtl_opt_pass (pass_data_rtl_unroll_and_peel_loops
, ctxt
)
632 /* opt_pass methods: */
633 bool gate () { return gate_rtl_unroll_and_peel_loops (); }
634 unsigned int execute () { return rtl_unroll_and_peel_loops (); }
636 }; // class pass_rtl_unroll_and_peel_loops
641 make_pass_rtl_unroll_and_peel_loops (gcc::context
*ctxt
)
643 return new pass_rtl_unroll_and_peel_loops (ctxt
);
647 /* The doloop optimization. */
649 gate_rtl_doloop (void)
651 #ifdef HAVE_doloop_end
652 return (flag_branch_on_count_reg
&& HAVE_doloop_end
);
661 #ifdef HAVE_doloop_end
662 if (number_of_loops (cfun
) > 1)
663 doloop_optimize_loops ();
670 const pass_data pass_data_rtl_doloop
=
673 "loop2_doloop", /* name */
674 OPTGROUP_LOOP
, /* optinfo_flags */
676 true, /* has_execute */
677 TV_LOOP_DOLOOP
, /* tv_id */
678 0, /* properties_required */
679 0, /* properties_provided */
680 0, /* properties_destroyed */
681 0, /* todo_flags_start */
682 TODO_verify_rtl_sharing
, /* todo_flags_finish */
685 class pass_rtl_doloop
: public rtl_opt_pass
688 pass_rtl_doloop (gcc::context
*ctxt
)
689 : rtl_opt_pass (pass_data_rtl_doloop
, ctxt
)
692 /* opt_pass methods: */
693 bool gate () { return gate_rtl_doloop (); }
694 unsigned int execute () { return rtl_doloop (); }
696 }; // class pass_rtl_doloop
701 make_pass_rtl_doloop (gcc::context
*ctxt
)
703 return new pass_rtl_doloop (ctxt
);