OLD | NEW |
1 /* Loop optimizations over tree-ssa. | 1 /* Loop optimizations over tree-ssa. |
2 Copyright (C) 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. | 2 Copyright (C) 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it | 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 | 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 | 8 Free Software Foundation; either version 3, or (at your option) any |
9 later version. | 9 later version. |
10 | 10 |
11 GCC is distributed in the hope that it will be useful, but WITHOUT | 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 | 12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
14 for more details. | 14 for more details. |
15 | 15 |
16 You should have received a copy of 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 | 17 along with GCC; see the file COPYING3. If not see |
18 <http://www.gnu.org/licenses/>. */ | 18 <http://www.gnu.org/licenses/>. */ |
19 | 19 |
20 #include "config.h" | 20 #include "config.h" |
21 #include "system.h" | 21 #include "system.h" |
22 #include "coretypes.h" | 22 #include "coretypes.h" |
23 #include "tm.h" | 23 #include "tm.h" |
24 #include "tree.h" | 24 #include "tree.h" |
25 #include "rtl.h" | 25 #include "rtl.h" |
26 #include "tm_p.h" | 26 #include "tm_p.h" |
27 #include "hard-reg-set.h" | 27 #include "hard-reg-set.h" |
28 #include "basic-block.h" | 28 #include "basic-block.h" |
29 #include "output.h" | 29 #include "output.h" |
30 #include "diagnostic.h" | 30 #include "diagnostic.h" |
31 #include "tree-flow.h" | 31 #include "tree-flow.h" |
32 #include "tree-dump.h" | 32 #include "tree-dump.h" |
33 #include "tree-pass.h" | 33 #include "tree-pass.h" |
34 #include "timevar.h" | 34 #include "timevar.h" |
35 #include "cfgloop.h" | 35 #include "cfgloop.h" |
36 #include "flags.h" | 36 #include "flags.h" |
37 #include "tree-inline.h" | 37 #include "tree-inline.h" |
38 #include "tree-scalar-evolution.h" | 38 #include "tree-scalar-evolution.h" |
| 39 #include "toplev.h" |
| 40 #include "tree-vectorizer.h" |
39 | 41 |
40 /* The loop superpass. */ | 42 /* The loop superpass. */ |
41 | 43 |
42 static bool | 44 static bool |
43 gate_tree_loop (void) | 45 gate_tree_loop (void) |
44 { | 46 { |
45 return flag_tree_loop_optimize != 0; | 47 return flag_tree_loop_optimize != 0; |
46 } | 48 } |
47 | 49 |
48 struct gimple_opt_pass pass_tree_loop = | 50 struct gimple_opt_pass pass_tree_loop = |
49 { | 51 { |
50 { | 52 { |
51 GIMPLE_PASS, | 53 GIMPLE_PASS, |
52 "loop", /* name */ | 54 "loop", /* name */ |
53 gate_tree_loop, /* gate */ | 55 gate_tree_loop, /* gate */ |
54 NULL, /* execute */ | 56 NULL, /* execute */ |
55 NULL, /* sub */ | 57 NULL, /* sub */ |
56 NULL, /* next */ | 58 NULL, /* next */ |
57 0, /* static_pass_number */ | 59 0, /* static_pass_number */ |
58 TV_TREE_LOOP, /* tv_id */ | 60 TV_TREE_LOOP, /* tv_id */ |
(...skipping 13 matching lines...) Expand all Loading... |
72 loop_optimizer_init (LOOPS_NORMAL | 74 loop_optimizer_init (LOOPS_NORMAL |
73 | LOOPS_HAVE_RECORDED_EXITS); | 75 | LOOPS_HAVE_RECORDED_EXITS); |
74 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); | 76 rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); |
75 | 77 |
76 if (number_of_loops () <= 1) | 78 if (number_of_loops () <= 1) |
77 return 0; | 79 return 0; |
78 | 80 |
79 scev_initialize (); | 81 scev_initialize (); |
80 return 0; | 82 return 0; |
81 } | 83 } |
82 | 84 |
83 struct gimple_opt_pass pass_tree_loop_init = | 85 struct gimple_opt_pass pass_tree_loop_init = |
84 { | 86 { |
85 { | 87 { |
86 GIMPLE_PASS, | 88 GIMPLE_PASS, |
87 "loopinit", /* name */ | 89 "loopinit", /* name */ |
88 NULL, /* gate */ | 90 NULL, /* gate */ |
89 tree_ssa_loop_init, /* execute */ | 91 tree_ssa_loop_init, /* execute */ |
90 NULL, /* sub */ | 92 NULL, /* sub */ |
91 NULL, /* next */ | 93 NULL, /* next */ |
92 0, /* static_pass_number */ | 94 0, /* static_pass_number */ |
93 TV_TREE_LOOP_INIT, /* tv_id */ | 95 TV_TREE_LOOP_INIT, /* tv_id */ |
(...skipping 16 matching lines...) Expand all Loading... |
110 tree_ssa_lim (); | 112 tree_ssa_lim (); |
111 return 0; | 113 return 0; |
112 } | 114 } |
113 | 115 |
114 static bool | 116 static bool |
115 gate_tree_ssa_loop_im (void) | 117 gate_tree_ssa_loop_im (void) |
116 { | 118 { |
117 return flag_tree_loop_im != 0; | 119 return flag_tree_loop_im != 0; |
118 } | 120 } |
119 | 121 |
120 struct gimple_opt_pass pass_lim = | 122 struct gimple_opt_pass pass_lim = |
121 { | 123 { |
122 { | 124 { |
123 GIMPLE_PASS, | 125 GIMPLE_PASS, |
124 "lim", /* name */ | 126 "lim", /* name */ |
125 gate_tree_ssa_loop_im, /* gate */ | 127 gate_tree_ssa_loop_im, /* gate */ |
126 tree_ssa_loop_im, /* execute */ | 128 tree_ssa_loop_im, /* execute */ |
127 NULL, /* sub */ | 129 NULL, /* sub */ |
128 NULL, /* next */ | 130 NULL, /* next */ |
129 0, /* static_pass_number */ | 131 0, /* static_pass_number */ |
130 TV_LIM, /* tv_id */ | 132 TV_LIM, /* tv_id */ |
(...skipping 15 matching lines...) Expand all Loading... |
146 | 148 |
147 return tree_ssa_unswitch_loops (); | 149 return tree_ssa_unswitch_loops (); |
148 } | 150 } |
149 | 151 |
150 static bool | 152 static bool |
151 gate_tree_ssa_loop_unswitch (void) | 153 gate_tree_ssa_loop_unswitch (void) |
152 { | 154 { |
153 return flag_unswitch_loops != 0; | 155 return flag_unswitch_loops != 0; |
154 } | 156 } |
155 | 157 |
156 struct gimple_opt_pass pass_tree_unswitch = | 158 struct gimple_opt_pass pass_tree_unswitch = |
157 { | 159 { |
158 { | 160 { |
159 GIMPLE_PASS, | 161 GIMPLE_PASS, |
160 "unswitch", /* name */ | 162 "unswitch", /* name */ |
161 gate_tree_ssa_loop_unswitch, /* gate */ | 163 gate_tree_ssa_loop_unswitch, /* gate */ |
162 tree_ssa_loop_unswitch, /* execute */ | 164 tree_ssa_loop_unswitch, /* execute */ |
163 NULL, /* sub */ | 165 NULL, /* sub */ |
164 NULL, /* next */ | 166 NULL, /* next */ |
165 0, /* static_pass_number */ | 167 0, /* static_pass_number */ |
166 TV_TREE_LOOP_UNSWITCH, /* tv_id */ | 168 TV_TREE_LOOP_UNSWITCH, /* tv_id */ |
(...skipping 17 matching lines...) Expand all Loading... |
184 tree_predictive_commoning (); | 186 tree_predictive_commoning (); |
185 return 0; | 187 return 0; |
186 } | 188 } |
187 | 189 |
188 static bool | 190 static bool |
189 gate_tree_predictive_commoning (void) | 191 gate_tree_predictive_commoning (void) |
190 { | 192 { |
191 return flag_predictive_commoning != 0; | 193 return flag_predictive_commoning != 0; |
192 } | 194 } |
193 | 195 |
194 struct gimple_opt_pass pass_predcom = | 196 struct gimple_opt_pass pass_predcom = |
195 { | 197 { |
196 { | 198 { |
197 GIMPLE_PASS, | 199 GIMPLE_PASS, |
198 "pcom", /* name */ | 200 "pcom", /* name */ |
199 gate_tree_predictive_commoning, /* gate */ | 201 gate_tree_predictive_commoning, /* gate */ |
200 run_tree_predictive_commoning, /* execute */ | 202 run_tree_predictive_commoning, /* execute */ |
201 NULL, /* sub */ | 203 NULL, /* sub */ |
202 NULL, /* next */ | 204 NULL, /* next */ |
203 0, /* static_pass_number */ | 205 0, /* static_pass_number */ |
204 TV_PREDCOM, /* tv_id */ | 206 TV_PREDCOM, /* tv_id */ |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 return 0; | 298 return 0; |
297 | 299 |
298 graphite_transform_loops (); | 300 graphite_transform_loops (); |
299 | 301 |
300 return 0; | 302 return 0; |
301 } | 303 } |
302 | 304 |
303 static bool | 305 static bool |
304 gate_graphite_transforms (void) | 306 gate_graphite_transforms (void) |
305 { | 307 { |
306 /* Enable -fgraphite pass if any one of the graphite optimization flags | 308 /* Enable -fgraphite pass if any one of the graphite optimization flags |
307 is turned on. */ | 309 is turned on. */ |
308 if (flag_loop_block || flag_loop_interchange || flag_loop_strip_mine | 310 if (flag_loop_block || flag_loop_interchange || flag_loop_strip_mine |
309 || flag_graphite_identity) | 311 || flag_graphite_identity || flag_loop_parallelize_all) |
310 flag_graphite = 1; | 312 flag_graphite = 1; |
311 | 313 |
312 return flag_graphite != 0; | 314 return flag_graphite != 0; |
313 } | 315 } |
314 | 316 |
315 struct gimple_opt_pass pass_graphite_transforms = | 317 struct gimple_opt_pass pass_graphite_transforms = |
316 { | 318 { |
317 { | 319 { |
318 GIMPLE_PASS, | 320 GIMPLE_PASS, |
319 "graphite", /* name */ | 321 "graphite", /* name */ |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 PROP_cfg | PROP_ssa, /* properties_required */ | 428 PROP_cfg | PROP_ssa, /* properties_required */ |
427 0, /* properties_provided */ | 429 0, /* properties_provided */ |
428 0, /* properties_destroyed */ | 430 0, /* properties_destroyed */ |
429 0, /* todo_flags_start */ | 431 0, /* todo_flags_start */ |
430 TODO_dump_func | TODO_cleanup_cfg | 432 TODO_dump_func | TODO_cleanup_cfg |
431 | TODO_update_ssa_only_virtuals | 433 | TODO_update_ssa_only_virtuals |
432 /* todo_flags_finish */ | 434 /* todo_flags_finish */ |
433 } | 435 } |
434 }; | 436 }; |
435 | 437 |
436 /* Remove empty loops. */ | |
437 | |
438 static unsigned int | |
439 tree_ssa_empty_loop (void) | |
440 { | |
441 if (number_of_loops () <= 1) | |
442 return 0; | |
443 | |
444 return remove_empty_loops (); | |
445 } | |
446 | |
447 struct gimple_opt_pass pass_empty_loop = | |
448 { | |
449 { | |
450 GIMPLE_PASS, | |
451 "empty", /* name */ | |
452 NULL, /* gate */ | |
453 tree_ssa_empty_loop, /* execute */ | |
454 NULL, /* sub */ | |
455 NULL, /* next */ | |
456 0, /* static_pass_number */ | |
457 TV_COMPLETE_UNROLL, /* tv_id */ | |
458 PROP_cfg | PROP_ssa, /* properties_required */ | |
459 0, /* properties_provided */ | |
460 0, /* properties_destroyed */ | |
461 0, /* todo_flags_start */ | |
462 TODO_dump_func | TODO_verify_loops | |
463 | TODO_ggc_collect /* todo_flags_finish */ | |
464 } | |
465 }; | |
466 | |
467 /* Record bounds on numbers of iterations of loops. */ | 438 /* Record bounds on numbers of iterations of loops. */ |
468 | 439 |
469 static unsigned int | 440 static unsigned int |
470 tree_ssa_loop_bounds (void) | 441 tree_ssa_loop_bounds (void) |
471 { | 442 { |
472 if (number_of_loops () <= 1) | 443 if (number_of_loops () <= 1) |
473 return 0; | 444 return 0; |
474 | 445 |
475 estimate_numbers_of_iterations (); | 446 estimate_numbers_of_iterations (); |
476 scev_reset (); | 447 scev_reset (); |
477 return 0; | 448 return 0; |
478 } | 449 } |
479 | 450 |
480 struct gimple_opt_pass pass_record_bounds = | 451 struct gimple_opt_pass pass_record_bounds = |
481 { | 452 { |
482 { | 453 { |
483 GIMPLE_PASS, | 454 GIMPLE_PASS, |
484 NULL,»» » » » /* name */ | 455 "*record_bounds",» » » /* name */ |
485 NULL, /* gate */ | 456 NULL, /* gate */ |
486 tree_ssa_loop_bounds, /* execute */ | 457 tree_ssa_loop_bounds, /* execute */ |
487 NULL, /* sub */ | 458 NULL, /* sub */ |
488 NULL, /* next */ | 459 NULL, /* next */ |
489 0, /* static_pass_number */ | 460 0, /* static_pass_number */ |
490 TV_TREE_LOOP_BOUNDS, /* tv_id */ | 461 TV_TREE_LOOP_BOUNDS, /* tv_id */ |
491 PROP_cfg | PROP_ssa, /* properties_required */ | 462 PROP_cfg | PROP_ssa, /* properties_required */ |
492 0, /* properties_provided */ | 463 0, /* properties_provided */ |
493 0, /* properties_destroyed */ | 464 0, /* properties_destroyed */ |
494 0, /* todo_flags_start */ | 465 0, /* todo_flags_start */ |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 /* Loop optimizer finalization. */ | 668 /* Loop optimizer finalization. */ |
698 | 669 |
699 static unsigned int | 670 static unsigned int |
700 tree_ssa_loop_done (void) | 671 tree_ssa_loop_done (void) |
701 { | 672 { |
702 free_numbers_of_iterations_estimates (); | 673 free_numbers_of_iterations_estimates (); |
703 scev_finalize (); | 674 scev_finalize (); |
704 loop_optimizer_finalize (); | 675 loop_optimizer_finalize (); |
705 return 0; | 676 return 0; |
706 } | 677 } |
707 | 678 |
708 struct gimple_opt_pass pass_tree_loop_done = | 679 struct gimple_opt_pass pass_tree_loop_done = |
709 { | 680 { |
710 { | 681 { |
711 GIMPLE_PASS, | 682 GIMPLE_PASS, |
712 "loopdone", /* name */ | 683 "loopdone", /* name */ |
713 NULL, /* gate */ | 684 NULL, /* gate */ |
714 tree_ssa_loop_done, /* execute */ | 685 tree_ssa_loop_done, /* execute */ |
715 NULL, /* sub */ | 686 NULL, /* sub */ |
716 NULL, /* next */ | 687 NULL, /* next */ |
717 0, /* static_pass_number */ | 688 0, /* static_pass_number */ |
718 TV_TREE_LOOP_FINI, /* tv_id */ | 689 TV_TREE_LOOP_FINI, /* tv_id */ |
719 PROP_cfg, /* properties_required */ | 690 PROP_cfg, /* properties_required */ |
720 0, /* properties_provided */ | 691 0, /* properties_provided */ |
721 0, /* properties_destroyed */ | 692 0, /* properties_destroyed */ |
722 0, /* todo_flags_start */ | 693 0, /* todo_flags_start */ |
723 TODO_cleanup_cfg | TODO_dump_func /* todo_flags_finish */ | 694 TODO_cleanup_cfg | TODO_dump_func /* todo_flags_finish */ |
724 } | 695 } |
725 }; | 696 }; |
OLD | NEW |