1 /* Loop optimizations over tree-ssa.
2 Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009, 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
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3, or (at your option) any
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY 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"
27 #include "basic-block.h"
28 #include "tree-flow.h"
29 #include "tree-pass.h"
32 #include "tree-inline.h"
33 #include "tree-scalar-evolution.h"
34 #include "diagnostic-core.h"
35 #include "tree-vectorizer.h"
37 /* The loop superpass. */
42 return flag_tree_loop_optimize
!= 0;
45 struct gimple_opt_pass pass_tree_loop
=
50 gate_tree_loop
, /* gate */
54 0, /* static_pass_number */
55 TV_TREE_LOOP
, /* tv_id */
56 PROP_cfg
, /* properties_required */
57 0, /* properties_provided */
58 0, /* properties_destroyed */
59 TODO_ggc_collect
, /* todo_flags_start */
60 TODO_verify_ssa
| TODO_ggc_collect
/* todo_flags_finish */
64 /* Loop optimizer initialization. */
67 tree_ssa_loop_init (void)
69 loop_optimizer_init (LOOPS_NORMAL
70 | LOOPS_HAVE_RECORDED_EXITS
);
71 rewrite_into_loop_closed_ssa (NULL
, TODO_update_ssa
);
73 if (number_of_loops () <= 1)
80 struct gimple_opt_pass pass_tree_loop_init
=
84 "loopinit", /* name */
86 tree_ssa_loop_init
, /* execute */
89 0, /* static_pass_number */
91 PROP_cfg
, /* properties_required */
92 PROP_loops
, /* properties_provided */
93 0, /* properties_destroyed */
94 0, /* todo_flags_start */
95 0 /* todo_flags_finish */
99 /* Loop invariant motion pass. */
102 tree_ssa_loop_im (void)
104 if (number_of_loops () <= 1)
107 return tree_ssa_lim ();
111 gate_tree_ssa_loop_im (void)
113 return flag_tree_loop_im
!= 0;
116 struct gimple_opt_pass pass_lim
=
121 gate_tree_ssa_loop_im
, /* gate */
122 tree_ssa_loop_im
, /* execute */
125 0, /* static_pass_number */
127 PROP_cfg
, /* properties_required */
128 0, /* properties_provided */
129 0, /* properties_destroyed */
130 0, /* todo_flags_start */
131 0 /* todo_flags_finish */
135 /* Loop unswitching pass. */
138 tree_ssa_loop_unswitch (void)
140 if (number_of_loops () <= 1)
143 return tree_ssa_unswitch_loops ();
147 gate_tree_ssa_loop_unswitch (void)
149 return flag_unswitch_loops
!= 0;
152 struct gimple_opt_pass pass_tree_unswitch
=
156 "unswitch", /* name */
157 gate_tree_ssa_loop_unswitch
, /* gate */
158 tree_ssa_loop_unswitch
, /* execute */
161 0, /* static_pass_number */
162 TV_TREE_LOOP_UNSWITCH
, /* tv_id */
163 PROP_cfg
, /* properties_required */
164 0, /* properties_provided */
165 0, /* properties_destroyed */
166 0, /* todo_flags_start */
167 TODO_ggc_collect
/* todo_flags_finish */
171 /* Predictive commoning. */
174 run_tree_predictive_commoning (void)
179 return tree_predictive_commoning ();
183 gate_tree_predictive_commoning (void)
185 return flag_predictive_commoning
!= 0;
188 struct gimple_opt_pass pass_predcom
=
193 gate_tree_predictive_commoning
, /* gate */
194 run_tree_predictive_commoning
, /* execute */
197 0, /* static_pass_number */
198 TV_PREDCOM
, /* tv_id */
199 PROP_cfg
, /* properties_required */
200 0, /* properties_provided */
201 0, /* properties_destroyed */
202 0, /* todo_flags_start */
203 TODO_update_ssa_only_virtuals
/* todo_flags_finish */
207 /* Loop autovectorization. */
210 tree_vectorize (void)
212 if (number_of_loops () <= 1)
215 return vectorize_loops ();
219 gate_tree_vectorize (void)
221 return flag_tree_vectorize
;
224 struct gimple_opt_pass pass_vectorize
=
229 gate_tree_vectorize
, /* gate */
230 tree_vectorize
, /* execute */
233 0, /* static_pass_number */
234 TV_TREE_VECTORIZATION
, /* tv_id */
235 PROP_cfg
| PROP_ssa
, /* properties_required */
236 0, /* properties_provided */
237 0, /* properties_destroyed */
238 0, /* todo_flags_start */
240 | TODO_ggc_collect
/* todo_flags_finish */
244 /* GRAPHITE optimizations. */
247 graphite_transforms (void)
252 graphite_transform_loops ();
258 gate_graphite_transforms (void)
260 /* Enable -fgraphite pass if any one of the graphite optimization flags
263 || flag_loop_interchange
264 || flag_loop_strip_mine
265 || flag_graphite_identity
266 || flag_loop_parallelize_all
267 || flag_loop_optimize_isl
)
270 return flag_graphite
!= 0;
273 struct gimple_opt_pass pass_graphite
=
277 "graphite0", /* name */
278 gate_graphite_transforms
, /* gate */
282 0, /* static_pass_number */
283 TV_GRAPHITE
, /* tv_id */
284 PROP_cfg
| PROP_ssa
, /* properties_required */
285 0, /* properties_provided */
286 0, /* properties_destroyed */
287 0, /* todo_flags_start */
288 0 /* todo_flags_finish */
292 struct gimple_opt_pass pass_graphite_transforms
=
296 "graphite", /* name */
297 gate_graphite_transforms
, /* gate */
298 graphite_transforms
, /* execute */
301 0, /* static_pass_number */
302 TV_GRAPHITE_TRANSFORMS
, /* tv_id */
303 PROP_cfg
| PROP_ssa
, /* properties_required */
304 0, /* properties_provided */
305 0, /* properties_destroyed */
306 0, /* todo_flags_start */
307 0 /* todo_flags_finish */
311 /* Check the correctness of the data dependence analyzers. */
314 check_data_deps (void)
316 if (number_of_loops () <= 1)
319 tree_check_data_deps ();
324 gate_check_data_deps (void)
326 return flag_check_data_deps
!= 0;
329 struct gimple_opt_pass pass_check_data_deps
=
334 gate_check_data_deps
, /* gate */
335 check_data_deps
, /* execute */
338 0, /* static_pass_number */
339 TV_CHECK_DATA_DEPS
, /* tv_id */
340 PROP_cfg
| PROP_ssa
, /* properties_required */
341 0, /* properties_provided */
342 0, /* properties_destroyed */
343 0, /* todo_flags_start */
344 0 /* todo_flags_finish */
348 /* Canonical induction variable creation pass. */
351 tree_ssa_loop_ivcanon (void)
353 if (number_of_loops () <= 1)
356 return canonicalize_induction_variables ();
360 gate_tree_ssa_loop_ivcanon (void)
362 return flag_tree_loop_ivcanon
!= 0;
365 struct gimple_opt_pass pass_iv_canon
=
369 "ivcanon", /* name */
370 gate_tree_ssa_loop_ivcanon
, /* gate */
371 tree_ssa_loop_ivcanon
, /* execute */
374 0, /* static_pass_number */
375 TV_TREE_LOOP_IVCANON
, /* tv_id */
376 PROP_cfg
| PROP_ssa
, /* properties_required */
377 0, /* properties_provided */
378 0, /* properties_destroyed */
379 0, /* todo_flags_start */
380 0 /* todo_flags_finish */
384 /* Propagation of constants using scev. */
387 gate_scev_const_prop (void)
389 return flag_tree_scev_cprop
;
392 struct gimple_opt_pass pass_scev_cprop
=
397 gate_scev_const_prop
, /* gate */
398 scev_const_prop
, /* execute */
401 0, /* static_pass_number */
402 TV_SCEV_CONST
, /* tv_id */
403 PROP_cfg
| PROP_ssa
, /* properties_required */
404 0, /* properties_provided */
405 0, /* properties_destroyed */
406 0, /* todo_flags_start */
408 | TODO_update_ssa_only_virtuals
409 /* todo_flags_finish */
413 /* Record bounds on numbers of iterations of loops. */
416 tree_ssa_loop_bounds (void)
418 if (number_of_loops () <= 1)
421 estimate_numbers_of_iterations ();
426 struct gimple_opt_pass pass_record_bounds
=
430 "*record_bounds", /* name */
432 tree_ssa_loop_bounds
, /* execute */
435 0, /* static_pass_number */
436 TV_TREE_LOOP_BOUNDS
, /* tv_id */
437 PROP_cfg
| PROP_ssa
, /* properties_required */
438 0, /* properties_provided */
439 0, /* properties_destroyed */
440 0, /* todo_flags_start */
441 0 /* todo_flags_finish */
445 /* Complete unrolling of loops. */
448 tree_complete_unroll (void)
450 if (number_of_loops () <= 1)
453 return tree_unroll_loops_completely (flag_unroll_loops
455 || optimize
>= 3, true);
459 gate_tree_complete_unroll (void)
464 struct gimple_opt_pass pass_complete_unroll
=
468 "cunroll", /* name */
469 gate_tree_complete_unroll
, /* gate */
470 tree_complete_unroll
, /* execute */
473 0, /* static_pass_number */
474 TV_COMPLETE_UNROLL
, /* tv_id */
475 PROP_cfg
| PROP_ssa
, /* properties_required */
476 0, /* properties_provided */
477 0, /* properties_destroyed */
478 0, /* todo_flags_start */
479 TODO_ggc_collect
/* todo_flags_finish */
483 /* Complete unrolling of inner loops. */
486 tree_complete_unroll_inner (void)
490 loop_optimizer_init (LOOPS_NORMAL
491 | LOOPS_HAVE_RECORDED_EXITS
);
492 if (number_of_loops () > 1)
495 ret
= tree_unroll_loops_completely (optimize
>= 3, false);
496 free_numbers_of_iterations_estimates ();
499 loop_optimizer_finalize ();
505 gate_tree_complete_unroll_inner (void)
507 return optimize
>= 2;
510 struct gimple_opt_pass pass_complete_unrolli
=
514 "cunrolli", /* name */
515 gate_tree_complete_unroll_inner
, /* gate */
516 tree_complete_unroll_inner
, /* execute */
519 0, /* static_pass_number */
520 TV_COMPLETE_UNROLL
, /* tv_id */
521 PROP_cfg
| PROP_ssa
, /* properties_required */
522 0, /* properties_provided */
523 0, /* properties_destroyed */
524 0, /* todo_flags_start */
526 | TODO_ggc_collect
/* todo_flags_finish */
530 /* Parallelization. */
533 gate_tree_parallelize_loops (void)
535 return flag_tree_parallelize_loops
> 1;
539 tree_parallelize_loops (void)
541 if (number_of_loops () <= 1)
544 if (parallelize_loops ())
545 return TODO_cleanup_cfg
| TODO_rebuild_alias
;
549 struct gimple_opt_pass pass_parallelize_loops
=
553 "parloops", /* name */
554 gate_tree_parallelize_loops
, /* gate */
555 tree_parallelize_loops
, /* execute */
558 0, /* static_pass_number */
559 TV_TREE_PARALLELIZE_LOOPS
, /* tv_id */
560 PROP_cfg
| PROP_ssa
, /* properties_required */
561 0, /* properties_provided */
562 0, /* properties_destroyed */
563 0, /* todo_flags_start */
564 0 /* todo_flags_finish */
571 tree_ssa_loop_prefetch (void)
573 if (number_of_loops () <= 1)
576 return tree_ssa_prefetch_arrays ();
580 gate_tree_ssa_loop_prefetch (void)
582 return flag_prefetch_loop_arrays
> 0;
585 struct gimple_opt_pass pass_loop_prefetch
=
589 "aprefetch", /* name */
590 gate_tree_ssa_loop_prefetch
, /* gate */
591 tree_ssa_loop_prefetch
, /* execute */
594 0, /* static_pass_number */
595 TV_TREE_PREFETCH
, /* tv_id */
596 PROP_cfg
| PROP_ssa
, /* properties_required */
597 0, /* properties_provided */
598 0, /* properties_destroyed */
599 0, /* todo_flags_start */
600 0 /* todo_flags_finish */
604 /* Induction variable optimizations. */
607 tree_ssa_loop_ivopts (void)
609 if (number_of_loops () <= 1)
612 tree_ssa_iv_optimize ();
617 gate_tree_ssa_loop_ivopts (void)
619 return flag_ivopts
!= 0;
622 struct gimple_opt_pass pass_iv_optimize
=
627 gate_tree_ssa_loop_ivopts
, /* gate */
628 tree_ssa_loop_ivopts
, /* execute */
631 0, /* static_pass_number */
632 TV_TREE_LOOP_IVOPTS
, /* tv_id */
633 PROP_cfg
| PROP_ssa
, /* properties_required */
634 0, /* properties_provided */
635 0, /* properties_destroyed */
636 0, /* todo_flags_start */
637 TODO_update_ssa
| TODO_ggc_collect
/* todo_flags_finish */
641 /* Loop optimizer finalization. */
644 tree_ssa_loop_done (void)
646 free_numbers_of_iterations_estimates ();
648 loop_optimizer_finalize ();
652 struct gimple_opt_pass pass_tree_loop_done
=
656 "loopdone", /* name */
658 tree_ssa_loop_done
, /* execute */
661 0, /* static_pass_number */
663 PROP_cfg
, /* properties_required */
664 0, /* properties_provided */
665 0, /* properties_destroyed */
666 0, /* todo_flags_start */
668 | TODO_verify_flow
/* todo_flags_finish */