xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/tree-if-conv.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /* If-conversion for vectorizer.
2    Copyright (C) 2004-2015 Free Software Foundation, Inc.
3    Contributed by Devang Patel <dpatel@apple.com>
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11 
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 /* This pass implements a tree level if-conversion of loops.  Its
22    initial goal is to help the vectorizer to vectorize loops with
23    conditions.
24 
25    A short description of if-conversion:
26 
27      o Decide if a loop is if-convertible or not.
28      o Walk all loop basic blocks in breadth first order (BFS order).
29        o Remove conditional statements (at the end of basic block)
30          and propagate condition into destination basic blocks'
31 	 predicate list.
32        o Replace modify expression with conditional modify expression
33          using current basic block's condition.
34      o Merge all basic blocks
35        o Replace phi nodes with conditional modify expr
36        o Merge all basic blocks into header
37 
38      Sample transformation:
39 
40      INPUT
41      -----
42 
43      # i_23 = PHI <0(0), i_18(10)>;
44      <L0>:;
45      j_15 = A[i_23];
46      if (j_15 > 41) goto <L1>; else goto <L17>;
47 
48      <L17>:;
49      goto <bb 3> (<L3>);
50 
51      <L1>:;
52 
53      # iftmp.2_4 = PHI <0(8), 42(2)>;
54      <L3>:;
55      A[i_23] = iftmp.2_4;
56      i_18 = i_23 + 1;
57      if (i_18 <= 15) goto <L19>; else goto <L18>;
58 
59      <L19>:;
60      goto <bb 1> (<L0>);
61 
62      <L18>:;
63 
64      OUTPUT
65      ------
66 
67      # i_23 = PHI <0(0), i_18(10)>;
68      <L0>:;
69      j_15 = A[i_23];
70 
71      <L3>:;
72      iftmp.2_4 = j_15 > 41 ? 42 : 0;
73      A[i_23] = iftmp.2_4;
74      i_18 = i_23 + 1;
75      if (i_18 <= 15) goto <L19>; else goto <L18>;
76 
77      <L19>:;
78      goto <bb 1> (<L0>);
79 
80      <L18>:;
81 */
82 
83 #include "config.h"
84 #include "system.h"
85 #include "coretypes.h"
86 #include "tm.h"
87 #include "hash-set.h"
88 #include "machmode.h"
89 #include "vec.h"
90 #include "double-int.h"
91 #include "input.h"
92 #include "alias.h"
93 #include "symtab.h"
94 #include "wide-int.h"
95 #include "inchash.h"
96 #include "tree.h"
97 #include "fold-const.h"
98 #include "stor-layout.h"
99 #include "flags.h"
100 #include "predict.h"
101 #include "hard-reg-set.h"
102 #include "function.h"
103 #include "dominance.h"
104 #include "cfg.h"
105 #include "basic-block.h"
106 #include "gimple-pretty-print.h"
107 #include "tree-ssa-alias.h"
108 #include "internal-fn.h"
109 #include "gimple-fold.h"
110 #include "gimple-expr.h"
111 #include "is-a.h"
112 #include "gimple.h"
113 #include "gimplify.h"
114 #include "gimple-iterator.h"
115 #include "gimplify-me.h"
116 #include "gimple-ssa.h"
117 #include "tree-cfg.h"
118 #include "tree-phinodes.h"
119 #include "ssa-iterators.h"
120 #include "stringpool.h"
121 #include "tree-ssanames.h"
122 #include "tree-into-ssa.h"
123 #include "tree-ssa.h"
124 #include "cfgloop.h"
125 #include "tree-chrec.h"
126 #include "tree-data-ref.h"
127 #include "tree-scalar-evolution.h"
128 #include "tree-ssa-loop-ivopts.h"
129 #include "tree-ssa-address.h"
130 #include "tree-pass.h"
131 #include "dbgcnt.h"
132 #include "hashtab.h"
133 #include "rtl.h"
134 #include "statistics.h"
135 #include "real.h"
136 #include "fixed-value.h"
137 #include "insn-config.h"
138 #include "expmed.h"
139 #include "dojump.h"
140 #include "explow.h"
141 #include "calls.h"
142 #include "emit-rtl.h"
143 #include "varasm.h"
144 #include "stmt.h"
145 #include "expr.h"
146 #include "insn-codes.h"
147 #include "optabs.h"
148 #include "hash-map.h"
149 
150 /* List of basic blocks in if-conversion-suitable order.  */
151 static basic_block *ifc_bbs;
152 
153 /* Apply more aggressive (extended) if-conversion if true.  */
154 static bool aggressive_if_conv;
155 
156 /* Structure used to predicate basic blocks.  This is attached to the
157    ->aux field of the BBs in the loop to be if-converted.  */
158 typedef struct bb_predicate_s {
159 
160   /* The condition under which this basic block is executed.  */
161   tree predicate;
162 
163   /* PREDICATE is gimplified, and the sequence of statements is
164      recorded here, in order to avoid the duplication of computations
165      that occur in previous conditions.  See PR44483.  */
166   gimple_seq predicate_gimplified_stmts;
167 } *bb_predicate_p;
168 
169 /* Returns true when the basic block BB has a predicate.  */
170 
171 static inline bool
172 bb_has_predicate (basic_block bb)
173 {
174   return bb->aux != NULL;
175 }
176 
177 /* Returns the gimplified predicate for basic block BB.  */
178 
179 static inline tree
180 bb_predicate (basic_block bb)
181 {
182   return ((bb_predicate_p) bb->aux)->predicate;
183 }
184 
185 /* Sets the gimplified predicate COND for basic block BB.  */
186 
187 static inline void
188 set_bb_predicate (basic_block bb, tree cond)
189 {
190   gcc_assert ((TREE_CODE (cond) == TRUTH_NOT_EXPR
191 	       && is_gimple_condexpr (TREE_OPERAND (cond, 0)))
192 	      || is_gimple_condexpr (cond));
193   ((bb_predicate_p) bb->aux)->predicate = cond;
194 }
195 
196 /* Returns the sequence of statements of the gimplification of the
197    predicate for basic block BB.  */
198 
199 static inline gimple_seq
200 bb_predicate_gimplified_stmts (basic_block bb)
201 {
202   return ((bb_predicate_p) bb->aux)->predicate_gimplified_stmts;
203 }
204 
205 /* Sets the sequence of statements STMTS of the gimplification of the
206    predicate for basic block BB.  */
207 
208 static inline void
209 set_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts)
210 {
211   ((bb_predicate_p) bb->aux)->predicate_gimplified_stmts = stmts;
212 }
213 
214 /* Adds the sequence of statements STMTS to the sequence of statements
215    of the predicate for basic block BB.  */
216 
217 static inline void
218 add_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts)
219 {
220   gimple_seq_add_seq
221     (&(((bb_predicate_p) bb->aux)->predicate_gimplified_stmts), stmts);
222 }
223 
224 /* Initializes to TRUE the predicate of basic block BB.  */
225 
226 static inline void
227 init_bb_predicate (basic_block bb)
228 {
229   bb->aux = XNEW (struct bb_predicate_s);
230   set_bb_predicate_gimplified_stmts (bb, NULL);
231   set_bb_predicate (bb, boolean_true_node);
232 }
233 
234 /* Release the SSA_NAMEs associated with the predicate of basic block BB,
235    but don't actually free it.  */
236 
237 static inline void
238 release_bb_predicate (basic_block bb)
239 {
240   gimple_seq stmts = bb_predicate_gimplified_stmts (bb);
241   if (stmts)
242     {
243       gimple_stmt_iterator i;
244 
245       for (i = gsi_start (stmts); !gsi_end_p (i); gsi_next (&i))
246 	free_stmt_operands (cfun, gsi_stmt (i));
247       set_bb_predicate_gimplified_stmts (bb, NULL);
248     }
249 }
250 
251 /* Free the predicate of basic block BB.  */
252 
253 static inline void
254 free_bb_predicate (basic_block bb)
255 {
256   if (!bb_has_predicate (bb))
257     return;
258 
259   release_bb_predicate (bb);
260   free (bb->aux);
261   bb->aux = NULL;
262 }
263 
264 /* Reinitialize predicate of BB with the true predicate.  */
265 
266 static inline void
267 reset_bb_predicate (basic_block bb)
268 {
269   if (!bb_has_predicate (bb))
270     init_bb_predicate (bb);
271   else
272     {
273       release_bb_predicate (bb);
274       set_bb_predicate (bb, boolean_true_node);
275     }
276 }
277 
278 /* Returns a new SSA_NAME of type TYPE that is assigned the value of
279    the expression EXPR.  Inserts the statement created for this
280    computation before GSI and leaves the iterator GSI at the same
281    statement.  */
282 
283 static tree
284 ifc_temp_var (tree type, tree expr, gimple_stmt_iterator *gsi)
285 {
286   tree new_name = make_temp_ssa_name (type, NULL, "_ifc_");
287   gimple stmt = gimple_build_assign (new_name, expr);
288   gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
289   return new_name;
290 }
291 
292 /* Return true when COND is a true predicate.  */
293 
294 static inline bool
295 is_true_predicate (tree cond)
296 {
297   return (cond == NULL_TREE
298 	  || cond == boolean_true_node
299 	  || integer_onep (cond));
300 }
301 
302 /* Returns true when BB has a predicate that is not trivial: true or
303    NULL_TREE.  */
304 
305 static inline bool
306 is_predicated (basic_block bb)
307 {
308   return !is_true_predicate (bb_predicate (bb));
309 }
310 
311 /* Parses the predicate COND and returns its comparison code and
312    operands OP0 and OP1.  */
313 
314 static enum tree_code
315 parse_predicate (tree cond, tree *op0, tree *op1)
316 {
317   gimple s;
318 
319   if (TREE_CODE (cond) == SSA_NAME
320       && is_gimple_assign (s = SSA_NAME_DEF_STMT (cond)))
321     {
322       if (TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison)
323 	{
324 	  *op0 = gimple_assign_rhs1 (s);
325 	  *op1 = gimple_assign_rhs2 (s);
326 	  return gimple_assign_rhs_code (s);
327 	}
328 
329       else if (gimple_assign_rhs_code (s) == TRUTH_NOT_EXPR)
330 	{
331 	  tree op = gimple_assign_rhs1 (s);
332 	  tree type = TREE_TYPE (op);
333 	  enum tree_code code = parse_predicate (op, op0, op1);
334 
335 	  return code == ERROR_MARK ? ERROR_MARK
336 	    : invert_tree_comparison (code, HONOR_NANS (type));
337 	}
338 
339       return ERROR_MARK;
340     }
341 
342   if (TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison)
343     {
344       *op0 = TREE_OPERAND (cond, 0);
345       *op1 = TREE_OPERAND (cond, 1);
346       return TREE_CODE (cond);
347     }
348 
349   return ERROR_MARK;
350 }
351 
352 /* Returns the fold of predicate C1 OR C2 at location LOC.  */
353 
354 static tree
355 fold_or_predicates (location_t loc, tree c1, tree c2)
356 {
357   tree op1a, op1b, op2a, op2b;
358   enum tree_code code1 = parse_predicate (c1, &op1a, &op1b);
359   enum tree_code code2 = parse_predicate (c2, &op2a, &op2b);
360 
361   if (code1 != ERROR_MARK && code2 != ERROR_MARK)
362     {
363       tree t = maybe_fold_or_comparisons (code1, op1a, op1b,
364 					  code2, op2a, op2b);
365       if (t)
366 	return t;
367     }
368 
369   return fold_build2_loc (loc, TRUTH_OR_EXPR, boolean_type_node, c1, c2);
370 }
371 
372 /* Returns true if N is either a constant or a SSA_NAME.  */
373 
374 static bool
375 constant_or_ssa_name (tree n)
376 {
377   switch (TREE_CODE (n))
378     {
379       case SSA_NAME:
380       case INTEGER_CST:
381       case REAL_CST:
382       case COMPLEX_CST:
383       case VECTOR_CST:
384 	return true;
385       default:
386 	return false;
387     }
388 }
389 
390 /* Returns either a COND_EXPR or the folded expression if the folded
391    expression is a MIN_EXPR, a MAX_EXPR, an ABS_EXPR,
392    a constant or a SSA_NAME. */
393 
394 static tree
395 fold_build_cond_expr (tree type, tree cond, tree rhs, tree lhs)
396 {
397   tree rhs1, lhs1, cond_expr;
398 
399   /* If COND is comparison r != 0 and r has boolean type, convert COND
400      to SSA_NAME to accept by vect bool pattern.  */
401   if (TREE_CODE (cond) == NE_EXPR)
402     {
403       tree op0 = TREE_OPERAND (cond, 0);
404       tree op1 = TREE_OPERAND (cond, 1);
405       if (TREE_CODE (op0) == SSA_NAME
406 	  && TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
407 	  && (integer_zerop (op1)))
408 	cond = op0;
409     }
410   cond_expr = fold_ternary (COND_EXPR, type, cond,
411 			    rhs, lhs);
412 
413   if (cond_expr == NULL_TREE)
414     return build3 (COND_EXPR, type, cond, rhs, lhs);
415 
416   STRIP_USELESS_TYPE_CONVERSION (cond_expr);
417 
418   if (constant_or_ssa_name (cond_expr))
419     return cond_expr;
420 
421   if (TREE_CODE (cond_expr) == ABS_EXPR)
422     {
423       rhs1 = TREE_OPERAND (cond_expr, 1);
424       STRIP_USELESS_TYPE_CONVERSION (rhs1);
425       if (constant_or_ssa_name (rhs1))
426 	return build1 (ABS_EXPR, type, rhs1);
427     }
428 
429   if (TREE_CODE (cond_expr) == MIN_EXPR
430       || TREE_CODE (cond_expr) == MAX_EXPR)
431     {
432       lhs1 = TREE_OPERAND (cond_expr, 0);
433       STRIP_USELESS_TYPE_CONVERSION (lhs1);
434       rhs1 = TREE_OPERAND (cond_expr, 1);
435       STRIP_USELESS_TYPE_CONVERSION (rhs1);
436       if (constant_or_ssa_name (rhs1)
437 	  && constant_or_ssa_name (lhs1))
438 	return build2 (TREE_CODE (cond_expr), type, lhs1, rhs1);
439     }
440   return build3 (COND_EXPR, type, cond, rhs, lhs);
441 }
442 
443 /* Add condition NC to the predicate list of basic block BB.  LOOP is
444    the loop to be if-converted. Use predicate of cd-equivalent block
445    for join bb if it exists: we call basic blocks bb1 and bb2
446    cd-equivalent if they are executed under the same condition.  */
447 
448 static inline void
449 add_to_predicate_list (struct loop *loop, basic_block bb, tree nc)
450 {
451   tree bc, *tp;
452   basic_block dom_bb;
453 
454   if (is_true_predicate (nc))
455     return;
456 
457   /* If dominance tells us this basic block is always executed,
458      don't record any predicates for it.  */
459   if (dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
460     return;
461 
462   dom_bb = get_immediate_dominator (CDI_DOMINATORS, bb);
463   /* We use notion of cd equivalence to get simpler predicate for
464      join block, e.g. if join block has 2 predecessors with predicates
465      p1 & p2 and p1 & !p2, we'd like to get p1 for it instead of
466      p1 & p2 | p1 & !p2.  */
467   if (dom_bb != loop->header
468       && get_immediate_dominator (CDI_POST_DOMINATORS, dom_bb) == bb)
469     {
470       gcc_assert (flow_bb_inside_loop_p (loop, dom_bb));
471       bc = bb_predicate (dom_bb);
472       if (!is_true_predicate (bc))
473 	set_bb_predicate (bb, bc);
474       else
475 	gcc_assert (is_true_predicate (bb_predicate (bb)));
476       if (dump_file && (dump_flags & TDF_DETAILS))
477 	fprintf (dump_file, "Use predicate of bb#%d for bb#%d\n",
478 		 dom_bb->index, bb->index);
479       return;
480     }
481 
482   if (!is_predicated (bb))
483     bc = nc;
484   else
485     {
486       bc = bb_predicate (bb);
487       bc = fold_or_predicates (EXPR_LOCATION (bc), nc, bc);
488       if (is_true_predicate (bc))
489 	{
490 	  reset_bb_predicate (bb);
491 	  return;
492 	}
493     }
494 
495   /* Allow a TRUTH_NOT_EXPR around the main predicate.  */
496   if (TREE_CODE (bc) == TRUTH_NOT_EXPR)
497     tp = &TREE_OPERAND (bc, 0);
498   else
499     tp = &bc;
500   if (!is_gimple_condexpr (*tp))
501     {
502       gimple_seq stmts;
503       *tp = force_gimple_operand_1 (*tp, &stmts, is_gimple_condexpr, NULL_TREE);
504       add_bb_predicate_gimplified_stmts (bb, stmts);
505     }
506   set_bb_predicate (bb, bc);
507 }
508 
509 /* Add the condition COND to the previous condition PREV_COND, and add
510    this to the predicate list of the destination of edge E.  LOOP is
511    the loop to be if-converted.  */
512 
513 static void
514 add_to_dst_predicate_list (struct loop *loop, edge e,
515 			   tree prev_cond, tree cond)
516 {
517   if (!flow_bb_inside_loop_p (loop, e->dest))
518     return;
519 
520   if (!is_true_predicate (prev_cond))
521     cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
522 			prev_cond, cond);
523 
524   if (!dominated_by_p (CDI_DOMINATORS, loop->latch, e->dest))
525     add_to_predicate_list (loop, e->dest, cond);
526 }
527 
528 /* Return true if one of the successor edges of BB exits LOOP.  */
529 
530 static bool
531 bb_with_exit_edge_p (struct loop *loop, basic_block bb)
532 {
533   edge e;
534   edge_iterator ei;
535 
536   FOR_EACH_EDGE (e, ei, bb->succs)
537     if (loop_exit_edge_p (loop, e))
538       return true;
539 
540   return false;
541 }
542 
543 /* Return true when PHI is if-convertible.  PHI is part of loop LOOP
544    and it belongs to basic block BB.
545 
546    PHI is not if-convertible if:
547    - it has more than 2 arguments.
548 
549    When the flag_tree_loop_if_convert_stores is not set, PHI is not
550    if-convertible if:
551    - a virtual PHI is immediately used in another PHI node,
552    - there is a virtual PHI in a BB other than the loop->header.
553    When the aggressive_if_conv is set, PHI can have more than
554    two arguments.  */
555 
556 static bool
557 if_convertible_phi_p (struct loop *loop, basic_block bb, gphi *phi,
558 		      bool any_mask_load_store)
559 {
560   if (dump_file && (dump_flags & TDF_DETAILS))
561     {
562       fprintf (dump_file, "-------------------------\n");
563       print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
564     }
565 
566   if (bb != loop->header)
567     {
568       if (gimple_phi_num_args (phi) != 2
569 	  && !aggressive_if_conv)
570 	{
571 	  if (dump_file && (dump_flags & TDF_DETAILS))
572 	    fprintf (dump_file, "More than two phi node args.\n");
573 	  return false;
574         }
575     }
576 
577   if (flag_tree_loop_if_convert_stores || any_mask_load_store)
578     return true;
579 
580   /* When the flag_tree_loop_if_convert_stores is not set, check
581      that there are no memory writes in the branches of the loop to be
582      if-converted.  */
583   if (virtual_operand_p (gimple_phi_result (phi)))
584     {
585       imm_use_iterator imm_iter;
586       use_operand_p use_p;
587 
588       if (bb != loop->header)
589 	{
590 	  if (dump_file && (dump_flags & TDF_DETAILS))
591 	    fprintf (dump_file, "Virtual phi not on loop->header.\n");
592 	  return false;
593 	}
594 
595       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, gimple_phi_result (phi))
596 	{
597 	  if (gimple_code (USE_STMT (use_p)) == GIMPLE_PHI)
598 	    {
599 	      if (dump_file && (dump_flags & TDF_DETAILS))
600 		fprintf (dump_file, "Difficult to handle this virtual phi.\n");
601 	      return false;
602 	    }
603 	}
604     }
605 
606   return true;
607 }
608 
609 /* Records the status of a data reference.  This struct is attached to
610    each DR->aux field.  */
611 
612 struct ifc_dr {
613   /* -1 when not initialized, 0 when false, 1 when true.  */
614   int written_at_least_once;
615 
616   /* -1 when not initialized, 0 when false, 1 when true.  */
617   int rw_unconditionally;
618 };
619 
620 #define IFC_DR(DR) ((struct ifc_dr *) (DR)->aux)
621 #define DR_WRITTEN_AT_LEAST_ONCE(DR) (IFC_DR (DR)->written_at_least_once)
622 #define DR_RW_UNCONDITIONALLY(DR) (IFC_DR (DR)->rw_unconditionally)
623 
624 /* Returns true when the memory references of STMT are read or written
625    unconditionally.  In other words, this function returns true when
626    for every data reference A in STMT there exist other accesses to
627    a data reference with the same base with predicates that add up (OR-up) to
628    the true predicate: this ensures that the data reference A is touched
629    (read or written) on every iteration of the if-converted loop.  */
630 
631 static bool
632 memrefs_read_or_written_unconditionally (gimple stmt,
633 					 vec<data_reference_p> drs)
634 {
635   int i, j;
636   data_reference_p a, b;
637   tree ca = bb_predicate (gimple_bb (stmt));
638 
639   for (i = 0; drs.iterate (i, &a); i++)
640     if (DR_STMT (a) == stmt)
641       {
642 	bool found = false;
643 	int x = DR_RW_UNCONDITIONALLY (a);
644 
645 	if (x == 0)
646 	  return false;
647 
648 	if (x == 1)
649 	  continue;
650 
651 	for (j = 0; drs.iterate (j, &b); j++)
652           {
653             tree ref_base_a = DR_REF (a);
654             tree ref_base_b = DR_REF (b);
655 
656             if (DR_STMT (b) == stmt)
657               continue;
658 
659             while (TREE_CODE (ref_base_a) == COMPONENT_REF
660                    || TREE_CODE (ref_base_a) == IMAGPART_EXPR
661                    || TREE_CODE (ref_base_a) == REALPART_EXPR)
662               ref_base_a = TREE_OPERAND (ref_base_a, 0);
663 
664             while (TREE_CODE (ref_base_b) == COMPONENT_REF
665                    || TREE_CODE (ref_base_b) == IMAGPART_EXPR
666                    || TREE_CODE (ref_base_b) == REALPART_EXPR)
667               ref_base_b = TREE_OPERAND (ref_base_b, 0);
668 
669   	    if (operand_equal_p (ref_base_a, ref_base_b, 0))
670 	      {
671 	        tree cb = bb_predicate (gimple_bb (DR_STMT (b)));
672 
673 	        if (DR_RW_UNCONDITIONALLY (b) == 1
674 		    || is_true_predicate (cb)
675 		    || is_true_predicate (ca
676                         = fold_or_predicates (EXPR_LOCATION (cb), ca, cb)))
677 		  {
678 		    DR_RW_UNCONDITIONALLY (a) = 1;
679   		    DR_RW_UNCONDITIONALLY (b) = 1;
680 		    found = true;
681 		    break;
682 		  }
683                }
684 	    }
685 
686 	if (!found)
687 	  {
688 	    DR_RW_UNCONDITIONALLY (a) = 0;
689 	    return false;
690 	  }
691       }
692 
693   return true;
694 }
695 
696 /* Returns true when the memory references of STMT are unconditionally
697    written.  In other words, this function returns true when for every
698    data reference A written in STMT, there exist other writes to the
699    same data reference with predicates that add up (OR-up) to the true
700    predicate: this ensures that the data reference A is written on
701    every iteration of the if-converted loop.  */
702 
703 static bool
704 write_memrefs_written_at_least_once (gimple stmt,
705 				     vec<data_reference_p> drs)
706 {
707   int i, j;
708   data_reference_p a, b;
709   tree ca = bb_predicate (gimple_bb (stmt));
710 
711   for (i = 0; drs.iterate (i, &a); i++)
712     if (DR_STMT (a) == stmt
713 	&& DR_IS_WRITE (a))
714       {
715 	bool found = false;
716 	int x = DR_WRITTEN_AT_LEAST_ONCE (a);
717 
718 	if (x == 0)
719 	  return false;
720 
721 	if (x == 1)
722 	  continue;
723 
724 	for (j = 0; drs.iterate (j, &b); j++)
725 	  if (DR_STMT (b) != stmt
726 	      && DR_IS_WRITE (b)
727 	      && same_data_refs_base_objects (a, b))
728 	    {
729 	      tree cb = bb_predicate (gimple_bb (DR_STMT (b)));
730 
731 	      if (DR_WRITTEN_AT_LEAST_ONCE (b) == 1
732 		  || is_true_predicate (cb)
733 		  || is_true_predicate (ca = fold_or_predicates (EXPR_LOCATION (cb),
734 								 ca, cb)))
735 		{
736 		  DR_WRITTEN_AT_LEAST_ONCE (a) = 1;
737 		  DR_WRITTEN_AT_LEAST_ONCE (b) = 1;
738 		  found = true;
739 		  break;
740 		}
741 	    }
742 
743 	if (!found)
744 	  {
745 	    DR_WRITTEN_AT_LEAST_ONCE (a) = 0;
746 	    return false;
747 	  }
748       }
749 
750   return true;
751 }
752 
753 /* Return true when the memory references of STMT won't trap in the
754    if-converted code.  There are two things that we have to check for:
755 
756    - writes to memory occur to writable memory: if-conversion of
757    memory writes transforms the conditional memory writes into
758    unconditional writes, i.e. "if (cond) A[i] = foo" is transformed
759    into "A[i] = cond ? foo : A[i]", and as the write to memory may not
760    be executed at all in the original code, it may be a readonly
761    memory.  To check that A is not const-qualified, we check that
762    there exists at least an unconditional write to A in the current
763    function.
764 
765    - reads or writes to memory are valid memory accesses for every
766    iteration.  To check that the memory accesses are correctly formed
767    and that we are allowed to read and write in these locations, we
768    check that the memory accesses to be if-converted occur at every
769    iteration unconditionally.  */
770 
771 static bool
772 ifcvt_memrefs_wont_trap (gimple stmt, vec<data_reference_p> refs)
773 {
774   return write_memrefs_written_at_least_once (stmt, refs)
775     && memrefs_read_or_written_unconditionally (stmt, refs);
776 }
777 
778 /* Wrapper around gimple_could_trap_p refined for the needs of the
779    if-conversion.  Try to prove that the memory accesses of STMT could
780    not trap in the innermost loop containing STMT.  */
781 
782 static bool
783 ifcvt_could_trap_p (gimple stmt, vec<data_reference_p> refs)
784 {
785   if (gimple_vuse (stmt)
786       && !gimple_could_trap_p_1 (stmt, false, false)
787       && ifcvt_memrefs_wont_trap (stmt, refs))
788     return false;
789 
790   return gimple_could_trap_p (stmt);
791 }
792 
793 /* Return true if STMT could be converted into a masked load or store
794    (conditional load or store based on a mask computed from bb predicate).  */
795 
796 static bool
797 ifcvt_can_use_mask_load_store (gimple stmt)
798 {
799   tree lhs, ref;
800   machine_mode mode;
801   basic_block bb = gimple_bb (stmt);
802   bool is_load;
803 
804   if (!(flag_tree_loop_vectorize || bb->loop_father->force_vectorize)
805       || bb->loop_father->dont_vectorize
806       || !gimple_assign_single_p (stmt)
807       || gimple_has_volatile_ops (stmt))
808     return false;
809 
810   /* Check whether this is a load or store.  */
811   lhs = gimple_assign_lhs (stmt);
812   if (gimple_store_p (stmt))
813     {
814       if (!is_gimple_val (gimple_assign_rhs1 (stmt)))
815 	return false;
816       is_load = false;
817       ref = lhs;
818     }
819   else if (gimple_assign_load_p (stmt))
820     {
821       is_load = true;
822       ref = gimple_assign_rhs1 (stmt);
823     }
824   else
825     return false;
826 
827   if (may_be_nonaddressable_p (ref))
828     return false;
829 
830   /* Mask should be integer mode of the same size as the load/store
831      mode.  */
832   mode = TYPE_MODE (TREE_TYPE (lhs));
833   if (int_mode_for_mode (mode) == BLKmode
834       || VECTOR_MODE_P (mode))
835     return false;
836 
837   if (can_vec_mask_load_store_p (mode, is_load))
838     return true;
839 
840   return false;
841 }
842 
843 /* Return true when STMT is if-convertible.
844 
845    GIMPLE_ASSIGN statement is not if-convertible if,
846    - it is not movable,
847    - it could trap,
848    - LHS is not var decl.  */
849 
850 static bool
851 if_convertible_gimple_assign_stmt_p (gimple stmt,
852 				     vec<data_reference_p> refs,
853 				     bool *any_mask_load_store)
854 {
855   tree lhs = gimple_assign_lhs (stmt);
856   basic_block bb;
857 
858   if (dump_file && (dump_flags & TDF_DETAILS))
859     {
860       fprintf (dump_file, "-------------------------\n");
861       print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
862     }
863 
864   if (!is_gimple_reg_type (TREE_TYPE (lhs)))
865     return false;
866 
867   /* Some of these constrains might be too conservative.  */
868   if (stmt_ends_bb_p (stmt)
869       || gimple_has_volatile_ops (stmt)
870       || (TREE_CODE (lhs) == SSA_NAME
871           && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
872       || gimple_has_side_effects (stmt))
873     {
874       if (dump_file && (dump_flags & TDF_DETAILS))
875         fprintf (dump_file, "stmt not suitable for ifcvt\n");
876       return false;
877     }
878 
879   /* tree-into-ssa.c uses GF_PLF_1, so avoid it, because
880      in between if_convertible_loop_p and combine_blocks
881      we can perform loop versioning.  */
882   gimple_set_plf (stmt, GF_PLF_2, false);
883 
884   if (flag_tree_loop_if_convert_stores)
885     {
886       if (ifcvt_could_trap_p (stmt, refs))
887 	{
888 	  if (ifcvt_can_use_mask_load_store (stmt))
889 	    {
890 	      gimple_set_plf (stmt, GF_PLF_2, true);
891 	      *any_mask_load_store = true;
892 	      return true;
893 	    }
894 	  if (dump_file && (dump_flags & TDF_DETAILS))
895 	    fprintf (dump_file, "tree could trap...\n");
896 	  return false;
897 	}
898       return true;
899     }
900 
901   if (gimple_assign_rhs_could_trap_p (stmt))
902     {
903       if (ifcvt_can_use_mask_load_store (stmt))
904 	{
905 	  gimple_set_plf (stmt, GF_PLF_2, true);
906 	  *any_mask_load_store = true;
907 	  return true;
908 	}
909       if (dump_file && (dump_flags & TDF_DETAILS))
910 	fprintf (dump_file, "tree could trap...\n");
911       return false;
912     }
913 
914   bb = gimple_bb (stmt);
915 
916   if (TREE_CODE (lhs) != SSA_NAME
917       && bb != bb->loop_father->header
918       && !bb_with_exit_edge_p (bb->loop_father, bb))
919     {
920       if (ifcvt_can_use_mask_load_store (stmt))
921 	{
922 	  gimple_set_plf (stmt, GF_PLF_2, true);
923 	  *any_mask_load_store = true;
924 	  return true;
925 	}
926       if (dump_file && (dump_flags & TDF_DETAILS))
927 	{
928 	  fprintf (dump_file, "LHS is not var\n");
929 	  print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
930 	}
931       return false;
932     }
933 
934   return true;
935 }
936 
937 /* Return true when STMT is if-convertible.
938 
939    A statement is if-convertible if:
940    - it is an if-convertible GIMPLE_ASSIGN,
941    - it is a GIMPLE_LABEL or a GIMPLE_COND,
942    - it is builtins call.  */
943 
944 static bool
945 if_convertible_stmt_p (gimple stmt, vec<data_reference_p> refs,
946 		       bool *any_mask_load_store)
947 {
948   switch (gimple_code (stmt))
949     {
950     case GIMPLE_LABEL:
951     case GIMPLE_DEBUG:
952     case GIMPLE_COND:
953       return true;
954 
955     case GIMPLE_ASSIGN:
956       return if_convertible_gimple_assign_stmt_p (stmt, refs,
957 						  any_mask_load_store);
958 
959     case GIMPLE_CALL:
960       {
961 	tree fndecl = gimple_call_fndecl (stmt);
962 	if (fndecl)
963 	  {
964 	    int flags = gimple_call_flags (stmt);
965 	    if ((flags & ECF_CONST)
966 		&& !(flags & ECF_LOOPING_CONST_OR_PURE)
967 		/* We can only vectorize some builtins at the moment,
968 		   so restrict if-conversion to those.  */
969 		&& DECL_BUILT_IN (fndecl))
970 	      return true;
971 	  }
972 	return false;
973       }
974 
975     default:
976       /* Don't know what to do with 'em so don't do anything.  */
977       if (dump_file && (dump_flags & TDF_DETAILS))
978 	{
979 	  fprintf (dump_file, "don't know what to do\n");
980 	  print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
981 	}
982       return false;
983       break;
984     }
985 
986   return true;
987 }
988 
989 /* Assumes that BB has more than 1 predecessors.
990    Returns false if at least one successor is not on critical edge
991    and true otherwise.  */
992 
993 static inline bool
994 all_preds_critical_p (basic_block bb)
995 {
996   edge e;
997   edge_iterator ei;
998 
999   FOR_EACH_EDGE (e, ei, bb->preds)
1000     if (EDGE_COUNT (e->src->succs) == 1)
1001       return false;
1002   return true;
1003 }
1004 
1005 /* Returns true if at least one successor in on critical edge.  */
1006 static inline bool
1007 has_pred_critical_p (basic_block bb)
1008 {
1009   edge e;
1010   edge_iterator ei;
1011 
1012   FOR_EACH_EDGE (e, ei, bb->preds)
1013     if (EDGE_COUNT (e->src->succs) > 1)
1014       return true;
1015   return false;
1016 }
1017 
1018 /* Return true when BB is if-convertible.  This routine does not check
1019    basic block's statements and phis.
1020 
1021    A basic block is not if-convertible if:
1022    - it is non-empty and it is after the exit block (in BFS order),
1023    - it is after the exit block but before the latch,
1024    - its edges are not normal.
1025 
1026    Last restriction is valid if aggressive_if_conv is false.
1027 
1028    EXIT_BB is the basic block containing the exit of the LOOP.  BB is
1029    inside LOOP.  */
1030 
1031 static bool
1032 if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb)
1033 {
1034   edge e;
1035   edge_iterator ei;
1036 
1037   if (dump_file && (dump_flags & TDF_DETAILS))
1038     fprintf (dump_file, "----------[%d]-------------\n", bb->index);
1039 
1040   if (EDGE_COUNT (bb->succs) > 2)
1041     return false;
1042 
1043   if (EDGE_COUNT (bb->preds) > 2
1044       && !aggressive_if_conv)
1045     return false;
1046 
1047   if (exit_bb)
1048     {
1049       if (bb != loop->latch)
1050 	{
1051 	  if (dump_file && (dump_flags & TDF_DETAILS))
1052 	    fprintf (dump_file, "basic block after exit bb but before latch\n");
1053 	  return false;
1054 	}
1055       else if (!empty_block_p (bb))
1056 	{
1057 	  if (dump_file && (dump_flags & TDF_DETAILS))
1058 	    fprintf (dump_file, "non empty basic block after exit bb\n");
1059 	  return false;
1060 	}
1061       else if (bb == loop->latch
1062 	       && bb != exit_bb
1063 	       && !dominated_by_p (CDI_DOMINATORS, bb, exit_bb))
1064 	  {
1065 	    if (dump_file && (dump_flags & TDF_DETAILS))
1066 	      fprintf (dump_file, "latch is not dominated by exit_block\n");
1067 	    return false;
1068 	  }
1069     }
1070 
1071   /* Be less adventurous and handle only normal edges.  */
1072   FOR_EACH_EDGE (e, ei, bb->succs)
1073     if (e->flags & (EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP))
1074       {
1075 	if (dump_file && (dump_flags & TDF_DETAILS))
1076 	  fprintf (dump_file, "Difficult to handle edges\n");
1077 	return false;
1078       }
1079 
1080   /* At least one incoming edge has to be non-critical as otherwise edge
1081      predicates are not equal to basic-block predicates of the edge
1082      source.  This check is skipped if aggressive_if_conv is true.  */
1083   if (!aggressive_if_conv
1084       && EDGE_COUNT (bb->preds) > 1
1085       && bb != loop->header
1086       && all_preds_critical_p (bb))
1087     {
1088       if (dump_file && (dump_flags & TDF_DETAILS))
1089 	fprintf (dump_file, "only critical predecessors\n");
1090 	return false;
1091     }
1092 
1093   return true;
1094 }
1095 
1096 /* Return true when all predecessor blocks of BB are visited.  The
1097    VISITED bitmap keeps track of the visited blocks.  */
1098 
1099 static bool
1100 pred_blocks_visited_p (basic_block bb, bitmap *visited)
1101 {
1102   edge e;
1103   edge_iterator ei;
1104   FOR_EACH_EDGE (e, ei, bb->preds)
1105     if (!bitmap_bit_p (*visited, e->src->index))
1106       return false;
1107 
1108   return true;
1109 }
1110 
1111 /* Get body of a LOOP in suitable order for if-conversion.  It is
1112    caller's responsibility to deallocate basic block list.
1113    If-conversion suitable order is, breadth first sort (BFS) order
1114    with an additional constraint: select a block only if all its
1115    predecessors are already selected.  */
1116 
1117 static basic_block *
1118 get_loop_body_in_if_conv_order (const struct loop *loop)
1119 {
1120   basic_block *blocks, *blocks_in_bfs_order;
1121   basic_block bb;
1122   bitmap visited;
1123   unsigned int index = 0;
1124   unsigned int visited_count = 0;
1125 
1126   gcc_assert (loop->num_nodes);
1127   gcc_assert (loop->latch != EXIT_BLOCK_PTR_FOR_FN (cfun));
1128 
1129   blocks = XCNEWVEC (basic_block, loop->num_nodes);
1130   visited = BITMAP_ALLOC (NULL);
1131 
1132   blocks_in_bfs_order = get_loop_body_in_bfs_order (loop);
1133 
1134   index = 0;
1135   while (index < loop->num_nodes)
1136     {
1137       bb = blocks_in_bfs_order [index];
1138 
1139       if (bb->flags & BB_IRREDUCIBLE_LOOP)
1140 	{
1141 	  free (blocks_in_bfs_order);
1142 	  BITMAP_FREE (visited);
1143 	  free (blocks);
1144 	  return NULL;
1145 	}
1146 
1147       if (!bitmap_bit_p (visited, bb->index))
1148 	{
1149 	  if (pred_blocks_visited_p (bb, &visited)
1150 	      || bb == loop->header)
1151 	    {
1152 	      /* This block is now visited.  */
1153 	      bitmap_set_bit (visited, bb->index);
1154 	      blocks[visited_count++] = bb;
1155 	    }
1156 	}
1157 
1158       index++;
1159 
1160       if (index == loop->num_nodes
1161 	  && visited_count != loop->num_nodes)
1162 	/* Not done yet.  */
1163 	index = 0;
1164     }
1165   free (blocks_in_bfs_order);
1166   BITMAP_FREE (visited);
1167   return blocks;
1168 }
1169 
1170 /* Returns true when the analysis of the predicates for all the basic
1171    blocks in LOOP succeeded.
1172 
1173    predicate_bbs first allocates the predicates of the basic blocks.
1174    These fields are then initialized with the tree expressions
1175    representing the predicates under which a basic block is executed
1176    in the LOOP.  As the loop->header is executed at each iteration, it
1177    has the "true" predicate.  Other statements executed under a
1178    condition are predicated with that condition, for example
1179 
1180    | if (x)
1181    |   S1;
1182    | else
1183    |   S2;
1184 
1185    S1 will be predicated with "x", and
1186    S2 will be predicated with "!x".  */
1187 
1188 static void
1189 predicate_bbs (loop_p loop)
1190 {
1191   unsigned int i;
1192 
1193   for (i = 0; i < loop->num_nodes; i++)
1194     init_bb_predicate (ifc_bbs[i]);
1195 
1196   for (i = 0; i < loop->num_nodes; i++)
1197     {
1198       basic_block bb = ifc_bbs[i];
1199       tree cond;
1200       gimple stmt;
1201 
1202       /* The loop latch and loop exit block are always executed and
1203 	 have no extra conditions to be processed: skip them.  */
1204       if (bb == loop->latch
1205 	  || bb_with_exit_edge_p (loop, bb))
1206 	{
1207 	  reset_bb_predicate (bb);
1208 	  continue;
1209 	}
1210 
1211       cond = bb_predicate (bb);
1212       stmt = last_stmt (bb);
1213       if (stmt && gimple_code (stmt) == GIMPLE_COND)
1214 	{
1215 	  tree c2;
1216 	  edge true_edge, false_edge;
1217 	  location_t loc = gimple_location (stmt);
1218 	  tree c = build2_loc (loc, gimple_cond_code (stmt),
1219 				    boolean_type_node,
1220 				    gimple_cond_lhs (stmt),
1221 				    gimple_cond_rhs (stmt));
1222 
1223 	  /* Add new condition into destination's predicate list.  */
1224 	  extract_true_false_edges_from_block (gimple_bb (stmt),
1225 					       &true_edge, &false_edge);
1226 
1227 	  /* If C is true, then TRUE_EDGE is taken.  */
1228 	  add_to_dst_predicate_list (loop, true_edge, unshare_expr (cond),
1229 				     unshare_expr (c));
1230 
1231 	  /* If C is false, then FALSE_EDGE is taken.  */
1232 	  c2 = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node,
1233 			   unshare_expr (c));
1234 	  add_to_dst_predicate_list (loop, false_edge,
1235 				     unshare_expr (cond), c2);
1236 
1237 	  cond = NULL_TREE;
1238 	}
1239 
1240       /* If current bb has only one successor, then consider it as an
1241 	 unconditional goto.  */
1242       if (single_succ_p (bb))
1243 	{
1244 	  basic_block bb_n = single_succ (bb);
1245 
1246 	  /* The successor bb inherits the predicate of its
1247 	     predecessor.  If there is no predicate in the predecessor
1248 	     bb, then consider the successor bb as always executed.  */
1249 	  if (cond == NULL_TREE)
1250 	    cond = boolean_true_node;
1251 
1252 	  add_to_predicate_list (loop, bb_n, cond);
1253 	}
1254     }
1255 
1256   /* The loop header is always executed.  */
1257   reset_bb_predicate (loop->header);
1258   gcc_assert (bb_predicate_gimplified_stmts (loop->header) == NULL
1259 	      && bb_predicate_gimplified_stmts (loop->latch) == NULL);
1260 }
1261 
1262 /* Return true when LOOP is if-convertible.  This is a helper function
1263    for if_convertible_loop_p.  REFS and DDRS are initialized and freed
1264    in if_convertible_loop_p.  */
1265 
1266 static bool
1267 if_convertible_loop_p_1 (struct loop *loop,
1268 			 vec<loop_p> *loop_nest,
1269 			 vec<data_reference_p> *refs,
1270 			 vec<ddr_p> *ddrs, bool *any_mask_load_store)
1271 {
1272   bool res;
1273   unsigned int i;
1274   basic_block exit_bb = NULL;
1275 
1276   /* Don't if-convert the loop when the data dependences cannot be
1277      computed: the loop won't be vectorized in that case.  */
1278   res = compute_data_dependences_for_loop (loop, true, loop_nest, refs, ddrs);
1279   if (!res)
1280     return false;
1281 
1282   calculate_dominance_info (CDI_DOMINATORS);
1283   calculate_dominance_info (CDI_POST_DOMINATORS);
1284 
1285   /* Allow statements that can be handled during if-conversion.  */
1286   ifc_bbs = get_loop_body_in_if_conv_order (loop);
1287   if (!ifc_bbs)
1288     {
1289       if (dump_file && (dump_flags & TDF_DETAILS))
1290 	fprintf (dump_file, "Irreducible loop\n");
1291       return false;
1292     }
1293 
1294   for (i = 0; i < loop->num_nodes; i++)
1295     {
1296       basic_block bb = ifc_bbs[i];
1297 
1298       if (!if_convertible_bb_p (loop, bb, exit_bb))
1299 	return false;
1300 
1301       if (bb_with_exit_edge_p (loop, bb))
1302 	exit_bb = bb;
1303     }
1304 
1305   for (i = 0; i < loop->num_nodes; i++)
1306     {
1307       basic_block bb = ifc_bbs[i];
1308       gimple_stmt_iterator gsi;
1309 
1310       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1311 	switch (gimple_code (gsi_stmt (gsi)))
1312 	  {
1313 	  case GIMPLE_LABEL:
1314 	  case GIMPLE_ASSIGN:
1315 	  case GIMPLE_CALL:
1316 	  case GIMPLE_DEBUG:
1317 	  case GIMPLE_COND:
1318 	    break;
1319 	  default:
1320 	    return false;
1321 	  }
1322     }
1323 
1324   if (flag_tree_loop_if_convert_stores)
1325     {
1326       data_reference_p dr;
1327 
1328       for (i = 0; refs->iterate (i, &dr); i++)
1329 	{
1330 	  dr->aux = XNEW (struct ifc_dr);
1331 	  DR_WRITTEN_AT_LEAST_ONCE (dr) = -1;
1332 	  DR_RW_UNCONDITIONALLY (dr) = -1;
1333 	}
1334       predicate_bbs (loop);
1335     }
1336 
1337   for (i = 0; i < loop->num_nodes; i++)
1338     {
1339       basic_block bb = ifc_bbs[i];
1340       gimple_stmt_iterator itr;
1341 
1342       /* Check the if-convertibility of statements in predicated BBs.  */
1343       if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
1344 	for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr))
1345 	  if (!if_convertible_stmt_p (gsi_stmt (itr), *refs,
1346 				      any_mask_load_store))
1347 	    return false;
1348     }
1349 
1350   if (flag_tree_loop_if_convert_stores)
1351     for (i = 0; i < loop->num_nodes; i++)
1352       free_bb_predicate (ifc_bbs[i]);
1353 
1354   /* Checking PHIs needs to be done after stmts, as the fact whether there
1355      are any masked loads or stores affects the tests.  */
1356   for (i = 0; i < loop->num_nodes; i++)
1357     {
1358       basic_block bb = ifc_bbs[i];
1359       gphi_iterator itr;
1360 
1361       for (itr = gsi_start_phis (bb); !gsi_end_p (itr); gsi_next (&itr))
1362 	if (!if_convertible_phi_p (loop, bb, itr.phi (),
1363 				   *any_mask_load_store))
1364 	  return false;
1365     }
1366 
1367   if (dump_file)
1368     fprintf (dump_file, "Applying if-conversion\n");
1369 
1370   return true;
1371 }
1372 
1373 /* Return true when LOOP is if-convertible.
1374    LOOP is if-convertible if:
1375    - it is innermost,
1376    - it has two or more basic blocks,
1377    - it has only one exit,
1378    - loop header is not the exit edge,
1379    - if its basic blocks and phi nodes are if convertible.  */
1380 
1381 static bool
1382 if_convertible_loop_p (struct loop *loop, bool *any_mask_load_store)
1383 {
1384   edge e;
1385   edge_iterator ei;
1386   bool res = false;
1387   vec<data_reference_p> refs;
1388   vec<ddr_p> ddrs;
1389 
1390   /* Handle only innermost loop.  */
1391   if (!loop || loop->inner)
1392     {
1393       if (dump_file && (dump_flags & TDF_DETAILS))
1394 	fprintf (dump_file, "not innermost loop\n");
1395       return false;
1396     }
1397 
1398   /* If only one block, no need for if-conversion.  */
1399   if (loop->num_nodes <= 2)
1400     {
1401       if (dump_file && (dump_flags & TDF_DETAILS))
1402 	fprintf (dump_file, "less than 2 basic blocks\n");
1403       return false;
1404     }
1405 
1406   /* More than one loop exit is too much to handle.  */
1407   if (!single_exit (loop))
1408     {
1409       if (dump_file && (dump_flags & TDF_DETAILS))
1410 	fprintf (dump_file, "multiple exits\n");
1411       return false;
1412     }
1413 
1414   /* If one of the loop header's edge is an exit edge then do not
1415      apply if-conversion.  */
1416   FOR_EACH_EDGE (e, ei, loop->header->succs)
1417     if (loop_exit_edge_p (loop, e))
1418       return false;
1419 
1420   refs.create (5);
1421   ddrs.create (25);
1422   auto_vec<loop_p, 3> loop_nest;
1423   res = if_convertible_loop_p_1 (loop, &loop_nest, &refs, &ddrs,
1424 				 any_mask_load_store);
1425 
1426   if (flag_tree_loop_if_convert_stores)
1427     {
1428       data_reference_p dr;
1429       unsigned int i;
1430 
1431       for (i = 0; refs.iterate (i, &dr); i++)
1432 	free (dr->aux);
1433     }
1434 
1435   free_data_refs (refs);
1436   free_dependence_relations (ddrs);
1437   return res;
1438 }
1439 
1440 /* Returns true if def-stmt for phi argument ARG is simple increment/decrement
1441    which is in predicated basic block.
1442    In fact, the following PHI pattern is searching:
1443       loop-header:
1444 	reduc_1 = PHI <..., reduc_2>
1445       ...
1446 	if (...)
1447 	  reduc_3 = ...
1448 	reduc_2 = PHI <reduc_1, reduc_3>
1449 
1450    ARG_0 and ARG_1 are correspondent PHI arguments.
1451    REDUC, OP0 and OP1 contain reduction stmt and its operands.
1452    EXTENDED is true if PHI has > 2 arguments.  */
1453 
1454 static bool
1455 is_cond_scalar_reduction (gimple phi, gimple *reduc, tree arg_0, tree arg_1,
1456 			  tree *op0, tree *op1, bool extended)
1457 {
1458   tree lhs, r_op1, r_op2;
1459   gimple stmt;
1460   gimple header_phi = NULL;
1461   enum tree_code reduction_op;
1462   basic_block bb = gimple_bb (phi);
1463   struct loop *loop = bb->loop_father;
1464   edge latch_e = loop_latch_edge (loop);
1465   imm_use_iterator imm_iter;
1466   use_operand_p use_p;
1467   edge e;
1468   edge_iterator ei;
1469   bool result = false;
1470   if (TREE_CODE (arg_0) != SSA_NAME || TREE_CODE (arg_1) != SSA_NAME)
1471     return false;
1472 
1473   if (!extended && gimple_code (SSA_NAME_DEF_STMT (arg_0)) == GIMPLE_PHI)
1474     {
1475       lhs = arg_1;
1476       header_phi = SSA_NAME_DEF_STMT (arg_0);
1477       stmt = SSA_NAME_DEF_STMT (arg_1);
1478     }
1479   else if (gimple_code (SSA_NAME_DEF_STMT (arg_1)) == GIMPLE_PHI)
1480     {
1481       lhs = arg_0;
1482       header_phi = SSA_NAME_DEF_STMT (arg_1);
1483       stmt = SSA_NAME_DEF_STMT (arg_0);
1484     }
1485   else
1486     return false;
1487   if (gimple_bb (header_phi) != loop->header)
1488     return false;
1489 
1490   if (PHI_ARG_DEF_FROM_EDGE (header_phi, latch_e) != PHI_RESULT (phi))
1491     return false;
1492 
1493   if (gimple_code (stmt) != GIMPLE_ASSIGN
1494       || gimple_has_volatile_ops (stmt))
1495     return false;
1496 
1497   if (!flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
1498     return false;
1499 
1500   if (!is_predicated (gimple_bb (stmt)))
1501     return false;
1502 
1503   /* Check that stmt-block is predecessor of phi-block.  */
1504   FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
1505     if (e->dest == bb)
1506       {
1507 	result = true;
1508 	break;
1509       }
1510   if (!result)
1511     return false;
1512 
1513   if (!has_single_use (lhs))
1514     return false;
1515 
1516   reduction_op = gimple_assign_rhs_code (stmt);
1517   if (reduction_op != PLUS_EXPR && reduction_op != MINUS_EXPR)
1518     return false;
1519   r_op1 = gimple_assign_rhs1 (stmt);
1520   r_op2 = gimple_assign_rhs2 (stmt);
1521 
1522   /* Make R_OP1 to hold reduction variable.  */
1523   if (r_op2 == PHI_RESULT (header_phi)
1524       && reduction_op == PLUS_EXPR)
1525     {
1526       tree tmp = r_op1;
1527       r_op1 = r_op2;
1528       r_op2 = tmp;
1529     }
1530   else if (r_op1 != PHI_RESULT (header_phi))
1531     return false;
1532 
1533   /* Check that R_OP1 is used in reduction stmt or in PHI only.  */
1534   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, r_op1)
1535     {
1536       gimple use_stmt = USE_STMT (use_p);
1537       if (is_gimple_debug (use_stmt))
1538 	continue;
1539       if (use_stmt == stmt)
1540 	continue;
1541       if (gimple_code (use_stmt) != GIMPLE_PHI)
1542 	return false;
1543     }
1544 
1545   *op0 = r_op1; *op1 = r_op2;
1546   *reduc = stmt;
1547   return true;
1548 }
1549 
1550 /* Converts conditional scalar reduction into unconditional form, e.g.
1551      bb_4
1552        if (_5 != 0) goto bb_5 else goto bb_6
1553      end_bb_4
1554      bb_5
1555        res_6 = res_13 + 1;
1556      end_bb_5
1557      bb_6
1558        # res_2 = PHI <res_13(4), res_6(5)>
1559      end_bb_6
1560 
1561    will be converted into sequence
1562     _ifc__1 = _5 != 0 ? 1 : 0;
1563     res_2 = res_13 + _ifc__1;
1564   Argument SWAP tells that arguments of conditional expression should be
1565   swapped.
1566   Returns rhs of resulting PHI assignment.  */
1567 
1568 static tree
1569 convert_scalar_cond_reduction (gimple reduc, gimple_stmt_iterator *gsi,
1570 			       tree cond, tree op0, tree op1, bool swap)
1571 {
1572   gimple_stmt_iterator stmt_it;
1573   gimple new_assign;
1574   tree rhs;
1575   tree rhs1 = gimple_assign_rhs1 (reduc);
1576   tree tmp = make_temp_ssa_name (TREE_TYPE (rhs1), NULL, "_ifc_");
1577   tree c;
1578   tree zero = build_zero_cst (TREE_TYPE (rhs1));
1579 
1580   if (dump_file && (dump_flags & TDF_DETAILS))
1581     {
1582       fprintf (dump_file, "Found cond scalar reduction.\n");
1583       print_gimple_stmt (dump_file, reduc, 0, TDF_SLIM);
1584     }
1585 
1586   /* Build cond expression using COND and constant operand
1587      of reduction rhs.  */
1588   c = fold_build_cond_expr (TREE_TYPE (rhs1),
1589 			    unshare_expr (cond),
1590 			    swap ? zero : op1,
1591 			    swap ? op1 : zero);
1592 
1593   /* Create assignment stmt and insert it at GSI.  */
1594   new_assign = gimple_build_assign (tmp, c);
1595   gsi_insert_before (gsi, new_assign, GSI_SAME_STMT);
1596   /* Build rhs for unconditional increment/decrement.  */
1597   rhs = fold_build2 (gimple_assign_rhs_code (reduc),
1598 		     TREE_TYPE (rhs1), op0, tmp);
1599 
1600   /* Delete original reduction stmt.  */
1601   stmt_it = gsi_for_stmt (reduc);
1602   gsi_remove (&stmt_it, true);
1603   release_defs (reduc);
1604   return rhs;
1605 }
1606 
1607 /* Helpers for PHI arguments hashtable map.  */
1608 
1609 struct phi_args_hash_traits : default_hashmap_traits
1610 {
1611   static inline hashval_t hash (tree);
1612   static inline bool equal_keys (tree, tree);
1613 };
1614 
1615 inline hashval_t
1616 phi_args_hash_traits::hash (tree value)
1617 {
1618   return iterative_hash_expr (value, 0);
1619 }
1620 
1621 inline bool
1622 phi_args_hash_traits::equal_keys (tree value1, tree value2)
1623 {
1624   return operand_equal_p (value1, value2, 0);
1625 }
1626 
1627   /* Produce condition for all occurrences of ARG in PHI node.  */
1628 
1629 static tree
1630 gen_phi_arg_condition (gphi *phi, vec<int> *occur,
1631 		       gimple_stmt_iterator *gsi)
1632 {
1633   int len;
1634   int i;
1635   tree cond = NULL_TREE;
1636   tree c;
1637   edge e;
1638 
1639   len = occur->length ();
1640   gcc_assert (len > 0);
1641   for (i = 0; i < len; i++)
1642     {
1643       e = gimple_phi_arg_edge (phi, (*occur)[i]);
1644       c = bb_predicate (e->src);
1645       if (is_true_predicate (c))
1646 	continue;
1647       c = force_gimple_operand_gsi_1 (gsi, unshare_expr (c),
1648 				      is_gimple_condexpr, NULL_TREE,
1649 				      true, GSI_SAME_STMT);
1650       if (cond != NULL_TREE)
1651 	{
1652 	  /* Must build OR expression.  */
1653 	  cond = fold_or_predicates (EXPR_LOCATION (c), c, cond);
1654 	  cond = force_gimple_operand_gsi_1 (gsi, unshare_expr (cond),
1655 					     is_gimple_condexpr, NULL_TREE,
1656 					     true, GSI_SAME_STMT);
1657 	}
1658       else
1659 	cond = c;
1660     }
1661   gcc_assert (cond != NULL_TREE);
1662   return cond;
1663 }
1664 
1665 /* Replace a scalar PHI node with a COND_EXPR using COND as condition.
1666    This routine can handle PHI nodes with more than two arguments.
1667 
1668    For example,
1669      S1: A = PHI <x1(1), x2(5)>
1670    is converted into,
1671      S2: A = cond ? x1 : x2;
1672 
1673    The generated code is inserted at GSI that points to the top of
1674    basic block's statement list.
1675    If PHI node has more than two arguments a chain of conditional
1676    expression is produced.  */
1677 
1678 
1679 static void
1680 predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi)
1681 {
1682   gimple new_stmt = NULL, reduc;
1683   tree rhs, res, arg0, arg1, op0, op1, scev;
1684   tree cond;
1685   unsigned int index0;
1686   unsigned int max, args_len;
1687   edge e;
1688   basic_block bb;
1689   unsigned int i;
1690 
1691   res = gimple_phi_result (phi);
1692   if (virtual_operand_p (res))
1693     return;
1694 
1695   if ((rhs = degenerate_phi_result (phi))
1696       || ((scev = analyze_scalar_evolution (gimple_bb (phi)->loop_father,
1697 					    res))
1698 	  && !chrec_contains_undetermined (scev)
1699 	  && scev != res
1700 	  && (rhs = gimple_phi_arg_def (phi, 0))))
1701     {
1702       if (dump_file && (dump_flags & TDF_DETAILS))
1703 	{
1704 	  fprintf (dump_file, "Degenerate phi!\n");
1705 	  print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
1706 	}
1707       new_stmt = gimple_build_assign (res, rhs);
1708       gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1709       update_stmt (new_stmt);
1710       return;
1711     }
1712 
1713   bb = gimple_bb (phi);
1714   if (EDGE_COUNT (bb->preds) == 2)
1715     {
1716       /* Predicate ordinary PHI node with 2 arguments.  */
1717       edge first_edge, second_edge;
1718       basic_block true_bb;
1719       first_edge = EDGE_PRED (bb, 0);
1720       second_edge = EDGE_PRED (bb, 1);
1721       cond = bb_predicate (first_edge->src);
1722       if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
1723 	{
1724 	  edge tmp_edge = first_edge;
1725 	  first_edge = second_edge;
1726 	  second_edge = tmp_edge;
1727 	}
1728       if (EDGE_COUNT (first_edge->src->succs) > 1)
1729 	{
1730 	  cond = bb_predicate (second_edge->src);
1731 	  if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
1732 	    cond = TREE_OPERAND (cond, 0);
1733 	  else
1734 	    first_edge = second_edge;
1735 	}
1736       else
1737 	cond = bb_predicate (first_edge->src);
1738       /* Gimplify the condition to a valid cond-expr conditonal operand.  */
1739       cond = force_gimple_operand_gsi_1 (gsi, unshare_expr (cond),
1740 					 is_gimple_condexpr, NULL_TREE,
1741 					 true, GSI_SAME_STMT);
1742       true_bb = first_edge->src;
1743       if (EDGE_PRED (bb, 1)->src == true_bb)
1744 	{
1745 	  arg0 = gimple_phi_arg_def (phi, 1);
1746 	  arg1 = gimple_phi_arg_def (phi, 0);
1747 	}
1748       else
1749 	{
1750 	  arg0 = gimple_phi_arg_def (phi, 0);
1751 	  arg1 = gimple_phi_arg_def (phi, 1);
1752 	}
1753       if (is_cond_scalar_reduction (phi, &reduc, arg0, arg1,
1754 				    &op0, &op1, false))
1755 	/* Convert reduction stmt into vectorizable form.  */
1756 	rhs = convert_scalar_cond_reduction (reduc, gsi, cond, op0, op1,
1757 					     true_bb != gimple_bb (reduc));
1758       else
1759 	/* Build new RHS using selected condition and arguments.  */
1760 	rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond),
1761 				    arg0, arg1);
1762       new_stmt = gimple_build_assign (res, rhs);
1763       gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1764       update_stmt (new_stmt);
1765 
1766       if (dump_file && (dump_flags & TDF_DETAILS))
1767 	{
1768 	  fprintf (dump_file, "new phi replacement stmt\n");
1769 	  print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
1770 	}
1771       return;
1772     }
1773 
1774   /* Create hashmap for PHI node which contain vector of argument indexes
1775      having the same value.  */
1776   bool swap = false;
1777   hash_map<tree, auto_vec<int>, phi_args_hash_traits> phi_arg_map;
1778   unsigned int num_args = gimple_phi_num_args (phi);
1779   int max_ind = -1;
1780   /* Vector of different PHI argument values.  */
1781   auto_vec<tree> args (num_args);
1782 
1783   /* Compute phi_arg_map.  */
1784   for (i = 0; i < num_args; i++)
1785     {
1786       tree arg;
1787 
1788       arg = gimple_phi_arg_def (phi, i);
1789       if (!phi_arg_map.get (arg))
1790 	args.quick_push (arg);
1791       phi_arg_map.get_or_insert (arg).safe_push (i);
1792     }
1793 
1794   /* Determine element with max number of occurrences.  */
1795   max_ind = -1;
1796   max = 1;
1797   args_len = args.length ();
1798   for (i = 0; i < args_len; i++)
1799     {
1800       unsigned int len;
1801       if ((len = phi_arg_map.get (args[i])->length ()) > max)
1802 	{
1803 	  max_ind = (int) i;
1804 	  max = len;
1805 	}
1806     }
1807 
1808   /* Put element with max number of occurences to the end of ARGS.  */
1809   if (max_ind != -1 && max_ind +1 != (int) args_len)
1810     {
1811       tree tmp = args[args_len - 1];
1812       args[args_len - 1] = args[max_ind];
1813       args[max_ind] = tmp;
1814     }
1815 
1816   /* Handle one special case when number of arguments with different values
1817      is equal 2 and one argument has the only occurrence.  Such PHI can be
1818      handled as if would have only 2 arguments.  */
1819   if (args_len == 2 && phi_arg_map.get (args[0])->length () == 1)
1820     {
1821       vec<int> *indexes;
1822       indexes = phi_arg_map.get (args[0]);
1823       index0 = (*indexes)[0];
1824       arg0 = args[0];
1825       arg1 = args[1];
1826       e = gimple_phi_arg_edge (phi, index0);
1827       cond = bb_predicate (e->src);
1828       if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
1829 	{
1830 	  swap = true;
1831 	  cond = TREE_OPERAND (cond, 0);
1832 	}
1833       /* Gimplify the condition to a valid cond-expr conditonal operand.  */
1834       cond = force_gimple_operand_gsi_1 (gsi, unshare_expr (cond),
1835 					 is_gimple_condexpr, NULL_TREE,
1836 					 true, GSI_SAME_STMT);
1837       if (!(is_cond_scalar_reduction (phi, &reduc, arg0 , arg1,
1838 				      &op0, &op1, true)))
1839 	rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond),
1840 				    swap? arg1 : arg0,
1841 				    swap? arg0 : arg1);
1842       else
1843 	/* Convert reduction stmt into vectorizable form.  */
1844 	rhs = convert_scalar_cond_reduction (reduc, gsi, cond, op0, op1,
1845 					     swap);
1846       new_stmt = gimple_build_assign (res, rhs);
1847       gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1848       update_stmt (new_stmt);
1849     }
1850   else
1851     {
1852       /* Common case.  */
1853       vec<int> *indexes;
1854       tree type = TREE_TYPE (gimple_phi_result (phi));
1855       tree lhs;
1856       arg1 = args[1];
1857       for (i = 0; i < args_len; i++)
1858 	{
1859 	  arg0 = args[i];
1860 	  indexes = phi_arg_map.get (args[i]);
1861 	  if (i != args_len - 1)
1862 	    lhs = make_temp_ssa_name (type, NULL, "_ifc_");
1863 	  else
1864 	    lhs = res;
1865 	  cond = gen_phi_arg_condition (phi, indexes, gsi);
1866 	  rhs = fold_build_cond_expr (type, unshare_expr (cond),
1867 				      arg0, arg1);
1868 	  new_stmt = gimple_build_assign (lhs, rhs);
1869 	  gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1870 	  update_stmt (new_stmt);
1871 	  arg1 = lhs;
1872 	}
1873     }
1874 
1875   if (dump_file && (dump_flags & TDF_DETAILS))
1876     {
1877       fprintf (dump_file, "new extended phi replacement stmt\n");
1878       print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
1879     }
1880 }
1881 
1882 /* Replaces in LOOP all the scalar phi nodes other than those in the
1883    LOOP->header block with conditional modify expressions.  */
1884 
1885 static void
1886 predicate_all_scalar_phis (struct loop *loop)
1887 {
1888   basic_block bb;
1889   unsigned int orig_loop_num_nodes = loop->num_nodes;
1890   unsigned int i;
1891 
1892   for (i = 1; i < orig_loop_num_nodes; i++)
1893     {
1894       gphi *phi;
1895       gimple_stmt_iterator gsi;
1896       gphi_iterator phi_gsi;
1897       bb = ifc_bbs[i];
1898 
1899       if (bb == loop->header)
1900 	continue;
1901 
1902       if (EDGE_COUNT (bb->preds) == 1)
1903 	continue;
1904 
1905       phi_gsi = gsi_start_phis (bb);
1906       if (gsi_end_p (phi_gsi))
1907 	continue;
1908 
1909       gsi = gsi_after_labels (bb);
1910       while (!gsi_end_p (phi_gsi))
1911 	{
1912 	  phi = phi_gsi.phi ();
1913 	  predicate_scalar_phi (phi, &gsi);
1914 	  release_phi_node (phi);
1915 	  gsi_next (&phi_gsi);
1916 	}
1917 
1918       set_phi_nodes (bb, NULL);
1919     }
1920 }
1921 
1922 /* Insert in each basic block of LOOP the statements produced by the
1923    gimplification of the predicates.  */
1924 
1925 static void
1926 insert_gimplified_predicates (loop_p loop, bool any_mask_load_store)
1927 {
1928   unsigned int i;
1929 
1930   for (i = 0; i < loop->num_nodes; i++)
1931     {
1932       basic_block bb = ifc_bbs[i];
1933       gimple_seq stmts;
1934       if (!is_predicated (bb))
1935 	gcc_assert (bb_predicate_gimplified_stmts (bb) == NULL);
1936       if (!is_predicated (bb))
1937 	{
1938 	  /* Do not insert statements for a basic block that is not
1939 	     predicated.  Also make sure that the predicate of the
1940 	     basic block is set to true.  */
1941 	  reset_bb_predicate (bb);
1942 	  continue;
1943 	}
1944 
1945       stmts = bb_predicate_gimplified_stmts (bb);
1946       if (stmts)
1947 	{
1948 	  if (flag_tree_loop_if_convert_stores
1949 	      || any_mask_load_store)
1950 	    {
1951 	      /* Insert the predicate of the BB just after the label,
1952 		 as the if-conversion of memory writes will use this
1953 		 predicate.  */
1954 	      gimple_stmt_iterator gsi = gsi_after_labels (bb);
1955 	      gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
1956 	    }
1957 	  else
1958 	    {
1959 	      /* Insert the predicate of the BB at the end of the BB
1960 		 as this would reduce the register pressure: the only
1961 		 use of this predicate will be in successor BBs.  */
1962 	      gimple_stmt_iterator gsi = gsi_last_bb (bb);
1963 
1964 	      if (gsi_end_p (gsi)
1965 		  || stmt_ends_bb_p (gsi_stmt (gsi)))
1966 		gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
1967 	      else
1968 		gsi_insert_seq_after (&gsi, stmts, GSI_SAME_STMT);
1969 	    }
1970 
1971 	  /* Once the sequence is code generated, set it to NULL.  */
1972 	  set_bb_predicate_gimplified_stmts (bb, NULL);
1973 	}
1974     }
1975 }
1976 
1977 /* Helper function for predicate_mem_writes. Returns index of existent
1978    mask if it was created for given SIZE and -1 otherwise.  */
1979 
1980 static int
1981 mask_exists (int size, vec<int> vec)
1982 {
1983   unsigned int ix;
1984   int v;
1985   FOR_EACH_VEC_ELT (vec, ix, v)
1986     if (v == size)
1987       return (int) ix;
1988   return -1;
1989 }
1990 
1991 /* Predicate each write to memory in LOOP.
1992 
1993    This function transforms control flow constructs containing memory
1994    writes of the form:
1995 
1996    | for (i = 0; i < N; i++)
1997    |   if (cond)
1998    |     A[i] = expr;
1999 
2000    into the following form that does not contain control flow:
2001 
2002    | for (i = 0; i < N; i++)
2003    |   A[i] = cond ? expr : A[i];
2004 
2005    The original CFG looks like this:
2006 
2007    | bb_0
2008    |   i = 0
2009    | end_bb_0
2010    |
2011    | bb_1
2012    |   if (i < N) goto bb_5 else goto bb_2
2013    | end_bb_1
2014    |
2015    | bb_2
2016    |   cond = some_computation;
2017    |   if (cond) goto bb_3 else goto bb_4
2018    | end_bb_2
2019    |
2020    | bb_3
2021    |   A[i] = expr;
2022    |   goto bb_4
2023    | end_bb_3
2024    |
2025    | bb_4
2026    |   goto bb_1
2027    | end_bb_4
2028 
2029    insert_gimplified_predicates inserts the computation of the COND
2030    expression at the beginning of the destination basic block:
2031 
2032    | bb_0
2033    |   i = 0
2034    | end_bb_0
2035    |
2036    | bb_1
2037    |   if (i < N) goto bb_5 else goto bb_2
2038    | end_bb_1
2039    |
2040    | bb_2
2041    |   cond = some_computation;
2042    |   if (cond) goto bb_3 else goto bb_4
2043    | end_bb_2
2044    |
2045    | bb_3
2046    |   cond = some_computation;
2047    |   A[i] = expr;
2048    |   goto bb_4
2049    | end_bb_3
2050    |
2051    | bb_4
2052    |   goto bb_1
2053    | end_bb_4
2054 
2055    predicate_mem_writes is then predicating the memory write as follows:
2056 
2057    | bb_0
2058    |   i = 0
2059    | end_bb_0
2060    |
2061    | bb_1
2062    |   if (i < N) goto bb_5 else goto bb_2
2063    | end_bb_1
2064    |
2065    | bb_2
2066    |   if (cond) goto bb_3 else goto bb_4
2067    | end_bb_2
2068    |
2069    | bb_3
2070    |   cond = some_computation;
2071    |   A[i] = cond ? expr : A[i];
2072    |   goto bb_4
2073    | end_bb_3
2074    |
2075    | bb_4
2076    |   goto bb_1
2077    | end_bb_4
2078 
2079    and finally combine_blocks removes the basic block boundaries making
2080    the loop vectorizable:
2081 
2082    | bb_0
2083    |   i = 0
2084    |   if (i < N) goto bb_5 else goto bb_1
2085    | end_bb_0
2086    |
2087    | bb_1
2088    |   cond = some_computation;
2089    |   A[i] = cond ? expr : A[i];
2090    |   if (i < N) goto bb_5 else goto bb_4
2091    | end_bb_1
2092    |
2093    | bb_4
2094    |   goto bb_1
2095    | end_bb_4
2096 */
2097 
2098 static void
2099 predicate_mem_writes (loop_p loop)
2100 {
2101   unsigned int i, orig_loop_num_nodes = loop->num_nodes;
2102   auto_vec<int, 1> vect_sizes;
2103   auto_vec<tree, 1> vect_masks;
2104 
2105   for (i = 1; i < orig_loop_num_nodes; i++)
2106     {
2107       gimple_stmt_iterator gsi;
2108       basic_block bb = ifc_bbs[i];
2109       tree cond = bb_predicate (bb);
2110       bool swap;
2111       gimple stmt;
2112       int index;
2113 
2114       if (is_true_predicate (cond))
2115 	continue;
2116 
2117       swap = false;
2118       if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
2119 	{
2120 	  swap = true;
2121 	  cond = TREE_OPERAND (cond, 0);
2122 	}
2123 
2124       vect_sizes.truncate (0);
2125       vect_masks.truncate (0);
2126 
2127       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2128 	if (!gimple_assign_single_p (stmt = gsi_stmt (gsi)))
2129 	  continue;
2130 	else if (gimple_plf (stmt, GF_PLF_2))
2131 	  {
2132 	    tree lhs = gimple_assign_lhs (stmt);
2133 	    tree rhs = gimple_assign_rhs1 (stmt);
2134 	    tree ref, addr, ptr, masktype, mask_op0, mask_op1, mask;
2135 	    gimple new_stmt;
2136 	    int bitsize = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (lhs)));
2137 	    ref = TREE_CODE (lhs) == SSA_NAME ? rhs : lhs;
2138 	    mark_addressable (ref);
2139 	    addr = force_gimple_operand_gsi (&gsi, build_fold_addr_expr (ref),
2140 					     true, NULL_TREE, true,
2141 					     GSI_SAME_STMT);
2142 	    if (!vect_sizes.is_empty ()
2143 		&& (index = mask_exists (bitsize, vect_sizes)) != -1)
2144 	      /* Use created mask.  */
2145 	      mask = vect_masks[index];
2146 	    else
2147 	      {
2148 		masktype = build_nonstandard_integer_type (bitsize, 1);
2149 		mask_op0 = build_int_cst (masktype, swap ? 0 : -1);
2150 		mask_op1 = build_int_cst (masktype, swap ? -1 : 0);
2151 		cond = force_gimple_operand_gsi_1 (&gsi, unshare_expr (cond),
2152 						   is_gimple_condexpr,
2153 						   NULL_TREE,
2154 						   true, GSI_SAME_STMT);
2155 		mask = fold_build_cond_expr (masktype, unshare_expr (cond),
2156 					     mask_op0, mask_op1);
2157 		mask = ifc_temp_var (masktype, mask, &gsi);
2158 		/* Save mask and its size for further use.  */
2159 	        vect_sizes.safe_push (bitsize);
2160 		vect_masks.safe_push (mask);
2161 	      }
2162 	    ptr = build_int_cst (reference_alias_ptr_type (ref), 0);
2163 	    /* Copy points-to info if possible.  */
2164 	    if (TREE_CODE (addr) == SSA_NAME && !SSA_NAME_PTR_INFO (addr))
2165 	      copy_ref_info (build2 (MEM_REF, TREE_TYPE (ref), addr, ptr),
2166 			     ref);
2167 	    if (TREE_CODE (lhs) == SSA_NAME)
2168 	      {
2169 		new_stmt
2170 		  = gimple_build_call_internal (IFN_MASK_LOAD, 3, addr,
2171 						ptr, mask);
2172 		gimple_call_set_lhs (new_stmt, lhs);
2173 	      }
2174 	    else
2175 	      new_stmt
2176 		= gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr,
2177 					      mask, rhs);
2178 	    gsi_replace (&gsi, new_stmt, true);
2179 	  }
2180 	else if (gimple_vdef (stmt))
2181 	  {
2182 	    tree lhs = gimple_assign_lhs (stmt);
2183 	    tree rhs = gimple_assign_rhs1 (stmt);
2184 	    tree type = TREE_TYPE (lhs);
2185 
2186 	    lhs = ifc_temp_var (type, unshare_expr (lhs), &gsi);
2187 	    rhs = ifc_temp_var (type, unshare_expr (rhs), &gsi);
2188 	    if (swap)
2189 	      {
2190 		tree tem = lhs;
2191 		lhs = rhs;
2192 		rhs = tem;
2193 	      }
2194 	    cond = force_gimple_operand_gsi_1 (&gsi, unshare_expr (cond),
2195 					       is_gimple_condexpr, NULL_TREE,
2196 					       true, GSI_SAME_STMT);
2197 	    rhs = fold_build_cond_expr (type, unshare_expr (cond), rhs, lhs);
2198 	    gimple_assign_set_rhs1 (stmt, ifc_temp_var (type, rhs, &gsi));
2199 	    update_stmt (stmt);
2200 	  }
2201     }
2202 }
2203 
2204 /* Remove all GIMPLE_CONDs and GIMPLE_LABELs of all the basic blocks
2205    other than the exit and latch of the LOOP.  Also resets the
2206    GIMPLE_DEBUG information.  */
2207 
2208 static void
2209 remove_conditions_and_labels (loop_p loop)
2210 {
2211   gimple_stmt_iterator gsi;
2212   unsigned int i;
2213 
2214   for (i = 0; i < loop->num_nodes; i++)
2215     {
2216       basic_block bb = ifc_bbs[i];
2217 
2218       if (bb_with_exit_edge_p (loop, bb)
2219         || bb == loop->latch)
2220       continue;
2221 
2222       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
2223 	switch (gimple_code (gsi_stmt (gsi)))
2224 	  {
2225 	  case GIMPLE_COND:
2226 	  case GIMPLE_LABEL:
2227 	    gsi_remove (&gsi, true);
2228 	    break;
2229 
2230 	  case GIMPLE_DEBUG:
2231 	    /* ??? Should there be conditional GIMPLE_DEBUG_BINDs?  */
2232 	    if (gimple_debug_bind_p (gsi_stmt (gsi)))
2233 	      {
2234 		gimple_debug_bind_reset_value (gsi_stmt (gsi));
2235 		update_stmt (gsi_stmt (gsi));
2236 	      }
2237 	    gsi_next (&gsi);
2238 	    break;
2239 
2240 	  default:
2241 	    gsi_next (&gsi);
2242 	  }
2243     }
2244 }
2245 
2246 /* Combine all the basic blocks from LOOP into one or two super basic
2247    blocks.  Replace PHI nodes with conditional modify expressions.  */
2248 
2249 static void
2250 combine_blocks (struct loop *loop, bool any_mask_load_store)
2251 {
2252   basic_block bb, exit_bb, merge_target_bb;
2253   unsigned int orig_loop_num_nodes = loop->num_nodes;
2254   unsigned int i;
2255   edge e;
2256   edge_iterator ei;
2257 
2258   predicate_bbs (loop);
2259   remove_conditions_and_labels (loop);
2260   insert_gimplified_predicates (loop, any_mask_load_store);
2261   predicate_all_scalar_phis (loop);
2262 
2263   if (flag_tree_loop_if_convert_stores || any_mask_load_store)
2264     predicate_mem_writes (loop);
2265 
2266   /* Merge basic blocks: first remove all the edges in the loop,
2267      except for those from the exit block.  */
2268   exit_bb = NULL;
2269   bool *predicated = XNEWVEC (bool, orig_loop_num_nodes);
2270   for (i = 0; i < orig_loop_num_nodes; i++)
2271     {
2272       bb = ifc_bbs[i];
2273       predicated[i] = !is_true_predicate (bb_predicate (bb));
2274       free_bb_predicate (bb);
2275       if (bb_with_exit_edge_p (loop, bb))
2276 	{
2277 	  gcc_assert (exit_bb == NULL);
2278 	  exit_bb = bb;
2279 	}
2280     }
2281   gcc_assert (exit_bb != loop->latch);
2282 
2283   for (i = 1; i < orig_loop_num_nodes; i++)
2284     {
2285       bb = ifc_bbs[i];
2286 
2287       for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei));)
2288 	{
2289 	  if (e->src == exit_bb)
2290 	    ei_next (&ei);
2291 	  else
2292 	    remove_edge (e);
2293 	}
2294     }
2295 
2296   if (exit_bb != NULL)
2297     {
2298       if (exit_bb != loop->header)
2299 	{
2300 	  /* Connect this node to loop header.  */
2301 	  make_edge (loop->header, exit_bb, EDGE_FALLTHRU);
2302 	  set_immediate_dominator (CDI_DOMINATORS, exit_bb, loop->header);
2303 	}
2304 
2305       /* Redirect non-exit edges to loop->latch.  */
2306       FOR_EACH_EDGE (e, ei, exit_bb->succs)
2307 	{
2308 	  if (!loop_exit_edge_p (loop, e))
2309 	    redirect_edge_and_branch (e, loop->latch);
2310 	}
2311       set_immediate_dominator (CDI_DOMINATORS, loop->latch, exit_bb);
2312     }
2313   else
2314     {
2315       /* If the loop does not have an exit, reconnect header and latch.  */
2316       make_edge (loop->header, loop->latch, EDGE_FALLTHRU);
2317       set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header);
2318     }
2319 
2320   merge_target_bb = loop->header;
2321   for (i = 1; i < orig_loop_num_nodes; i++)
2322     {
2323       gimple_stmt_iterator gsi;
2324       gimple_stmt_iterator last;
2325 
2326       bb = ifc_bbs[i];
2327 
2328       if (bb == exit_bb || bb == loop->latch)
2329 	continue;
2330 
2331       /* Make stmts member of loop->header and clear range info from all stmts
2332 	 in BB which is now no longer executed conditional on a predicate we
2333 	 could have derived it from.  */
2334       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2335 	{
2336 	  gimple stmt = gsi_stmt (gsi);
2337 	  gimple_set_bb (stmt, merge_target_bb);
2338 	  if (predicated[i])
2339 	    {
2340 	      ssa_op_iter i;
2341 	      tree op;
2342 	      FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF)
2343 		reset_flow_sensitive_info (op);
2344 	    }
2345 	}
2346 
2347       /* Update stmt list.  */
2348       last = gsi_last_bb (merge_target_bb);
2349       gsi_insert_seq_after (&last, bb_seq (bb), GSI_NEW_STMT);
2350       set_bb_seq (bb, NULL);
2351 
2352       delete_basic_block (bb);
2353     }
2354 
2355   /* If possible, merge loop header to the block with the exit edge.
2356      This reduces the number of basic blocks to two, to please the
2357      vectorizer that handles only loops with two nodes.  */
2358   if (exit_bb
2359       && exit_bb != loop->header
2360       && can_merge_blocks_p (loop->header, exit_bb))
2361     merge_blocks (loop->header, exit_bb);
2362 
2363   free (ifc_bbs);
2364   ifc_bbs = NULL;
2365   free (predicated);
2366 }
2367 
2368 /* Version LOOP before if-converting it, the original loop
2369    will be then if-converted, the new copy of the loop will not,
2370    and the LOOP_VECTORIZED internal call will be guarding which
2371    loop to execute.  The vectorizer pass will fold this
2372    internal call into either true or false.  */
2373 
2374 static bool
2375 version_loop_for_if_conversion (struct loop *loop)
2376 {
2377   basic_block cond_bb;
2378   tree cond = make_ssa_name (boolean_type_node);
2379   struct loop *new_loop;
2380   gimple g;
2381   gimple_stmt_iterator gsi;
2382 
2383   g = gimple_build_call_internal (IFN_LOOP_VECTORIZED, 2,
2384 				  build_int_cst (integer_type_node, loop->num),
2385 				  integer_zero_node);
2386   gimple_call_set_lhs (g, cond);
2387 
2388   initialize_original_copy_tables ();
2389   new_loop = loop_version (loop, cond, &cond_bb,
2390 			   REG_BR_PROB_BASE, REG_BR_PROB_BASE,
2391 			   REG_BR_PROB_BASE, true);
2392   free_original_copy_tables ();
2393   if (new_loop == NULL)
2394     return false;
2395   new_loop->dont_vectorize = true;
2396   new_loop->force_vectorize = false;
2397   gsi = gsi_last_bb (cond_bb);
2398   gimple_call_set_arg (g, 1, build_int_cst (integer_type_node, new_loop->num));
2399   gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2400   update_ssa (TODO_update_ssa);
2401   return true;
2402 }
2403 
2404 /* Performs splitting of critical edges if aggressive_if_conv is true.
2405    Returns false if loop won't be if converted and true otherwise.  */
2406 
2407 static bool
2408 ifcvt_split_critical_edges (struct loop *loop)
2409 {
2410   basic_block *body;
2411   basic_block bb;
2412   unsigned int num = loop->num_nodes;
2413   unsigned int i;
2414   gimple stmt;
2415   edge e;
2416   edge_iterator ei;
2417 
2418   if (num <= 2)
2419     return false;
2420   if (loop->inner)
2421     return false;
2422   if (!single_exit (loop))
2423     return false;
2424 
2425   body = get_loop_body (loop);
2426   for (i = 0; i < num; i++)
2427     {
2428       bb = body[i];
2429       if (bb == loop->latch
2430 	  || bb_with_exit_edge_p (loop, bb))
2431 	continue;
2432       stmt = last_stmt (bb);
2433       /* Skip basic blocks not ending with conditional branch.  */
2434       if (!(stmt && gimple_code (stmt) == GIMPLE_COND))
2435 	continue;
2436       FOR_EACH_EDGE (e, ei, bb->succs)
2437 	if (EDGE_CRITICAL_P (e) && e->dest->loop_father == loop)
2438 	  split_edge (e);
2439     }
2440   free (body);
2441   return true;
2442 }
2443 
2444 /* Assumes that lhs of DEF_STMT have multiple uses.
2445    Delete one use by (1) creation of copy DEF_STMT with
2446    unique lhs; (2) change original use of lhs in one
2447    use statement with newly created lhs.  */
2448 
2449 static void
2450 ifcvt_split_def_stmt (gimple def_stmt, gimple use_stmt)
2451 {
2452   tree var;
2453   tree lhs;
2454   gimple copy_stmt;
2455   gimple_stmt_iterator gsi;
2456   use_operand_p use_p;
2457   imm_use_iterator imm_iter;
2458 
2459   var = gimple_assign_lhs (def_stmt);
2460   copy_stmt = gimple_copy (def_stmt);
2461   lhs = make_temp_ssa_name (TREE_TYPE (var), NULL, "_ifc_");
2462   gimple_assign_set_lhs (copy_stmt, lhs);
2463   SSA_NAME_DEF_STMT (lhs) = copy_stmt;
2464   /* Insert copy of DEF_STMT.  */
2465   gsi = gsi_for_stmt (def_stmt);
2466   gsi_insert_after (&gsi, copy_stmt, GSI_SAME_STMT);
2467   /* Change use of var to lhs in use_stmt.  */
2468   if (dump_file && (dump_flags & TDF_DETAILS))
2469     {
2470       fprintf (dump_file, "Change use of var  ");
2471       print_generic_expr (dump_file, var, TDF_SLIM);
2472       fprintf (dump_file, " to ");
2473       print_generic_expr (dump_file, lhs, TDF_SLIM);
2474       fprintf (dump_file, "\n");
2475     }
2476   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var)
2477     {
2478       if (USE_STMT (use_p) != use_stmt)
2479 	continue;
2480       SET_USE (use_p, lhs);
2481       break;
2482     }
2483 }
2484 
2485 /* Traverse bool pattern recursively starting from VAR.
2486    Save its def and use statements to defuse_list if VAR does
2487    not have single use.  */
2488 
2489 static void
2490 ifcvt_walk_pattern_tree (tree var, vec<gimple> *defuse_list,
2491 			 gimple use_stmt)
2492 {
2493   tree rhs1, rhs2;
2494   enum tree_code code;
2495   gimple def_stmt;
2496 
2497   def_stmt = SSA_NAME_DEF_STMT (var);
2498   if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
2499     return;
2500   if (!has_single_use (var))
2501     {
2502       /* Put def and use stmts into defuse_list.  */
2503       defuse_list->safe_push (def_stmt);
2504       defuse_list->safe_push (use_stmt);
2505       if (dump_file && (dump_flags & TDF_DETAILS))
2506 	{
2507 	  fprintf (dump_file, "Multiple lhs uses in stmt\n");
2508 	  print_gimple_stmt (dump_file, def_stmt, 0, TDF_SLIM);
2509 	}
2510     }
2511   rhs1 = gimple_assign_rhs1 (def_stmt);
2512   code = gimple_assign_rhs_code (def_stmt);
2513   switch (code)
2514     {
2515     case SSA_NAME:
2516       ifcvt_walk_pattern_tree (rhs1, defuse_list, def_stmt);
2517       break;
2518     CASE_CONVERT:
2519       if ((TYPE_PRECISION (TREE_TYPE (rhs1)) != 1
2520 	   || !TYPE_UNSIGNED (TREE_TYPE (rhs1)))
2521 	  && TREE_CODE (TREE_TYPE (rhs1)) != BOOLEAN_TYPE)
2522 	break;
2523       ifcvt_walk_pattern_tree (rhs1, defuse_list, def_stmt);
2524       break;
2525     case BIT_NOT_EXPR:
2526       ifcvt_walk_pattern_tree (rhs1, defuse_list, def_stmt);
2527       break;
2528     case BIT_AND_EXPR:
2529     case BIT_IOR_EXPR:
2530     case BIT_XOR_EXPR:
2531       ifcvt_walk_pattern_tree (rhs1, defuse_list, def_stmt);
2532       rhs2 = gimple_assign_rhs2 (def_stmt);
2533       ifcvt_walk_pattern_tree (rhs2, defuse_list, def_stmt);
2534       break;
2535     default:
2536       break;
2537     }
2538   return;
2539 }
2540 
2541 /* Returns true if STMT can be a root of bool pattern apllied
2542    by vectorizer.  */
2543 
2544 static bool
2545 stmt_is_root_of_bool_pattern (gimple stmt)
2546 {
2547   enum tree_code code;
2548   tree lhs, rhs;
2549 
2550   code = gimple_assign_rhs_code (stmt);
2551   if (CONVERT_EXPR_CODE_P (code))
2552     {
2553       lhs = gimple_assign_lhs (stmt);
2554       rhs = gimple_assign_rhs1 (stmt);
2555       if (TREE_CODE (TREE_TYPE (rhs)) != BOOLEAN_TYPE)
2556 	return false;
2557       if (TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE)
2558 	return false;
2559       return true;
2560     }
2561   else if (code == COND_EXPR)
2562     {
2563       rhs = gimple_assign_rhs1 (stmt);
2564       if (TREE_CODE (rhs) != SSA_NAME)
2565 	return false;
2566       return true;
2567     }
2568   return false;
2569 }
2570 
2571 /*  Traverse all statements in BB which correspondent to loop header to
2572     find out all statements which can start bool pattern applied by
2573     vectorizer and convert multiple uses in it to conform pattern
2574     restrictions.  Such case can occur if the same predicate is used both
2575     for phi node conversion and load/store mask.  */
2576 
2577 static void
2578 ifcvt_repair_bool_pattern (basic_block bb)
2579 {
2580   tree rhs;
2581   gimple stmt;
2582   gimple_stmt_iterator gsi;
2583   vec<gimple> defuse_list = vNULL;
2584   vec<gimple> pattern_roots = vNULL;
2585   bool repeat = true;
2586   int niter = 0;
2587   unsigned int ix;
2588 
2589   /* Collect all root pattern statements.  */
2590   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2591     {
2592       stmt = gsi_stmt (gsi);
2593       if (gimple_code (stmt) != GIMPLE_ASSIGN)
2594 	continue;
2595       if (!stmt_is_root_of_bool_pattern (stmt))
2596 	continue;
2597       pattern_roots.safe_push (stmt);
2598     }
2599 
2600   if (pattern_roots.is_empty ())
2601     return;
2602 
2603   /* Split all statements with multiple uses iteratively since splitting
2604      may create new multiple uses.  */
2605   while (repeat)
2606     {
2607       repeat = false;
2608       niter++;
2609       FOR_EACH_VEC_ELT (pattern_roots, ix, stmt)
2610 	{
2611 	  rhs = gimple_assign_rhs1 (stmt);
2612 	  ifcvt_walk_pattern_tree (rhs, &defuse_list, stmt);
2613 	  while (defuse_list.length () > 0)
2614 	    {
2615 	      repeat = true;
2616 	      gimple def_stmt, use_stmt;
2617 	      use_stmt = defuse_list.pop ();
2618 	      def_stmt = defuse_list.pop ();
2619 	      ifcvt_split_def_stmt (def_stmt, use_stmt);
2620 	    }
2621 
2622 	}
2623     }
2624   if (dump_file && (dump_flags & TDF_DETAILS))
2625     fprintf (dump_file, "Repair bool pattern takes %d iterations. \n",
2626 	     niter);
2627 }
2628 
2629 /* Delete redundant statements produced by predication which prevents
2630    loop vectorization.  */
2631 
2632 static void
2633 ifcvt_local_dce (basic_block bb)
2634 {
2635   gimple stmt;
2636   gimple stmt1;
2637   gimple phi;
2638   gimple_stmt_iterator gsi;
2639   vec<gimple> worklist;
2640   enum gimple_code code;
2641   use_operand_p use_p;
2642   imm_use_iterator imm_iter;
2643 
2644   worklist.create (64);
2645   /* Consider all phi as live statements.  */
2646   for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2647     {
2648       phi = gsi_stmt (gsi);
2649       gimple_set_plf (phi, GF_PLF_2, true);
2650       worklist.safe_push (phi);
2651     }
2652   /* Consider load/store statemnts, CALL and COND as live.  */
2653   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2654     {
2655       stmt = gsi_stmt (gsi);
2656       if (gimple_store_p (stmt)
2657 	  || gimple_assign_load_p (stmt)
2658 	  || is_gimple_debug (stmt))
2659 	{
2660 	  gimple_set_plf (stmt, GF_PLF_2, true);
2661 	  worklist.safe_push (stmt);
2662 	  continue;
2663 	}
2664       code = gimple_code (stmt);
2665       if (code == GIMPLE_COND || code == GIMPLE_CALL)
2666 	{
2667 	  gimple_set_plf (stmt, GF_PLF_2, true);
2668 	  worklist.safe_push (stmt);
2669 	  continue;
2670 	}
2671       gimple_set_plf (stmt, GF_PLF_2, false);
2672 
2673       if (code == GIMPLE_ASSIGN)
2674 	{
2675 	  tree lhs = gimple_assign_lhs (stmt);
2676 	  FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
2677 	    {
2678 	      stmt1 = USE_STMT (use_p);
2679 	      if (gimple_bb (stmt1) != bb)
2680 		{
2681 		  gimple_set_plf (stmt, GF_PLF_2, true);
2682 		  worklist.safe_push (stmt);
2683 		  break;
2684 		}
2685 	    }
2686 	}
2687     }
2688   /* Propagate liveness through arguments of live stmt.  */
2689   while (worklist.length () > 0)
2690     {
2691       ssa_op_iter iter;
2692       use_operand_p use_p;
2693       tree use;
2694 
2695       stmt = worklist.pop ();
2696       FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
2697 	{
2698 	  use = USE_FROM_PTR (use_p);
2699 	  if (TREE_CODE (use) != SSA_NAME)
2700 	    continue;
2701 	  stmt1 = SSA_NAME_DEF_STMT (use);
2702 	  if (gimple_bb (stmt1) != bb
2703 	      || gimple_plf (stmt1, GF_PLF_2))
2704 	    continue;
2705 	  gimple_set_plf (stmt1, GF_PLF_2, true);
2706 	  worklist.safe_push (stmt1);
2707 	}
2708     }
2709   /* Delete dead statements.  */
2710   gsi = gsi_start_bb (bb);
2711   while (!gsi_end_p (gsi))
2712     {
2713       stmt = gsi_stmt (gsi);
2714       if (gimple_plf (stmt, GF_PLF_2))
2715 	{
2716 	  gsi_next (&gsi);
2717 	  continue;
2718 	}
2719       if (dump_file && (dump_flags & TDF_DETAILS))
2720 	{
2721 	  fprintf (dump_file, "Delete dead stmt in bb#%d\n", bb->index);
2722 	  print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
2723 	}
2724       gsi_remove (&gsi, true);
2725       release_defs (stmt);
2726     }
2727 }
2728 
2729 /* If-convert LOOP when it is legal.  For the moment this pass has no
2730    profitability analysis.  Returns non-zero todo flags when something
2731    changed.  */
2732 
2733 static unsigned int
2734 tree_if_conversion (struct loop *loop)
2735 {
2736   unsigned int todo = 0;
2737   ifc_bbs = NULL;
2738   bool any_mask_load_store = false;
2739 
2740   /* Set-up aggressive if-conversion for loops marked with simd pragma.  */
2741   aggressive_if_conv = loop->force_vectorize;
2742   /* Check either outer loop was marked with simd pragma.  */
2743   if (!aggressive_if_conv)
2744     {
2745       struct loop *outer_loop = loop_outer (loop);
2746       if (outer_loop && outer_loop->force_vectorize)
2747 	aggressive_if_conv = true;
2748     }
2749 
2750   if (aggressive_if_conv)
2751     if (!ifcvt_split_critical_edges (loop))
2752       goto cleanup;
2753 
2754   if (!if_convertible_loop_p (loop, &any_mask_load_store)
2755       || !dbg_cnt (if_conversion_tree))
2756     goto cleanup;
2757 
2758   if (any_mask_load_store
2759       && ((!flag_tree_loop_vectorize && !loop->force_vectorize)
2760 	  || loop->dont_vectorize))
2761     goto cleanup;
2762 
2763   if (any_mask_load_store && !version_loop_for_if_conversion (loop))
2764     goto cleanup;
2765 
2766   /* Now all statements are if-convertible.  Combine all the basic
2767      blocks into one huge basic block doing the if-conversion
2768      on-the-fly.  */
2769   combine_blocks (loop, any_mask_load_store);
2770 
2771   /* Delete dead predicate computations and repair tree correspondent
2772      to bool pattern to delete multiple uses of preidcates.  */
2773   if (aggressive_if_conv)
2774     {
2775       ifcvt_local_dce (loop->header);
2776       ifcvt_repair_bool_pattern (loop->header);
2777     }
2778 
2779   todo |= TODO_cleanup_cfg;
2780   if (flag_tree_loop_if_convert_stores || any_mask_load_store)
2781     {
2782       mark_virtual_operands_for_renaming (cfun);
2783       todo |= TODO_update_ssa_only_virtuals;
2784     }
2785 
2786  cleanup:
2787   if (ifc_bbs)
2788     {
2789       unsigned int i;
2790 
2791       for (i = 0; i < loop->num_nodes; i++)
2792 	free_bb_predicate (ifc_bbs[i]);
2793 
2794       free (ifc_bbs);
2795       ifc_bbs = NULL;
2796     }
2797   free_dominance_info (CDI_POST_DOMINATORS);
2798 
2799   return todo;
2800 }
2801 
2802 /* Tree if-conversion pass management.  */
2803 
2804 namespace {
2805 
2806 const pass_data pass_data_if_conversion =
2807 {
2808   GIMPLE_PASS, /* type */
2809   "ifcvt", /* name */
2810   OPTGROUP_NONE, /* optinfo_flags */
2811   TV_NONE, /* tv_id */
2812   ( PROP_cfg | PROP_ssa ), /* properties_required */
2813   0, /* properties_provided */
2814   0, /* properties_destroyed */
2815   0, /* todo_flags_start */
2816   0, /* todo_flags_finish */
2817 };
2818 
2819 class pass_if_conversion : public gimple_opt_pass
2820 {
2821 public:
2822   pass_if_conversion (gcc::context *ctxt)
2823     : gimple_opt_pass (pass_data_if_conversion, ctxt)
2824   {}
2825 
2826   /* opt_pass methods: */
2827   virtual bool gate (function *);
2828   virtual unsigned int execute (function *);
2829 
2830 }; // class pass_if_conversion
2831 
2832 bool
2833 pass_if_conversion::gate (function *fun)
2834 {
2835   return (((flag_tree_loop_vectorize || fun->has_force_vectorize_loops)
2836 	   && flag_tree_loop_if_convert != 0)
2837 	  || flag_tree_loop_if_convert == 1
2838 	  || flag_tree_loop_if_convert_stores == 1);
2839 }
2840 
2841 unsigned int
2842 pass_if_conversion::execute (function *fun)
2843 {
2844   struct loop *loop;
2845   unsigned todo = 0;
2846 
2847   if (number_of_loops (fun) <= 1)
2848     return 0;
2849 
2850   FOR_EACH_LOOP (loop, 0)
2851     if (flag_tree_loop_if_convert == 1
2852 	|| flag_tree_loop_if_convert_stores == 1
2853 	|| ((flag_tree_loop_vectorize || loop->force_vectorize)
2854 	    && !loop->dont_vectorize))
2855       todo |= tree_if_conversion (loop);
2856 
2857 #ifdef ENABLE_CHECKING
2858   {
2859     basic_block bb;
2860     FOR_EACH_BB_FN (bb, fun)
2861       gcc_assert (!bb->aux);
2862   }
2863 #endif
2864 
2865   return todo;
2866 }
2867 
2868 } // anon namespace
2869 
2870 gimple_opt_pass *
2871 make_pass_if_conversion (gcc::context *ctxt)
2872 {
2873   return new pass_if_conversion (ctxt);
2874 }
2875