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