]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-ssa-loop.c
* Makefile.in (omp-low.o): Depend on $(TARGET_H).
[thirdparty/gcc.git] / gcc / tree-ssa-loop.c
CommitLineData
4ee9c684 1/* Loop optimizations over tree-ssa.
711789cc 2 Copyright (C) 2003-2013 Free Software Foundation, Inc.
48e1416a 3
4ee9c684 4This file is part of GCC.
48e1416a 5
4ee9c684 6GCC is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8c4c00c1 8Free Software Foundation; either version 3, or (at your option) any
4ee9c684 9later version.
48e1416a 10
4ee9c684 11GCC is distributed in the hope that it will be useful, but WITHOUT
12ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
48e1416a 15
4ee9c684 16You should have received a copy of the GNU General Public License
8c4c00c1 17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
4ee9c684 19
20#include "config.h"
21#include "system.h"
22#include "coretypes.h"
23#include "tm.h"
24#include "tree.h"
4ee9c684 25#include "tm_p.h"
4ee9c684 26#include "basic-block.h"
4ee9c684 27#include "tree-flow.h"
4ee9c684 28#include "tree-pass.h"
4ee9c684 29#include "cfgloop.h"
30#include "flags.h"
31#include "tree-inline.h"
c91e8223 32#include "tree-scalar-evolution.h"
0b205f4c 33#include "diagnostic-core.h"
10230637 34#include "tree-vectorizer.h"
4ee9c684 35
dcb9eccb 36/* The loop superpass. */
37
38static bool
0526a3ff 39gate_tree_loop (void)
dcb9eccb 40{
41 return flag_tree_loop_optimize != 0;
42}
43
cbe8bda8 44namespace {
45
46const pass_data pass_data_tree_loop =
47{
48 GIMPLE_PASS, /* type */
49 "loop", /* name */
50 OPTGROUP_LOOP, /* optinfo_flags */
51 true, /* has_gate */
52 false, /* has_execute */
53 TV_TREE_LOOP, /* tv_id */
54 PROP_cfg, /* properties_required */
55 0, /* properties_provided */
56 0, /* properties_destroyed */
57 0, /* todo_flags_start */
58 TODO_verify_ssa, /* todo_flags_finish */
dcb9eccb 59};
60
cbe8bda8 61class pass_tree_loop : public gimple_opt_pass
62{
63public:
64 pass_tree_loop(gcc::context *ctxt)
65 : gimple_opt_pass(pass_data_tree_loop, ctxt)
66 {}
67
68 /* opt_pass methods: */
69 bool gate () { return gate_tree_loop (); }
70
71}; // class pass_tree_loop
72
73} // anon namespace
74
75gimple_opt_pass *
76make_pass_tree_loop (gcc::context *ctxt)
77{
78 return new pass_tree_loop (ctxt);
79}
80
dcb9eccb 81/* Loop optimizer initialization. */
82
2a1990e9 83static unsigned int
dcb9eccb 84tree_ssa_loop_init (void)
85{
75a70cf9 86 loop_optimizer_init (LOOPS_NORMAL
87 | LOOPS_HAVE_RECORDED_EXITS);
88 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
89
9df082d2 90 /* We might discover new loops, e.g. when turning irreducible
91 regions into reducible. */
92 scev_initialize ();
93
41f75a99 94 if (number_of_loops (cfun) <= 1)
2a1990e9 95 return 0;
bb445479 96
2a1990e9 97 return 0;
dcb9eccb 98}
48e1416a 99
cbe8bda8 100namespace {
101
102const pass_data pass_data_tree_loop_init =
103{
104 GIMPLE_PASS, /* type */
105 "loopinit", /* name */
106 OPTGROUP_LOOP, /* optinfo_flags */
107 false, /* has_gate */
108 true, /* has_execute */
109 TV_NONE, /* tv_id */
110 PROP_cfg, /* properties_required */
111 0, /* properties_provided */
112 0, /* properties_destroyed */
113 0, /* todo_flags_start */
114 0, /* todo_flags_finish */
dcb9eccb 115};
116
cbe8bda8 117class pass_tree_loop_init : public gimple_opt_pass
118{
119public:
120 pass_tree_loop_init(gcc::context *ctxt)
121 : gimple_opt_pass(pass_data_tree_loop_init, ctxt)
122 {}
123
124 /* opt_pass methods: */
125 unsigned int execute () { return tree_ssa_loop_init (); }
126
127}; // class pass_tree_loop_init
128
129} // anon namespace
130
131gimple_opt_pass *
132make_pass_tree_loop_init (gcc::context *ctxt)
133{
134 return new pass_tree_loop_init (ctxt);
135}
136
7d23383d 137/* Loop invariant motion pass. */
138
2a1990e9 139static unsigned int
7d23383d 140tree_ssa_loop_im (void)
141{
41f75a99 142 if (number_of_loops (cfun) <= 1)
2a1990e9 143 return 0;
7d23383d 144
9bf0a3f9 145 return tree_ssa_lim ();
7d23383d 146}
147
148static bool
149gate_tree_ssa_loop_im (void)
150{
41b5cc78 151 return flag_tree_loop_im != 0;
7d23383d 152}
153
cbe8bda8 154namespace {
155
156const pass_data pass_data_lim =
157{
158 GIMPLE_PASS, /* type */
159 "lim", /* name */
160 OPTGROUP_LOOP, /* optinfo_flags */
161 true, /* has_gate */
162 true, /* has_execute */
163 TV_LIM, /* tv_id */
164 PROP_cfg, /* properties_required */
165 0, /* properties_provided */
166 0, /* properties_destroyed */
167 0, /* todo_flags_start */
168 0, /* todo_flags_finish */
e12d0591 169};
170
cbe8bda8 171class pass_lim : public gimple_opt_pass
172{
173public:
174 pass_lim(gcc::context *ctxt)
175 : gimple_opt_pass(pass_data_lim, ctxt)
176 {}
177
178 /* opt_pass methods: */
179 opt_pass * clone () { return new pass_lim (ctxt_); }
180 bool gate () { return gate_tree_ssa_loop_im (); }
181 unsigned int execute () { return tree_ssa_loop_im (); }
182
183}; // class pass_lim
184
185} // anon namespace
186
187gimple_opt_pass *
188make_pass_lim (gcc::context *ctxt)
189{
190 return new pass_lim (ctxt);
191}
192
e12d0591 193/* Loop unswitching pass. */
194
2a1990e9 195static unsigned int
e12d0591 196tree_ssa_loop_unswitch (void)
197{
41f75a99 198 if (number_of_loops (cfun) <= 1)
2a1990e9 199 return 0;
e12d0591 200
7194de72 201 return tree_ssa_unswitch_loops ();
e12d0591 202}
203
204static bool
205gate_tree_ssa_loop_unswitch (void)
206{
207 return flag_unswitch_loops != 0;
208}
209
cbe8bda8 210namespace {
211
212const pass_data pass_data_tree_unswitch =
213{
214 GIMPLE_PASS, /* type */
215 "unswitch", /* name */
216 OPTGROUP_LOOP, /* optinfo_flags */
217 true, /* has_gate */
218 true, /* has_execute */
219 TV_TREE_LOOP_UNSWITCH, /* tv_id */
220 PROP_cfg, /* properties_required */
221 0, /* properties_provided */
222 0, /* properties_destroyed */
223 0, /* todo_flags_start */
224 0, /* todo_flags_finish */
7d23383d 225};
226
cbe8bda8 227class pass_tree_unswitch : public gimple_opt_pass
228{
229public:
230 pass_tree_unswitch(gcc::context *ctxt)
231 : gimple_opt_pass(pass_data_tree_unswitch, ctxt)
232 {}
233
234 /* opt_pass methods: */
235 bool gate () { return gate_tree_ssa_loop_unswitch (); }
236 unsigned int execute () { return tree_ssa_loop_unswitch (); }
237
238}; // class pass_tree_unswitch
239
240} // anon namespace
241
242gimple_opt_pass *
243make_pass_tree_unswitch (gcc::context *ctxt)
244{
245 return new pass_tree_unswitch (ctxt);
246}
247
ad4a85ad 248/* Predictive commoning. */
249
250static unsigned
251run_tree_predictive_commoning (void)
252{
253 if (!current_loops)
254 return 0;
255
e5d5c850 256 return tree_predictive_commoning ();
ad4a85ad 257}
258
259static bool
260gate_tree_predictive_commoning (void)
261{
262 return flag_predictive_commoning != 0;
263}
264
cbe8bda8 265namespace {
266
267const pass_data pass_data_predcom =
268{
269 GIMPLE_PASS, /* type */
270 "pcom", /* name */
271 OPTGROUP_LOOP, /* optinfo_flags */
272 true, /* has_gate */
273 true, /* has_execute */
274 TV_PREDCOM, /* tv_id */
275 PROP_cfg, /* properties_required */
276 0, /* properties_provided */
277 0, /* properties_destroyed */
278 0, /* todo_flags_start */
279 TODO_update_ssa_only_virtuals, /* todo_flags_finish */
ad4a85ad 280};
281
cbe8bda8 282class pass_predcom : public gimple_opt_pass
283{
284public:
285 pass_predcom(gcc::context *ctxt)
286 : gimple_opt_pass(pass_data_predcom, ctxt)
287 {}
288
289 /* opt_pass methods: */
290 bool gate () { return gate_tree_predictive_commoning (); }
291 unsigned int execute () { return run_tree_predictive_commoning (); }
292
293}; // class pass_predcom
294
295} // anon namespace
296
297gimple_opt_pass *
298make_pass_predcom (gcc::context *ctxt)
299{
300 return new pass_predcom (ctxt);
301}
302
c91e8223 303/* Loop autovectorization. */
304
2a1990e9 305static unsigned int
c91e8223 306tree_vectorize (void)
307{
41f75a99 308 if (number_of_loops (cfun) <= 1)
d88fd237 309 return 0;
310
7194de72 311 return vectorize_loops ();
c91e8223 312}
313
314static bool
315gate_tree_vectorize (void)
316{
3d483a94 317 return flag_tree_vectorize || cfun->has_force_vect_loops;
c91e8223 318}
319
cbe8bda8 320namespace {
321
322const pass_data pass_data_vectorize =
323{
324 GIMPLE_PASS, /* type */
325 "vect", /* name */
326 OPTGROUP_LOOP | OPTGROUP_VEC, /* optinfo_flags */
327 true, /* has_gate */
328 true, /* has_execute */
329 TV_TREE_VECTORIZATION, /* tv_id */
330 ( PROP_cfg | PROP_ssa ), /* properties_required */
331 0, /* properties_provided */
332 0, /* properties_destroyed */
333 0, /* todo_flags_start */
334 0, /* todo_flags_finish */
c91e8223 335};
336
cbe8bda8 337class pass_vectorize : public gimple_opt_pass
338{
339public:
340 pass_vectorize(gcc::context *ctxt)
341 : gimple_opt_pass(pass_data_vectorize, ctxt)
342 {}
343
344 /* opt_pass methods: */
345 bool gate () { return gate_tree_vectorize (); }
346 unsigned int execute () { return tree_vectorize (); }
347
348}; // class pass_vectorize
349
350} // anon namespace
351
352gimple_opt_pass *
353make_pass_vectorize (gcc::context *ctxt)
354{
355 return new pass_vectorize (ctxt);
356}
357
255b6be7 358/* GRAPHITE optimizations. */
359
360static unsigned int
361graphite_transforms (void)
362{
363 if (!current_loops)
364 return 0;
365
366 graphite_transform_loops ();
367
368 return 0;
369}
370
371static bool
372gate_graphite_transforms (void)
373{
48e1416a 374 /* Enable -fgraphite pass if any one of the graphite optimization flags
255b6be7 375 is turned on. */
d60a90cc 376 if (flag_loop_block
377 || flag_loop_interchange
378 || flag_loop_strip_mine
379 || flag_graphite_identity
89049f25 380 || flag_loop_parallelize_all
381 || flag_loop_optimize_isl)
255b6be7 382 flag_graphite = 1;
383
384 return flag_graphite != 0;
385}
386
cbe8bda8 387namespace {
388
389const pass_data pass_data_graphite =
390{
391 GIMPLE_PASS, /* type */
392 "graphite0", /* name */
393 OPTGROUP_LOOP, /* optinfo_flags */
394 true, /* has_gate */
395 false, /* has_execute */
396 TV_GRAPHITE, /* tv_id */
397 ( PROP_cfg | PROP_ssa ), /* properties_required */
398 0, /* properties_provided */
399 0, /* properties_destroyed */
400 0, /* todo_flags_start */
401 0, /* todo_flags_finish */
b90bb125 402};
403
cbe8bda8 404class pass_graphite : public gimple_opt_pass
405{
406public:
407 pass_graphite(gcc::context *ctxt)
408 : gimple_opt_pass(pass_data_graphite, ctxt)
409 {}
410
411 /* opt_pass methods: */
412 bool gate () { return gate_graphite_transforms (); }
413
414}; // class pass_graphite
415
416} // anon namespace
417
418gimple_opt_pass *
419make_pass_graphite (gcc::context *ctxt)
420{
421 return new pass_graphite (ctxt);
422}
423
424namespace {
425
426const pass_data pass_data_graphite_transforms =
427{
428 GIMPLE_PASS, /* type */
429 "graphite", /* name */
430 OPTGROUP_LOOP, /* optinfo_flags */
431 true, /* has_gate */
432 true, /* has_execute */
433 TV_GRAPHITE_TRANSFORMS, /* tv_id */
434 ( PROP_cfg | PROP_ssa ), /* properties_required */
435 0, /* properties_provided */
436 0, /* properties_destroyed */
437 0, /* todo_flags_start */
438 0, /* todo_flags_finish */
255b6be7 439};
440
cbe8bda8 441class pass_graphite_transforms : public gimple_opt_pass
442{
443public:
444 pass_graphite_transforms(gcc::context *ctxt)
445 : gimple_opt_pass(pass_data_graphite_transforms, ctxt)
446 {}
447
448 /* opt_pass methods: */
449 bool gate () { return gate_graphite_transforms (); }
450 unsigned int execute () { return graphite_transforms (); }
451
452}; // class pass_graphite_transforms
453
454} // anon namespace
455
456gimple_opt_pass *
457make_pass_graphite_transforms (gcc::context *ctxt)
458{
459 return new pass_graphite_transforms (ctxt);
460}
461
355572cc 462/* Check the correctness of the data dependence analyzers. */
463
464static unsigned int
465check_data_deps (void)
466{
41f75a99 467 if (number_of_loops (cfun) <= 1)
355572cc 468 return 0;
469
470 tree_check_data_deps ();
471 return 0;
472}
473
474static bool
475gate_check_data_deps (void)
476{
477 return flag_check_data_deps != 0;
478}
479
cbe8bda8 480namespace {
481
482const pass_data pass_data_check_data_deps =
483{
484 GIMPLE_PASS, /* type */
485 "ckdd", /* name */
486 OPTGROUP_LOOP, /* optinfo_flags */
487 true, /* has_gate */
488 true, /* has_execute */
489 TV_CHECK_DATA_DEPS, /* tv_id */
490 ( PROP_cfg | PROP_ssa ), /* properties_required */
491 0, /* properties_provided */
492 0, /* properties_destroyed */
493 0, /* todo_flags_start */
494 0, /* todo_flags_finish */
355572cc 495};
496
cbe8bda8 497class pass_check_data_deps : public gimple_opt_pass
498{
499public:
500 pass_check_data_deps(gcc::context *ctxt)
501 : gimple_opt_pass(pass_data_check_data_deps, ctxt)
502 {}
503
504 /* opt_pass methods: */
505 bool gate () { return gate_check_data_deps (); }
506 unsigned int execute () { return check_data_deps (); }
507
508}; // class pass_check_data_deps
509
510} // anon namespace
511
512gimple_opt_pass *
513make_pass_check_data_deps (gcc::context *ctxt)
514{
515 return new pass_check_data_deps (ctxt);
516}
517
bb445479 518/* Canonical induction variable creation pass. */
519
2a1990e9 520static unsigned int
bb445479 521tree_ssa_loop_ivcanon (void)
522{
41f75a99 523 if (number_of_loops (cfun) <= 1)
2a1990e9 524 return 0;
bb445479 525
7194de72 526 return canonicalize_induction_variables ();
bb445479 527}
528
529static bool
530gate_tree_ssa_loop_ivcanon (void)
531{
41b5cc78 532 return flag_tree_loop_ivcanon != 0;
bb445479 533}
534
cbe8bda8 535namespace {
536
537const pass_data pass_data_iv_canon =
538{
539 GIMPLE_PASS, /* type */
540 "ivcanon", /* name */
541 OPTGROUP_LOOP, /* optinfo_flags */
542 true, /* has_gate */
543 true, /* has_execute */
544 TV_TREE_LOOP_IVCANON, /* tv_id */
545 ( PROP_cfg | PROP_ssa ), /* properties_required */
546 0, /* properties_provided */
547 0, /* properties_destroyed */
548 0, /* todo_flags_start */
549 0, /* todo_flags_finish */
10fec820 550};
551
cbe8bda8 552class pass_iv_canon : public gimple_opt_pass
553{
554public:
555 pass_iv_canon(gcc::context *ctxt)
556 : gimple_opt_pass(pass_data_iv_canon, ctxt)
557 {}
558
559 /* opt_pass methods: */
560 bool gate () { return gate_tree_ssa_loop_ivcanon (); }
561 unsigned int execute () { return tree_ssa_loop_ivcanon (); }
562
563}; // class pass_iv_canon
564
565} // anon namespace
566
567gimple_opt_pass *
568make_pass_iv_canon (gcc::context *ctxt)
569{
570 return new pass_iv_canon (ctxt);
571}
572
10fec820 573/* Propagation of constants using scev. */
574
575static bool
576gate_scev_const_prop (void)
577{
2a6e95ba 578 return flag_tree_scev_cprop;
10fec820 579}
580
cbe8bda8 581namespace {
582
583const pass_data pass_data_scev_cprop =
584{
585 GIMPLE_PASS, /* type */
586 "sccp", /* name */
587 OPTGROUP_LOOP, /* optinfo_flags */
588 true, /* has_gate */
589 true, /* has_execute */
590 TV_SCEV_CONST, /* tv_id */
591 ( PROP_cfg | PROP_ssa ), /* properties_required */
592 0, /* properties_provided */
593 0, /* properties_destroyed */
594 0, /* todo_flags_start */
595 ( TODO_cleanup_cfg
596 | TODO_update_ssa_only_virtuals ), /* todo_flags_finish */
8feba661 597};
598
cbe8bda8 599class pass_scev_cprop : public gimple_opt_pass
600{
601public:
602 pass_scev_cprop(gcc::context *ctxt)
603 : gimple_opt_pass(pass_data_scev_cprop, ctxt)
604 {}
605
606 /* opt_pass methods: */
607 bool gate () { return gate_scev_const_prop (); }
608 unsigned int execute () { return scev_const_prop (); }
609
610}; // class pass_scev_cprop
611
612} // anon namespace
613
614gimple_opt_pass *
615make_pass_scev_cprop (gcc::context *ctxt)
616{
617 return new pass_scev_cprop (ctxt);
618}
619
41fc6ce4 620/* Record bounds on numbers of iterations of loops. */
621
2a1990e9 622static unsigned int
41fc6ce4 623tree_ssa_loop_bounds (void)
624{
41f75a99 625 if (number_of_loops (cfun) <= 1)
2a1990e9 626 return 0;
41fc6ce4 627
7f521ab4 628 estimate_numbers_of_iterations ();
41fc6ce4 629 scev_reset ();
2a1990e9 630 return 0;
41fc6ce4 631}
632
cbe8bda8 633namespace {
634
635const pass_data pass_data_record_bounds =
636{
637 GIMPLE_PASS, /* type */
638 "*record_bounds", /* name */
639 OPTGROUP_NONE, /* optinfo_flags */
640 false, /* has_gate */
641 true, /* has_execute */
642 TV_TREE_LOOP_BOUNDS, /* tv_id */
643 ( PROP_cfg | PROP_ssa ), /* properties_required */
644 0, /* properties_provided */
645 0, /* properties_destroyed */
646 0, /* todo_flags_start */
647 0, /* todo_flags_finish */
41fc6ce4 648};
649
cbe8bda8 650class pass_record_bounds : public gimple_opt_pass
651{
652public:
653 pass_record_bounds(gcc::context *ctxt)
654 : gimple_opt_pass(pass_data_record_bounds, ctxt)
655 {}
656
657 /* opt_pass methods: */
658 unsigned int execute () { return tree_ssa_loop_bounds (); }
659
660}; // class pass_record_bounds
661
662} // anon namespace
663
664gimple_opt_pass *
665make_pass_record_bounds (gcc::context *ctxt)
666{
667 return new pass_record_bounds (ctxt);
668}
669
bb445479 670/* Complete unrolling of loops. */
671
2a1990e9 672static unsigned int
bb445479 673tree_complete_unroll (void)
674{
41f75a99 675 if (number_of_loops (cfun) <= 1)
2a1990e9 676 return 0;
bb445479 677
7194de72 678 return tree_unroll_loops_completely (flag_unroll_loops
679 || flag_peel_loops
d88fd237 680 || optimize >= 3, true);
bb445479 681}
682
683static bool
684gate_tree_complete_unroll (void)
685{
604f7b8a 686 return true;
bb445479 687}
688
cbe8bda8 689namespace {
690
691const pass_data pass_data_complete_unroll =
692{
693 GIMPLE_PASS, /* type */
694 "cunroll", /* name */
695 OPTGROUP_LOOP, /* optinfo_flags */
696 true, /* has_gate */
697 true, /* has_execute */
698 TV_COMPLETE_UNROLL, /* tv_id */
699 ( PROP_cfg | PROP_ssa ), /* properties_required */
700 0, /* properties_provided */
701 0, /* properties_destroyed */
702 0, /* todo_flags_start */
703 0, /* todo_flags_finish */
dec41e98 704};
705
cbe8bda8 706class pass_complete_unroll : public gimple_opt_pass
707{
708public:
709 pass_complete_unroll(gcc::context *ctxt)
710 : gimple_opt_pass(pass_data_complete_unroll, ctxt)
711 {}
712
713 /* opt_pass methods: */
714 bool gate () { return gate_tree_complete_unroll (); }
715 unsigned int execute () { return tree_complete_unroll (); }
716
717}; // class pass_complete_unroll
718
719} // anon namespace
720
721gimple_opt_pass *
722make_pass_complete_unroll (gcc::context *ctxt)
723{
724 return new pass_complete_unroll (ctxt);
725}
726
d88fd237 727/* Complete unrolling of inner loops. */
728
729static unsigned int
730tree_complete_unroll_inner (void)
731{
732 unsigned ret = 0;
733
734 loop_optimizer_init (LOOPS_NORMAL
735 | LOOPS_HAVE_RECORDED_EXITS);
41f75a99 736 if (number_of_loops (cfun) > 1)
d88fd237 737 {
738 scev_initialize ();
739 ret = tree_unroll_loops_completely (optimize >= 3, false);
740 free_numbers_of_iterations_estimates ();
741 scev_finalize ();
742 }
743 loop_optimizer_finalize ();
744
745 return ret;
746}
747
748static bool
749gate_tree_complete_unroll_inner (void)
750{
751 return optimize >= 2;
752}
753
cbe8bda8 754namespace {
755
756const pass_data pass_data_complete_unrolli =
757{
758 GIMPLE_PASS, /* type */
759 "cunrolli", /* name */
760 OPTGROUP_LOOP, /* optinfo_flags */
761 true, /* has_gate */
762 true, /* has_execute */
763 TV_COMPLETE_UNROLL, /* tv_id */
764 ( PROP_cfg | PROP_ssa ), /* properties_required */
765 0, /* properties_provided */
766 0, /* properties_destroyed */
767 0, /* todo_flags_start */
768 TODO_verify_flow, /* todo_flags_finish */
d88fd237 769};
770
cbe8bda8 771class pass_complete_unrolli : public gimple_opt_pass
772{
773public:
774 pass_complete_unrolli(gcc::context *ctxt)
775 : gimple_opt_pass(pass_data_complete_unrolli, ctxt)
776 {}
777
778 /* opt_pass methods: */
779 bool gate () { return gate_tree_complete_unroll_inner (); }
780 unsigned int execute () { return tree_complete_unroll_inner (); }
781
782}; // class pass_complete_unrolli
783
784} // anon namespace
785
786gimple_opt_pass *
787make_pass_complete_unrolli (gcc::context *ctxt)
788{
789 return new pass_complete_unrolli (ctxt);
790}
791
28c92cbb 792/* Parallelization. */
793
794static bool
795gate_tree_parallelize_loops (void)
796{
326f0dc4 797 return flag_tree_parallelize_loops > 1;
28c92cbb 798}
799
800static unsigned
801tree_parallelize_loops (void)
802{
41f75a99 803 if (number_of_loops (cfun) <= 1)
28c92cbb 804 return 0;
805
806 if (parallelize_loops ())
807 return TODO_cleanup_cfg | TODO_rebuild_alias;
808 return 0;
809}
810
cbe8bda8 811namespace {
812
813const pass_data pass_data_parallelize_loops =
814{
815 GIMPLE_PASS, /* type */
816 "parloops", /* name */
817 OPTGROUP_LOOP, /* optinfo_flags */
818 true, /* has_gate */
819 true, /* has_execute */
820 TV_TREE_PARALLELIZE_LOOPS, /* tv_id */
821 ( PROP_cfg | PROP_ssa ), /* properties_required */
822 0, /* properties_provided */
823 0, /* properties_destroyed */
824 0, /* todo_flags_start */
825 TODO_verify_flow, /* todo_flags_finish */
28c92cbb 826};
827
cbe8bda8 828class pass_parallelize_loops : public gimple_opt_pass
829{
830public:
831 pass_parallelize_loops(gcc::context *ctxt)
832 : gimple_opt_pass(pass_data_parallelize_loops, ctxt)
833 {}
834
835 /* opt_pass methods: */
836 bool gate () { return gate_tree_parallelize_loops (); }
837 unsigned int execute () { return tree_parallelize_loops (); }
838
839}; // class pass_parallelize_loops
840
841} // anon namespace
842
843gimple_opt_pass *
844make_pass_parallelize_loops (gcc::context *ctxt)
845{
846 return new pass_parallelize_loops (ctxt);
847}
848
b30560de 849/* Prefetching. */
850
2a1990e9 851static unsigned int
b30560de 852tree_ssa_loop_prefetch (void)
853{
41f75a99 854 if (number_of_loops (cfun) <= 1)
2a1990e9 855 return 0;
b30560de 856
7194de72 857 return tree_ssa_prefetch_arrays ();
b30560de 858}
859
860static bool
861gate_tree_ssa_loop_prefetch (void)
862{
cd459e62 863 return flag_prefetch_loop_arrays > 0;
b30560de 864}
865
cbe8bda8 866namespace {
867
868const pass_data pass_data_loop_prefetch =
869{
870 GIMPLE_PASS, /* type */
871 "aprefetch", /* name */
872 OPTGROUP_LOOP, /* optinfo_flags */
873 true, /* has_gate */
874 true, /* has_execute */
875 TV_TREE_PREFETCH, /* tv_id */
876 ( PROP_cfg | PROP_ssa ), /* properties_required */
877 0, /* properties_provided */
878 0, /* properties_destroyed */
879 0, /* todo_flags_start */
880 0, /* todo_flags_finish */
b30560de 881};
882
cbe8bda8 883class pass_loop_prefetch : public gimple_opt_pass
884{
885public:
886 pass_loop_prefetch(gcc::context *ctxt)
887 : gimple_opt_pass(pass_data_loop_prefetch, ctxt)
888 {}
889
890 /* opt_pass methods: */
891 bool gate () { return gate_tree_ssa_loop_prefetch (); }
892 unsigned int execute () { return tree_ssa_loop_prefetch (); }
893
894}; // class pass_loop_prefetch
895
896} // anon namespace
897
898gimple_opt_pass *
899make_pass_loop_prefetch (gcc::context *ctxt)
900{
901 return new pass_loop_prefetch (ctxt);
902}
903
dec41e98 904/* Induction variable optimizations. */
905
2a1990e9 906static unsigned int
dec41e98 907tree_ssa_loop_ivopts (void)
908{
41f75a99 909 if (number_of_loops (cfun) <= 1)
2a1990e9 910 return 0;
dec41e98 911
7194de72 912 tree_ssa_iv_optimize ();
2a1990e9 913 return 0;
dec41e98 914}
915
916static bool
917gate_tree_ssa_loop_ivopts (void)
918{
919 return flag_ivopts != 0;
920}
921
cbe8bda8 922namespace {
923
924const pass_data pass_data_iv_optimize =
925{
926 GIMPLE_PASS, /* type */
927 "ivopts", /* name */
928 OPTGROUP_LOOP, /* optinfo_flags */
929 true, /* has_gate */
930 true, /* has_execute */
931 TV_TREE_LOOP_IVOPTS, /* tv_id */
932 ( PROP_cfg | PROP_ssa ), /* properties_required */
933 0, /* properties_provided */
934 0, /* properties_destroyed */
935 0, /* todo_flags_start */
936 TODO_update_ssa, /* todo_flags_finish */
bb445479 937};
938
cbe8bda8 939class pass_iv_optimize : public gimple_opt_pass
940{
941public:
942 pass_iv_optimize(gcc::context *ctxt)
943 : gimple_opt_pass(pass_data_iv_optimize, ctxt)
944 {}
945
946 /* opt_pass methods: */
947 bool gate () { return gate_tree_ssa_loop_ivopts (); }
948 unsigned int execute () { return tree_ssa_loop_ivopts (); }
949
950}; // class pass_iv_optimize
951
952} // anon namespace
953
954gimple_opt_pass *
955make_pass_iv_optimize (gcc::context *ctxt)
956{
957 return new pass_iv_optimize (ctxt);
958}
959
dcb9eccb 960/* Loop optimizer finalization. */
961
2a1990e9 962static unsigned int
dcb9eccb 963tree_ssa_loop_done (void)
964{
7194de72 965 free_numbers_of_iterations_estimates ();
bb445479 966 scev_finalize ();
88e6f696 967 loop_optimizer_finalize ();
2a1990e9 968 return 0;
dcb9eccb 969}
48e1416a 970
cbe8bda8 971namespace {
972
973const pass_data pass_data_tree_loop_done =
974{
975 GIMPLE_PASS, /* type */
976 "loopdone", /* name */
977 OPTGROUP_LOOP, /* optinfo_flags */
978 false, /* has_gate */
979 true, /* has_execute */
980 TV_NONE, /* tv_id */
981 PROP_cfg, /* properties_required */
982 0, /* properties_provided */
983 0, /* properties_destroyed */
984 0, /* todo_flags_start */
985 ( TODO_cleanup_cfg | TODO_verify_flow ), /* todo_flags_finish */
dcb9eccb 986};
cbe8bda8 987
988class pass_tree_loop_done : public gimple_opt_pass
989{
990public:
991 pass_tree_loop_done(gcc::context *ctxt)
992 : gimple_opt_pass(pass_data_tree_loop_done, ctxt)
993 {}
994
995 /* opt_pass methods: */
996 unsigned int execute () { return tree_ssa_loop_done (); }
997
998}; // class pass_tree_loop_done
999
1000} // anon namespace
1001
1002gimple_opt_pass *
1003make_pass_tree_loop_done (gcc::context *ctxt)
1004{
1005 return new pass_tree_loop_done (ctxt);
1006}