1 /* Loop header copying on trees.
2 Copyright (C) 2004-2023 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
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/>. */
22 #include "coretypes.h"
27 #include "tree-pass.h"
28 #include "gimple-ssa.h"
29 #include "gimple-iterator.h"
31 #include "tree-into-ssa.h"
33 #include "tree-inline.h"
34 #include "tree-ssa-threadedge.h"
35 #include "tree-ssa-sccvn.h"
36 #include "tree-phinodes.h"
37 #include "ssa-iterators.h"
38 #include "value-range.h"
39 #include "gimple-range.h"
40 #include "gimple-range-path.h"
43 /* Duplicates headers of loops if they are small enough, so that the statements
44 in the loop body are always executed when the loop is entered. This
45 increases effectiveness of code motion optimizations, and reduces the need
46 for loop preconditioning. */
48 /* Given a path through edge E, whose last statement is COND, return
49 the range of the solved conditional in R. */
52 edge_range_query (irange
&r
, edge e
, gcond
*cond
, gimple_ranger
&ranger
)
54 auto_vec
<basic_block
> path (2);
55 path
.safe_push (e
->dest
);
56 path
.safe_push (e
->src
);
57 path_range_query
query (ranger
, path
);
58 if (!query
.range_of_stmt (r
, cond
))
59 r
.set_varying (boolean_type_node
);
62 /* Return edge that is true in the first iteration of the loop
63 and NULL otherwise. */
66 static_loop_exit (class loop
*l
, gimple_ranger
*ranger
)
68 edge e
= loop_preheader_edge (l
);
69 gcond
*last
= safe_dyn_cast
<gcond
*> (*gsi_last_bb (e
->dest
));
76 extract_true_false_edges_from_block (e
->dest
, &true_e
, &false_e
);
78 /* If neither edge is the exit edge, this is not a case we'd like to
80 if (!loop_exit_edge_p (l
, true_e
) && !loop_exit_edge_p (l
, false_e
))
83 int_range
<1> desired_static_range
;
84 if (loop_exit_edge_p (l
, true_e
))
86 desired_static_range
= range_false ();
91 desired_static_range
= range_true ();
96 edge_range_query (r
, e
, last
, *ranger
);
97 return r
== desired_static_range
? ret_e
: NULL
;
100 /* Check whether we should duplicate HEADER of LOOP. At most *LIMIT
101 instructions should be duplicated, limit is decreased by the actual
105 should_duplicate_loop_header_p (basic_block header
, class loop
*loop
,
108 gimple_stmt_iterator bsi
;
110 gcc_assert (!header
->aux
);
112 gcc_assert (EDGE_COUNT (header
->succs
) > 0);
113 if (single_succ_p (header
))
115 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
117 " Not duplicating bb %i: it is single succ.\n",
122 if (flow_bb_inside_loop_p (loop
, EDGE_SUCC (header
, 0)->dest
)
123 && flow_bb_inside_loop_p (loop
, EDGE_SUCC (header
, 1)->dest
))
125 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
127 " Not duplicating bb %i: both successors are in loop.\n",
132 /* If this is not the original loop header, we want it to have just
133 one predecessor in order to match the && pattern. */
134 if (header
!= loop
->header
&& !single_pred_p (header
))
136 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
138 " Not duplicating bb %i: it has mutiple predecestors.\n",
143 gcond
*last
= safe_dyn_cast
<gcond
*> (*gsi_last_bb (header
));
146 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
148 " Not duplicating bb %i: it does not end by conditional.\n",
153 for (gphi_iterator psi
= gsi_start_phis (header
); !gsi_end_p (psi
);
156 gphi
*phi
= psi
.phi ();
157 tree res
= gimple_phi_result (phi
);
158 if (INTEGRAL_TYPE_P (TREE_TYPE (res
))
159 || POINTER_TYPE_P (TREE_TYPE (res
)))
160 gimple_set_uid (phi
, 1 /* IV */);
162 gimple_set_uid (phi
, 0);
165 /* Count number of instructions and punt on calls.
166 Populate stmts INV/IV flag to later apply heuristics to the
167 kind of conditions we want to copy. */
168 for (bsi
= gsi_start_bb (header
); !gsi_end_p (bsi
); gsi_next (&bsi
))
170 gimple
*last
= gsi_stmt (bsi
);
172 if (gimple_code (last
) == GIMPLE_LABEL
)
175 if (is_gimple_debug (last
))
178 if (gimple_code (last
) == GIMPLE_CALL
179 && (!gimple_inexpensive_call_p (as_a
<gcall
*> (last
))
180 /* IFN_LOOP_DIST_ALIAS means that inner loop is distributed
181 at current loop's header. Don't copy in this case. */
182 || gimple_call_internal_p (last
, IFN_LOOP_DIST_ALIAS
)))
184 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
186 " Not duplicating bb %i: it contains call.\n",
191 *limit
-= estimate_num_insns (last
, &eni_size_weights
);
194 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
196 " Not duplicating bb %i contains too many insns.\n",
201 /* Classify the stmt based on whether its computation is based
202 on a IV or whether it is invariant in the loop. */
203 gimple_set_uid (last
, 0);
204 if (!gimple_vuse (last
))
210 FOR_EACH_SSA_TREE_OPERAND (op
, last
, i
, SSA_OP_USE
)
211 if (!SSA_NAME_IS_DEFAULT_DEF (op
)
212 && flow_bb_inside_loop_p (loop
,
213 gimple_bb (SSA_NAME_DEF_STMT (op
))))
215 if (!(gimple_uid (SSA_NAME_DEF_STMT (op
)) & 2 /* INV */))
217 if (gimple_uid (SSA_NAME_DEF_STMT (op
)) & 1 /* IV */)
220 gimple_set_uid (last
, (iv
? 1 : 0) | (inv
? 2 : 0));
224 /* If the condition tests a non-IV loop variant we do not want to rotate
225 the loop further. Unless this is the original loop header. */
226 tree lhs
= gimple_cond_lhs (last
);
227 tree rhs
= gimple_cond_rhs (last
);
228 if (header
!= loop
->header
229 && ((TREE_CODE (lhs
) == SSA_NAME
230 && !SSA_NAME_IS_DEFAULT_DEF (lhs
)
231 && flow_bb_inside_loop_p (loop
, gimple_bb (SSA_NAME_DEF_STMT (lhs
)))
232 && gimple_uid (SSA_NAME_DEF_STMT (lhs
)) == 0)
233 || (TREE_CODE (rhs
) == SSA_NAME
234 && !SSA_NAME_IS_DEFAULT_DEF (rhs
)
235 && flow_bb_inside_loop_p (loop
,
236 gimple_bb (SSA_NAME_DEF_STMT (rhs
)))
237 && gimple_uid (SSA_NAME_DEF_STMT (rhs
)) == 0)))
239 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
241 " Not duplicating bb %i: condition based on non-IV loop"
242 " variant.\n", header
->index
);
249 /* Checks whether LOOP is a do-while style loop. */
252 do_while_loop_p (class loop
*loop
)
254 gimple
*stmt
= last_nondebug_stmt (loop
->latch
);
256 /* If the latch of the loop is not empty, it is not a do-while loop. */
258 && gimple_code (stmt
) != GIMPLE_LABEL
)
260 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
262 "Loop %i is not do-while loop: latch is not empty.\n",
267 /* If the latch does not have a single predecessor, it is not a
269 if (!single_pred_p (loop
->latch
))
271 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
273 "Loop %i is not do-while loop: latch has multiple "
274 "predecessors.\n", loop
->num
);
278 /* If the latch predecessor doesn't exit the loop, it is not a
280 if (!loop_exits_from_bb_p (loop
, single_pred (loop
->latch
)))
282 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
284 "Loop %i is not do-while loop: latch predecessor "
285 "does not exit loop.\n", loop
->num
);
289 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
290 fprintf (dump_file
, "Loop %i is do-while loop\n", loop
->num
);
297 /* Common superclass for both header-copying phases. */
298 class ch_base
: public gimple_opt_pass
301 ch_base (pass_data data
, gcc::context
*ctxt
)
302 : gimple_opt_pass (data
, ctxt
)
305 /* Copies headers of all loops in FUN for which process_loop_p is true. */
306 unsigned int copy_headers (function
*fun
);
308 /* Return true to copy headers of LOOP or false to skip. */
309 virtual bool process_loop_p (class loop
*loop
) = 0;
312 const pass_data pass_data_ch
=
314 GIMPLE_PASS
, /* type */
316 OPTGROUP_LOOP
, /* optinfo_flags */
317 TV_TREE_CH
, /* tv_id */
318 ( PROP_cfg
| PROP_ssa
), /* properties_required */
319 0, /* properties_provided */
320 0, /* properties_destroyed */
321 0, /* todo_flags_start */
322 0, /* todo_flags_finish */
325 class pass_ch
: public ch_base
328 pass_ch (gcc::context
*ctxt
)
329 : ch_base (pass_data_ch
, ctxt
)
332 /* opt_pass methods: */
333 bool gate (function
*) final override
{ return flag_tree_ch
!= 0; }
335 /* Initialize and finalize loop structures, copying headers inbetween. */
336 unsigned int execute (function
*) final override
;
338 opt_pass
* clone () final override
{ return new pass_ch (m_ctxt
); }
341 /* ch_base method: */
342 bool process_loop_p (class loop
*loop
) final override
;
345 const pass_data pass_data_ch_vect
=
347 GIMPLE_PASS
, /* type */
348 "ch_vect", /* name */
349 OPTGROUP_LOOP
, /* optinfo_flags */
350 TV_TREE_CH
, /* tv_id */
351 ( PROP_cfg
| PROP_ssa
), /* properties_required */
352 0, /* properties_provided */
353 0, /* properties_destroyed */
354 0, /* todo_flags_start */
355 0, /* todo_flags_finish */
358 /* This is a more aggressive version of the same pass, designed to run just
359 before if-conversion and vectorization, to put more loops into the form
360 required for those phases. */
361 class pass_ch_vect
: public ch_base
364 pass_ch_vect (gcc::context
*ctxt
)
365 : ch_base (pass_data_ch_vect
, ctxt
)
368 /* opt_pass methods: */
369 bool gate (function
*fun
) final override
371 return flag_tree_ch
!= 0
372 && (flag_tree_loop_vectorize
!= 0 || fun
->has_force_vectorize_loops
);
375 /* Just copy headers, no initialization/finalization of loop structures. */
376 unsigned int execute (function
*) final override
;
379 /* ch_base method: */
380 bool process_loop_p (class loop
*loop
) final override
;
381 }; // class pass_ch_vect
383 /* For all loops, copy the condition at the end of the loop body in front
384 of the loop. This is beneficial since it increases efficiency of
385 code motion optimizations. It also saves one jump on entry to the loop. */
388 ch_base::copy_headers (function
*fun
)
391 edge exit
, nonexit
, entry
;
392 basic_block
*bbs
, *copied_bbs
;
395 bool changed
= false;
397 if (number_of_loops (fun
) <= 1)
400 bbs
= XNEWVEC (basic_block
, n_basic_blocks_for_fn (fun
));
401 copied_bbs
= XNEWVEC (basic_block
, n_basic_blocks_for_fn (fun
));
402 bbs_size
= n_basic_blocks_for_fn (fun
);
404 struct candidate
{class loop
*loop
; edge static_exit
;};
405 auto_vec
<struct candidate
> candidates
;
406 auto_vec
<std::pair
<edge
, loop_p
> > copied
;
407 auto_vec
<class loop
*> loops_to_unloop
;
408 auto_vec
<int> loops_to_unloop_nunroll
;
410 mark_dfs_back_edges ();
411 gimple_ranger
*ranger
= new gimple_ranger
;
412 for (auto loop
: loops_list (cfun
, 0))
414 int initial_limit
= param_max_loop_header_insns
;
415 int remaining_limit
= initial_limit
;
416 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
418 "Analyzing loop %i\n", loop
->num
);
420 header
= loop
->header
;
421 if (!get_max_loop_iterations_int (loop
))
423 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
424 fprintf (dump_file
, "Loop %d never loops.\n", loop
->num
);
425 loops_to_unloop
.safe_push (loop
);
426 loops_to_unloop_nunroll
.safe_push (0);
430 /* If the loop is already a do-while style one (either because it was
431 written as such, or because jump threading transformed it into one),
432 we might be in fact peeling the first iteration of the loop. This
433 in general is not a good idea. Also avoid touching infinite loops. */
434 if (!loop_has_exit_edges (loop
)
435 || !process_loop_p (loop
))
438 edge static_exit
= static_loop_exit (loop
, ranger
);
440 /* Avoid loop header copying when optimizing for size unless we can
441 determine that the loop condition is static in the first
443 if (optimize_loop_for_size_p (loop
)
444 && !loop
->force_vectorize
447 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
449 " Not duplicating bb %i: optimizing for size.\n",
454 if (should_duplicate_loop_header_p (header
, loop
, &remaining_limit
))
455 candidates
.safe_push ({loop
, static_exit
});
457 /* Do not use ranger after we change the IL and not have updated SSA. */
460 for (auto candidate
: candidates
)
462 class loop
*loop
= candidate
.loop
;
463 int initial_limit
= param_max_loop_header_insns
;
464 int remaining_limit
= initial_limit
;
465 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
467 "Copying headers of loop %i\n", loop
->num
);
469 header
= loop
->header
;
471 /* Iterate the header copying up to limit; this takes care of the cases
472 like while (a && b) {...}, where we want to have both of the conditions
473 copied. TODO -- handle while (a || b) - like cases, by not requiring
474 the header to have just a single successor and copying up to
480 profile_count exit_count
= profile_count::zero ();
481 profile_count entry_count
= profile_count::zero ();
484 FOR_EACH_EDGE (e
, ei
, loop
->header
->preds
)
485 if (e
->src
!= loop
->latch
)
486 entry_count
+= e
->count ();
487 while (should_duplicate_loop_header_p (header
, loop
, &remaining_limit
))
489 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
490 fprintf (dump_file
, " Will duplicate bb %i\n", header
->index
);
492 /* Find a successor of header that is inside a loop; i.e. the new
493 header after the condition is copied. */
494 if (flow_bb_inside_loop_p (loop
, EDGE_SUCC (header
, 0)->dest
))
496 nonexit
= EDGE_SUCC (header
, 0);
497 exit
= EDGE_SUCC (header
, 1);
501 nonexit
= EDGE_SUCC (header
, 1);
502 exit
= EDGE_SUCC (header
, 0);
504 exit_count
+= exit
->count ();
506 bbs
[n_bbs
++] = header
;
507 gcc_assert (bbs_size
> n_bbs
);
508 header
= nonexit
->dest
;
514 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
517 "Duplicating header of the loop %d up to edge %d->%d,"
519 loop
->num
, exit
->src
->index
, exit
->dest
->index
,
520 initial_limit
- remaining_limit
);
521 if (candidate
.static_exit
)
523 " Will eliminate peeled conditional in bb %d.\n",
524 candidate
.static_exit
->src
->index
);
527 /* Ensure that the header will have just the latch as a predecessor
529 if (!single_pred_p (nonexit
->dest
))
531 header
= split_edge (nonexit
);
532 exit
= single_pred_edge (header
);
535 entry
= loop_preheader_edge (loop
);
537 propagate_threaded_block_debug_into (exit
->dest
, entry
->dest
);
538 if (!gimple_duplicate_sese_region (entry
, exit
, bbs
, n_bbs
, copied_bbs
,
539 true, candidate
.static_exit
))
541 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
542 fprintf (dump_file
, "Duplication failed.\n");
545 copied
.safe_push (std::make_pair (entry
, loop
));
547 /* If the loop has the form "for (i = j; i < j + 10; i++)" then
548 this copying can introduce a case where we rely on undefined
549 signed overflow to eliminate the preheader condition, because
550 we assume that "j < j + 10" is true. We don't want to warn
551 about that case for -Wstrict-overflow, because in general we
552 don't warn about overflow involving loops. Prevent the
553 warning by setting the no_warning flag in the condition. */
554 if (warn_strict_overflow
> 0)
558 for (i
= 0; i
< n_bbs
; ++i
)
560 gimple_stmt_iterator bsi
;
562 for (bsi
= gsi_start_bb (copied_bbs
[i
]);
566 gimple
*stmt
= gsi_stmt (bsi
);
567 if (gimple_code (stmt
) == GIMPLE_COND
)
569 tree lhs
= gimple_cond_lhs (stmt
);
570 if (gimple_cond_code (stmt
) != EQ_EXPR
571 && gimple_cond_code (stmt
) != NE_EXPR
572 && INTEGRAL_TYPE_P (TREE_TYPE (lhs
))
573 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (lhs
)))
574 suppress_warning (stmt
, OPT_Wstrict_overflow_
);
576 else if (is_gimple_assign (stmt
))
578 enum tree_code rhs_code
= gimple_assign_rhs_code (stmt
);
579 tree rhs1
= gimple_assign_rhs1 (stmt
);
580 if (TREE_CODE_CLASS (rhs_code
) == tcc_comparison
581 && rhs_code
!= EQ_EXPR
582 && rhs_code
!= NE_EXPR
583 && INTEGRAL_TYPE_P (TREE_TYPE (rhs1
))
584 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs1
)))
585 suppress_warning (stmt
, OPT_Wstrict_overflow_
);
591 /* Update header of the loop. */
592 loop
->header
= header
;
593 /* Find correct latch. We only duplicate chain of conditionals so
594 there should be precisely two edges to the new header. One entry
595 edge and one to latch. */
596 FOR_EACH_EDGE (e
, ei
, loop
->header
->preds
)
597 if (header
!= e
->src
)
599 loop
->latch
= e
->src
;
602 /* Ensure that the latch is simple. */
603 if (!single_succ_p (loop_latch_edge (loop
)->src
))
604 split_edge (loop_latch_edge (loop
));
606 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
608 if (do_while_loop_p (loop
))
609 fprintf (dump_file
, "Loop %d is now do-while loop.\n", loop
->num
);
611 fprintf (dump_file
, "Loop %d is still not do-while loop.\n",
613 fprintf (dump_file
, "Exit count: ");
614 exit_count
.dump (dump_file
);
615 fprintf (dump_file
, "\nEntry count: ");
616 entry_count
.dump (dump_file
);
617 fprintf (dump_file
, "\n");
620 /* We possibly decreased number of itrations by 1. */
621 auto_vec
<edge
> exits
= get_loop_exit_edges (loop
);
622 bool precise
= (nexits
== (int) exits
.length ());
623 /* Check that loop may not terminate in other way than via
624 basic blocks we duplicated. */
627 basic_block
*bbs
= get_loop_body (loop
);
628 for (unsigned i
= 0; i
< loop
->num_nodes
&& precise
; ++i
)
630 basic_block bb
= bbs
[i
];
631 bool found_exit
= false;
632 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
633 if (!flow_bb_inside_loop_p (loop
, e
->dest
))
638 /* If BB has exit, it was duplicated. */
641 /* Give up on irreducible loops. */
642 if (bb
->flags
& BB_IRREDUCIBLE_LOOP
)
647 /* Check that inner loops are finite. */
648 for (class loop
*l
= bb
->loop_father
; l
!= loop
&& precise
;
655 /* Verify that there is no statement that may be terminate
656 execution in a way not visible to CFG. */
657 for (gimple_stmt_iterator bsi
= gsi_start_bb (bb
);
658 !gsi_end_p (bsi
); gsi_next (&bsi
))
659 if (stmt_can_terminate_bb_p (gsi_stmt (bsi
)))
665 && get_max_loop_iterations_int (loop
) == 1)
667 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
668 fprintf (dump_file
, "Loop %d no longer loops.\n", loop
->num
);
669 loops_to_unloop
.safe_push (loop
);
670 loops_to_unloop_nunroll
.safe_push (0);
674 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
677 " decreased number of iterations of loop %d by 1.\n",
679 adjust_loop_info_after_peeling (loop
, 1, true);
681 else if (exit_count
>= entry_count
.apply_scale (9, 10))
683 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
685 "Peeled likely exits: likely decreased number "
686 "of iterations of loop %d by 1.\n", loop
->num
);
687 adjust_loop_info_after_peeling (loop
, 1, false);
689 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
691 "Not decreased number"
692 " of iterations of loop %d; likely exits remains.\n",
700 update_ssa (TODO_update_ssa
);
701 /* After updating SSA form perform CSE on the loop header
702 copies. This is esp. required for the pass before
703 vectorization since nothing cleans up copied exit tests
704 that can now be simplified. CSE from the entry of the
705 region we copied till all loop exit blocks but not
706 entering the loop itself. */
707 for (unsigned i
= 0; i
< copied
.length (); ++i
)
709 edge entry
= copied
[i
].first
;
710 loop_p loop
= copied
[i
].second
;
711 auto_vec
<edge
> exit_edges
= get_loop_exit_edges (loop
);
712 bitmap exit_bbs
= BITMAP_ALLOC (NULL
);
713 for (unsigned j
= 0; j
< exit_edges
.length (); ++j
)
714 bitmap_set_bit (exit_bbs
, exit_edges
[j
]->dest
->index
);
715 bitmap_set_bit (exit_bbs
, loop
->header
->index
);
716 do_rpo_vn (cfun
, entry
, exit_bbs
);
717 BITMAP_FREE (exit_bbs
);
720 if (!loops_to_unloop
.is_empty ())
722 bool irred_invalidated
;
723 unloop_loops (loops_to_unloop
, loops_to_unloop_nunroll
, NULL
, &irred_invalidated
);
729 return changed
? TODO_cleanup_cfg
: 0;
732 /* Initialize the loop structures we need, and finalize after. */
735 pass_ch::execute (function
*fun
)
737 loop_optimizer_init (LOOPS_HAVE_PREHEADERS
738 | LOOPS_HAVE_SIMPLE_LATCHES
739 | LOOPS_HAVE_RECORDED_EXITS
);
741 unsigned int res
= copy_headers (fun
);
743 loop_optimizer_finalize ();
747 /* Assume an earlier phase has already initialized all the loop structures that
748 we need here (and perhaps others too), and that these will be finalized by
752 pass_ch_vect::execute (function
*fun
)
754 return copy_headers (fun
);
757 /* Apply header copying according to a very simple test of do-while shape. */
760 pass_ch::process_loop_p (class loop
*loop
)
762 return !do_while_loop_p (loop
);
765 /* Apply header-copying to loops where we might enable vectorization. */
768 pass_ch_vect::process_loop_p (class loop
*loop
)
770 if (!flag_tree_loop_vectorize
&& !loop
->force_vectorize
)
773 if (loop
->dont_vectorize
)
776 /* The vectorizer won't handle anything with multiple exits, so skip. */
777 edge exit
= single_exit (loop
);
781 if (!do_while_loop_p (loop
))
790 make_pass_ch_vect (gcc::context
*ctxt
)
792 return new pass_ch_vect (ctxt
);
796 make_pass_ch (gcc::context
*ctxt
)
798 return new pass_ch (ctxt
);