]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/loop-init.c
Eliminate FOR_EACH_BB macro.
[thirdparty/gcc.git] / gcc / loop-init.c
CommitLineData
0526a3ff 1/* Loop optimizer initialization routines and RTL loop optimization passes.
711789cc 2 Copyright (C) 2002-2013 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"
23#include "tm.h"
24#include "rtl.h"
41a8aa41 25#include "tree.h"
4a020a8c 26#include "regs.h"
42fe97ed 27#include "obstack.h"
6a606e3c 28#include "basic-block.h"
29#include "cfgloop.h"
77fce4cd 30#include "tree-pass.h"
77fce4cd 31#include "flags.h"
3072d30e 32#include "df.h"
ccae4f9f 33#include "ggc.h"
05d9c18a 34#include "tree-ssa-loop-niter.h"
6a606e3c 35
0526a3ff 36\f
ff829efa 37/* Apply FLAGS to the loop state. */
6a606e3c 38
ff829efa 39static void
40apply_loop_flags (unsigned flags)
6a606e3c 41{
4a6f9e19 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);
f24ec26f 50 loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
4a6f9e19 51 }
52 else
53 disambiguate_loops_with_multiple_latches ();
54
6a606e3c 55 /* Create pre-headers. */
c8d055f6 56 if (flags & LOOPS_HAVE_PREHEADERS)
e1ab7874 57 {
58 int cp_flags = CP_SIMPLE_PREHEADERS;
59
60 if (flags & LOOPS_HAVE_FALLTHRU_PREHEADERS)
61 cp_flags |= CP_FALLTHRU_PREHEADERS;
48e1416a 62
e1ab7874 63 create_preheaders (cp_flags);
64 }
6a606e3c 65
66 /* Force all latches to have only single successor. */
c8d055f6 67 if (flags & LOOPS_HAVE_SIMPLE_LATCHES)
7194de72 68 force_single_succ_latches ();
6a606e3c 69
70 /* Mark irreducible loops. */
c8d055f6 71 if (flags & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
7194de72 72 mark_irreducible_loops ();
c8d055f6 73
dce58e66 74 if (flags & LOOPS_HAVE_RECORDED_EXITS)
75 record_loop_exits ();
ff829efa 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
82void
83loop_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 {
f6568ea4 96 bool recorded_exits = loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS);
97
ff829efa 98 gcc_assert (cfun->curr_properties & PROP_loops);
99
100 /* Ensure that the dominators are computed, like flow_loops_find does. */
101 calculate_dominance_info (CDI_DOMINATORS);
102
f6568ea4 103 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
104 {
105 loops_state_clear (~0U);
106 fix_loop_structure (NULL);
107 }
108
ff829efa 109#ifdef ENABLE_CHECKING
f6568ea4 110 else
111 verify_loop_structure ();
ff829efa 112#endif
51f707ce 113
114 /* Clear all flags. */
f6568ea4 115 if (recorded_exits)
116 release_recorded_exits ();
51f707ce 117 loops_state_clear (~0U);
ff829efa 118 }
119
120 /* Apply flags to loops. */
121 apply_loop_flags (flags);
6a606e3c 122
123 /* Dump loops. */
7194de72 124 flow_loops_dump (dump_file, NULL, 1);
6a606e3c 125
126#ifdef ENABLE_CHECKING
7194de72 127 verify_loop_structure ();
6a606e3c 128#endif
a66c9777 129
130 timevar_pop (TV_LOOP_INIT);
6a606e3c 131}
132
88e6f696 133/* Finalize loop structures. */
134
6a606e3c 135void
88e6f696 136loop_optimizer_finalize (void)
6a606e3c 137{
17519ba0 138 struct loop *loop;
88e6f696 139 basic_block bb;
6a606e3c 140
a66c9777 141 timevar_push (TV_LOOP_FINI);
142
79f958cb 143 if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
144 release_recorded_exits ();
145
9584aa9d 146 free_numbers_of_iterations_estimates ();
147
79f958cb 148 /* If we should preserve loop structure, do not free it but clear
149 flags that advanced properties are there as we are not preserving
150 that in full. */
151 if (cfun->curr_properties & PROP_loops)
152 {
153 loops_state_clear (LOOP_CLOSED_SSA
154 | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS
155 | LOOPS_HAVE_PREHEADERS
156 | LOOPS_HAVE_SIMPLE_LATCHES
157 | LOOPS_HAVE_FALLTHRU_PREHEADERS);
a4430012 158 loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
a66c9777 159 goto loop_fini_done;
79f958cb 160 }
161
7a3bf727 162 gcc_assert (current_loops != NULL);
f9cce2dc 163
f21d4d00 164 FOR_EACH_LOOP (loop, 0)
165 free_simple_loop_desc (loop);
6a606e3c 166
6a606e3c 167 /* Clean up. */
88e6f696 168 flow_loops_free (current_loops);
ccae4f9f 169 ggc_free (current_loops);
88e6f696 170 current_loops = NULL;
171
172 FOR_ALL_BB (bb)
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
204 /* We need exact and fast dominance info to be available. */
205 gcc_assert (dom_info_state (CDI_DOMINATORS) == DOM_OK);
206
207 if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
208 {
209 release_recorded_exits ();
210 record_exits = LOOPS_HAVE_RECORDED_EXITS;
211 }
212
213 /* Remember the depth of the blocks in the loop hierarchy, so that we can
214 recognize blocks whose loop nesting relationship has changed. */
215 if (changed_bbs)
fc00614f 216 FOR_EACH_BB_FN (bb, cfun)
ff829efa 217 bb->aux = (void *) (size_t) loop_depth (bb->loop_father);
218
219 /* Remove the dead loops from structures. We start from the innermost
220 loops, so that when we remove the loops, we know that the loops inside
221 are preserved, and do not waste time relinking loops that will be
222 removed later. */
f21d4d00 223 FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
ff829efa 224 {
225 /* Detect the case that the loop is no longer present even though
226 it wasn't marked for removal.
227 ??? If we do that we can get away with not marking loops for
228 removal at all. And possibly avoid some spurious removals. */
229 if (loop->header
230 && bb_loop_header_p (loop->header))
231 continue;
232
233 if (dump_file && (dump_flags & TDF_DETAILS))
234 fprintf (dump_file, "fix_loop_structure: removing loop %d\n",
235 loop->num);
236
237 while (loop->inner)
238 {
239 struct loop *ploop = loop->inner;
240 flow_loop_tree_node_remove (ploop);
241 flow_loop_tree_node_add (loop_outer (loop), ploop);
242 }
243
84087109 244 /* Remove the loop. */
245 loop->header = NULL;
246 flow_loop_tree_node_remove (loop);
ff829efa 247 }
248
b6f3c6f1 249 /* Remember the number of loops so we can return how many new loops
250 flow_loops_find discovered. */
41f75a99 251 old_nloops = number_of_loops (cfun);
b6f3c6f1 252
ff829efa 253 /* Re-compute loop structure in-place. */
254 flow_loops_find (current_loops);
255
256 /* Mark the blocks whose loop has changed. */
257 if (changed_bbs)
258 {
fc00614f 259 FOR_EACH_BB_FN (bb, cfun)
ff829efa 260 {
261 if ((void *) (size_t) loop_depth (bb->loop_father) != bb->aux)
262 bitmap_set_bit (changed_bbs, bb->index);
263
264 bb->aux = NULL;
265 }
266 }
267
84087109 268 /* Finally free deleted loops. */
41f75a99 269 FOR_EACH_VEC_ELT (*get_loops (cfun), i, loop)
84087109 270 if (loop && loop->header == NULL)
271 {
41f75a99 272 (*get_loops (cfun))[i] = NULL;
84087109 273 flow_loop_free (loop);
274 }
275
ff829efa 276 loops_state_clear (LOOPS_NEED_FIXUP);
277
278 /* Apply flags to loops. */
279 apply_loop_flags (current_loops->state | record_exits);
280
281#ifdef ENABLE_CHECKING
282 verify_loop_structure ();
283#endif
284
285 timevar_pop (TV_LOOP_INIT);
b6f3c6f1 286
41f75a99 287 return number_of_loops (cfun) - old_nloops;
ff829efa 288}
77fce4cd 289\f
0526a3ff 290/* Gate for the RTL loop superpass. The actual passes are subpasses.
291 See passes.c for more on that. */
292
77fce4cd 293static bool
294gate_handle_loop2 (void)
295{
759626e6 296 if (optimize > 0
297 && (flag_move_loop_invariants
298 || flag_unswitch_loops
299 || flag_peel_loops
300 || flag_unroll_loops
a82484af 301#ifdef HAVE_doloop_end
759626e6 302 || (flag_branch_on_count_reg && HAVE_doloop_end)
a82484af 303#endif
759626e6 304 ))
305 return true;
306 else
307 {
308 /* No longer preserve loops, remove them now. */
309 cfun->curr_properties &= ~PROP_loops;
310 if (current_loops)
311 loop_optimizer_finalize ();
312 return false;
313 }
77fce4cd 314}
315
cbe8bda8 316namespace {
317
318const pass_data pass_data_loop2 =
319{
320 RTL_PASS, /* type */
321 "loop2", /* name */
322 OPTGROUP_LOOP, /* optinfo_flags */
323 true, /* has_gate */
324 false, /* has_execute */
325 TV_LOOP, /* tv_id */
326 0, /* properties_required */
327 0, /* properties_provided */
328 0, /* properties_destroyed */
329 0, /* todo_flags_start */
330 0, /* todo_flags_finish */
0526a3ff 331};
77fce4cd 332
cbe8bda8 333class pass_loop2 : public rtl_opt_pass
334{
335public:
9af5ce0c 336 pass_loop2 (gcc::context *ctxt)
337 : rtl_opt_pass (pass_data_loop2, ctxt)
cbe8bda8 338 {}
339
340 /* opt_pass methods: */
341 bool gate () { return gate_handle_loop2 (); }
342
343}; // class pass_loop2
344
345} // anon namespace
346
347rtl_opt_pass *
348make_pass_loop2 (gcc::context *ctxt)
349{
350 return new pass_loop2 (ctxt);
351}
352
0526a3ff 353\f
354/* Initialization of the RTL loop passes. */
2a1990e9 355static unsigned int
0526a3ff 356rtl_loop_init (void)
357{
207c7ab2 358 gcc_assert (current_ir_type () == IR_RTL_CFGLAYOUT);
48e1416a 359
77fce4cd 360 if (dump_file)
4a020a8c 361 {
362 dump_reg_info (dump_file);
363 dump_flow_info (dump_file, dump_flags);
364 }
77fce4cd 365
88e6f696 366 loop_optimizer_init (LOOPS_NORMAL);
2a1990e9 367 return 0;
0526a3ff 368}
77fce4cd 369
cbe8bda8 370namespace {
371
372const pass_data pass_data_rtl_loop_init =
373{
374 RTL_PASS, /* type */
375 "loop2_init", /* name */
376 OPTGROUP_LOOP, /* optinfo_flags */
377 false, /* has_gate */
378 true, /* has_execute */
379 TV_LOOP, /* tv_id */
380 0, /* properties_required */
381 0, /* properties_provided */
382 0, /* properties_destroyed */
383 0, /* todo_flags_start */
384 TODO_verify_rtl_sharing, /* todo_flags_finish */
0526a3ff 385};
77fce4cd 386
cbe8bda8 387class pass_rtl_loop_init : public rtl_opt_pass
388{
389public:
9af5ce0c 390 pass_rtl_loop_init (gcc::context *ctxt)
391 : rtl_opt_pass (pass_data_rtl_loop_init, ctxt)
cbe8bda8 392 {}
393
394 /* opt_pass methods: */
395 unsigned int execute () { return rtl_loop_init (); }
396
397}; // class pass_rtl_loop_init
398
399} // anon namespace
400
401rtl_opt_pass *
402make_pass_rtl_loop_init (gcc::context *ctxt)
403{
404 return new pass_rtl_loop_init (ctxt);
405}
406
0526a3ff 407\f
408/* Finalization of the RTL loop passes. */
88e6f696 409
2a1990e9 410static unsigned int
0526a3ff 411rtl_loop_done (void)
412{
79f958cb 413 /* No longer preserve loops, remove them now. */
414 cfun->curr_properties &= ~PROP_loops;
88e6f696 415 loop_optimizer_finalize ();
77fce4cd 416 free_dominance_info (CDI_DOMINATORS);
417
c38b28e7 418 cleanup_cfg (0);
77fce4cd 419 if (dump_file)
4a020a8c 420 {
421 dump_reg_info (dump_file);
422 dump_flow_info (dump_file, dump_flags);
423 }
0526a3ff 424
2a1990e9 425 return 0;
77fce4cd 426}
427
cbe8bda8 428namespace {
429
430const pass_data pass_data_rtl_loop_done =
431{
432 RTL_PASS, /* type */
433 "loop2_done", /* name */
434 OPTGROUP_LOOP, /* optinfo_flags */
435 false, /* has_gate */
436 true, /* has_execute */
437 TV_LOOP, /* tv_id */
438 0, /* properties_required */
439 0, /* properties_provided */
440 PROP_loops, /* properties_destroyed */
441 0, /* todo_flags_start */
442 ( TODO_verify_flow | TODO_verify_rtl_sharing ), /* todo_flags_finish */
0526a3ff 443};
444
cbe8bda8 445class pass_rtl_loop_done : public rtl_opt_pass
446{
447public:
9af5ce0c 448 pass_rtl_loop_done (gcc::context *ctxt)
449 : rtl_opt_pass (pass_data_rtl_loop_done, ctxt)
cbe8bda8 450 {}
451
452 /* opt_pass methods: */
453 unsigned int execute () { return rtl_loop_done (); }
454
455}; // class pass_rtl_loop_done
456
457} // anon namespace
458
459rtl_opt_pass *
460make_pass_rtl_loop_done (gcc::context *ctxt)
461{
462 return new pass_rtl_loop_done (ctxt);
463}
464
0526a3ff 465\f
466/* Loop invariant code motion. */
228967a9 467static bool
468gate_rtl_move_loop_invariants (void)
469{
470 return flag_move_loop_invariants;
471}
472
2a1990e9 473static unsigned int
0526a3ff 474rtl_move_loop_invariants (void)
475{
41f75a99 476 if (number_of_loops (cfun) > 1)
7194de72 477 move_loop_invariants ();
2a1990e9 478 return 0;
0526a3ff 479}
480
cbe8bda8 481namespace {
482
483const pass_data pass_data_rtl_move_loop_invariants =
484{
485 RTL_PASS, /* type */
486 "loop2_invariant", /* name */
487 OPTGROUP_LOOP, /* optinfo_flags */
488 true, /* has_gate */
489 true, /* has_execute */
490 TV_LOOP_MOVE_INVARIANTS, /* tv_id */
491 0, /* properties_required */
492 0, /* properties_provided */
493 0, /* properties_destroyed */
494 0, /* todo_flags_start */
495 ( TODO_df_verify | TODO_df_finish
496 | TODO_verify_rtl_sharing ), /* todo_flags_finish */
0526a3ff 497};
498
cbe8bda8 499class pass_rtl_move_loop_invariants : public rtl_opt_pass
500{
501public:
9af5ce0c 502 pass_rtl_move_loop_invariants (gcc::context *ctxt)
503 : rtl_opt_pass (pass_data_rtl_move_loop_invariants, ctxt)
cbe8bda8 504 {}
505
506 /* opt_pass methods: */
507 bool gate () { return gate_rtl_move_loop_invariants (); }
508 unsigned int execute () { return rtl_move_loop_invariants (); }
509
510}; // class pass_rtl_move_loop_invariants
511
512} // anon namespace
513
514rtl_opt_pass *
515make_pass_rtl_move_loop_invariants (gcc::context *ctxt)
516{
517 return new pass_rtl_move_loop_invariants (ctxt);
518}
519
0526a3ff 520\f
521/* Loop unswitching for RTL. */
228967a9 522static bool
523gate_rtl_unswitch (void)
524{
525 return flag_unswitch_loops;
526}
527
2a1990e9 528static unsigned int
0526a3ff 529rtl_unswitch (void)
530{
41f75a99 531 if (number_of_loops (cfun) > 1)
7194de72 532 unswitch_loops ();
2a1990e9 533 return 0;
0526a3ff 534}
535
cbe8bda8 536namespace {
537
538const pass_data pass_data_rtl_unswitch =
539{
540 RTL_PASS, /* type */
541 "loop2_unswitch", /* name */
542 OPTGROUP_LOOP, /* optinfo_flags */
543 true, /* has_gate */
544 true, /* has_execute */
545 TV_LOOP_UNSWITCH, /* tv_id */
546 0, /* properties_required */
547 0, /* properties_provided */
548 0, /* properties_destroyed */
549 0, /* todo_flags_start */
550 TODO_verify_rtl_sharing, /* todo_flags_finish */
0526a3ff 551};
552
cbe8bda8 553class pass_rtl_unswitch : public rtl_opt_pass
554{
555public:
9af5ce0c 556 pass_rtl_unswitch (gcc::context *ctxt)
557 : rtl_opt_pass (pass_data_rtl_unswitch, ctxt)
cbe8bda8 558 {}
559
560 /* opt_pass methods: */
561 bool gate () { return gate_rtl_unswitch (); }
562 unsigned int execute () { return rtl_unswitch (); }
563
564}; // class pass_rtl_unswitch
565
566} // anon namespace
567
568rtl_opt_pass *
569make_pass_rtl_unswitch (gcc::context *ctxt)
570{
571 return new pass_rtl_unswitch (ctxt);
572}
573
0526a3ff 574\f
575/* Loop unswitching for RTL. */
228967a9 576static bool
577gate_rtl_unroll_and_peel_loops (void)
578{
579 return (flag_peel_loops || flag_unroll_loops || flag_unroll_all_loops);
580}
581
2a1990e9 582static unsigned int
0526a3ff 583rtl_unroll_and_peel_loops (void)
584{
41f75a99 585 if (number_of_loops (cfun) > 1)
0526a3ff 586 {
587 int flags = 0;
3072d30e 588 if (dump_file)
589 df_dump (dump_file);
0526a3ff 590
591 if (flag_peel_loops)
592 flags |= UAP_PEEL;
593 if (flag_unroll_loops)
594 flags |= UAP_UNROLL;
595 if (flag_unroll_all_loops)
596 flags |= UAP_UNROLL_ALL;
597
7194de72 598 unroll_and_peel_loops (flags);
0526a3ff 599 }
2a1990e9 600 return 0;
0526a3ff 601}
602
cbe8bda8 603namespace {
604
605const pass_data pass_data_rtl_unroll_and_peel_loops =
606{
607 RTL_PASS, /* type */
608 "loop2_unroll", /* name */
609 OPTGROUP_LOOP, /* optinfo_flags */
610 true, /* has_gate */
611 true, /* has_execute */
612 TV_LOOP_UNROLL, /* tv_id */
613 0, /* properties_required */
614 0, /* properties_provided */
615 0, /* properties_destroyed */
616 0, /* todo_flags_start */
617 TODO_verify_rtl_sharing, /* todo_flags_finish */
0526a3ff 618};
619
cbe8bda8 620class pass_rtl_unroll_and_peel_loops : public rtl_opt_pass
621{
622public:
9af5ce0c 623 pass_rtl_unroll_and_peel_loops (gcc::context *ctxt)
624 : rtl_opt_pass (pass_data_rtl_unroll_and_peel_loops, ctxt)
cbe8bda8 625 {}
626
627 /* opt_pass methods: */
628 bool gate () { return gate_rtl_unroll_and_peel_loops (); }
629 unsigned int execute () { return rtl_unroll_and_peel_loops (); }
630
631}; // class pass_rtl_unroll_and_peel_loops
632
633} // anon namespace
634
635rtl_opt_pass *
636make_pass_rtl_unroll_and_peel_loops (gcc::context *ctxt)
637{
638 return new pass_rtl_unroll_and_peel_loops (ctxt);
639}
640
0526a3ff 641\f
642/* The doloop optimization. */
228967a9 643static bool
644gate_rtl_doloop (void)
645{
646#ifdef HAVE_doloop_end
647 return (flag_branch_on_count_reg && HAVE_doloop_end);
648#else
649 return 0;
650#endif
651}
652
2a1990e9 653static unsigned int
0526a3ff 654rtl_doloop (void)
655{
656#ifdef HAVE_doloop_end
41f75a99 657 if (number_of_loops (cfun) > 1)
7194de72 658 doloop_optimize_loops ();
0526a3ff 659#endif
2a1990e9 660 return 0;
0526a3ff 661}
662
cbe8bda8 663namespace {
664
665const pass_data pass_data_rtl_doloop =
666{
667 RTL_PASS, /* type */
668 "loop2_doloop", /* name */
669 OPTGROUP_LOOP, /* optinfo_flags */
670 true, /* has_gate */
671 true, /* has_execute */
672 TV_LOOP_DOLOOP, /* tv_id */
673 0, /* properties_required */
674 0, /* properties_provided */
675 0, /* properties_destroyed */
676 0, /* todo_flags_start */
677 TODO_verify_rtl_sharing, /* todo_flags_finish */
77fce4cd 678};
cbe8bda8 679
680class pass_rtl_doloop : public rtl_opt_pass
681{
682public:
9af5ce0c 683 pass_rtl_doloop (gcc::context *ctxt)
684 : rtl_opt_pass (pass_data_rtl_doloop, ctxt)
cbe8bda8 685 {}
686
687 /* opt_pass methods: */
688 bool gate () { return gate_rtl_doloop (); }
689 unsigned int execute () { return rtl_doloop (); }
690
691}; // class pass_rtl_doloop
692
693} // anon namespace
694
695rtl_opt_pass *
696make_pass_rtl_doloop (gcc::context *ctxt)
697{
698 return new pass_rtl_doloop (ctxt);
699}