2013-09-12 Paolo Carlini <paolo.carlini@oracle.com>
[official-gcc.git] / gcc / tree-ssa-loop.c
blobf97a94643b33e8a21e02871c1cd57cdd0dae358f
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
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 "tm_p.h"
26 #include "basic-block.h"
27 #include "tree-ssa.h"
28 #include "tree-pass.h"
29 #include "cfgloop.h"
30 #include "flags.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. */
38 static bool
39 gate_tree_loop (void)
41 return flag_tree_loop_optimize != 0;
44 namespace {
46 const pass_data pass_data_tree_loop =
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 */
61 class pass_tree_loop : public gimple_opt_pass
63 public:
64 pass_tree_loop(gcc::context *ctxt)
65 : gimple_opt_pass(pass_data_tree_loop, ctxt)
68 /* opt_pass methods: */
69 bool gate () { return gate_tree_loop (); }
71 }; // class pass_tree_loop
73 } // anon namespace
75 gimple_opt_pass *
76 make_pass_tree_loop (gcc::context *ctxt)
78 return new pass_tree_loop (ctxt);
81 /* Loop optimizer initialization. */
83 static unsigned int
84 tree_ssa_loop_init (void)
86 loop_optimizer_init (LOOPS_NORMAL
87 | LOOPS_HAVE_RECORDED_EXITS);
88 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
90 /* We might discover new loops, e.g. when turning irreducible
91 regions into reducible. */
92 scev_initialize ();
94 if (number_of_loops (cfun) <= 1)
95 return 0;
97 return 0;
100 namespace {
102 const pass_data pass_data_tree_loop_init =
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 */
117 class pass_tree_loop_init : public gimple_opt_pass
119 public:
120 pass_tree_loop_init(gcc::context *ctxt)
121 : gimple_opt_pass(pass_data_tree_loop_init, ctxt)
124 /* opt_pass methods: */
125 unsigned int execute () { return tree_ssa_loop_init (); }
127 }; // class pass_tree_loop_init
129 } // anon namespace
131 gimple_opt_pass *
132 make_pass_tree_loop_init (gcc::context *ctxt)
134 return new pass_tree_loop_init (ctxt);
137 /* Loop invariant motion pass. */
139 static unsigned int
140 tree_ssa_loop_im (void)
142 if (number_of_loops (cfun) <= 1)
143 return 0;
145 return tree_ssa_lim ();
148 static bool
149 gate_tree_ssa_loop_im (void)
151 return flag_tree_loop_im != 0;
154 namespace {
156 const pass_data pass_data_lim =
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 */
171 class pass_lim : public gimple_opt_pass
173 public:
174 pass_lim(gcc::context *ctxt)
175 : gimple_opt_pass(pass_data_lim, ctxt)
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 (); }
183 }; // class pass_lim
185 } // anon namespace
187 gimple_opt_pass *
188 make_pass_lim (gcc::context *ctxt)
190 return new pass_lim (ctxt);
193 /* Loop unswitching pass. */
195 static unsigned int
196 tree_ssa_loop_unswitch (void)
198 if (number_of_loops (cfun) <= 1)
199 return 0;
201 return tree_ssa_unswitch_loops ();
204 static bool
205 gate_tree_ssa_loop_unswitch (void)
207 return flag_unswitch_loops != 0;
210 namespace {
212 const pass_data pass_data_tree_unswitch =
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 */
227 class pass_tree_unswitch : public gimple_opt_pass
229 public:
230 pass_tree_unswitch(gcc::context *ctxt)
231 : gimple_opt_pass(pass_data_tree_unswitch, ctxt)
234 /* opt_pass methods: */
235 bool gate () { return gate_tree_ssa_loop_unswitch (); }
236 unsigned int execute () { return tree_ssa_loop_unswitch (); }
238 }; // class pass_tree_unswitch
240 } // anon namespace
242 gimple_opt_pass *
243 make_pass_tree_unswitch (gcc::context *ctxt)
245 return new pass_tree_unswitch (ctxt);
248 /* Predictive commoning. */
250 static unsigned
251 run_tree_predictive_commoning (void)
253 if (!current_loops)
254 return 0;
256 return tree_predictive_commoning ();
259 static bool
260 gate_tree_predictive_commoning (void)
262 return flag_predictive_commoning != 0;
265 namespace {
267 const pass_data pass_data_predcom =
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 */
282 class pass_predcom : public gimple_opt_pass
284 public:
285 pass_predcom(gcc::context *ctxt)
286 : gimple_opt_pass(pass_data_predcom, ctxt)
289 /* opt_pass methods: */
290 bool gate () { return gate_tree_predictive_commoning (); }
291 unsigned int execute () { return run_tree_predictive_commoning (); }
293 }; // class pass_predcom
295 } // anon namespace
297 gimple_opt_pass *
298 make_pass_predcom (gcc::context *ctxt)
300 return new pass_predcom (ctxt);
303 /* Loop autovectorization. */
305 static unsigned int
306 tree_vectorize (void)
308 if (number_of_loops (cfun) <= 1)
309 return 0;
311 return vectorize_loops ();
314 static bool
315 gate_tree_vectorize (void)
317 return flag_tree_vectorize || cfun->has_force_vect_loops;
320 namespace {
322 const pass_data pass_data_vectorize =
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 */
337 class pass_vectorize : public gimple_opt_pass
339 public:
340 pass_vectorize(gcc::context *ctxt)
341 : gimple_opt_pass(pass_data_vectorize, ctxt)
344 /* opt_pass methods: */
345 bool gate () { return gate_tree_vectorize (); }
346 unsigned int execute () { return tree_vectorize (); }
348 }; // class pass_vectorize
350 } // anon namespace
352 gimple_opt_pass *
353 make_pass_vectorize (gcc::context *ctxt)
355 return new pass_vectorize (ctxt);
358 /* GRAPHITE optimizations. */
360 static unsigned int
361 graphite_transforms (void)
363 if (!current_loops)
364 return 0;
366 graphite_transform_loops ();
368 return 0;
371 static bool
372 gate_graphite_transforms (void)
374 /* Enable -fgraphite pass if any one of the graphite optimization flags
375 is turned on. */
376 if (flag_loop_block
377 || flag_loop_interchange
378 || flag_loop_strip_mine
379 || flag_graphite_identity
380 || flag_loop_parallelize_all
381 || flag_loop_optimize_isl)
382 flag_graphite = 1;
384 return flag_graphite != 0;
387 namespace {
389 const pass_data pass_data_graphite =
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 */
404 class pass_graphite : public gimple_opt_pass
406 public:
407 pass_graphite(gcc::context *ctxt)
408 : gimple_opt_pass(pass_data_graphite, ctxt)
411 /* opt_pass methods: */
412 bool gate () { return gate_graphite_transforms (); }
414 }; // class pass_graphite
416 } // anon namespace
418 gimple_opt_pass *
419 make_pass_graphite (gcc::context *ctxt)
421 return new pass_graphite (ctxt);
424 namespace {
426 const pass_data pass_data_graphite_transforms =
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 */
441 class pass_graphite_transforms : public gimple_opt_pass
443 public:
444 pass_graphite_transforms(gcc::context *ctxt)
445 : gimple_opt_pass(pass_data_graphite_transforms, ctxt)
448 /* opt_pass methods: */
449 bool gate () { return gate_graphite_transforms (); }
450 unsigned int execute () { return graphite_transforms (); }
452 }; // class pass_graphite_transforms
454 } // anon namespace
456 gimple_opt_pass *
457 make_pass_graphite_transforms (gcc::context *ctxt)
459 return new pass_graphite_transforms (ctxt);
462 /* Check the correctness of the data dependence analyzers. */
464 static unsigned int
465 check_data_deps (void)
467 if (number_of_loops (cfun) <= 1)
468 return 0;
470 tree_check_data_deps ();
471 return 0;
474 static bool
475 gate_check_data_deps (void)
477 return flag_check_data_deps != 0;
480 namespace {
482 const pass_data pass_data_check_data_deps =
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 */
497 class pass_check_data_deps : public gimple_opt_pass
499 public:
500 pass_check_data_deps(gcc::context *ctxt)
501 : gimple_opt_pass(pass_data_check_data_deps, ctxt)
504 /* opt_pass methods: */
505 bool gate () { return gate_check_data_deps (); }
506 unsigned int execute () { return check_data_deps (); }
508 }; // class pass_check_data_deps
510 } // anon namespace
512 gimple_opt_pass *
513 make_pass_check_data_deps (gcc::context *ctxt)
515 return new pass_check_data_deps (ctxt);
518 /* Canonical induction variable creation pass. */
520 static unsigned int
521 tree_ssa_loop_ivcanon (void)
523 if (number_of_loops (cfun) <= 1)
524 return 0;
526 return canonicalize_induction_variables ();
529 static bool
530 gate_tree_ssa_loop_ivcanon (void)
532 return flag_tree_loop_ivcanon != 0;
535 namespace {
537 const pass_data pass_data_iv_canon =
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 */
552 class pass_iv_canon : public gimple_opt_pass
554 public:
555 pass_iv_canon(gcc::context *ctxt)
556 : gimple_opt_pass(pass_data_iv_canon, ctxt)
559 /* opt_pass methods: */
560 bool gate () { return gate_tree_ssa_loop_ivcanon (); }
561 unsigned int execute () { return tree_ssa_loop_ivcanon (); }
563 }; // class pass_iv_canon
565 } // anon namespace
567 gimple_opt_pass *
568 make_pass_iv_canon (gcc::context *ctxt)
570 return new pass_iv_canon (ctxt);
573 /* Propagation of constants using scev. */
575 static bool
576 gate_scev_const_prop (void)
578 return flag_tree_scev_cprop;
581 namespace {
583 const pass_data pass_data_scev_cprop =
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 */
599 class pass_scev_cprop : public gimple_opt_pass
601 public:
602 pass_scev_cprop(gcc::context *ctxt)
603 : gimple_opt_pass(pass_data_scev_cprop, ctxt)
606 /* opt_pass methods: */
607 bool gate () { return gate_scev_const_prop (); }
608 unsigned int execute () { return scev_const_prop (); }
610 }; // class pass_scev_cprop
612 } // anon namespace
614 gimple_opt_pass *
615 make_pass_scev_cprop (gcc::context *ctxt)
617 return new pass_scev_cprop (ctxt);
620 /* Record bounds on numbers of iterations of loops. */
622 static unsigned int
623 tree_ssa_loop_bounds (void)
625 if (number_of_loops (cfun) <= 1)
626 return 0;
628 estimate_numbers_of_iterations ();
629 scev_reset ();
630 return 0;
633 namespace {
635 const pass_data pass_data_record_bounds =
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 */
650 class pass_record_bounds : public gimple_opt_pass
652 public:
653 pass_record_bounds(gcc::context *ctxt)
654 : gimple_opt_pass(pass_data_record_bounds, ctxt)
657 /* opt_pass methods: */
658 unsigned int execute () { return tree_ssa_loop_bounds (); }
660 }; // class pass_record_bounds
662 } // anon namespace
664 gimple_opt_pass *
665 make_pass_record_bounds (gcc::context *ctxt)
667 return new pass_record_bounds (ctxt);
670 /* Complete unrolling of loops. */
672 static unsigned int
673 tree_complete_unroll (void)
675 if (number_of_loops (cfun) <= 1)
676 return 0;
678 return tree_unroll_loops_completely (flag_unroll_loops
679 || flag_peel_loops
680 || optimize >= 3, true);
683 static bool
684 gate_tree_complete_unroll (void)
686 return true;
689 namespace {
691 const pass_data pass_data_complete_unroll =
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 */
706 class pass_complete_unroll : public gimple_opt_pass
708 public:
709 pass_complete_unroll(gcc::context *ctxt)
710 : gimple_opt_pass(pass_data_complete_unroll, ctxt)
713 /* opt_pass methods: */
714 bool gate () { return gate_tree_complete_unroll (); }
715 unsigned int execute () { return tree_complete_unroll (); }
717 }; // class pass_complete_unroll
719 } // anon namespace
721 gimple_opt_pass *
722 make_pass_complete_unroll (gcc::context *ctxt)
724 return new pass_complete_unroll (ctxt);
727 /* Complete unrolling of inner loops. */
729 static unsigned int
730 tree_complete_unroll_inner (void)
732 unsigned ret = 0;
734 loop_optimizer_init (LOOPS_NORMAL
735 | LOOPS_HAVE_RECORDED_EXITS);
736 if (number_of_loops (cfun) > 1)
738 scev_initialize ();
739 ret = tree_unroll_loops_completely (optimize >= 3, false);
740 free_numbers_of_iterations_estimates ();
741 scev_finalize ();
743 loop_optimizer_finalize ();
745 return ret;
748 static bool
749 gate_tree_complete_unroll_inner (void)
751 return optimize >= 2;
754 namespace {
756 const pass_data pass_data_complete_unrolli =
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 */
771 class pass_complete_unrolli : public gimple_opt_pass
773 public:
774 pass_complete_unrolli(gcc::context *ctxt)
775 : gimple_opt_pass(pass_data_complete_unrolli, ctxt)
778 /* opt_pass methods: */
779 bool gate () { return gate_tree_complete_unroll_inner (); }
780 unsigned int execute () { return tree_complete_unroll_inner (); }
782 }; // class pass_complete_unrolli
784 } // anon namespace
786 gimple_opt_pass *
787 make_pass_complete_unrolli (gcc::context *ctxt)
789 return new pass_complete_unrolli (ctxt);
792 /* Parallelization. */
794 static bool
795 gate_tree_parallelize_loops (void)
797 return flag_tree_parallelize_loops > 1;
800 static unsigned
801 tree_parallelize_loops (void)
803 if (number_of_loops (cfun) <= 1)
804 return 0;
806 if (parallelize_loops ())
807 return TODO_cleanup_cfg | TODO_rebuild_alias;
808 return 0;
811 namespace {
813 const pass_data pass_data_parallelize_loops =
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 */
828 class pass_parallelize_loops : public gimple_opt_pass
830 public:
831 pass_parallelize_loops(gcc::context *ctxt)
832 : gimple_opt_pass(pass_data_parallelize_loops, ctxt)
835 /* opt_pass methods: */
836 bool gate () { return gate_tree_parallelize_loops (); }
837 unsigned int execute () { return tree_parallelize_loops (); }
839 }; // class pass_parallelize_loops
841 } // anon namespace
843 gimple_opt_pass *
844 make_pass_parallelize_loops (gcc::context *ctxt)
846 return new pass_parallelize_loops (ctxt);
849 /* Prefetching. */
851 static unsigned int
852 tree_ssa_loop_prefetch (void)
854 if (number_of_loops (cfun) <= 1)
855 return 0;
857 return tree_ssa_prefetch_arrays ();
860 static bool
861 gate_tree_ssa_loop_prefetch (void)
863 return flag_prefetch_loop_arrays > 0;
866 namespace {
868 const pass_data pass_data_loop_prefetch =
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 */
883 class pass_loop_prefetch : public gimple_opt_pass
885 public:
886 pass_loop_prefetch(gcc::context *ctxt)
887 : gimple_opt_pass(pass_data_loop_prefetch, ctxt)
890 /* opt_pass methods: */
891 bool gate () { return gate_tree_ssa_loop_prefetch (); }
892 unsigned int execute () { return tree_ssa_loop_prefetch (); }
894 }; // class pass_loop_prefetch
896 } // anon namespace
898 gimple_opt_pass *
899 make_pass_loop_prefetch (gcc::context *ctxt)
901 return new pass_loop_prefetch (ctxt);
904 /* Induction variable optimizations. */
906 static unsigned int
907 tree_ssa_loop_ivopts (void)
909 if (number_of_loops (cfun) <= 1)
910 return 0;
912 tree_ssa_iv_optimize ();
913 return 0;
916 static bool
917 gate_tree_ssa_loop_ivopts (void)
919 return flag_ivopts != 0;
922 namespace {
924 const pass_data pass_data_iv_optimize =
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 */
939 class pass_iv_optimize : public gimple_opt_pass
941 public:
942 pass_iv_optimize(gcc::context *ctxt)
943 : gimple_opt_pass(pass_data_iv_optimize, ctxt)
946 /* opt_pass methods: */
947 bool gate () { return gate_tree_ssa_loop_ivopts (); }
948 unsigned int execute () { return tree_ssa_loop_ivopts (); }
950 }; // class pass_iv_optimize
952 } // anon namespace
954 gimple_opt_pass *
955 make_pass_iv_optimize (gcc::context *ctxt)
957 return new pass_iv_optimize (ctxt);
960 /* Loop optimizer finalization. */
962 static unsigned int
963 tree_ssa_loop_done (void)
965 free_numbers_of_iterations_estimates ();
966 scev_finalize ();
967 loop_optimizer_finalize ();
968 return 0;
971 namespace {
973 const pass_data pass_data_tree_loop_done =
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 */
988 class pass_tree_loop_done : public gimple_opt_pass
990 public:
991 pass_tree_loop_done(gcc::context *ctxt)
992 : gimple_opt_pass(pass_data_tree_loop_done, ctxt)
995 /* opt_pass methods: */
996 unsigned int execute () { return tree_ssa_loop_done (); }
998 }; // class pass_tree_loop_done
1000 } // anon namespace
1002 gimple_opt_pass *
1003 make_pass_tree_loop_done (gcc::context *ctxt)
1005 return new pass_tree_loop_done (ctxt);