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"
37 /* Apply FLAGS to the loop state. */
40 apply_loop_flags (unsigned flags
)
42 if (flags
& LOOPS_MAY_HAVE_MULTIPLE_LATCHES
)
44 /* If the loops may have multiple latches, we cannot canonicalize
45 them further (and most of the loop manipulation functions will
46 not work). However, we avoid modifying cfg, which some
48 gcc_assert ((flags
& ~(LOOPS_MAY_HAVE_MULTIPLE_LATCHES
49 | LOOPS_HAVE_RECORDED_EXITS
)) == 0);
50 loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES
);
53 disambiguate_loops_with_multiple_latches ();
55 /* Create pre-headers. */
56 if (flags
& LOOPS_HAVE_PREHEADERS
)
58 int cp_flags
= CP_SIMPLE_PREHEADERS
;
60 if (flags
& LOOPS_HAVE_FALLTHRU_PREHEADERS
)
61 cp_flags
|= CP_FALLTHRU_PREHEADERS
;
63 create_preheaders (cp_flags
);
66 /* Force all latches to have only single successor. */
67 if (flags
& LOOPS_HAVE_SIMPLE_LATCHES
)
68 force_single_succ_latches ();
70 /* Mark irreducible loops. */
71 if (flags
& LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS
)
72 mark_irreducible_loops ();
74 if (flags
& LOOPS_HAVE_RECORDED_EXITS
)
78 /* Initialize loop structures. This is used by the tree and RTL loop
79 optimizers. FLAGS specify what properties to compute and/or ensure for
83 loop_optimizer_init (unsigned flags
)
85 timevar_push (TV_LOOP_INIT
);
89 gcc_assert (!(cfun
->curr_properties
& PROP_loops
));
92 current_loops
= flow_loops_find (NULL
);
96 bool recorded_exits
= loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS
);
98 gcc_assert (cfun
->curr_properties
& PROP_loops
);
100 /* Ensure that the dominators are computed, like flow_loops_find does. */
101 calculate_dominance_info (CDI_DOMINATORS
);
103 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP
))
105 loops_state_clear (~0U);
106 fix_loop_structure (NULL
);
109 #ifdef ENABLE_CHECKING
111 verify_loop_structure ();
114 /* Clear all flags. */
116 release_recorded_exits ();
117 loops_state_clear (~0U);
120 /* Apply flags to loops. */
121 apply_loop_flags (flags
);
124 flow_loops_dump (dump_file
, NULL
, 1);
126 #ifdef ENABLE_CHECKING
127 verify_loop_structure ();
130 timevar_pop (TV_LOOP_INIT
);
133 /* Finalize loop structures. */
136 loop_optimizer_finalize (void)
142 timevar_push (TV_LOOP_FINI
);
144 if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS
))
145 release_recorded_exits ();
147 free_numbers_of_iterations_estimates ();
149 /* If we should preserve loop structure, do not free it but clear
150 flags that advanced properties are there as we are not preserving
152 if (cfun
->curr_properties
& PROP_loops
)
154 loops_state_clear (LOOP_CLOSED_SSA
155 | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS
156 | LOOPS_HAVE_PREHEADERS
157 | LOOPS_HAVE_SIMPLE_LATCHES
158 | LOOPS_HAVE_FALLTHRU_PREHEADERS
);
159 loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES
);
163 gcc_assert (current_loops
!= NULL
);
165 FOR_EACH_LOOP (li
, loop
, 0)
167 free_simple_loop_desc (loop
);
171 flow_loops_free (current_loops
);
172 ggc_free (current_loops
);
173 current_loops
= NULL
;
177 bb
->loop_father
= NULL
;
181 timevar_pop (TV_LOOP_FINI
);
184 /* The structure of loops might have changed. Some loops might get removed
185 (and their headers and latches were set to NULL), loop exists might get
186 removed (thus the loop nesting may be wrong), and some blocks and edges
187 were changed (so the information about bb --> loop mapping does not have
188 to be correct). But still for the remaining loops the header dominates
189 the latch, and loops did not get new subloops (new loops might possibly
190 get created, but we are not interested in them). Fix up the mess.
192 If CHANGED_BBS is not NULL, basic blocks whose loop depth has changed are
195 Returns the number of new discovered loops. */
198 fix_loop_structure (bitmap changed_bbs
)
201 int record_exits
= 0;
204 unsigned old_nloops
, i
;
206 timevar_push (TV_LOOP_INIT
);
208 /* We need exact and fast dominance info to be available. */
209 gcc_assert (dom_info_state (CDI_DOMINATORS
) == DOM_OK
);
211 if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS
))
213 release_recorded_exits ();
214 record_exits
= LOOPS_HAVE_RECORDED_EXITS
;
217 /* Remember the depth of the blocks in the loop hierarchy, so that we can
218 recognize blocks whose loop nesting relationship has changed. */
221 bb
->aux
= (void *) (size_t) loop_depth (bb
->loop_father
);
223 /* Remove the dead loops from structures. We start from the innermost
224 loops, so that when we remove the loops, we know that the loops inside
225 are preserved, and do not waste time relinking loops that will be
227 FOR_EACH_LOOP (li
, loop
, LI_FROM_INNERMOST
)
229 /* Detect the case that the loop is no longer present even though
230 it wasn't marked for removal.
231 ??? If we do that we can get away with not marking loops for
232 removal at all. And possibly avoid some spurious removals. */
234 && bb_loop_header_p (loop
->header
))
237 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
238 fprintf (dump_file
, "fix_loop_structure: removing loop %d\n",
243 struct loop
*ploop
= loop
->inner
;
244 flow_loop_tree_node_remove (ploop
);
245 flow_loop_tree_node_add (loop_outer (loop
), ploop
);
248 /* Remove the loop. */
250 flow_loop_tree_node_remove (loop
);
253 /* Remember the number of loops so we can return how many new loops
254 flow_loops_find discovered. */
255 old_nloops
= number_of_loops (cfun
);
257 /* Re-compute loop structure in-place. */
258 flow_loops_find (current_loops
);
260 /* Mark the blocks whose loop has changed. */
265 if ((void *) (size_t) loop_depth (bb
->loop_father
) != bb
->aux
)
266 bitmap_set_bit (changed_bbs
, bb
->index
);
272 /* Finally free deleted loops. */
273 FOR_EACH_VEC_ELT (*get_loops (cfun
), i
, loop
)
274 if (loop
&& loop
->header
== NULL
)
276 (*get_loops (cfun
))[i
] = NULL
;
277 flow_loop_free (loop
);
280 loops_state_clear (LOOPS_NEED_FIXUP
);
282 /* Apply flags to loops. */
283 apply_loop_flags (current_loops
->state
| record_exits
);
285 #ifdef ENABLE_CHECKING
286 verify_loop_structure ();
289 timevar_pop (TV_LOOP_INIT
);
291 return number_of_loops (cfun
) - old_nloops
;
294 /* Gate for the RTL loop superpass. The actual passes are subpasses.
295 See passes.c for more on that. */
298 gate_handle_loop2 (void)
301 && (flag_move_loop_invariants
302 || flag_unswitch_loops
305 #ifdef HAVE_doloop_end
306 || (flag_branch_on_count_reg
&& HAVE_doloop_end
)
312 /* No longer preserve loops, remove them now. */
313 cfun
->curr_properties
&= ~PROP_loops
;
315 loop_optimizer_finalize ();
322 const pass_data pass_data_loop2
=
326 OPTGROUP_LOOP
, /* optinfo_flags */
328 false, /* has_execute */
330 0, /* properties_required */
331 0, /* properties_provided */
332 0, /* properties_destroyed */
333 0, /* todo_flags_start */
334 0, /* todo_flags_finish */
337 class pass_loop2
: public rtl_opt_pass
340 pass_loop2 (gcc::context
*ctxt
)
341 : rtl_opt_pass (pass_data_loop2
, ctxt
)
344 /* opt_pass methods: */
345 bool gate () { return gate_handle_loop2 (); }
347 }; // class pass_loop2
352 make_pass_loop2 (gcc::context
*ctxt
)
354 return new pass_loop2 (ctxt
);
358 /* Initialization of the RTL loop passes. */
362 gcc_assert (current_ir_type () == IR_RTL_CFGLAYOUT
);
366 dump_reg_info (dump_file
);
367 dump_flow_info (dump_file
, dump_flags
);
370 loop_optimizer_init (LOOPS_NORMAL
);
376 const pass_data pass_data_rtl_loop_init
=
379 "loop2_init", /* name */
380 OPTGROUP_LOOP
, /* optinfo_flags */
381 false, /* has_gate */
382 true, /* has_execute */
384 0, /* properties_required */
385 0, /* properties_provided */
386 0, /* properties_destroyed */
387 0, /* todo_flags_start */
388 TODO_verify_rtl_sharing
, /* todo_flags_finish */
391 class pass_rtl_loop_init
: public rtl_opt_pass
394 pass_rtl_loop_init (gcc::context
*ctxt
)
395 : rtl_opt_pass (pass_data_rtl_loop_init
, ctxt
)
398 /* opt_pass methods: */
399 unsigned int execute () { return rtl_loop_init (); }
401 }; // class pass_rtl_loop_init
406 make_pass_rtl_loop_init (gcc::context
*ctxt
)
408 return new pass_rtl_loop_init (ctxt
);
412 /* Finalization of the RTL loop passes. */
417 /* No longer preserve loops, remove them now. */
418 cfun
->curr_properties
&= ~PROP_loops
;
419 loop_optimizer_finalize ();
420 free_dominance_info (CDI_DOMINATORS
);
425 dump_reg_info (dump_file
);
426 dump_flow_info (dump_file
, dump_flags
);
434 const pass_data pass_data_rtl_loop_done
=
437 "loop2_done", /* name */
438 OPTGROUP_LOOP
, /* optinfo_flags */
439 false, /* has_gate */
440 true, /* has_execute */
442 0, /* properties_required */
443 0, /* properties_provided */
444 PROP_loops
, /* properties_destroyed */
445 0, /* todo_flags_start */
446 ( TODO_verify_flow
| TODO_verify_rtl_sharing
), /* todo_flags_finish */
449 class pass_rtl_loop_done
: public rtl_opt_pass
452 pass_rtl_loop_done (gcc::context
*ctxt
)
453 : rtl_opt_pass (pass_data_rtl_loop_done
, ctxt
)
456 /* opt_pass methods: */
457 unsigned int execute () { return rtl_loop_done (); }
459 }; // class pass_rtl_loop_done
464 make_pass_rtl_loop_done (gcc::context
*ctxt
)
466 return new pass_rtl_loop_done (ctxt
);
470 /* Loop invariant code motion. */
472 gate_rtl_move_loop_invariants (void)
474 return flag_move_loop_invariants
;
478 rtl_move_loop_invariants (void)
480 if (number_of_loops (cfun
) > 1)
481 move_loop_invariants ();
487 const pass_data pass_data_rtl_move_loop_invariants
=
490 "loop2_invariant", /* name */
491 OPTGROUP_LOOP
, /* optinfo_flags */
493 true, /* has_execute */
494 TV_LOOP_MOVE_INVARIANTS
, /* tv_id */
495 0, /* properties_required */
496 0, /* properties_provided */
497 0, /* properties_destroyed */
498 0, /* todo_flags_start */
499 ( TODO_df_verify
| TODO_df_finish
500 | TODO_verify_rtl_sharing
), /* todo_flags_finish */
503 class pass_rtl_move_loop_invariants
: public rtl_opt_pass
506 pass_rtl_move_loop_invariants (gcc::context
*ctxt
)
507 : rtl_opt_pass (pass_data_rtl_move_loop_invariants
, ctxt
)
510 /* opt_pass methods: */
511 bool gate () { return gate_rtl_move_loop_invariants (); }
512 unsigned int execute () { return rtl_move_loop_invariants (); }
514 }; // class pass_rtl_move_loop_invariants
519 make_pass_rtl_move_loop_invariants (gcc::context
*ctxt
)
521 return new pass_rtl_move_loop_invariants (ctxt
);
525 /* Loop unswitching for RTL. */
527 gate_rtl_unswitch (void)
529 return flag_unswitch_loops
;
535 if (number_of_loops (cfun
) > 1)
542 const pass_data pass_data_rtl_unswitch
=
545 "loop2_unswitch", /* name */
546 OPTGROUP_LOOP
, /* optinfo_flags */
548 true, /* has_execute */
549 TV_LOOP_UNSWITCH
, /* tv_id */
550 0, /* properties_required */
551 0, /* properties_provided */
552 0, /* properties_destroyed */
553 0, /* todo_flags_start */
554 TODO_verify_rtl_sharing
, /* todo_flags_finish */
557 class pass_rtl_unswitch
: public rtl_opt_pass
560 pass_rtl_unswitch (gcc::context
*ctxt
)
561 : rtl_opt_pass (pass_data_rtl_unswitch
, ctxt
)
564 /* opt_pass methods: */
565 bool gate () { return gate_rtl_unswitch (); }
566 unsigned int execute () { return rtl_unswitch (); }
568 }; // class pass_rtl_unswitch
573 make_pass_rtl_unswitch (gcc::context
*ctxt
)
575 return new pass_rtl_unswitch (ctxt
);
579 /* Loop unswitching for RTL. */
581 gate_rtl_unroll_and_peel_loops (void)
583 return (flag_peel_loops
|| flag_unroll_loops
|| flag_unroll_all_loops
);
587 rtl_unroll_and_peel_loops (void)
589 if (number_of_loops (cfun
) > 1)
597 if (flag_unroll_loops
)
599 if (flag_unroll_all_loops
)
600 flags
|= UAP_UNROLL_ALL
;
602 unroll_and_peel_loops (flags
);
609 const pass_data pass_data_rtl_unroll_and_peel_loops
=
612 "loop2_unroll", /* name */
613 OPTGROUP_LOOP
, /* optinfo_flags */
615 true, /* has_execute */
616 TV_LOOP_UNROLL
, /* tv_id */
617 0, /* properties_required */
618 0, /* properties_provided */
619 0, /* properties_destroyed */
620 0, /* todo_flags_start */
621 TODO_verify_rtl_sharing
, /* todo_flags_finish */
624 class pass_rtl_unroll_and_peel_loops
: public rtl_opt_pass
627 pass_rtl_unroll_and_peel_loops (gcc::context
*ctxt
)
628 : rtl_opt_pass (pass_data_rtl_unroll_and_peel_loops
, ctxt
)
631 /* opt_pass methods: */
632 bool gate () { return gate_rtl_unroll_and_peel_loops (); }
633 unsigned int execute () { return rtl_unroll_and_peel_loops (); }
635 }; // class pass_rtl_unroll_and_peel_loops
640 make_pass_rtl_unroll_and_peel_loops (gcc::context
*ctxt
)
642 return new pass_rtl_unroll_and_peel_loops (ctxt
);
646 /* The doloop optimization. */
648 gate_rtl_doloop (void)
650 #ifdef HAVE_doloop_end
651 return (flag_branch_on_count_reg
&& HAVE_doloop_end
);
660 #ifdef HAVE_doloop_end
661 if (number_of_loops (cfun
) > 1)
662 doloop_optimize_loops ();
669 const pass_data pass_data_rtl_doloop
=
672 "loop2_doloop", /* name */
673 OPTGROUP_LOOP
, /* optinfo_flags */
675 true, /* has_execute */
676 TV_LOOP_DOLOOP
, /* tv_id */
677 0, /* properties_required */
678 0, /* properties_provided */
679 0, /* properties_destroyed */
680 0, /* todo_flags_start */
681 TODO_verify_rtl_sharing
, /* todo_flags_finish */
684 class pass_rtl_doloop
: public rtl_opt_pass
687 pass_rtl_doloop (gcc::context
*ctxt
)
688 : rtl_opt_pass (pass_data_rtl_doloop
, ctxt
)
691 /* opt_pass methods: */
692 bool gate () { return gate_rtl_doloop (); }
693 unsigned int execute () { return rtl_doloop (); }
695 }; // class pass_rtl_doloop
700 make_pass_rtl_doloop (gcc::context
*ctxt
)
702 return new pass_rtl_doloop (ctxt
);