gcc/cp/
[official-gcc.git] / gcc / tree-ssa-loop.c
blob52f5a7f58f8c47a5b69b13b91bcd0c10c40a51cc
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
9 later version.
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
14 for more details.
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/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "tree.h"
25 #include "rtl.h"
26 #include "tm_p.h"
27 #include "hard-reg-set.h"
28 #include "basic-block.h"
29 #include "output.h"
30 #include "diagnostic.h"
31 #include "tree-flow.h"
32 #include "tree-dump.h"
33 #include "tree-pass.h"
34 #include "timevar.h"
35 #include "cfgloop.h"
36 #include "flags.h"
37 #include "tree-inline.h"
38 #include "tree-scalar-evolution.h"
40 /* Initializes the loop structures. */
42 static void
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. */
52 static bool
53 gate_tree_loop (void)
55 return flag_tree_loop_optimize != 0;
58 struct gimple_opt_pass pass_tree_loop =
61 GIMPLE_PASS,
62 "loop", /* name */
63 gate_tree_loop, /* gate */
64 NULL, /* execute */
65 NULL, /* sub */
66 NULL, /* next */
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. */
79 static unsigned int
80 tree_ssa_loop_init (void)
82 tree_loop_optimizer_init ();
83 if (number_of_loops () <= 1)
84 return 0;
86 scev_initialize ();
87 return 0;
90 struct gimple_opt_pass pass_tree_loop_init =
93 GIMPLE_PASS,
94 "loopinit", /* name */
95 NULL, /* gate */
96 tree_ssa_loop_init, /* execute */
97 NULL, /* sub */
98 NULL, /* next */
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. */
111 static unsigned int
112 tree_ssa_loop_im (void)
114 if (number_of_loops () <= 1)
115 return 0;
117 tree_ssa_lim ();
118 return 0;
121 static bool
122 gate_tree_ssa_loop_im (void)
124 return flag_tree_loop_im != 0;
127 struct gimple_opt_pass pass_lim =
130 GIMPLE_PASS,
131 "lim", /* name */
132 gate_tree_ssa_loop_im, /* gate */
133 tree_ssa_loop_im, /* execute */
134 NULL, /* sub */
135 NULL, /* next */
136 0, /* static_pass_number */
137 TV_LIM, /* tv_id */
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. */
148 static unsigned int
149 tree_ssa_loop_unswitch (void)
151 if (number_of_loops () <= 1)
152 return 0;
154 return tree_ssa_unswitch_loops ();
157 static bool
158 gate_tree_ssa_loop_unswitch (void)
160 return flag_unswitch_loops != 0;
163 struct gimple_opt_pass pass_tree_unswitch =
166 GIMPLE_PASS,
167 "unswitch", /* name */
168 gate_tree_ssa_loop_unswitch, /* gate */
169 tree_ssa_loop_unswitch, /* execute */
170 NULL, /* sub */
171 NULL, /* next */
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. */
185 static unsigned
186 run_tree_predictive_commoning (void)
188 if (!current_loops)
189 return 0;
191 tree_predictive_commoning ();
192 return 0;
195 static bool
196 gate_tree_predictive_commoning (void)
198 return flag_predictive_commoning != 0;
201 struct gimple_opt_pass pass_predcom =
204 GIMPLE_PASS,
205 "pcom", /* name */
206 gate_tree_predictive_commoning, /* gate */
207 run_tree_predictive_commoning, /* execute */
208 NULL, /* sub */
209 NULL, /* next */
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. */
223 static unsigned int
224 tree_vectorize (void)
226 if (number_of_loops () <= 1)
227 return 0;
229 return vectorize_loops ();
232 static bool
233 gate_tree_vectorize (void)
235 return flag_tree_vectorize;
238 struct gimple_opt_pass pass_vectorize =
241 GIMPLE_PASS,
242 "vect", /* name */
243 gate_tree_vectorize, /* gate */
244 tree_vectorize, /* execute */
245 NULL, /* sub */
246 NULL, /* next */
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. */
260 static unsigned int
261 tree_linear_transform (void)
263 if (number_of_loops () <= 1)
264 return 0;
266 linear_transform_loops ();
267 return 0;
270 static bool
271 gate_tree_linear_transform (void)
273 return flag_tree_loop_linear != 0;
276 struct gimple_opt_pass pass_linear_transform =
279 GIMPLE_PASS,
280 "ltrans", /* name */
281 gate_tree_linear_transform, /* gate */
282 tree_linear_transform, /* execute */
283 NULL, /* sub */
284 NULL, /* next */
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. */
299 static unsigned int
300 check_data_deps (void)
302 if (number_of_loops () <= 1)
303 return 0;
305 tree_check_data_deps ();
306 return 0;
309 static bool
310 gate_check_data_deps (void)
312 return flag_check_data_deps != 0;
315 struct gimple_opt_pass pass_check_data_deps =
318 GIMPLE_PASS,
319 "ckdd", /* name */
320 gate_check_data_deps, /* gate */
321 check_data_deps, /* execute */
322 NULL, /* sub */
323 NULL, /* next */
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. */
336 static unsigned int
337 tree_ssa_loop_ivcanon (void)
339 if (number_of_loops () <= 1)
340 return 0;
342 return canonicalize_induction_variables ();
345 static bool
346 gate_tree_ssa_loop_ivcanon (void)
348 return flag_tree_loop_ivcanon != 0;
351 struct gimple_opt_pass pass_iv_canon =
354 GIMPLE_PASS,
355 "ivcanon", /* name */
356 gate_tree_ssa_loop_ivcanon, /* gate */
357 tree_ssa_loop_ivcanon, /* execute */
358 NULL, /* sub */
359 NULL, /* next */
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. */
372 static bool
373 gate_scev_const_prop (void)
375 return flag_tree_scev_cprop;
378 struct gimple_opt_pass pass_scev_cprop =
381 GIMPLE_PASS,
382 "sccp", /* name */
383 gate_scev_const_prop, /* gate */
384 scev_const_prop, /* execute */
385 NULL, /* sub */
386 NULL, /* next */
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. */
401 static unsigned int
402 tree_ssa_empty_loop (void)
404 if (number_of_loops () <= 1)
405 return 0;
407 return remove_empty_loops ();
410 struct gimple_opt_pass pass_empty_loop =
413 GIMPLE_PASS,
414 "empty", /* name */
415 NULL, /* gate */
416 tree_ssa_empty_loop, /* execute */
417 NULL, /* sub */
418 NULL, /* next */
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. */
432 static unsigned int
433 tree_ssa_loop_bounds (void)
435 if (number_of_loops () <= 1)
436 return 0;
438 estimate_numbers_of_iterations ();
439 scev_reset ();
440 return 0;
443 struct gimple_opt_pass pass_record_bounds =
446 GIMPLE_PASS,
447 NULL, /* name */
448 NULL, /* gate */
449 tree_ssa_loop_bounds, /* execute */
450 NULL, /* sub */
451 NULL, /* next */
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. */
464 static unsigned int
465 tree_complete_unroll (void)
467 if (number_of_loops () <= 1)
468 return 0;
470 return tree_unroll_loops_completely (flag_unroll_loops
471 || flag_peel_loops
472 || optimize >= 3, true);
475 static bool
476 gate_tree_complete_unroll (void)
478 return true;
481 struct gimple_opt_pass pass_complete_unroll =
484 GIMPLE_PASS,
485 "cunroll", /* name */
486 gate_tree_complete_unroll, /* gate */
487 tree_complete_unroll, /* execute */
488 NULL, /* sub */
489 NULL, /* next */
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. */
503 static unsigned int
504 tree_complete_unroll_inner (void)
506 unsigned ret = 0;
508 loop_optimizer_init (LOOPS_NORMAL
509 | LOOPS_HAVE_RECORDED_EXITS);
510 if (number_of_loops () > 1)
512 scev_initialize ();
513 ret = tree_unroll_loops_completely (optimize >= 3, false);
514 free_numbers_of_iterations_estimates ();
515 scev_finalize ();
517 loop_optimizer_finalize ();
519 return ret;
522 static bool
523 gate_tree_complete_unroll_inner (void)
525 return optimize >= 2;
528 struct gimple_opt_pass pass_complete_unrolli =
531 GIMPLE_PASS,
532 "cunrolli", /* name */
533 gate_tree_complete_unroll_inner, /* gate */
534 tree_complete_unroll_inner, /* execute */
535 NULL, /* sub */
536 NULL, /* next */
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. */
550 static bool
551 gate_tree_parallelize_loops (void)
553 return flag_tree_parallelize_loops > 1;
556 static unsigned
557 tree_parallelize_loops (void)
559 if (number_of_loops () <= 1)
560 return 0;
562 if (parallelize_loops ())
563 return TODO_cleanup_cfg | TODO_rebuild_alias;
564 return 0;
567 struct gimple_opt_pass pass_parallelize_loops =
570 GIMPLE_PASS,
571 "parloops", /* name */
572 gate_tree_parallelize_loops, /* gate */
573 tree_parallelize_loops, /* execute */
574 NULL, /* sub */
575 NULL, /* next */
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 */
586 /* Prefetching. */
588 static unsigned int
589 tree_ssa_loop_prefetch (void)
591 if (number_of_loops () <= 1)
592 return 0;
594 return tree_ssa_prefetch_arrays ();
597 static bool
598 gate_tree_ssa_loop_prefetch (void)
600 return flag_prefetch_loop_arrays != 0;
603 struct gimple_opt_pass pass_loop_prefetch =
606 GIMPLE_PASS,
607 "aprefetch", /* name */
608 gate_tree_ssa_loop_prefetch, /* gate */
609 tree_ssa_loop_prefetch, /* execute */
610 NULL, /* sub */
611 NULL, /* next */
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. */
624 static unsigned int
625 tree_ssa_loop_ivopts (void)
627 if (number_of_loops () <= 1)
628 return 0;
630 tree_ssa_iv_optimize ();
631 return 0;
634 static bool
635 gate_tree_ssa_loop_ivopts (void)
637 return flag_ivopts != 0;
640 struct gimple_opt_pass pass_iv_optimize =
643 GIMPLE_PASS,
644 "ivopts", /* name */
645 gate_tree_ssa_loop_ivopts, /* gate */
646 tree_ssa_loop_ivopts, /* execute */
647 NULL, /* sub */
648 NULL, /* next */
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. */
662 static unsigned int
663 tree_ssa_loop_done (void)
665 free_numbers_of_iterations_estimates ();
666 scev_finalize ();
667 loop_optimizer_finalize ();
668 return 0;
671 struct gimple_opt_pass pass_tree_loop_done =
674 GIMPLE_PASS,
675 "loopdone", /* name */
676 NULL, /* gate */
677 tree_ssa_loop_done, /* execute */
678 NULL, /* sub */
679 NULL, /* next */
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 */