2016-09-25 François Dumont <fdumont@gcc.gnu.org>
[official-gcc.git] / gcc / tree-ssa-loop-unswitch.c
blob40905af45eb55e1b68907a063615c20542e1b98b
1 /* Loop unswitching.
2 Copyright (C) 2004-2016 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
9 later version.
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
14 for more details.
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/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "tree.h"
25 #include "gimple.h"
26 #include "tree-pass.h"
27 #include "ssa.h"
28 #include "fold-const.h"
29 #include "gimplify.h"
30 #include "tree-cfg.h"
31 #include "tree-ssa.h"
32 #include "tree-ssa-loop-niter.h"
33 #include "tree-ssa-loop.h"
34 #include "tree-into-ssa.h"
35 #include "cfgloop.h"
36 #include "params.h"
37 #include "tree-inline.h"
38 #include "gimple-iterator.h"
39 #include "cfghooks.h"
40 #include "tree-ssa-loop-manip.h"
42 /* This file implements the loop unswitching, i.e. transformation of loops like
44 while (A)
46 if (inv)
51 if (!inv)
55 where inv is the loop invariant, into
57 if (inv)
59 while (A)
65 else
67 while (A)
74 Inv is considered invariant iff the values it compares are both invariant;
75 tree-ssa-loop-im.c ensures that all the suitable conditions are in this
76 shape. */
78 static struct loop *tree_unswitch_loop (struct loop *, basic_block, tree);
79 static bool tree_unswitch_single_loop (struct loop *, int);
80 static tree tree_may_unswitch_on (basic_block, struct loop *);
81 static bool tree_unswitch_outer_loop (struct loop *);
82 static edge find_loop_guard (struct loop *);
83 static bool empty_bb_without_guard_p (struct loop *, basic_block);
84 static bool used_outside_loop_p (struct loop *, tree);
85 static void hoist_guard (struct loop *, edge);
86 static bool check_exit_phi (struct loop *);
87 static tree get_vop_from_header (struct loop *);
89 /* Main entry point. Perform loop unswitching on all suitable loops. */
91 unsigned int
92 tree_ssa_unswitch_loops (void)
94 struct loop *loop;
95 bool changed = false;
97 /* Go through all loops starting from innermost. */
98 FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
100 if (!loop->inner)
101 /* Unswitch innermost loop. */
102 changed |= tree_unswitch_single_loop (loop, 0);
103 else
104 changed |= tree_unswitch_outer_loop (loop);
107 if (changed)
108 return TODO_cleanup_cfg;
109 return 0;
112 /* Checks whether we can unswitch LOOP on condition at end of BB -- one of its
113 basic blocks (for what it means see comments below). */
115 static tree
116 tree_may_unswitch_on (basic_block bb, struct loop *loop)
118 gimple *last, *def;
119 gcond *stmt;
120 tree cond, use;
121 basic_block def_bb;
122 ssa_op_iter iter;
124 /* BB must end in a simple conditional jump. */
125 last = last_stmt (bb);
126 if (!last || gimple_code (last) != GIMPLE_COND)
127 return NULL_TREE;
128 stmt = as_a <gcond *> (last);
130 /* To keep the things simple, we do not directly remove the conditions,
131 but just replace tests with 0 != 0 resp. 1 != 0. Prevent the infinite
132 loop where we would unswitch again on such a condition. */
133 if (gimple_cond_true_p (stmt) || gimple_cond_false_p (stmt))
134 return NULL_TREE;
136 /* Condition must be invariant. */
137 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
139 /* Unswitching on undefined values would introduce undefined
140 behavior that the original program might never exercise. */
141 if (ssa_undefined_value_p (use, true))
142 return NULL_TREE;
143 def = SSA_NAME_DEF_STMT (use);
144 def_bb = gimple_bb (def);
145 if (def_bb
146 && flow_bb_inside_loop_p (loop, def_bb))
147 return NULL_TREE;
150 cond = build2 (gimple_cond_code (stmt), boolean_type_node,
151 gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
153 return cond;
156 /* Simplifies COND using checks in front of the entry of the LOOP. Just very
157 simplish (sufficient to prevent us from duplicating loop in unswitching
158 unnecessarily). */
160 static tree
161 simplify_using_entry_checks (struct loop *loop, tree cond)
163 edge e = loop_preheader_edge (loop);
164 gimple *stmt;
166 while (1)
168 stmt = last_stmt (e->src);
169 if (stmt
170 && gimple_code (stmt) == GIMPLE_COND
171 && gimple_cond_code (stmt) == TREE_CODE (cond)
172 && operand_equal_p (gimple_cond_lhs (stmt),
173 TREE_OPERAND (cond, 0), 0)
174 && operand_equal_p (gimple_cond_rhs (stmt),
175 TREE_OPERAND (cond, 1), 0))
176 return (e->flags & EDGE_TRUE_VALUE
177 ? boolean_true_node
178 : boolean_false_node);
180 if (!single_pred_p (e->src))
181 return cond;
183 e = single_pred_edge (e->src);
184 if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
185 return cond;
189 /* Unswitch single LOOP. NUM is number of unswitchings done; we do not allow
190 it to grow too much, it is too easy to create example on that the code would
191 grow exponentially. */
193 static bool
194 tree_unswitch_single_loop (struct loop *loop, int num)
196 basic_block *bbs;
197 struct loop *nloop;
198 unsigned i, found;
199 tree cond = NULL_TREE;
200 gimple *stmt;
201 bool changed = false;
202 HOST_WIDE_INT iterations;
204 /* Perform initial tests if unswitch is eligible. */
205 if (num == 0)
207 /* Do not unswitch in cold regions. */
208 if (optimize_loop_for_size_p (loop))
210 if (dump_file && (dump_flags & TDF_DETAILS))
211 fprintf (dump_file, ";; Not unswitching cold loops\n");
212 return false;
215 /* The loop should not be too large, to limit code growth. */
216 if (tree_num_loop_insns (loop, &eni_size_weights)
217 > (unsigned) PARAM_VALUE (PARAM_MAX_UNSWITCH_INSNS))
219 if (dump_file && (dump_flags & TDF_DETAILS))
220 fprintf (dump_file, ";; Not unswitching, loop too big\n");
221 return false;
224 /* If the loop is not expected to iterate, there is no need
225 for unswitching. */
226 iterations = estimated_loop_iterations_int (loop);
227 if (iterations < 0)
228 iterations = likely_max_loop_iterations_int (loop);
229 if (iterations >= 0 && iterations <= 1)
231 if (dump_file && (dump_flags & TDF_DETAILS))
232 fprintf (dump_file, ";; Not unswitching, loop is not expected"
233 " to iterate\n");
234 return false;
238 i = 0;
239 bbs = get_loop_body (loop);
240 found = loop->num_nodes;
242 while (1)
244 /* Find a bb to unswitch on. */
245 for (; i < loop->num_nodes; i++)
246 if ((cond = tree_may_unswitch_on (bbs[i], loop)))
247 break;
249 if (i == loop->num_nodes)
251 if (dump_file
252 && num > PARAM_VALUE (PARAM_MAX_UNSWITCH_LEVEL)
253 && (dump_flags & TDF_DETAILS))
254 fprintf (dump_file, ";; Not unswitching anymore, hit max level\n");
256 if (found == loop->num_nodes)
258 free (bbs);
259 return changed;
261 break;
264 cond = simplify_using_entry_checks (loop, cond);
265 stmt = last_stmt (bbs[i]);
266 if (integer_nonzerop (cond))
268 /* Remove false path. */
269 gimple_cond_set_condition_from_tree (as_a <gcond *> (stmt),
270 boolean_true_node);
271 changed = true;
273 else if (integer_zerop (cond))
275 /* Remove true path. */
276 gimple_cond_set_condition_from_tree (as_a <gcond *> (stmt),
277 boolean_false_node);
278 changed = true;
280 /* Do not unswitch too much. */
281 else if (num > PARAM_VALUE (PARAM_MAX_UNSWITCH_LEVEL))
283 i++;
284 continue;
286 /* In nested tree_unswitch_single_loop first optimize all conditions
287 using entry checks, then discover still reachable blocks in the
288 loop and find the condition only among those still reachable bbs. */
289 else if (num != 0)
291 if (found == loop->num_nodes)
292 found = i;
293 i++;
294 continue;
296 else
298 found = i;
299 break;
302 update_stmt (stmt);
303 i++;
306 if (num != 0)
308 basic_block *tos, *worklist;
310 /* When called recursively, first do a quick discovery
311 of reachable bbs after the above changes and only
312 consider conditions in still reachable bbs. */
313 tos = worklist = XNEWVEC (basic_block, loop->num_nodes);
315 for (i = 0; i < loop->num_nodes; i++)
316 bbs[i]->flags &= ~BB_REACHABLE;
318 /* Start with marking header. */
319 *tos++ = bbs[0];
320 bbs[0]->flags |= BB_REACHABLE;
322 /* Iterate: find everything reachable from what we've already seen
323 within the same innermost loop. Don't look through false edges
324 if condition is always true or true edges if condition is
325 always false. */
326 while (tos != worklist)
328 basic_block b = *--tos;
329 edge e;
330 edge_iterator ei;
331 int flags = 0;
333 if (EDGE_COUNT (b->succs) == 2)
335 gimple *stmt = last_stmt (b);
336 if (stmt
337 && gimple_code (stmt) == GIMPLE_COND)
339 gcond *cond_stmt = as_a <gcond *> (stmt);
340 if (gimple_cond_true_p (cond_stmt))
341 flags = EDGE_FALSE_VALUE;
342 else if (gimple_cond_false_p (cond_stmt))
343 flags = EDGE_TRUE_VALUE;
347 FOR_EACH_EDGE (e, ei, b->succs)
349 basic_block dest = e->dest;
351 if (dest->loop_father == loop
352 && !(dest->flags & BB_REACHABLE)
353 && !(e->flags & flags))
355 *tos++ = dest;
356 dest->flags |= BB_REACHABLE;
361 free (worklist);
363 /* Find a bb to unswitch on. */
364 for (; found < loop->num_nodes; found++)
365 if ((bbs[found]->flags & BB_REACHABLE)
366 && (cond = tree_may_unswitch_on (bbs[found], loop)))
367 break;
369 if (found == loop->num_nodes)
371 free (bbs);
372 return changed;
376 if (dump_file && (dump_flags & TDF_DETAILS))
377 fprintf (dump_file, ";; Unswitching loop\n");
379 initialize_original_copy_tables ();
380 /* Unswitch the loop on this condition. */
381 nloop = tree_unswitch_loop (loop, bbs[found], cond);
382 if (!nloop)
384 free_original_copy_tables ();
385 free (bbs);
386 return changed;
389 /* Update the SSA form after unswitching. */
390 update_ssa (TODO_update_ssa);
391 free_original_copy_tables ();
393 /* Invoke itself on modified loops. */
394 tree_unswitch_single_loop (nloop, num + 1);
395 tree_unswitch_single_loop (loop, num + 1);
396 free (bbs);
397 return true;
400 /* Unswitch a LOOP w.r. to given basic block UNSWITCH_ON. We only support
401 unswitching of innermost loops. COND is the condition determining which
402 loop is entered -- the new loop is entered if COND is true. Returns NULL
403 if impossible, new loop otherwise. */
405 static struct loop *
406 tree_unswitch_loop (struct loop *loop,
407 basic_block unswitch_on, tree cond)
409 unsigned prob_true;
410 edge edge_true, edge_false;
412 /* Some sanity checking. */
413 gcc_assert (flow_bb_inside_loop_p (loop, unswitch_on));
414 gcc_assert (EDGE_COUNT (unswitch_on->succs) == 2);
415 gcc_assert (loop->inner == NULL);
417 extract_true_false_edges_from_block (unswitch_on, &edge_true, &edge_false);
418 prob_true = edge_true->probability;
419 return loop_version (loop, unshare_expr (cond),
420 NULL, prob_true, prob_true,
421 REG_BR_PROB_BASE - prob_true, false);
424 /* Unswitch outer loops by hoisting invariant guard on
425 inner loop without code duplication. */
426 static bool
427 tree_unswitch_outer_loop (struct loop *loop)
429 edge exit, guard;
430 HOST_WIDE_INT iterations;
432 gcc_assert (loop->inner);
433 if (loop->inner->next)
434 return false;
435 /* Accept loops with single exit only which is not from inner loop. */
436 exit = single_exit (loop);
437 if (!exit || exit->src->loop_father != loop)
438 return false;
439 /* Check that phi argument of exit edge is not defined inside loop. */
440 if (!check_exit_phi (loop))
441 return false;
442 /* If the loop is not expected to iterate, there is no need
443 for unswitching. */
444 iterations = estimated_loop_iterations_int (loop);
445 if (iterations < 0)
446 iterations = likely_max_loop_iterations_int (loop);
447 if (iterations >= 0 && iterations <= 1)
449 if (dump_file && (dump_flags & TDF_DETAILS))
450 fprintf (dump_file, ";; Not unswitching, loop is not expected"
451 " to iterate\n");
452 return false;
455 bool changed = false;
456 while ((guard = find_loop_guard (loop)))
458 if (! changed)
459 rewrite_virtuals_into_loop_closed_ssa (loop);
460 hoist_guard (loop, guard);
461 changed = true;
463 return changed;
466 /* Checks if the body of the LOOP is within an invariant guard. If this
467 is the case, returns the edge that jumps over the real body of the loop,
468 otherwise returns NULL. */
470 static edge
471 find_loop_guard (struct loop *loop)
473 basic_block header = loop->header;
474 edge guard_edge, te, fe;
475 basic_block *body = NULL;
476 unsigned i;
477 tree use;
478 ssa_op_iter iter;
480 /* We check for the following situation:
482 while (1)
484 [header]]
485 loop_phi_nodes;
486 something1;
487 if (cond1)
488 body;
489 nvar = phi(orig, bvar) ... for all variables changed in body;
490 [guard_end]
491 something2;
492 if (cond2)
493 break;
494 something3;
497 where:
499 1) cond1 is loop invariant
500 2) If cond1 is false, then the loop is essentially empty; i.e.,
501 a) nothing in something1, something2 and something3 has side
502 effects
503 b) anything defined in something1, something2 and something3
504 is not used outside of the loop. */
506 gcond *cond;
509 if (single_succ_p (header))
510 header = single_succ (header);
511 else
513 cond = dyn_cast <gcond *> (last_stmt (header));
514 if (! cond)
515 return NULL;
516 extract_true_false_edges_from_block (header, &te, &fe);
517 /* Make sure to skip earlier hoisted guards that are left
518 in place as if (true). */
519 if (gimple_cond_true_p (cond))
520 header = te->dest;
521 else if (gimple_cond_false_p (cond))
522 header = fe->dest;
523 else
524 break;
527 while (1);
528 if (!flow_bb_inside_loop_p (loop, te->dest)
529 || !flow_bb_inside_loop_p (loop, fe->dest))
530 return NULL;
532 if (just_once_each_iteration_p (loop, te->dest)
533 || (single_succ_p (te->dest)
534 && just_once_each_iteration_p (loop, single_succ (te->dest))))
536 if (just_once_each_iteration_p (loop, fe->dest))
537 return NULL;
538 guard_edge = te;
540 else if (just_once_each_iteration_p (loop, fe->dest)
541 || (single_succ_p (fe->dest)
542 && just_once_each_iteration_p (loop, single_succ (fe->dest))))
543 guard_edge = fe;
544 else
545 return NULL;
547 /* Guard edge must skip inner loop. */
548 if (!dominated_by_p (CDI_DOMINATORS, loop->inner->header,
549 guard_edge == fe ? te->dest : fe->dest))
551 if (dump_file && (dump_flags & TDF_DETAILS))
552 fprintf (dump_file, "Guard edge %d --> %d is not around the loop!\n",
553 guard_edge->src->index, guard_edge->dest->index);
554 return NULL;
556 if (guard_edge->dest == loop->latch)
558 if (dump_file && (dump_flags & TDF_DETAILS))
559 fprintf (dump_file, "Guard edge destination is loop latch.\n");
560 return NULL;
563 if (dump_file && (dump_flags & TDF_DETAILS))
564 fprintf (dump_file,
565 "Considering guard %d -> %d in loop %d\n",
566 guard_edge->src->index, guard_edge->dest->index, loop->num);
567 /* Check if condition operands do not have definitions inside loop since
568 any bb copying is not performed. */
569 FOR_EACH_SSA_TREE_OPERAND (use, cond, iter, SSA_OP_USE)
571 gimple *def = SSA_NAME_DEF_STMT (use);
572 basic_block def_bb = gimple_bb (def);
573 if (def_bb
574 && flow_bb_inside_loop_p (loop, def_bb))
576 if (dump_file && (dump_flags & TDF_DETAILS))
577 fprintf (dump_file, " guard operands have definitions"
578 " inside loop\n");
579 return NULL;
583 body = get_loop_body (loop);
584 for (i = 0; i < loop->num_nodes; i++)
586 basic_block bb = body[i];
587 if (bb->loop_father != loop)
588 continue;
589 if (bb->flags & BB_IRREDUCIBLE_LOOP)
591 if (dump_file && (dump_flags & TDF_DETAILS))
592 fprintf (dump_file, "Block %d is marked as irreducible in loop\n",
593 bb->index);
594 guard_edge = NULL;
595 goto end;
597 if (!empty_bb_without_guard_p (loop, bb))
599 if (dump_file && (dump_flags & TDF_DETAILS))
600 fprintf (dump_file, " block %d has side effects\n", bb->index);
601 guard_edge = NULL;
602 goto end;
606 if (dump_file && (dump_flags & TDF_DETAILS))
607 fprintf (dump_file, " suitable to hoist\n");
608 end:
609 if (body)
610 free (body);
611 return guard_edge;
614 /* Returns true if
615 1) no statement in BB has side effects
616 2) assuming that edge GUARD is always taken, all definitions in BB
617 are noy used outside of the loop.
618 KNOWN_INVARIANTS is a set of ssa names we know to be invariant, and
619 PROCESSED is a set of ssa names for that we already tested whether they
620 are invariant or not. */
622 static bool
623 empty_bb_without_guard_p (struct loop *loop, basic_block bb)
625 basic_block exit_bb = single_exit (loop)->src;
626 bool may_be_used_outside = (bb == exit_bb
627 || !dominated_by_p (CDI_DOMINATORS, bb, exit_bb));
628 tree name;
629 ssa_op_iter op_iter;
631 /* Phi nodes do not have side effects, but their results might be used
632 outside of the loop. */
633 if (may_be_used_outside)
635 for (gphi_iterator gsi = gsi_start_phis (bb);
636 !gsi_end_p (gsi); gsi_next (&gsi))
638 gphi *phi = gsi.phi ();
639 name = PHI_RESULT (phi);
640 if (virtual_operand_p (name))
641 continue;
643 if (used_outside_loop_p (loop, name))
644 return false;
648 for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
649 !gsi_end_p (gsi); gsi_next (&gsi))
651 gimple *stmt = gsi_stmt (gsi);
652 if (gimple_has_side_effects (stmt))
653 return false;
655 if (gimple_vdef(stmt))
656 return false;
658 FOR_EACH_SSA_TREE_OPERAND (name, stmt, op_iter, SSA_OP_DEF)
660 if (may_be_used_outside
661 && used_outside_loop_p (loop, name))
662 return false;
665 return true;
668 /* Return true if NAME is used outside of LOOP. */
670 static bool
671 used_outside_loop_p (struct loop *loop, tree name)
673 imm_use_iterator it;
674 use_operand_p use;
676 FOR_EACH_IMM_USE_FAST (use, it, name)
678 gimple *stmt = USE_STMT (use);
679 if (!flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
680 return true;
683 return false;
686 /* Return argument for loop preheader edge in header virtual phi if any. */
688 static tree
689 get_vop_from_header (struct loop *loop)
691 for (gphi_iterator gsi = gsi_start_phis (loop->header);
692 !gsi_end_p (gsi); gsi_next (&gsi))
694 gphi *phi = gsi.phi ();
695 if (!virtual_operand_p (gimple_phi_result (phi)))
696 continue;
697 return PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
699 return NULL_TREE;
702 /* Move the check of GUARD outside of LOOP. */
704 static void
705 hoist_guard (struct loop *loop, edge guard)
707 edge exit = single_exit (loop);
708 edge preh = loop_preheader_edge (loop);
709 basic_block pre_header = preh->src;
710 basic_block bb;
711 edge te, fe, e, new_edge;
712 gimple *stmt;
713 basic_block guard_bb = guard->src;
714 gimple_stmt_iterator gsi;
715 int flags = 0;
716 bool fix_dom_of_exit;
717 gcond *cond_stmt, *new_cond_stmt;
719 bb = get_immediate_dominator (CDI_DOMINATORS, exit->dest);
720 fix_dom_of_exit = flow_bb_inside_loop_p (loop, bb);
721 gsi = gsi_last_bb (guard_bb);
722 stmt = gsi_stmt (gsi);
723 gcc_assert (gimple_code (stmt) == GIMPLE_COND);
724 cond_stmt = as_a <gcond *> (stmt);
725 extract_true_false_edges_from_block (guard_bb, &te, &fe);
726 /* Insert guard to PRE_HEADER. */
727 if (!empty_block_p (pre_header))
728 gsi = gsi_last_bb (pre_header);
729 else
730 gsi = gsi_start_bb (pre_header);
731 /* Create copy of COND_STMT. */
732 new_cond_stmt = gimple_build_cond (gimple_cond_code (cond_stmt),
733 gimple_cond_lhs (cond_stmt),
734 gimple_cond_rhs (cond_stmt),
735 NULL_TREE, NULL_TREE);
736 gsi_insert_after (&gsi, new_cond_stmt, GSI_NEW_STMT);
737 /* Convert COND_STMT to true/false conditional. */
738 if (guard == te)
739 gimple_cond_make_false (cond_stmt);
740 else
741 gimple_cond_make_true (cond_stmt);
742 update_stmt (cond_stmt);
743 /* Create new loop pre-header. */
744 e = split_block (pre_header, last_stmt (pre_header));
745 gcc_assert (loop_preheader_edge (loop)->src == e->dest);
746 if (guard == fe)
748 e->flags = EDGE_TRUE_VALUE;
749 flags |= EDGE_FALSE_VALUE;
751 else
753 e->flags = EDGE_FALSE_VALUE;
754 flags |= EDGE_TRUE_VALUE;
756 new_edge = make_edge (pre_header, exit->dest, flags);
757 if (fix_dom_of_exit)
758 set_immediate_dominator (CDI_DOMINATORS, exit->dest, pre_header);
759 /* Add NEW_ADGE argument for all phi in post-header block. */
760 bb = exit->dest;
761 for (gphi_iterator gsi = gsi_start_phis (bb);
762 !gsi_end_p (gsi); gsi_next (&gsi))
764 gphi *phi = gsi.phi ();
765 tree arg;
766 if (virtual_operand_p (gimple_phi_result (phi)))
768 arg = get_vop_from_header (loop);
769 if (arg == NULL_TREE)
770 /* Use exit edge argument. */
771 arg = PHI_ARG_DEF_FROM_EDGE (phi, exit);
772 add_phi_arg (phi, arg, new_edge, UNKNOWN_LOCATION);
774 else
776 /* Use exit edge argument. */
777 arg = PHI_ARG_DEF_FROM_EDGE (phi, exit);
778 add_phi_arg (phi, arg, new_edge, UNKNOWN_LOCATION);
782 if (dump_file && (dump_flags & TDF_DETAILS))
783 fprintf (dump_file, " guard hoisted.\n");
786 /* Return true if phi argument for exit edge can be used
787 for edge around loop. */
789 static bool
790 check_exit_phi (struct loop *loop)
792 edge exit = single_exit (loop);
793 basic_block pre_header = loop_preheader_edge (loop)->src;
795 for (gphi_iterator gsi = gsi_start_phis (exit->dest);
796 !gsi_end_p (gsi); gsi_next (&gsi))
798 gphi *phi = gsi.phi ();
799 tree arg;
800 gimple *def;
801 basic_block def_bb;
802 if (virtual_operand_p (gimple_phi_result (phi)))
803 continue;
804 arg = PHI_ARG_DEF_FROM_EDGE (phi, exit);
805 if (TREE_CODE (arg) != SSA_NAME)
806 continue;
807 def = SSA_NAME_DEF_STMT (arg);
808 if (!def)
809 continue;
810 def_bb = gimple_bb (def);
811 if (!def_bb)
812 continue;
813 if (!dominated_by_p (CDI_DOMINATORS, pre_header, def_bb))
814 /* Definition inside loop! */
815 return false;
816 /* Check loop closed phi invariant. */
817 if (!flow_bb_inside_loop_p (def_bb->loop_father, pre_header))
818 return false;
820 return true;
823 /* Loop unswitching pass. */
825 namespace {
827 const pass_data pass_data_tree_unswitch =
829 GIMPLE_PASS, /* type */
830 "unswitch", /* name */
831 OPTGROUP_LOOP, /* optinfo_flags */
832 TV_TREE_LOOP_UNSWITCH, /* tv_id */
833 PROP_cfg, /* properties_required */
834 0, /* properties_provided */
835 0, /* properties_destroyed */
836 0, /* todo_flags_start */
837 0, /* todo_flags_finish */
840 class pass_tree_unswitch : public gimple_opt_pass
842 public:
843 pass_tree_unswitch (gcc::context *ctxt)
844 : gimple_opt_pass (pass_data_tree_unswitch, ctxt)
847 /* opt_pass methods: */
848 virtual bool gate (function *) { return flag_unswitch_loops != 0; }
849 virtual unsigned int execute (function *);
851 }; // class pass_tree_unswitch
853 unsigned int
854 pass_tree_unswitch::execute (function *fun)
856 if (number_of_loops (fun) <= 1)
857 return 0;
859 return tree_ssa_unswitch_loops ();
862 } // anon namespace
864 gimple_opt_pass *
865 make_pass_tree_unswitch (gcc::context *ctxt)
867 return new pass_tree_unswitch (ctxt);