1 /* Loop optimizations over tree-ssa.
2 Copyright (C) 2003, 2005, 2006, 2007 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"
27 #include "hard-reg-set.h"
28 #include "basic-block.h"
30 #include "diagnostic.h"
31 #include "tree-flow.h"
32 #include "tree-dump.h"
33 #include "tree-pass.h"
37 #include "tree-inline.h"
38 #include "tree-scalar-evolution.h"
40 /* Initializes the loop structures. */
43 tree_loop_optimizer_init (void)
45 loop_optimizer_init (LOOPS_NORMAL
46 | LOOPS_HAVE_RECORDED_EXITS
);
47 rewrite_into_loop_closed_ssa (NULL
, TODO_update_ssa
);
50 /* The loop superpass. */
55 return flag_tree_loop_optimize
!= 0;
58 struct gimple_opt_pass pass_tree_loop
=
63 gate_tree_loop
, /* gate */
67 0, /* static_pass_number */
68 TV_TREE_LOOP
, /* tv_id */
69 PROP_cfg
, /* properties_required */
70 0, /* properties_provided */
71 0, /* properties_destroyed */
72 TODO_ggc_collect
, /* todo_flags_start */
73 TODO_dump_func
| TODO_verify_ssa
| TODO_ggc_collect
/* todo_flags_finish */
77 /* Loop optimizer initialization. */
80 tree_ssa_loop_init (void)
82 tree_loop_optimizer_init ();
83 if (number_of_loops () <= 1)
90 struct gimple_opt_pass pass_tree_loop_init
=
94 "loopinit", /* name */
96 tree_ssa_loop_init
, /* execute */
99 0, /* static_pass_number */
100 TV_TREE_LOOP_INIT
, /* tv_id */
101 PROP_cfg
, /* properties_required */
102 0, /* properties_provided */
103 0, /* properties_destroyed */
104 0, /* todo_flags_start */
105 TODO_dump_func
| TODO_verify_loops
/* todo_flags_finish */
109 /* Loop invariant motion pass. */
112 tree_ssa_loop_im (void)
114 if (number_of_loops () <= 1)
122 gate_tree_ssa_loop_im (void)
124 return flag_tree_loop_im
!= 0;
127 struct gimple_opt_pass pass_lim
=
132 gate_tree_ssa_loop_im
, /* gate */
133 tree_ssa_loop_im
, /* execute */
136 0, /* static_pass_number */
138 PROP_cfg
, /* properties_required */
139 0, /* properties_provided */
140 0, /* properties_destroyed */
141 0, /* todo_flags_start */
142 TODO_dump_func
| TODO_verify_loops
/* todo_flags_finish */
146 /* Loop unswitching pass. */
149 tree_ssa_loop_unswitch (void)
151 if (number_of_loops () <= 1)
154 return tree_ssa_unswitch_loops ();
158 gate_tree_ssa_loop_unswitch (void)
160 return flag_unswitch_loops
!= 0;
163 struct gimple_opt_pass pass_tree_unswitch
=
167 "unswitch", /* name */
168 gate_tree_ssa_loop_unswitch
, /* gate */
169 tree_ssa_loop_unswitch
, /* execute */
172 0, /* static_pass_number */
173 TV_TREE_LOOP_UNSWITCH
, /* tv_id */
174 PROP_cfg
, /* properties_required */
175 0, /* properties_provided */
176 0, /* properties_destroyed */
177 0, /* todo_flags_start */
178 TODO_ggc_collect
| TODO_dump_func
179 | TODO_verify_loops
/* todo_flags_finish */
183 /* Predictive commoning. */
186 run_tree_predictive_commoning (void)
191 tree_predictive_commoning ();
196 gate_tree_predictive_commoning (void)
198 return flag_predictive_commoning
!= 0;
201 struct gimple_opt_pass pass_predcom
=
206 gate_tree_predictive_commoning
, /* gate */
207 run_tree_predictive_commoning
, /* execute */
210 0, /* static_pass_number */
211 TV_PREDCOM
, /* tv_id */
212 PROP_cfg
, /* properties_required */
213 0, /* properties_provided */
214 0, /* properties_destroyed */
215 0, /* todo_flags_start */
216 TODO_dump_func
| TODO_verify_loops
217 | TODO_update_ssa_only_virtuals
/* todo_flags_finish */
221 /* Loop autovectorization. */
224 tree_vectorize (void)
226 if (number_of_loops () <= 1)
229 return vectorize_loops ();
233 gate_tree_vectorize (void)
235 return flag_tree_vectorize
;
238 struct gimple_opt_pass pass_vectorize
=
243 gate_tree_vectorize
, /* gate */
244 tree_vectorize
, /* execute */
247 0, /* static_pass_number */
248 TV_TREE_VECTORIZATION
, /* tv_id */
249 PROP_cfg
| PROP_ssa
, /* properties_required */
250 0, /* properties_provided */
251 0, /* properties_destroyed */
252 TODO_verify_loops
, /* todo_flags_start */
253 TODO_dump_func
| TODO_update_ssa
254 | TODO_ggc_collect
/* todo_flags_finish */
258 /* Loop nest optimizations. */
261 tree_linear_transform (void)
263 if (number_of_loops () <= 1)
266 linear_transform_loops ();
271 gate_tree_linear_transform (void)
273 return flag_tree_loop_linear
!= 0;
276 struct gimple_opt_pass pass_linear_transform
=
281 gate_tree_linear_transform
, /* gate */
282 tree_linear_transform
, /* execute */
285 0, /* static_pass_number */
286 TV_TREE_LINEAR_TRANSFORM
, /* tv_id */
287 PROP_cfg
| PROP_ssa
, /* properties_required */
288 0, /* properties_provided */
289 0, /* properties_destroyed */
290 0, /* todo_flags_start */
291 TODO_dump_func
| TODO_verify_loops
292 | TODO_update_ssa_only_virtuals
293 | TODO_ggc_collect
/* todo_flags_finish */
297 /* Check the correctness of the data dependence analyzers. */
300 check_data_deps (void)
302 if (number_of_loops () <= 1)
305 tree_check_data_deps ();
310 gate_check_data_deps (void)
312 return flag_check_data_deps
!= 0;
315 struct gimple_opt_pass pass_check_data_deps
=
320 gate_check_data_deps
, /* gate */
321 check_data_deps
, /* execute */
324 0, /* static_pass_number */
325 TV_CHECK_DATA_DEPS
, /* tv_id */
326 PROP_cfg
| PROP_ssa
, /* properties_required */
327 0, /* properties_provided */
328 0, /* properties_destroyed */
329 0, /* todo_flags_start */
330 TODO_dump_func
/* todo_flags_finish */
334 /* Canonical induction variable creation pass. */
337 tree_ssa_loop_ivcanon (void)
339 if (number_of_loops () <= 1)
342 return canonicalize_induction_variables ();
346 gate_tree_ssa_loop_ivcanon (void)
348 return flag_tree_loop_ivcanon
!= 0;
351 struct gimple_opt_pass pass_iv_canon
=
355 "ivcanon", /* name */
356 gate_tree_ssa_loop_ivcanon
, /* gate */
357 tree_ssa_loop_ivcanon
, /* execute */
360 0, /* static_pass_number */
361 TV_TREE_LOOP_IVCANON
, /* tv_id */
362 PROP_cfg
| PROP_ssa
, /* properties_required */
363 0, /* properties_provided */
364 0, /* properties_destroyed */
365 0, /* todo_flags_start */
366 TODO_dump_func
| TODO_verify_loops
/* todo_flags_finish */
370 /* Propagation of constants using scev. */
373 gate_scev_const_prop (void)
375 return flag_tree_scev_cprop
;
378 struct gimple_opt_pass pass_scev_cprop
=
383 gate_scev_const_prop
, /* gate */
384 scev_const_prop
, /* execute */
387 0, /* static_pass_number */
388 TV_SCEV_CONST
, /* tv_id */
389 PROP_cfg
| PROP_ssa
, /* properties_required */
390 0, /* properties_provided */
391 0, /* properties_destroyed */
392 0, /* todo_flags_start */
393 TODO_dump_func
| TODO_cleanup_cfg
394 | TODO_update_ssa_only_virtuals
395 /* todo_flags_finish */
399 /* Remove empty loops. */
402 tree_ssa_empty_loop (void)
404 if (number_of_loops () <= 1)
407 return remove_empty_loops ();
410 struct gimple_opt_pass pass_empty_loop
=
416 tree_ssa_empty_loop
, /* execute */
419 0, /* static_pass_number */
420 TV_COMPLETE_UNROLL
, /* tv_id */
421 PROP_cfg
| PROP_ssa
, /* properties_required */
422 0, /* properties_provided */
423 0, /* properties_destroyed */
424 0, /* todo_flags_start */
425 TODO_dump_func
| TODO_verify_loops
426 | TODO_ggc_collect
/* todo_flags_finish */
430 /* Record bounds on numbers of iterations of loops. */
433 tree_ssa_loop_bounds (void)
435 if (number_of_loops () <= 1)
438 estimate_numbers_of_iterations ();
443 struct gimple_opt_pass pass_record_bounds
=
449 tree_ssa_loop_bounds
, /* execute */
452 0, /* static_pass_number */
453 TV_TREE_LOOP_BOUNDS
, /* tv_id */
454 PROP_cfg
| PROP_ssa
, /* properties_required */
455 0, /* properties_provided */
456 0, /* properties_destroyed */
457 0, /* todo_flags_start */
458 0 /* todo_flags_finish */
462 /* Complete unrolling of loops. */
465 tree_complete_unroll (void)
467 if (number_of_loops () <= 1)
470 return tree_unroll_loops_completely (flag_unroll_loops
472 || optimize
>= 3, true);
476 gate_tree_complete_unroll (void)
481 struct gimple_opt_pass pass_complete_unroll
=
485 "cunroll", /* name */
486 gate_tree_complete_unroll
, /* gate */
487 tree_complete_unroll
, /* execute */
490 0, /* static_pass_number */
491 TV_COMPLETE_UNROLL
, /* tv_id */
492 PROP_cfg
| PROP_ssa
, /* properties_required */
493 0, /* properties_provided */
494 0, /* properties_destroyed */
495 0, /* todo_flags_start */
496 TODO_dump_func
| TODO_verify_loops
497 | TODO_ggc_collect
/* todo_flags_finish */
501 /* Complete unrolling of inner loops. */
504 tree_complete_unroll_inner (void)
508 loop_optimizer_init (LOOPS_NORMAL
509 | LOOPS_HAVE_RECORDED_EXITS
);
510 if (number_of_loops () > 1)
513 ret
= tree_unroll_loops_completely (optimize
>= 3, false);
514 free_numbers_of_iterations_estimates ();
517 loop_optimizer_finalize ();
523 gate_tree_complete_unroll_inner (void)
525 return optimize
>= 2;
528 struct gimple_opt_pass pass_complete_unrolli
=
532 "cunrolli", /* name */
533 gate_tree_complete_unroll_inner
, /* gate */
534 tree_complete_unroll_inner
, /* execute */
537 0, /* static_pass_number */
538 TV_COMPLETE_UNROLL
, /* tv_id */
539 PROP_cfg
| PROP_ssa
, /* properties_required */
540 0, /* properties_provided */
541 0, /* properties_destroyed */
542 0, /* todo_flags_start */
543 TODO_dump_func
| TODO_verify_loops
544 | TODO_ggc_collect
/* todo_flags_finish */
548 /* Parallelization. */
551 gate_tree_parallelize_loops (void)
553 return flag_tree_parallelize_loops
> 1;
557 tree_parallelize_loops (void)
559 if (number_of_loops () <= 1)
562 if (parallelize_loops ())
563 return TODO_cleanup_cfg
| TODO_rebuild_alias
;
567 struct gimple_opt_pass pass_parallelize_loops
=
571 "parloops", /* name */
572 gate_tree_parallelize_loops
, /* gate */
573 tree_parallelize_loops
, /* execute */
576 0, /* static_pass_number */
577 TV_TREE_PARALLELIZE_LOOPS
, /* tv_id */
578 PROP_cfg
| PROP_ssa
, /* properties_required */
579 0, /* properties_provided */
580 0, /* properties_destroyed */
581 0, /* todo_flags_start */
582 TODO_dump_func
| TODO_verify_loops
/* todo_flags_finish */
589 tree_ssa_loop_prefetch (void)
591 if (number_of_loops () <= 1)
594 return tree_ssa_prefetch_arrays ();
598 gate_tree_ssa_loop_prefetch (void)
600 return flag_prefetch_loop_arrays
!= 0;
603 struct gimple_opt_pass pass_loop_prefetch
=
607 "aprefetch", /* name */
608 gate_tree_ssa_loop_prefetch
, /* gate */
609 tree_ssa_loop_prefetch
, /* execute */
612 0, /* static_pass_number */
613 TV_TREE_PREFETCH
, /* tv_id */
614 PROP_cfg
| PROP_ssa
, /* properties_required */
615 0, /* properties_provided */
616 0, /* properties_destroyed */
617 0, /* todo_flags_start */
618 TODO_dump_func
| TODO_verify_loops
/* todo_flags_finish */
622 /* Induction variable optimizations. */
625 tree_ssa_loop_ivopts (void)
627 if (number_of_loops () <= 1)
630 tree_ssa_iv_optimize ();
635 gate_tree_ssa_loop_ivopts (void)
637 return flag_ivopts
!= 0;
640 struct gimple_opt_pass pass_iv_optimize
=
645 gate_tree_ssa_loop_ivopts
, /* gate */
646 tree_ssa_loop_ivopts
, /* execute */
649 0, /* static_pass_number */
650 TV_TREE_LOOP_IVOPTS
, /* tv_id */
651 PROP_cfg
| PROP_ssa
, /* properties_required */
652 0, /* properties_provided */
653 0, /* properties_destroyed */
654 0, /* todo_flags_start */
655 TODO_dump_func
| TODO_verify_loops
656 | TODO_update_ssa
| TODO_ggc_collect
/* todo_flags_finish */
660 /* Loop optimizer finalization. */
663 tree_ssa_loop_done (void)
665 free_numbers_of_iterations_estimates ();
667 loop_optimizer_finalize ();
671 struct gimple_opt_pass pass_tree_loop_done
=
675 "loopdone", /* name */
677 tree_ssa_loop_done
, /* execute */
680 0, /* static_pass_number */
681 TV_TREE_LOOP_FINI
, /* tv_id */
682 PROP_cfg
, /* properties_required */
683 0, /* properties_provided */
684 0, /* properties_destroyed */
685 0, /* todo_flags_start */
686 TODO_cleanup_cfg
| TODO_dump_func
/* todo_flags_finish */