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
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
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/>. */
23 #include "coretypes.h"
26 #include "hard-reg-set.h"
28 #include "basic-block.h"
30 #include "cfglayout.h"
31 #include "tree-pass.h"
38 /* Initialize loop structures. This is used by the tree and RTL loop
39 optimizers. FLAGS specify what properties to compute and/or ensure for
43 loop_optimizer_init (unsigned flags
)
47 struct loops
*loops
= ggc_alloc_cleared_loops ();
49 gcc_assert (!(cfun
->curr_properties
& PROP_loops
));
53 flow_loops_find (loops
);
54 current_loops
= loops
;
58 gcc_assert (cfun
->curr_properties
& PROP_loops
);
60 /* Ensure that the dominators are computed, like flow_loops_find does. */
61 calculate_dominance_info (CDI_DOMINATORS
);
63 #ifdef ENABLE_CHECKING
64 verify_loop_structure ();
68 if (flags
& LOOPS_MAY_HAVE_MULTIPLE_LATCHES
)
70 /* If the loops may have multiple latches, we cannot canonicalize
71 them further (and most of the loop manipulation functions will
72 not work). However, we avoid modifying cfg, which some
74 gcc_assert ((flags
& ~(LOOPS_MAY_HAVE_MULTIPLE_LATCHES
75 | LOOPS_HAVE_RECORDED_EXITS
)) == 0);
76 loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES
);
79 disambiguate_loops_with_multiple_latches ();
81 /* Create pre-headers. */
82 if (flags
& LOOPS_HAVE_PREHEADERS
)
84 int cp_flags
= CP_SIMPLE_PREHEADERS
;
86 if (flags
& LOOPS_HAVE_FALLTHRU_PREHEADERS
)
87 cp_flags
|= CP_FALLTHRU_PREHEADERS
;
89 create_preheaders (cp_flags
);
92 /* Force all latches to have only single successor. */
93 if (flags
& LOOPS_HAVE_SIMPLE_LATCHES
)
94 force_single_succ_latches ();
96 /* Mark irreducible loops. */
97 if (flags
& LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS
)
98 mark_irreducible_loops ();
100 if (flags
& LOOPS_HAVE_RECORDED_EXITS
)
101 record_loop_exits ();
104 flow_loops_dump (dump_file
, NULL
, 1);
106 #ifdef ENABLE_CHECKING
107 verify_loop_structure ();
111 /* Finalize loop structures. */
114 loop_optimizer_finalize (void)
120 if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS
))
121 release_recorded_exits ();
123 /* If we should preserve loop structure, do not free it but clear
124 flags that advanced properties are there as we are not preserving
126 if (cfun
->curr_properties
& PROP_loops
)
128 loops_state_clear (LOOP_CLOSED_SSA
129 | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS
130 | LOOPS_HAVE_PREHEADERS
131 | LOOPS_HAVE_SIMPLE_LATCHES
132 | LOOPS_HAVE_FALLTHRU_PREHEADERS
);
136 gcc_assert (current_loops
!= NULL
);
138 FOR_EACH_LOOP (li
, loop
, 0)
140 free_simple_loop_desc (loop
);
144 flow_loops_free (current_loops
);
145 ggc_free (current_loops
);
146 current_loops
= NULL
;
150 bb
->loop_father
= NULL
;
155 /* Gate for the RTL loop superpass. The actual passes are subpasses.
156 See passes.c for more on that. */
159 gate_handle_loop2 (void)
162 && (flag_move_loop_invariants
163 || flag_unswitch_loops
166 #ifdef HAVE_doloop_end
167 || (flag_branch_on_count_reg
&& HAVE_doloop_end
)
173 /* No longer preserve loops, remove them now. */
174 cfun
->curr_properties
&= ~PROP_loops
;
176 loop_optimizer_finalize ();
181 struct rtl_opt_pass pass_loop2
=
186 gate_handle_loop2
, /* gate */
190 0, /* static_pass_number */
192 0, /* properties_required */
193 0, /* properties_provided */
194 0, /* properties_destroyed */
195 0, /* todo_flags_start */
196 TODO_ggc_collect
/* todo_flags_finish */
201 /* Initialization of the RTL loop passes. */
205 gcc_assert (current_ir_type () == IR_RTL_CFGLAYOUT
);
208 dump_flow_info (dump_file
, dump_flags
);
210 loop_optimizer_init (LOOPS_NORMAL
);
214 struct rtl_opt_pass pass_rtl_loop_init
=
218 "loop2_init", /* name */
220 rtl_loop_init
, /* execute */
223 0, /* static_pass_number */
225 0, /* properties_required */
226 0, /* properties_provided */
227 0, /* properties_destroyed */
228 0, /* todo_flags_start */
229 TODO_verify_rtl_sharing
/* todo_flags_finish */
234 /* Finalization of the RTL loop passes. */
239 /* No longer preserve loops, remove them now. */
240 cfun
->curr_properties
&= ~PROP_loops
;
241 loop_optimizer_finalize ();
242 free_dominance_info (CDI_DOMINATORS
);
246 dump_flow_info (dump_file
, dump_flags
);
251 struct rtl_opt_pass pass_rtl_loop_done
=
255 "loop2_done", /* name */
257 rtl_loop_done
, /* execute */
260 0, /* static_pass_number */
262 0, /* properties_required */
263 0, /* properties_provided */
264 PROP_loops
, /* properties_destroyed */
265 0, /* todo_flags_start */
267 | TODO_verify_rtl_sharing
/* todo_flags_finish */
272 /* Loop invariant code motion. */
274 gate_rtl_move_loop_invariants (void)
276 return flag_move_loop_invariants
;
280 rtl_move_loop_invariants (void)
282 if (number_of_loops () > 1)
283 move_loop_invariants ();
287 struct rtl_opt_pass pass_rtl_move_loop_invariants
=
291 "loop2_invariant", /* name */
292 gate_rtl_move_loop_invariants
, /* gate */
293 rtl_move_loop_invariants
, /* execute */
296 0, /* static_pass_number */
297 TV_LOOP_MOVE_INVARIANTS
, /* tv_id */
298 0, /* properties_required */
299 0, /* properties_provided */
300 0, /* properties_destroyed */
301 0, /* todo_flags_start */
303 TODO_df_finish
| TODO_verify_rtl_sharing
/* todo_flags_finish */
308 /* Loop unswitching for RTL. */
310 gate_rtl_unswitch (void)
312 return flag_unswitch_loops
;
318 if (number_of_loops () > 1)
323 struct rtl_opt_pass pass_rtl_unswitch
=
327 "loop2_unswitch", /* name */
328 gate_rtl_unswitch
, /* gate */
329 rtl_unswitch
, /* execute */
332 0, /* static_pass_number */
333 TV_LOOP_UNSWITCH
, /* tv_id */
334 0, /* properties_required */
335 0, /* properties_provided */
336 0, /* properties_destroyed */
337 0, /* todo_flags_start */
338 TODO_verify_rtl_sharing
, /* todo_flags_finish */
343 /* Loop unswitching for RTL. */
345 gate_rtl_unroll_and_peel_loops (void)
347 return (flag_peel_loops
|| flag_unroll_loops
|| flag_unroll_all_loops
);
351 rtl_unroll_and_peel_loops (void)
353 if (number_of_loops () > 1)
361 if (flag_unroll_loops
)
363 if (flag_unroll_all_loops
)
364 flags
|= UAP_UNROLL_ALL
;
366 unroll_and_peel_loops (flags
);
371 struct rtl_opt_pass pass_rtl_unroll_and_peel_loops
=
375 "loop2_unroll", /* name */
376 gate_rtl_unroll_and_peel_loops
, /* gate */
377 rtl_unroll_and_peel_loops
, /* execute */
380 0, /* static_pass_number */
381 TV_LOOP_UNROLL
, /* tv_id */
382 0, /* properties_required */
383 0, /* properties_provided */
384 0, /* properties_destroyed */
385 0, /* todo_flags_start */
386 TODO_verify_rtl_sharing
, /* todo_flags_finish */
391 /* The doloop optimization. */
393 gate_rtl_doloop (void)
395 #ifdef HAVE_doloop_end
396 return (flag_branch_on_count_reg
&& HAVE_doloop_end
);
405 #ifdef HAVE_doloop_end
406 if (number_of_loops () > 1)
407 doloop_optimize_loops ();
412 struct rtl_opt_pass pass_rtl_doloop
=
416 "loop2_doloop", /* name */
417 gate_rtl_doloop
, /* gate */
418 rtl_doloop
, /* execute */
421 0, /* static_pass_number */
422 TV_LOOP_DOLOOP
, /* tv_id */
423 0, /* properties_required */
424 0, /* properties_provided */
425 0, /* properties_destroyed */
426 0, /* todo_flags_start */
427 TODO_verify_rtl_sharing
/* todo_flags_finish */