1 /* Loop optimizations over tree-ssa.
2 Copyright (C) 2003-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
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY 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"
26 #include "basic-block.h"
27 #include "tree-flow.h"
28 #include "tree-pass.h"
31 #include "tree-inline.h"
32 #include "tree-scalar-evolution.h"
33 #include "diagnostic-core.h"
34 #include "tree-vectorizer.h"
36 /* The loop superpass. */
41 return flag_tree_loop_optimize
!= 0;
44 struct gimple_opt_pass pass_tree_loop
=
49 OPTGROUP_LOOP
, /* optinfo_flags */
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 */
85 OPTGROUP_LOOP
, /* optinfo_flags */
87 tree_ssa_loop_init
, /* execute */
90 0, /* static_pass_number */
92 PROP_cfg
, /* properties_required */
93 PROP_loops
, /* properties_provided */
94 0, /* properties_destroyed */
95 0, /* todo_flags_start */
96 0 /* todo_flags_finish */
100 /* Loop invariant motion pass. */
103 tree_ssa_loop_im (void)
105 if (number_of_loops () <= 1)
108 return tree_ssa_lim ();
112 gate_tree_ssa_loop_im (void)
114 return flag_tree_loop_im
!= 0;
117 struct gimple_opt_pass pass_lim
=
122 OPTGROUP_LOOP
, /* optinfo_flags */
123 gate_tree_ssa_loop_im
, /* gate */
124 tree_ssa_loop_im
, /* execute */
127 0, /* static_pass_number */
129 PROP_cfg
, /* properties_required */
130 0, /* properties_provided */
131 0, /* properties_destroyed */
132 0, /* todo_flags_start */
133 0 /* todo_flags_finish */
137 /* Loop unswitching pass. */
140 tree_ssa_loop_unswitch (void)
142 if (number_of_loops () <= 1)
145 return tree_ssa_unswitch_loops ();
149 gate_tree_ssa_loop_unswitch (void)
151 return flag_unswitch_loops
!= 0;
154 struct gimple_opt_pass pass_tree_unswitch
=
158 "unswitch", /* name */
159 OPTGROUP_LOOP
, /* optinfo_flags */
160 gate_tree_ssa_loop_unswitch
, /* gate */
161 tree_ssa_loop_unswitch
, /* execute */
164 0, /* static_pass_number */
165 TV_TREE_LOOP_UNSWITCH
, /* tv_id */
166 PROP_cfg
, /* properties_required */
167 0, /* properties_provided */
168 0, /* properties_destroyed */
169 0, /* todo_flags_start */
170 TODO_ggc_collect
/* todo_flags_finish */
174 /* Predictive commoning. */
177 run_tree_predictive_commoning (void)
182 return tree_predictive_commoning ();
186 gate_tree_predictive_commoning (void)
188 return flag_predictive_commoning
!= 0;
191 struct gimple_opt_pass pass_predcom
=
196 OPTGROUP_LOOP
, /* optinfo_flags */
197 gate_tree_predictive_commoning
, /* gate */
198 run_tree_predictive_commoning
, /* execute */
201 0, /* static_pass_number */
202 TV_PREDCOM
, /* tv_id */
203 PROP_cfg
, /* properties_required */
204 0, /* properties_provided */
205 0, /* properties_destroyed */
206 0, /* todo_flags_start */
207 TODO_update_ssa_only_virtuals
/* todo_flags_finish */
211 /* Loop autovectorization. */
214 tree_vectorize (void)
216 if (number_of_loops () <= 1)
219 return vectorize_loops ();
223 gate_tree_vectorize (void)
225 return flag_tree_vectorize
;
228 struct gimple_opt_pass pass_vectorize
=
234 | OPTGROUP_VEC
, /* optinfo_flags */
235 gate_tree_vectorize
, /* gate */
236 tree_vectorize
, /* execute */
239 0, /* static_pass_number */
240 TV_TREE_VECTORIZATION
, /* tv_id */
241 PROP_cfg
| PROP_ssa
, /* properties_required */
242 0, /* properties_provided */
243 0, /* properties_destroyed */
244 0, /* todo_flags_start */
246 | TODO_ggc_collect
/* todo_flags_finish */
250 /* GRAPHITE optimizations. */
253 graphite_transforms (void)
258 graphite_transform_loops ();
264 gate_graphite_transforms (void)
266 /* Enable -fgraphite pass if any one of the graphite optimization flags
269 || flag_loop_interchange
270 || flag_loop_strip_mine
271 || flag_graphite_identity
272 || flag_loop_parallelize_all
273 || flag_loop_optimize_isl
)
276 return flag_graphite
!= 0;
279 struct gimple_opt_pass pass_graphite
=
283 "graphite0", /* name */
284 OPTGROUP_LOOP
, /* optinfo_flags */
285 gate_graphite_transforms
, /* gate */
289 0, /* static_pass_number */
290 TV_GRAPHITE
, /* tv_id */
291 PROP_cfg
| PROP_ssa
, /* properties_required */
292 0, /* properties_provided */
293 0, /* properties_destroyed */
294 0, /* todo_flags_start */
295 0 /* todo_flags_finish */
299 struct gimple_opt_pass pass_graphite_transforms
=
303 "graphite", /* name */
304 OPTGROUP_LOOP
, /* optinfo_flags */
305 gate_graphite_transforms
, /* gate */
306 graphite_transforms
, /* execute */
309 0, /* static_pass_number */
310 TV_GRAPHITE_TRANSFORMS
, /* tv_id */
311 PROP_cfg
| PROP_ssa
, /* properties_required */
312 0, /* properties_provided */
313 0, /* properties_destroyed */
314 0, /* todo_flags_start */
315 0 /* todo_flags_finish */
319 /* Check the correctness of the data dependence analyzers. */
322 check_data_deps (void)
324 if (number_of_loops () <= 1)
327 tree_check_data_deps ();
332 gate_check_data_deps (void)
334 return flag_check_data_deps
!= 0;
337 struct gimple_opt_pass pass_check_data_deps
=
342 OPTGROUP_LOOP
, /* optinfo_flags */
343 gate_check_data_deps
, /* gate */
344 check_data_deps
, /* execute */
347 0, /* static_pass_number */
348 TV_CHECK_DATA_DEPS
, /* tv_id */
349 PROP_cfg
| PROP_ssa
, /* properties_required */
350 0, /* properties_provided */
351 0, /* properties_destroyed */
352 0, /* todo_flags_start */
353 0 /* todo_flags_finish */
357 /* Canonical induction variable creation pass. */
360 tree_ssa_loop_ivcanon (void)
362 if (number_of_loops () <= 1)
365 return canonicalize_induction_variables ();
369 gate_tree_ssa_loop_ivcanon (void)
371 return flag_tree_loop_ivcanon
!= 0;
374 struct gimple_opt_pass pass_iv_canon
=
378 "ivcanon", /* name */
379 OPTGROUP_LOOP
, /* optinfo_flags */
380 gate_tree_ssa_loop_ivcanon
, /* gate */
381 tree_ssa_loop_ivcanon
, /* execute */
384 0, /* static_pass_number */
385 TV_TREE_LOOP_IVCANON
, /* tv_id */
386 PROP_cfg
| PROP_ssa
, /* properties_required */
387 0, /* properties_provided */
388 0, /* properties_destroyed */
389 0, /* todo_flags_start */
390 0 /* todo_flags_finish */
394 /* Propagation of constants using scev. */
397 gate_scev_const_prop (void)
399 return flag_tree_scev_cprop
;
402 struct gimple_opt_pass pass_scev_cprop
=
407 OPTGROUP_LOOP
, /* optinfo_flags */
408 gate_scev_const_prop
, /* gate */
409 scev_const_prop
, /* execute */
412 0, /* static_pass_number */
413 TV_SCEV_CONST
, /* tv_id */
414 PROP_cfg
| PROP_ssa
, /* properties_required */
415 0, /* properties_provided */
416 0, /* properties_destroyed */
417 0, /* todo_flags_start */
419 | TODO_update_ssa_only_virtuals
420 /* todo_flags_finish */
424 /* Record bounds on numbers of iterations of loops. */
427 tree_ssa_loop_bounds (void)
429 if (number_of_loops () <= 1)
432 estimate_numbers_of_iterations ();
437 struct gimple_opt_pass pass_record_bounds
=
441 "*record_bounds", /* name */
442 OPTGROUP_NONE
, /* optinfo_flags */
444 tree_ssa_loop_bounds
, /* execute */
447 0, /* static_pass_number */
448 TV_TREE_LOOP_BOUNDS
, /* tv_id */
449 PROP_cfg
| PROP_ssa
, /* properties_required */
450 0, /* properties_provided */
451 0, /* properties_destroyed */
452 0, /* todo_flags_start */
453 0 /* todo_flags_finish */
457 /* Complete unrolling of loops. */
460 tree_complete_unroll (void)
462 if (number_of_loops () <= 1)
465 return tree_unroll_loops_completely (flag_unroll_loops
467 || optimize
>= 3, true);
471 gate_tree_complete_unroll (void)
476 struct gimple_opt_pass pass_complete_unroll
=
480 "cunroll", /* name */
481 OPTGROUP_LOOP
, /* optinfo_flags */
482 gate_tree_complete_unroll
, /* gate */
483 tree_complete_unroll
, /* execute */
486 0, /* static_pass_number */
487 TV_COMPLETE_UNROLL
, /* tv_id */
488 PROP_cfg
| PROP_ssa
, /* properties_required */
489 0, /* properties_provided */
490 0, /* properties_destroyed */
491 0, /* todo_flags_start */
492 TODO_ggc_collect
/* todo_flags_finish */
496 /* Complete unrolling of inner loops. */
499 tree_complete_unroll_inner (void)
503 loop_optimizer_init (LOOPS_NORMAL
504 | LOOPS_HAVE_RECORDED_EXITS
);
505 if (number_of_loops () > 1)
508 ret
= tree_unroll_loops_completely (optimize
>= 3, false);
509 free_numbers_of_iterations_estimates ();
512 loop_optimizer_finalize ();
518 gate_tree_complete_unroll_inner (void)
520 return optimize
>= 2;
523 struct gimple_opt_pass pass_complete_unrolli
=
527 "cunrolli", /* name */
528 OPTGROUP_LOOP
, /* optinfo_flags */
529 gate_tree_complete_unroll_inner
, /* gate */
530 tree_complete_unroll_inner
, /* execute */
533 0, /* static_pass_number */
534 TV_COMPLETE_UNROLL
, /* tv_id */
535 PROP_cfg
| PROP_ssa
, /* properties_required */
536 0, /* properties_provided */
537 0, /* properties_destroyed */
538 0, /* todo_flags_start */
540 | TODO_ggc_collect
/* todo_flags_finish */
544 /* Parallelization. */
547 gate_tree_parallelize_loops (void)
549 return flag_tree_parallelize_loops
> 1;
553 tree_parallelize_loops (void)
555 if (number_of_loops () <= 1)
558 if (parallelize_loops ())
559 return TODO_cleanup_cfg
| TODO_rebuild_alias
;
563 struct gimple_opt_pass pass_parallelize_loops
=
567 "parloops", /* name */
568 OPTGROUP_LOOP
, /* optinfo_flags */
569 gate_tree_parallelize_loops
, /* gate */
570 tree_parallelize_loops
, /* execute */
573 0, /* static_pass_number */
574 TV_TREE_PARALLELIZE_LOOPS
, /* tv_id */
575 PROP_cfg
| PROP_ssa
, /* properties_required */
576 0, /* properties_provided */
577 0, /* properties_destroyed */
578 0, /* todo_flags_start */
579 0 /* todo_flags_finish */
586 tree_ssa_loop_prefetch (void)
588 if (number_of_loops () <= 1)
591 return tree_ssa_prefetch_arrays ();
595 gate_tree_ssa_loop_prefetch (void)
597 return flag_prefetch_loop_arrays
> 0;
600 struct gimple_opt_pass pass_loop_prefetch
=
604 "aprefetch", /* name */
605 OPTGROUP_LOOP
, /* optinfo_flags */
606 gate_tree_ssa_loop_prefetch
, /* gate */
607 tree_ssa_loop_prefetch
, /* execute */
610 0, /* static_pass_number */
611 TV_TREE_PREFETCH
, /* tv_id */
612 PROP_cfg
| PROP_ssa
, /* properties_required */
613 0, /* properties_provided */
614 0, /* properties_destroyed */
615 0, /* todo_flags_start */
616 0 /* todo_flags_finish */
620 /* Induction variable optimizations. */
623 tree_ssa_loop_ivopts (void)
625 if (number_of_loops () <= 1)
628 tree_ssa_iv_optimize ();
633 gate_tree_ssa_loop_ivopts (void)
635 return flag_ivopts
!= 0;
638 struct gimple_opt_pass pass_iv_optimize
=
643 OPTGROUP_LOOP
, /* optinfo_flags */
644 gate_tree_ssa_loop_ivopts
, /* gate */
645 tree_ssa_loop_ivopts
, /* execute */
648 0, /* static_pass_number */
649 TV_TREE_LOOP_IVOPTS
, /* tv_id */
650 PROP_cfg
| PROP_ssa
, /* properties_required */
651 0, /* properties_provided */
652 0, /* properties_destroyed */
653 0, /* todo_flags_start */
654 TODO_update_ssa
| TODO_ggc_collect
/* todo_flags_finish */
658 /* Loop optimizer finalization. */
661 tree_ssa_loop_done (void)
663 free_numbers_of_iterations_estimates ();
665 loop_optimizer_finalize ();
669 struct gimple_opt_pass pass_tree_loop_done
=
673 "loopdone", /* name */
674 OPTGROUP_LOOP
, /* optinfo_flags */
676 tree_ssa_loop_done
, /* execute */
679 0, /* static_pass_number */
681 PROP_cfg
, /* properties_required */
682 0, /* properties_provided */
683 0, /* properties_destroyed */
684 0, /* todo_flags_start */
686 | TODO_verify_flow
/* todo_flags_finish */