]>
Commit | Line | Data |
---|---|---|
6de9cd9a | 1 | /* Loop optimizations over tree-ssa. |
7c475d11 JM |
2 | Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009, 2010 |
3 | Free Software Foundation, Inc. | |
b8698a0f | 4 | |
6de9cd9a | 5 | This file is part of GCC. |
b8698a0f | 6 | |
6de9cd9a DN |
7 | GCC is free software; you can redistribute it and/or modify it |
8 | under the terms of the GNU General Public License as published by the | |
9dcd6f09 | 9 | Free Software Foundation; either version 3, or (at your option) any |
6de9cd9a | 10 | later version. |
b8698a0f | 11 | |
6de9cd9a DN |
12 | GCC is distributed in the hope that it will be useful, but WITHOUT |
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 | for more details. | |
b8698a0f | 16 | |
6de9cd9a | 17 | You should have received a copy of the GNU General Public License |
9dcd6f09 NC |
18 | along with GCC; see the file COPYING3. If not see |
19 | <http://www.gnu.org/licenses/>. */ | |
6de9cd9a DN |
20 | |
21 | #include "config.h" | |
22 | #include "system.h" | |
23 | #include "coretypes.h" | |
24 | #include "tm.h" | |
25 | #include "tree.h" | |
6de9cd9a | 26 | #include "tm_p.h" |
6de9cd9a DN |
27 | #include "basic-block.h" |
28 | #include "output.h" | |
6de9cd9a DN |
29 | #include "tree-flow.h" |
30 | #include "tree-dump.h" | |
31 | #include "tree-pass.h" | |
32 | #include "timevar.h" | |
33 | #include "cfgloop.h" | |
34 | #include "flags.h" | |
35 | #include "tree-inline.h" | |
79fe1b3b | 36 | #include "tree-scalar-evolution.h" |
718f9c0f | 37 | #include "diagnostic-core.h" |
8ed77e22 | 38 | #include "tree-vectorizer.h" |
6de9cd9a | 39 | |
c66b6c66 ZD |
40 | /* The loop superpass. */ |
41 | ||
42 | static bool | |
9fa26457 | 43 | gate_tree_loop (void) |
c66b6c66 ZD |
44 | { |
45 | return flag_tree_loop_optimize != 0; | |
46 | } | |
47 | ||
b8698a0f | 48 | struct gimple_opt_pass pass_tree_loop = |
c66b6c66 | 49 | { |
8ddbbcae JH |
50 | { |
51 | GIMPLE_PASS, | |
c66b6c66 | 52 | "loop", /* name */ |
9fa26457 | 53 | gate_tree_loop, /* gate */ |
c66b6c66 ZD |
54 | NULL, /* execute */ |
55 | NULL, /* sub */ | |
56 | NULL, /* next */ | |
57 | 0, /* static_pass_number */ | |
58 | TV_TREE_LOOP, /* tv_id */ | |
59 | PROP_cfg, /* properties_required */ | |
60 | 0, /* properties_provided */ | |
61 | 0, /* properties_destroyed */ | |
62 | TODO_ggc_collect, /* todo_flags_start */ | |
22c5fa5f | 63 | TODO_verify_ssa | TODO_ggc_collect /* todo_flags_finish */ |
8ddbbcae | 64 | } |
c66b6c66 ZD |
65 | }; |
66 | ||
67 | /* Loop optimizer initialization. */ | |
68 | ||
c2924966 | 69 | static unsigned int |
c66b6c66 ZD |
70 | tree_ssa_loop_init (void) |
71 | { | |
726a989a RB |
72 | loop_optimizer_init (LOOPS_NORMAL |
73 | | LOOPS_HAVE_RECORDED_EXITS); | |
74 | rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); | |
75 | ||
d51157de | 76 | if (number_of_loops () <= 1) |
c2924966 | 77 | return 0; |
82b85a85 | 78 | |
d73be268 | 79 | scev_initialize (); |
c2924966 | 80 | return 0; |
c66b6c66 | 81 | } |
b8698a0f L |
82 | |
83 | struct gimple_opt_pass pass_tree_loop_init = | |
c66b6c66 | 84 | { |
8ddbbcae JH |
85 | { |
86 | GIMPLE_PASS, | |
c66b6c66 ZD |
87 | "loopinit", /* name */ |
88 | NULL, /* gate */ | |
89 | tree_ssa_loop_init, /* execute */ | |
90 | NULL, /* sub */ | |
91 | NULL, /* next */ | |
92 | 0, /* static_pass_number */ | |
87c11134 | 93 | TV_TREE_LOOP_INIT, /* tv_id */ |
c66b6c66 ZD |
94 | PROP_cfg, /* properties_required */ |
95 | 0, /* properties_provided */ | |
96 | 0, /* properties_destroyed */ | |
97 | 0, /* todo_flags_start */ | |
22c5fa5f | 98 | 0 /* todo_flags_finish */ |
8ddbbcae | 99 | } |
c66b6c66 ZD |
100 | }; |
101 | ||
a7e5372d ZD |
102 | /* Loop invariant motion pass. */ |
103 | ||
c2924966 | 104 | static unsigned int |
a7e5372d ZD |
105 | tree_ssa_loop_im (void) |
106 | { | |
d51157de | 107 | if (number_of_loops () <= 1) |
c2924966 | 108 | return 0; |
a7e5372d | 109 | |
e3bdfed6 | 110 | return tree_ssa_lim (); |
a7e5372d ZD |
111 | } |
112 | ||
113 | static bool | |
114 | gate_tree_ssa_loop_im (void) | |
115 | { | |
1b08d87d | 116 | return flag_tree_loop_im != 0; |
a7e5372d ZD |
117 | } |
118 | ||
b8698a0f | 119 | struct gimple_opt_pass pass_lim = |
a7e5372d | 120 | { |
8ddbbcae JH |
121 | { |
122 | GIMPLE_PASS, | |
a7e5372d ZD |
123 | "lim", /* name */ |
124 | gate_tree_ssa_loop_im, /* gate */ | |
125 | tree_ssa_loop_im, /* execute */ | |
126 | NULL, /* sub */ | |
127 | NULL, /* next */ | |
128 | 0, /* static_pass_number */ | |
129 | TV_LIM, /* tv_id */ | |
130 | PROP_cfg, /* properties_required */ | |
92fc4a2f ZD |
131 | 0, /* properties_provided */ |
132 | 0, /* properties_destroyed */ | |
133 | 0, /* todo_flags_start */ | |
22c5fa5f | 134 | 0 /* todo_flags_finish */ |
8ddbbcae | 135 | } |
92fc4a2f ZD |
136 | }; |
137 | ||
138 | /* Loop unswitching pass. */ | |
139 | ||
c2924966 | 140 | static unsigned int |
92fc4a2f ZD |
141 | tree_ssa_loop_unswitch (void) |
142 | { | |
d51157de | 143 | if (number_of_loops () <= 1) |
c2924966 | 144 | return 0; |
92fc4a2f | 145 | |
d73be268 | 146 | return tree_ssa_unswitch_loops (); |
92fc4a2f ZD |
147 | } |
148 | ||
149 | static bool | |
150 | gate_tree_ssa_loop_unswitch (void) | |
151 | { | |
152 | return flag_unswitch_loops != 0; | |
153 | } | |
154 | ||
b8698a0f | 155 | struct gimple_opt_pass pass_tree_unswitch = |
92fc4a2f | 156 | { |
8ddbbcae JH |
157 | { |
158 | GIMPLE_PASS, | |
92fc4a2f ZD |
159 | "unswitch", /* name */ |
160 | gate_tree_ssa_loop_unswitch, /* gate */ | |
161 | tree_ssa_loop_unswitch, /* execute */ | |
162 | NULL, /* sub */ | |
163 | NULL, /* next */ | |
164 | 0, /* static_pass_number */ | |
165 | TV_TREE_LOOP_UNSWITCH, /* tv_id */ | |
166 | PROP_cfg, /* properties_required */ | |
a7e5372d ZD |
167 | 0, /* properties_provided */ |
168 | 0, /* properties_destroyed */ | |
169 | 0, /* todo_flags_start */ | |
22c5fa5f | 170 | TODO_ggc_collect /* todo_flags_finish */ |
8ddbbcae | 171 | } |
a7e5372d ZD |
172 | }; |
173 | ||
bbc8a8dc ZD |
174 | /* Predictive commoning. */ |
175 | ||
176 | static unsigned | |
177 | run_tree_predictive_commoning (void) | |
178 | { | |
179 | if (!current_loops) | |
180 | return 0; | |
181 | ||
65aab64f | 182 | return tree_predictive_commoning (); |
bbc8a8dc ZD |
183 | } |
184 | ||
185 | static bool | |
186 | gate_tree_predictive_commoning (void) | |
187 | { | |
188 | return flag_predictive_commoning != 0; | |
189 | } | |
190 | ||
b8698a0f | 191 | struct gimple_opt_pass pass_predcom = |
bbc8a8dc | 192 | { |
8ddbbcae JH |
193 | { |
194 | GIMPLE_PASS, | |
bbc8a8dc ZD |
195 | "pcom", /* name */ |
196 | gate_tree_predictive_commoning, /* gate */ | |
197 | run_tree_predictive_commoning, /* execute */ | |
198 | NULL, /* sub */ | |
199 | NULL, /* next */ | |
200 | 0, /* static_pass_number */ | |
201 | TV_PREDCOM, /* tv_id */ | |
202 | PROP_cfg, /* properties_required */ | |
203 | 0, /* properties_provided */ | |
204 | 0, /* properties_destroyed */ | |
205 | 0, /* todo_flags_start */ | |
22c5fa5f | 206 | TODO_update_ssa_only_virtuals /* todo_flags_finish */ |
8ddbbcae | 207 | } |
bbc8a8dc ZD |
208 | }; |
209 | ||
79fe1b3b DN |
210 | /* Loop autovectorization. */ |
211 | ||
c2924966 | 212 | static unsigned int |
79fe1b3b DN |
213 | tree_vectorize (void) |
214 | { | |
d6e840ee RG |
215 | if (number_of_loops () <= 1) |
216 | return 0; | |
217 | ||
d73be268 | 218 | return vectorize_loops (); |
79fe1b3b DN |
219 | } |
220 | ||
221 | static bool | |
222 | gate_tree_vectorize (void) | |
223 | { | |
d6e840ee | 224 | return flag_tree_vectorize; |
79fe1b3b DN |
225 | } |
226 | ||
8ddbbcae | 227 | struct gimple_opt_pass pass_vectorize = |
79fe1b3b | 228 | { |
8ddbbcae JH |
229 | { |
230 | GIMPLE_PASS, | |
79fe1b3b DN |
231 | "vect", /* name */ |
232 | gate_tree_vectorize, /* gate */ | |
233 | tree_vectorize, /* execute */ | |
234 | NULL, /* sub */ | |
235 | NULL, /* next */ | |
236 | 0, /* static_pass_number */ | |
237 | TV_TREE_VECTORIZATION, /* tv_id */ | |
238 | PROP_cfg | PROP_ssa, /* properties_required */ | |
239 | 0, /* properties_provided */ | |
240 | 0, /* properties_destroyed */ | |
98b6e9dd | 241 | 0, /* todo_flags_start */ |
22c5fa5f | 242 | TODO_update_ssa |
8ddbbcae JH |
243 | | TODO_ggc_collect /* todo_flags_finish */ |
244 | } | |
79fe1b3b DN |
245 | }; |
246 | ||
f8bf9252 SP |
247 | /* GRAPHITE optimizations. */ |
248 | ||
249 | static unsigned int | |
250 | graphite_transforms (void) | |
251 | { | |
252 | if (!current_loops) | |
253 | return 0; | |
254 | ||
255 | graphite_transform_loops (); | |
256 | ||
257 | return 0; | |
258 | } | |
259 | ||
260 | static bool | |
261 | gate_graphite_transforms (void) | |
262 | { | |
b8698a0f | 263 | /* Enable -fgraphite pass if any one of the graphite optimization flags |
f8bf9252 | 264 | is turned on. */ |
98af4c9f SP |
265 | if (flag_loop_block |
266 | || flag_loop_interchange | |
267 | || flag_loop_strip_mine | |
268 | || flag_graphite_identity | |
269 | || flag_loop_parallelize_all | |
270 | || flag_loop_flatten) | |
f8bf9252 SP |
271 | flag_graphite = 1; |
272 | ||
273 | return flag_graphite != 0; | |
274 | } | |
275 | ||
d4332d00 SP |
276 | struct gimple_opt_pass pass_graphite = |
277 | { | |
278 | { | |
279 | GIMPLE_PASS, | |
280 | "graphite0", /* name */ | |
281 | gate_graphite_transforms, /* gate */ | |
282 | NULL, /* execute */ | |
283 | NULL, /* sub */ | |
284 | NULL, /* next */ | |
285 | 0, /* static_pass_number */ | |
286 | TV_GRAPHITE, /* tv_id */ | |
287 | PROP_cfg | PROP_ssa, /* properties_required */ | |
288 | 0, /* properties_provided */ | |
289 | 0, /* properties_destroyed */ | |
290 | 0, /* todo_flags_start */ | |
291 | 0 /* todo_flags_finish */ | |
292 | } | |
293 | }; | |
294 | ||
f8bf9252 SP |
295 | struct gimple_opt_pass pass_graphite_transforms = |
296 | { | |
297 | { | |
298 | GIMPLE_PASS, | |
299 | "graphite", /* name */ | |
300 | gate_graphite_transforms, /* gate */ | |
301 | graphite_transforms, /* execute */ | |
302 | NULL, /* sub */ | |
303 | NULL, /* next */ | |
304 | 0, /* static_pass_number */ | |
305 | TV_GRAPHITE_TRANSFORMS, /* tv_id */ | |
306 | PROP_cfg | PROP_ssa, /* properties_required */ | |
307 | 0, /* properties_provided */ | |
308 | 0, /* properties_destroyed */ | |
309 | 0, /* todo_flags_start */ | |
22c5fa5f | 310 | 0 /* todo_flags_finish */ |
f8bf9252 SP |
311 | } |
312 | }; | |
313 | ||
3d8864c0 SP |
314 | /* Check the correctness of the data dependence analyzers. */ |
315 | ||
316 | static unsigned int | |
317 | check_data_deps (void) | |
318 | { | |
d51157de | 319 | if (number_of_loops () <= 1) |
3d8864c0 SP |
320 | return 0; |
321 | ||
322 | tree_check_data_deps (); | |
323 | return 0; | |
324 | } | |
325 | ||
326 | static bool | |
327 | gate_check_data_deps (void) | |
328 | { | |
329 | return flag_check_data_deps != 0; | |
330 | } | |
331 | ||
8ddbbcae | 332 | struct gimple_opt_pass pass_check_data_deps = |
3d8864c0 | 333 | { |
8ddbbcae JH |
334 | { |
335 | GIMPLE_PASS, | |
3d8864c0 SP |
336 | "ckdd", /* name */ |
337 | gate_check_data_deps, /* gate */ | |
338 | check_data_deps, /* execute */ | |
339 | NULL, /* sub */ | |
340 | NULL, /* next */ | |
341 | 0, /* static_pass_number */ | |
342 | TV_CHECK_DATA_DEPS, /* tv_id */ | |
343 | PROP_cfg | PROP_ssa, /* properties_required */ | |
344 | 0, /* properties_provided */ | |
345 | 0, /* properties_destroyed */ | |
346 | 0, /* todo_flags_start */ | |
22c5fa5f | 347 | 0 /* todo_flags_finish */ |
8ddbbcae | 348 | } |
3d8864c0 SP |
349 | }; |
350 | ||
82b85a85 ZD |
351 | /* Canonical induction variable creation pass. */ |
352 | ||
c2924966 | 353 | static unsigned int |
82b85a85 ZD |
354 | tree_ssa_loop_ivcanon (void) |
355 | { | |
d51157de | 356 | if (number_of_loops () <= 1) |
c2924966 | 357 | return 0; |
82b85a85 | 358 | |
d73be268 | 359 | return canonicalize_induction_variables (); |
82b85a85 ZD |
360 | } |
361 | ||
362 | static bool | |
363 | gate_tree_ssa_loop_ivcanon (void) | |
364 | { | |
1b08d87d | 365 | return flag_tree_loop_ivcanon != 0; |
82b85a85 ZD |
366 | } |
367 | ||
8ddbbcae | 368 | struct gimple_opt_pass pass_iv_canon = |
82b85a85 | 369 | { |
8ddbbcae JH |
370 | { |
371 | GIMPLE_PASS, | |
82b85a85 ZD |
372 | "ivcanon", /* name */ |
373 | gate_tree_ssa_loop_ivcanon, /* gate */ | |
374 | tree_ssa_loop_ivcanon, /* execute */ | |
375 | NULL, /* sub */ | |
376 | NULL, /* next */ | |
377 | 0, /* static_pass_number */ | |
378 | TV_TREE_LOOP_IVCANON, /* tv_id */ | |
379 | PROP_cfg | PROP_ssa, /* properties_required */ | |
380 | 0, /* properties_provided */ | |
381 | 0, /* properties_destroyed */ | |
382 | 0, /* todo_flags_start */ | |
22c5fa5f | 383 | 0 /* todo_flags_finish */ |
8ddbbcae | 384 | } |
684aaf29 ZD |
385 | }; |
386 | ||
387 | /* Propagation of constants using scev. */ | |
388 | ||
389 | static bool | |
390 | gate_scev_const_prop (void) | |
391 | { | |
fbf798fc | 392 | return flag_tree_scev_cprop; |
684aaf29 ZD |
393 | } |
394 | ||
8ddbbcae | 395 | struct gimple_opt_pass pass_scev_cprop = |
684aaf29 | 396 | { |
8ddbbcae JH |
397 | { |
398 | GIMPLE_PASS, | |
684aaf29 ZD |
399 | "sccp", /* name */ |
400 | gate_scev_const_prop, /* gate */ | |
401 | scev_const_prop, /* execute */ | |
402 | NULL, /* sub */ | |
403 | NULL, /* next */ | |
404 | 0, /* static_pass_number */ | |
405 | TV_SCEV_CONST, /* tv_id */ | |
406 | PROP_cfg | PROP_ssa, /* properties_required */ | |
407 | 0, /* properties_provided */ | |
408 | 0, /* properties_destroyed */ | |
409 | 0, /* todo_flags_start */ | |
22c5fa5f | 410 | TODO_cleanup_cfg |
8ddbbcae | 411 | | TODO_update_ssa_only_virtuals |
d49195a3 | 412 | /* todo_flags_finish */ |
8ddbbcae | 413 | } |
b7eae7b8 ZD |
414 | }; |
415 | ||
f3cd574f ZD |
416 | /* Record bounds on numbers of iterations of loops. */ |
417 | ||
c2924966 | 418 | static unsigned int |
f3cd574f ZD |
419 | tree_ssa_loop_bounds (void) |
420 | { | |
d51157de | 421 | if (number_of_loops () <= 1) |
c2924966 | 422 | return 0; |
f3cd574f | 423 | |
e3488283 | 424 | estimate_numbers_of_iterations (true); |
f3cd574f | 425 | scev_reset (); |
c2924966 | 426 | return 0; |
f3cd574f ZD |
427 | } |
428 | ||
8ddbbcae | 429 | struct gimple_opt_pass pass_record_bounds = |
f3cd574f | 430 | { |
8ddbbcae JH |
431 | { |
432 | GIMPLE_PASS, | |
e0a42b0f | 433 | "*record_bounds", /* name */ |
f3cd574f ZD |
434 | NULL, /* gate */ |
435 | tree_ssa_loop_bounds, /* execute */ | |
436 | NULL, /* sub */ | |
437 | NULL, /* next */ | |
438 | 0, /* static_pass_number */ | |
ccbdbf0a | 439 | TV_TREE_LOOP_BOUNDS, /* tv_id */ |
f3cd574f ZD |
440 | PROP_cfg | PROP_ssa, /* properties_required */ |
441 | 0, /* properties_provided */ | |
442 | 0, /* properties_destroyed */ | |
443 | 0, /* todo_flags_start */ | |
8ddbbcae JH |
444 | 0 /* todo_flags_finish */ |
445 | } | |
f3cd574f ZD |
446 | }; |
447 | ||
82b85a85 ZD |
448 | /* Complete unrolling of loops. */ |
449 | ||
c2924966 | 450 | static unsigned int |
82b85a85 ZD |
451 | tree_complete_unroll (void) |
452 | { | |
d51157de | 453 | if (number_of_loops () <= 1) |
c2924966 | 454 | return 0; |
82b85a85 | 455 | |
d73be268 ZD |
456 | return tree_unroll_loops_completely (flag_unroll_loops |
457 | || flag_peel_loops | |
d6e840ee | 458 | || optimize >= 3, true); |
82b85a85 ZD |
459 | } |
460 | ||
461 | static bool | |
462 | gate_tree_complete_unroll (void) | |
463 | { | |
91a01f21 | 464 | return true; |
82b85a85 ZD |
465 | } |
466 | ||
8ddbbcae | 467 | struct gimple_opt_pass pass_complete_unroll = |
82b85a85 | 468 | { |
8ddbbcae JH |
469 | { |
470 | GIMPLE_PASS, | |
82b85a85 ZD |
471 | "cunroll", /* name */ |
472 | gate_tree_complete_unroll, /* gate */ | |
473 | tree_complete_unroll, /* execute */ | |
474 | NULL, /* sub */ | |
475 | NULL, /* next */ | |
476 | 0, /* static_pass_number */ | |
477 | TV_COMPLETE_UNROLL, /* tv_id */ | |
478 | PROP_cfg | PROP_ssa, /* properties_required */ | |
8b11a64c ZD |
479 | 0, /* properties_provided */ |
480 | 0, /* properties_destroyed */ | |
481 | 0, /* todo_flags_start */ | |
22c5fa5f | 482 | TODO_ggc_collect /* todo_flags_finish */ |
8ddbbcae | 483 | } |
8b11a64c ZD |
484 | }; |
485 | ||
d6e840ee RG |
486 | /* Complete unrolling of inner loops. */ |
487 | ||
488 | static unsigned int | |
489 | tree_complete_unroll_inner (void) | |
490 | { | |
491 | unsigned ret = 0; | |
492 | ||
493 | loop_optimizer_init (LOOPS_NORMAL | |
494 | | LOOPS_HAVE_RECORDED_EXITS); | |
495 | if (number_of_loops () > 1) | |
496 | { | |
497 | scev_initialize (); | |
498 | ret = tree_unroll_loops_completely (optimize >= 3, false); | |
499 | free_numbers_of_iterations_estimates (); | |
500 | scev_finalize (); | |
501 | } | |
502 | loop_optimizer_finalize (); | |
503 | ||
504 | return ret; | |
505 | } | |
506 | ||
507 | static bool | |
508 | gate_tree_complete_unroll_inner (void) | |
509 | { | |
510 | return optimize >= 2; | |
511 | } | |
512 | ||
513 | struct gimple_opt_pass pass_complete_unrolli = | |
514 | { | |
515 | { | |
516 | GIMPLE_PASS, | |
517 | "cunrolli", /* name */ | |
518 | gate_tree_complete_unroll_inner, /* gate */ | |
519 | tree_complete_unroll_inner, /* execute */ | |
520 | NULL, /* sub */ | |
521 | NULL, /* next */ | |
522 | 0, /* static_pass_number */ | |
523 | TV_COMPLETE_UNROLL, /* tv_id */ | |
524 | PROP_cfg | PROP_ssa, /* properties_required */ | |
525 | 0, /* properties_provided */ | |
526 | 0, /* properties_destroyed */ | |
527 | 0, /* todo_flags_start */ | |
c7dd803e | 528 | TODO_verify_flow |
d6e840ee RG |
529 | | TODO_ggc_collect /* todo_flags_finish */ |
530 | } | |
531 | }; | |
532 | ||
5f40b3cb ZD |
533 | /* Parallelization. */ |
534 | ||
535 | static bool | |
536 | gate_tree_parallelize_loops (void) | |
537 | { | |
4e9012fd | 538 | return flag_tree_parallelize_loops > 1; |
5f40b3cb ZD |
539 | } |
540 | ||
541 | static unsigned | |
542 | tree_parallelize_loops (void) | |
543 | { | |
544 | if (number_of_loops () <= 1) | |
545 | return 0; | |
546 | ||
547 | if (parallelize_loops ()) | |
548 | return TODO_cleanup_cfg | TODO_rebuild_alias; | |
549 | return 0; | |
550 | } | |
551 | ||
8ddbbcae | 552 | struct gimple_opt_pass pass_parallelize_loops = |
5f40b3cb | 553 | { |
8ddbbcae JH |
554 | { |
555 | GIMPLE_PASS, | |
5f40b3cb ZD |
556 | "parloops", /* name */ |
557 | gate_tree_parallelize_loops, /* gate */ | |
558 | tree_parallelize_loops, /* execute */ | |
559 | NULL, /* sub */ | |
560 | NULL, /* next */ | |
561 | 0, /* static_pass_number */ | |
562 | TV_TREE_PARALLELIZE_LOOPS, /* tv_id */ | |
563 | PROP_cfg | PROP_ssa, /* properties_required */ | |
564 | 0, /* properties_provided */ | |
565 | 0, /* properties_destroyed */ | |
566 | 0, /* todo_flags_start */ | |
22c5fa5f | 567 | 0 /* todo_flags_finish */ |
8ddbbcae | 568 | } |
5f40b3cb ZD |
569 | }; |
570 | ||
17684618 ZD |
571 | /* Prefetching. */ |
572 | ||
c2924966 | 573 | static unsigned int |
17684618 ZD |
574 | tree_ssa_loop_prefetch (void) |
575 | { | |
d51157de | 576 | if (number_of_loops () <= 1) |
c2924966 | 577 | return 0; |
17684618 | 578 | |
d73be268 | 579 | return tree_ssa_prefetch_arrays (); |
17684618 ZD |
580 | } |
581 | ||
582 | static bool | |
583 | gate_tree_ssa_loop_prefetch (void) | |
584 | { | |
1fbb509a | 585 | return flag_prefetch_loop_arrays > 0; |
17684618 ZD |
586 | } |
587 | ||
8ddbbcae | 588 | struct gimple_opt_pass pass_loop_prefetch = |
17684618 | 589 | { |
8ddbbcae JH |
590 | { |
591 | GIMPLE_PASS, | |
e324a72f | 592 | "aprefetch", /* name */ |
17684618 ZD |
593 | gate_tree_ssa_loop_prefetch, /* gate */ |
594 | tree_ssa_loop_prefetch, /* execute */ | |
595 | NULL, /* sub */ | |
596 | NULL, /* next */ | |
597 | 0, /* static_pass_number */ | |
598 | TV_TREE_PREFETCH, /* tv_id */ | |
599 | PROP_cfg | PROP_ssa, /* properties_required */ | |
600 | 0, /* properties_provided */ | |
601 | 0, /* properties_destroyed */ | |
602 | 0, /* todo_flags_start */ | |
22c5fa5f | 603 | 0 /* todo_flags_finish */ |
8ddbbcae | 604 | } |
17684618 ZD |
605 | }; |
606 | ||
8b11a64c ZD |
607 | /* Induction variable optimizations. */ |
608 | ||
c2924966 | 609 | static unsigned int |
8b11a64c ZD |
610 | tree_ssa_loop_ivopts (void) |
611 | { | |
d51157de | 612 | if (number_of_loops () <= 1) |
c2924966 | 613 | return 0; |
8b11a64c | 614 | |
d73be268 | 615 | tree_ssa_iv_optimize (); |
c2924966 | 616 | return 0; |
8b11a64c ZD |
617 | } |
618 | ||
619 | static bool | |
620 | gate_tree_ssa_loop_ivopts (void) | |
621 | { | |
622 | return flag_ivopts != 0; | |
623 | } | |
624 | ||
8ddbbcae | 625 | struct gimple_opt_pass pass_iv_optimize = |
8b11a64c | 626 | { |
8ddbbcae JH |
627 | { |
628 | GIMPLE_PASS, | |
8b11a64c ZD |
629 | "ivopts", /* name */ |
630 | gate_tree_ssa_loop_ivopts, /* gate */ | |
631 | tree_ssa_loop_ivopts, /* execute */ | |
632 | NULL, /* sub */ | |
633 | NULL, /* next */ | |
634 | 0, /* static_pass_number */ | |
635 | TV_TREE_LOOP_IVOPTS, /* tv_id */ | |
636 | PROP_cfg | PROP_ssa, /* properties_required */ | |
82b85a85 ZD |
637 | 0, /* properties_provided */ |
638 | 0, /* properties_destroyed */ | |
639 | 0, /* todo_flags_start */ | |
22c5fa5f | 640 | TODO_update_ssa | TODO_ggc_collect /* todo_flags_finish */ |
8ddbbcae | 641 | } |
82b85a85 ZD |
642 | }; |
643 | ||
c66b6c66 ZD |
644 | /* Loop optimizer finalization. */ |
645 | ||
c2924966 | 646 | static unsigned int |
c66b6c66 ZD |
647 | tree_ssa_loop_done (void) |
648 | { | |
d73be268 | 649 | free_numbers_of_iterations_estimates (); |
82b85a85 | 650 | scev_finalize (); |
598ec7bd | 651 | loop_optimizer_finalize (); |
c2924966 | 652 | return 0; |
c66b6c66 | 653 | } |
b8698a0f L |
654 | |
655 | struct gimple_opt_pass pass_tree_loop_done = | |
c66b6c66 | 656 | { |
8ddbbcae JH |
657 | { |
658 | GIMPLE_PASS, | |
c66b6c66 ZD |
659 | "loopdone", /* name */ |
660 | NULL, /* gate */ | |
661 | tree_ssa_loop_done, /* execute */ | |
662 | NULL, /* sub */ | |
663 | NULL, /* next */ | |
664 | 0, /* static_pass_number */ | |
87c11134 | 665 | TV_TREE_LOOP_FINI, /* tv_id */ |
c66b6c66 ZD |
666 | PROP_cfg, /* properties_required */ |
667 | 0, /* properties_provided */ | |
668 | 0, /* properties_destroyed */ | |
669 | 0, /* todo_flags_start */ | |
c7dd803e | 670 | TODO_cleanup_cfg |
22c5fa5f | 671 | | TODO_verify_flow /* todo_flags_finish */ |
8ddbbcae | 672 | } |
c66b6c66 | 673 | }; |