]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/loop-init.c
loop-unroll.c: (decide_unrolling_and_peeling): Rename to
[thirdparty/gcc.git] / gcc / loop-init.c
1 /* Loop optimizer initialization routines and RTL loop optimization passes.
2 Copyright (C) 2002-2014 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 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.
15
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/>. */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "rtl.h"
25 #include "tree.h"
26 #include "regs.h"
27 #include "obstack.h"
28 #include "basic-block.h"
29 #include "cfgloop.h"
30 #include "tree-pass.h"
31 #include "flags.h"
32 #include "df.h"
33 #include "ggc.h"
34 #include "tree-ssa-loop-niter.h"
35
36 \f
37 /* Apply FLAGS to the loop state. */
38
39 static void
40 apply_loop_flags (unsigned flags)
41 {
42 if (flags & LOOPS_MAY_HAVE_MULTIPLE_LATCHES)
43 {
44 /* If the loops may have multiple latches, we cannot canonicalize
45 them further (and most of the loop manipulation functions will
46 not work). However, we avoid modifying cfg, which some
47 passes may want. */
48 gcc_assert ((flags & ~(LOOPS_MAY_HAVE_MULTIPLE_LATCHES
49 | LOOPS_HAVE_RECORDED_EXITS)) == 0);
50 loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
51 }
52 else
53 disambiguate_loops_with_multiple_latches ();
54
55 /* Create pre-headers. */
56 if (flags & LOOPS_HAVE_PREHEADERS)
57 {
58 int cp_flags = CP_SIMPLE_PREHEADERS;
59
60 if (flags & LOOPS_HAVE_FALLTHRU_PREHEADERS)
61 cp_flags |= CP_FALLTHRU_PREHEADERS;
62
63 create_preheaders (cp_flags);
64 }
65
66 /* Force all latches to have only single successor. */
67 if (flags & LOOPS_HAVE_SIMPLE_LATCHES)
68 force_single_succ_latches ();
69
70 /* Mark irreducible loops. */
71 if (flags & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
72 mark_irreducible_loops ();
73
74 if (flags & LOOPS_HAVE_RECORDED_EXITS)
75 record_loop_exits ();
76 }
77
78 /* Initialize loop structures. This is used by the tree and RTL loop
79 optimizers. FLAGS specify what properties to compute and/or ensure for
80 loops. */
81
82 void
83 loop_optimizer_init (unsigned flags)
84 {
85 timevar_push (TV_LOOP_INIT);
86
87 if (!current_loops)
88 {
89 gcc_assert (!(cfun->curr_properties & PROP_loops));
90
91 /* Find the loops. */
92 current_loops = flow_loops_find (NULL);
93 }
94 else
95 {
96 bool recorded_exits = loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS);
97 bool needs_fixup = loops_state_satisfies_p (LOOPS_NEED_FIXUP);
98
99 gcc_assert (cfun->curr_properties & PROP_loops);
100
101 /* Ensure that the dominators are computed, like flow_loops_find does. */
102 calculate_dominance_info (CDI_DOMINATORS);
103
104 #ifdef ENABLE_CHECKING
105 if (!needs_fixup)
106 verify_loop_structure ();
107 #endif
108
109 /* Clear all flags. */
110 if (recorded_exits)
111 release_recorded_exits ();
112 loops_state_clear (~0U);
113
114 if (needs_fixup)
115 {
116 /* Apply LOOPS_MAY_HAVE_MULTIPLE_LATCHES early as fix_loop_structure
117 re-applies flags. */
118 loops_state_set (flags & LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
119 fix_loop_structure (NULL);
120 }
121 }
122
123 /* Apply flags to loops. */
124 apply_loop_flags (flags);
125
126 /* Dump loops. */
127 flow_loops_dump (dump_file, NULL, 1);
128
129 #ifdef ENABLE_CHECKING
130 verify_loop_structure ();
131 #endif
132
133 timevar_pop (TV_LOOP_INIT);
134 }
135
136 /* Finalize loop structures. */
137
138 void
139 loop_optimizer_finalize (void)
140 {
141 struct loop *loop;
142 basic_block bb;
143
144 timevar_push (TV_LOOP_FINI);
145
146 if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
147 release_recorded_exits ();
148
149 free_numbers_of_iterations_estimates ();
150
151 /* If we should preserve loop structure, do not free it but clear
152 flags that advanced properties are there as we are not preserving
153 that in full. */
154 if (cfun->curr_properties & PROP_loops)
155 {
156 loops_state_clear (LOOP_CLOSED_SSA
157 | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS
158 | LOOPS_HAVE_PREHEADERS
159 | LOOPS_HAVE_SIMPLE_LATCHES
160 | LOOPS_HAVE_FALLTHRU_PREHEADERS);
161 loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
162 goto loop_fini_done;
163 }
164
165 gcc_assert (current_loops != NULL);
166
167 FOR_EACH_LOOP (loop, 0)
168 free_simple_loop_desc (loop);
169
170 /* Clean up. */
171 flow_loops_free (current_loops);
172 ggc_free (current_loops);
173 current_loops = NULL;
174
175 FOR_ALL_BB_FN (bb, cfun)
176 {
177 bb->loop_father = NULL;
178 }
179
180 loop_fini_done:
181 timevar_pop (TV_LOOP_FINI);
182 }
183
184 /* The structure of loops might have changed. Some loops might get removed
185 (and their headers and latches were set to NULL), loop exists might get
186 removed (thus the loop nesting may be wrong), and some blocks and edges
187 were changed (so the information about bb --> loop mapping does not have
188 to be correct). But still for the remaining loops the header dominates
189 the latch, and loops did not get new subloops (new loops might possibly
190 get created, but we are not interested in them). Fix up the mess.
191
192 If CHANGED_BBS is not NULL, basic blocks whose loop depth has changed are
193 marked in it.
194
195 Returns the number of new discovered loops. */
196
197 unsigned
198 fix_loop_structure (bitmap changed_bbs)
199 {
200 basic_block bb;
201 int record_exits = 0;
202 struct loop *loop;
203 unsigned old_nloops, i;
204
205 timevar_push (TV_LOOP_INIT);
206
207 /* We need exact and fast dominance info to be available. */
208 gcc_assert (dom_info_state (CDI_DOMINATORS) == DOM_OK);
209
210 if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
211 {
212 release_recorded_exits ();
213 record_exits = LOOPS_HAVE_RECORDED_EXITS;
214 }
215
216 /* Remember the depth of the blocks in the loop hierarchy, so that we can
217 recognize blocks whose loop nesting relationship has changed. */
218 if (changed_bbs)
219 FOR_EACH_BB_FN (bb, cfun)
220 bb->aux = (void *) (size_t) loop_depth (bb->loop_father);
221
222 /* Remove the dead loops from structures. We start from the innermost
223 loops, so that when we remove the loops, we know that the loops inside
224 are preserved, and do not waste time relinking loops that will be
225 removed later. */
226 FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
227 {
228 /* Detect the case that the loop is no longer present even though
229 it wasn't marked for removal.
230 ??? If we do that we can get away with not marking loops for
231 removal at all. And possibly avoid some spurious removals. */
232 if (loop->header
233 && bb_loop_header_p (loop->header))
234 continue;
235
236 if (dump_file && (dump_flags & TDF_DETAILS))
237 fprintf (dump_file, "fix_loop_structure: removing loop %d\n",
238 loop->num);
239
240 while (loop->inner)
241 {
242 struct loop *ploop = loop->inner;
243 flow_loop_tree_node_remove (ploop);
244 flow_loop_tree_node_add (loop_outer (loop), ploop);
245 }
246
247 /* Remove the loop. */
248 if (loop->header)
249 loop->former_header = loop->header;
250 else
251 gcc_assert (loop->former_header != NULL);
252 loop->header = NULL;
253 flow_loop_tree_node_remove (loop);
254 }
255
256 /* Remember the number of loops so we can return how many new loops
257 flow_loops_find discovered. */
258 old_nloops = number_of_loops (cfun);
259
260 /* Re-compute loop structure in-place. */
261 flow_loops_find (current_loops);
262
263 /* Mark the blocks whose loop has changed. */
264 if (changed_bbs)
265 {
266 FOR_EACH_BB_FN (bb, cfun)
267 {
268 if ((void *) (size_t) loop_depth (bb->loop_father) != bb->aux)
269 bitmap_set_bit (changed_bbs, bb->index);
270
271 bb->aux = NULL;
272 }
273 }
274
275 /* Finally free deleted loops. */
276 FOR_EACH_VEC_ELT (*get_loops (cfun), i, loop)
277 if (loop && loop->header == NULL)
278 {
279 if (dump_file
280 && ((unsigned) loop->former_header->index
281 < basic_block_info_for_fn (cfun)->length ()))
282 {
283 basic_block former_header
284 = BASIC_BLOCK_FOR_FN (cfun, loop->former_header->index);
285 /* If the old header still exists we want to check if the
286 original loop is re-discovered or the old header is now
287 part of a newly discovered loop.
288 In both cases we should have avoided removing the loop. */
289 if (former_header == loop->former_header)
290 {
291 if (former_header->loop_father->header == former_header)
292 fprintf (dump_file, "fix_loop_structure: rediscovered "
293 "removed loop %d as loop %d with old header %d\n",
294 loop->num, former_header->loop_father->num,
295 former_header->index);
296 else if ((unsigned) former_header->loop_father->num
297 >= old_nloops)
298 fprintf (dump_file, "fix_loop_structure: header %d of "
299 "removed loop %d is part of the newly "
300 "discovered loop %d with header %d\n",
301 former_header->index, loop->num,
302 former_header->loop_father->num,
303 former_header->loop_father->header->index);
304 }
305 }
306 (*get_loops (cfun))[i] = NULL;
307 flow_loop_free (loop);
308 }
309
310 loops_state_clear (LOOPS_NEED_FIXUP);
311
312 /* Apply flags to loops. */
313 apply_loop_flags (current_loops->state | record_exits);
314
315 #ifdef ENABLE_CHECKING
316 verify_loop_structure ();
317 #endif
318
319 timevar_pop (TV_LOOP_INIT);
320
321 return number_of_loops (cfun) - old_nloops;
322 }
323 \f
324 /* The RTL loop superpass. The actual passes are subpasses. See passes.c for
325 more on that. */
326
327 namespace {
328
329 const pass_data pass_data_loop2 =
330 {
331 RTL_PASS, /* type */
332 "loop2", /* name */
333 OPTGROUP_LOOP, /* optinfo_flags */
334 TV_LOOP, /* tv_id */
335 0, /* properties_required */
336 0, /* properties_provided */
337 0, /* properties_destroyed */
338 0, /* todo_flags_start */
339 0, /* todo_flags_finish */
340 };
341
342 class pass_loop2 : public rtl_opt_pass
343 {
344 public:
345 pass_loop2 (gcc::context *ctxt)
346 : rtl_opt_pass (pass_data_loop2, ctxt)
347 {}
348
349 /* opt_pass methods: */
350 virtual bool gate (function *);
351
352 }; // class pass_loop2
353
354 bool
355 pass_loop2::gate (function *fun)
356 {
357 if (optimize > 0
358 && (flag_move_loop_invariants
359 || flag_unswitch_loops
360 || flag_unroll_loops
361 #ifdef HAVE_doloop_end
362 || (flag_branch_on_count_reg && HAVE_doloop_end)
363 #endif
364 ))
365 return true;
366 else
367 {
368 /* No longer preserve loops, remove them now. */
369 fun->curr_properties &= ~PROP_loops;
370 if (current_loops)
371 loop_optimizer_finalize ();
372 return false;
373 }
374 }
375
376 } // anon namespace
377
378 rtl_opt_pass *
379 make_pass_loop2 (gcc::context *ctxt)
380 {
381 return new pass_loop2 (ctxt);
382 }
383
384 \f
385 /* Initialization of the RTL loop passes. */
386 static unsigned int
387 rtl_loop_init (void)
388 {
389 gcc_assert (current_ir_type () == IR_RTL_CFGLAYOUT);
390
391 if (dump_file)
392 {
393 dump_reg_info (dump_file);
394 dump_flow_info (dump_file, dump_flags);
395 }
396
397 loop_optimizer_init (LOOPS_NORMAL);
398 return 0;
399 }
400
401 namespace {
402
403 const pass_data pass_data_rtl_loop_init =
404 {
405 RTL_PASS, /* type */
406 "loop2_init", /* name */
407 OPTGROUP_LOOP, /* optinfo_flags */
408 TV_LOOP, /* tv_id */
409 0, /* properties_required */
410 0, /* properties_provided */
411 0, /* properties_destroyed */
412 0, /* todo_flags_start */
413 0, /* todo_flags_finish */
414 };
415
416 class pass_rtl_loop_init : public rtl_opt_pass
417 {
418 public:
419 pass_rtl_loop_init (gcc::context *ctxt)
420 : rtl_opt_pass (pass_data_rtl_loop_init, ctxt)
421 {}
422
423 /* opt_pass methods: */
424 virtual unsigned int execute (function *) { return rtl_loop_init (); }
425
426 }; // class pass_rtl_loop_init
427
428 } // anon namespace
429
430 rtl_opt_pass *
431 make_pass_rtl_loop_init (gcc::context *ctxt)
432 {
433 return new pass_rtl_loop_init (ctxt);
434 }
435
436 \f
437 /* Finalization of the RTL loop passes. */
438
439 namespace {
440
441 const pass_data pass_data_rtl_loop_done =
442 {
443 RTL_PASS, /* type */
444 "loop2_done", /* name */
445 OPTGROUP_LOOP, /* optinfo_flags */
446 TV_LOOP, /* tv_id */
447 0, /* properties_required */
448 0, /* properties_provided */
449 PROP_loops, /* properties_destroyed */
450 0, /* todo_flags_start */
451 0, /* todo_flags_finish */
452 };
453
454 class pass_rtl_loop_done : public rtl_opt_pass
455 {
456 public:
457 pass_rtl_loop_done (gcc::context *ctxt)
458 : rtl_opt_pass (pass_data_rtl_loop_done, ctxt)
459 {}
460
461 /* opt_pass methods: */
462 virtual unsigned int execute (function *);
463
464 }; // class pass_rtl_loop_done
465
466 unsigned int
467 pass_rtl_loop_done::execute (function *fun)
468 {
469 /* No longer preserve loops, remove them now. */
470 fun->curr_properties &= ~PROP_loops;
471 loop_optimizer_finalize ();
472 free_dominance_info (CDI_DOMINATORS);
473
474 cleanup_cfg (0);
475 if (dump_file)
476 {
477 dump_reg_info (dump_file);
478 dump_flow_info (dump_file, dump_flags);
479 }
480
481 return 0;
482 }
483
484 } // anon namespace
485
486 rtl_opt_pass *
487 make_pass_rtl_loop_done (gcc::context *ctxt)
488 {
489 return new pass_rtl_loop_done (ctxt);
490 }
491
492 \f
493 /* Loop invariant code motion. */
494
495 namespace {
496
497 const pass_data pass_data_rtl_move_loop_invariants =
498 {
499 RTL_PASS, /* type */
500 "loop2_invariant", /* name */
501 OPTGROUP_LOOP, /* optinfo_flags */
502 TV_LOOP_MOVE_INVARIANTS, /* tv_id */
503 0, /* properties_required */
504 0, /* properties_provided */
505 0, /* properties_destroyed */
506 0, /* todo_flags_start */
507 ( TODO_df_verify | TODO_df_finish ), /* todo_flags_finish */
508 };
509
510 class pass_rtl_move_loop_invariants : public rtl_opt_pass
511 {
512 public:
513 pass_rtl_move_loop_invariants (gcc::context *ctxt)
514 : rtl_opt_pass (pass_data_rtl_move_loop_invariants, ctxt)
515 {}
516
517 /* opt_pass methods: */
518 virtual bool gate (function *) { return flag_move_loop_invariants; }
519 virtual unsigned int execute (function *fun)
520 {
521 if (number_of_loops (fun) > 1)
522 move_loop_invariants ();
523 return 0;
524 }
525
526 }; // class pass_rtl_move_loop_invariants
527
528 } // anon namespace
529
530 rtl_opt_pass *
531 make_pass_rtl_move_loop_invariants (gcc::context *ctxt)
532 {
533 return new pass_rtl_move_loop_invariants (ctxt);
534 }
535
536 \f
537 namespace {
538
539 const pass_data pass_data_rtl_unroll_loops =
540 {
541 RTL_PASS, /* type */
542 "loop2_unroll", /* name */
543 OPTGROUP_LOOP, /* optinfo_flags */
544 TV_LOOP_UNROLL, /* tv_id */
545 0, /* properties_required */
546 0, /* properties_provided */
547 0, /* properties_destroyed */
548 0, /* todo_flags_start */
549 0, /* todo_flags_finish */
550 };
551
552 class pass_rtl_unroll_loops : public rtl_opt_pass
553 {
554 public:
555 pass_rtl_unroll_loops (gcc::context *ctxt)
556 : rtl_opt_pass (pass_data_rtl_unroll_loops, ctxt)
557 {}
558
559 /* opt_pass methods: */
560 virtual bool gate (function *)
561 {
562 return (flag_peel_loops || flag_unroll_loops || flag_unroll_all_loops);
563 }
564
565 virtual unsigned int execute (function *);
566
567 }; // class pass_rtl_unroll_loops
568
569 unsigned int
570 pass_rtl_unroll_loops::execute (function *fun)
571 {
572 if (number_of_loops (fun) > 1)
573 {
574 int flags = 0;
575 if (dump_file)
576 df_dump (dump_file);
577
578 if (flag_unroll_loops)
579 flags |= UAP_UNROLL;
580 if (flag_unroll_all_loops)
581 flags |= UAP_UNROLL_ALL;
582
583 unroll_loops (flags);
584 }
585 return 0;
586 }
587
588 } // anon namespace
589
590 rtl_opt_pass *
591 make_pass_rtl_unroll_loops (gcc::context *ctxt)
592 {
593 return new pass_rtl_unroll_loops (ctxt);
594 }
595
596 \f
597 namespace {
598
599 const pass_data pass_data_rtl_doloop =
600 {
601 RTL_PASS, /* type */
602 "loop2_doloop", /* name */
603 OPTGROUP_LOOP, /* optinfo_flags */
604 TV_LOOP_DOLOOP, /* tv_id */
605 0, /* properties_required */
606 0, /* properties_provided */
607 0, /* properties_destroyed */
608 0, /* todo_flags_start */
609 0, /* todo_flags_finish */
610 };
611
612 class pass_rtl_doloop : public rtl_opt_pass
613 {
614 public:
615 pass_rtl_doloop (gcc::context *ctxt)
616 : rtl_opt_pass (pass_data_rtl_doloop, ctxt)
617 {}
618
619 /* opt_pass methods: */
620 virtual bool gate (function *);
621 virtual unsigned int execute (function *);
622
623 }; // class pass_rtl_doloop
624
625 bool
626 pass_rtl_doloop::gate (function *)
627 {
628 #ifdef HAVE_doloop_end
629 return (flag_branch_on_count_reg && HAVE_doloop_end);
630 #else
631 return false;
632 #endif
633 }
634
635 unsigned int
636 pass_rtl_doloop::execute (function *fun ATTRIBUTE_UNUSED)
637 {
638 #ifdef HAVE_doloop_end
639 if (number_of_loops (fun) > 1)
640 doloop_optimize_loops ();
641 #endif
642 return 0;
643 }
644
645 } // anon namespace
646
647 rtl_opt_pass *
648 make_pass_rtl_doloop (gcc::context *ctxt)
649 {
650 return new pass_rtl_doloop (ctxt);
651 }