| 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 |