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