* gcc.dg/torture/pr66345.c: Fix assumption about size_t type.
[official-gcc.git] / gcc / tree-if-conv.c
blobe0ac936d72cfb2a4878452e2725e1475cd6ba137
1 /* If-conversion for vectorizer.
2 Copyright (C) 2004-2015 Free Software Foundation, Inc.
3 Contributed by Devang Patel <dpatel@apple.com>
5 This file is part of GCC.
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.
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.
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/>. */
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.
25 A short description of if-conversion:
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
38 Sample transformation:
40 INPUT
41 -----
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>;
48 <L17>:;
49 goto <bb 3> (<L3>);
51 <L1>:;
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>;
59 <L19>:;
60 goto <bb 1> (<L0>);
62 <L18>:;
64 OUTPUT
65 ------
67 # i_23 = PHI <0(0), i_18(10)>;
68 <L0>:;
69 j_15 = A[i_23];
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>;
77 <L19>:;
78 goto <bb 1> (<L0>);
80 <L18>:;
83 #include "config.h"
84 #include "system.h"
85 #include "coretypes.h"
86 #include "tm.h"
87 #include "alias.h"
88 #include "symtab.h"
89 #include "tree.h"
90 #include "fold-const.h"
91 #include "stor-layout.h"
92 #include "flags.h"
93 #include "predict.h"
94 #include "hard-reg-set.h"
95 #include "function.h"
96 #include "dominance.h"
97 #include "cfg.h"
98 #include "basic-block.h"
99 #include "gimple-pretty-print.h"
100 #include "tree-ssa-alias.h"
101 #include "internal-fn.h"
102 #include "gimple-fold.h"
103 #include "gimple-expr.h"
104 #include "gimple.h"
105 #include "gimplify.h"
106 #include "gimple-iterator.h"
107 #include "gimplify-me.h"
108 #include "gimple-ssa.h"
109 #include "tree-cfg.h"
110 #include "tree-phinodes.h"
111 #include "ssa-iterators.h"
112 #include "stringpool.h"
113 #include "tree-ssanames.h"
114 #include "tree-into-ssa.h"
115 #include "tree-ssa.h"
116 #include "cfgloop.h"
117 #include "tree-chrec.h"
118 #include "tree-data-ref.h"
119 #include "tree-scalar-evolution.h"
120 #include "tree-ssa-loop-ivopts.h"
121 #include "tree-ssa-address.h"
122 #include "tree-pass.h"
123 #include "dbgcnt.h"
124 #include "rtl.h"
125 #include "insn-config.h"
126 #include "expmed.h"
127 #include "dojump.h"
128 #include "explow.h"
129 #include "calls.h"
130 #include "emit-rtl.h"
131 #include "varasm.h"
132 #include "stmt.h"
133 #include "expr.h"
134 #include "insn-codes.h"
135 #include "optabs.h"
137 /* List of basic blocks in if-conversion-suitable order. */
138 static basic_block *ifc_bbs;
140 /* Apply more aggressive (extended) if-conversion if true. */
141 static bool aggressive_if_conv;
143 /* Structure used to predicate basic blocks. This is attached to the
144 ->aux field of the BBs in the loop to be if-converted. */
145 typedef struct bb_predicate_s {
147 /* The condition under which this basic block is executed. */
148 tree predicate;
150 /* PREDICATE is gimplified, and the sequence of statements is
151 recorded here, in order to avoid the duplication of computations
152 that occur in previous conditions. See PR44483. */
153 gimple_seq predicate_gimplified_stmts;
154 } *bb_predicate_p;
156 /* Returns true when the basic block BB has a predicate. */
158 static inline bool
159 bb_has_predicate (basic_block bb)
161 return bb->aux != NULL;
164 /* Returns the gimplified predicate for basic block BB. */
166 static inline tree
167 bb_predicate (basic_block bb)
169 return ((bb_predicate_p) bb->aux)->predicate;
172 /* Sets the gimplified predicate COND for basic block BB. */
174 static inline void
175 set_bb_predicate (basic_block bb, tree cond)
177 gcc_assert ((TREE_CODE (cond) == TRUTH_NOT_EXPR
178 && is_gimple_condexpr (TREE_OPERAND (cond, 0)))
179 || is_gimple_condexpr (cond));
180 ((bb_predicate_p) bb->aux)->predicate = cond;
183 /* Returns the sequence of statements of the gimplification of the
184 predicate for basic block BB. */
186 static inline gimple_seq
187 bb_predicate_gimplified_stmts (basic_block bb)
189 return ((bb_predicate_p) bb->aux)->predicate_gimplified_stmts;
192 /* Sets the sequence of statements STMTS of the gimplification of the
193 predicate for basic block BB. */
195 static inline void
196 set_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts)
198 ((bb_predicate_p) bb->aux)->predicate_gimplified_stmts = stmts;
201 /* Adds the sequence of statements STMTS to the sequence of statements
202 of the predicate for basic block BB. */
204 static inline void
205 add_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts)
207 gimple_seq_add_seq
208 (&(((bb_predicate_p) bb->aux)->predicate_gimplified_stmts), stmts);
211 /* Initializes to TRUE the predicate of basic block BB. */
213 static inline void
214 init_bb_predicate (basic_block bb)
216 bb->aux = XNEW (struct bb_predicate_s);
217 set_bb_predicate_gimplified_stmts (bb, NULL);
218 set_bb_predicate (bb, boolean_true_node);
221 /* Release the SSA_NAMEs associated with the predicate of basic block BB,
222 but don't actually free it. */
224 static inline void
225 release_bb_predicate (basic_block bb)
227 gimple_seq stmts = bb_predicate_gimplified_stmts (bb);
228 if (stmts)
230 gimple_stmt_iterator i;
232 for (i = gsi_start (stmts); !gsi_end_p (i); gsi_next (&i))
233 free_stmt_operands (cfun, gsi_stmt (i));
234 set_bb_predicate_gimplified_stmts (bb, NULL);
238 /* Free the predicate of basic block BB. */
240 static inline void
241 free_bb_predicate (basic_block bb)
243 if (!bb_has_predicate (bb))
244 return;
246 release_bb_predicate (bb);
247 free (bb->aux);
248 bb->aux = NULL;
251 /* Reinitialize predicate of BB with the true predicate. */
253 static inline void
254 reset_bb_predicate (basic_block bb)
256 if (!bb_has_predicate (bb))
257 init_bb_predicate (bb);
258 else
260 release_bb_predicate (bb);
261 set_bb_predicate (bb, boolean_true_node);
265 /* Returns a new SSA_NAME of type TYPE that is assigned the value of
266 the expression EXPR. Inserts the statement created for this
267 computation before GSI and leaves the iterator GSI at the same
268 statement. */
270 static tree
271 ifc_temp_var (tree type, tree expr, gimple_stmt_iterator *gsi)
273 tree new_name = make_temp_ssa_name (type, NULL, "_ifc_");
274 gimple stmt = gimple_build_assign (new_name, expr);
275 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
276 return new_name;
279 /* Return true when COND is a true predicate. */
281 static inline bool
282 is_true_predicate (tree cond)
284 return (cond == NULL_TREE
285 || cond == boolean_true_node
286 || integer_onep (cond));
289 /* Returns true when BB has a predicate that is not trivial: true or
290 NULL_TREE. */
292 static inline bool
293 is_predicated (basic_block bb)
295 return !is_true_predicate (bb_predicate (bb));
298 /* Parses the predicate COND and returns its comparison code and
299 operands OP0 and OP1. */
301 static enum tree_code
302 parse_predicate (tree cond, tree *op0, tree *op1)
304 gimple s;
306 if (TREE_CODE (cond) == SSA_NAME
307 && is_gimple_assign (s = SSA_NAME_DEF_STMT (cond)))
309 if (TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison)
311 *op0 = gimple_assign_rhs1 (s);
312 *op1 = gimple_assign_rhs2 (s);
313 return gimple_assign_rhs_code (s);
316 else if (gimple_assign_rhs_code (s) == TRUTH_NOT_EXPR)
318 tree op = gimple_assign_rhs1 (s);
319 tree type = TREE_TYPE (op);
320 enum tree_code code = parse_predicate (op, op0, op1);
322 return code == ERROR_MARK ? ERROR_MARK
323 : invert_tree_comparison (code, HONOR_NANS (type));
326 return ERROR_MARK;
329 if (COMPARISON_CLASS_P (cond))
331 *op0 = TREE_OPERAND (cond, 0);
332 *op1 = TREE_OPERAND (cond, 1);
333 return TREE_CODE (cond);
336 return ERROR_MARK;
339 /* Returns the fold of predicate C1 OR C2 at location LOC. */
341 static tree
342 fold_or_predicates (location_t loc, tree c1, tree c2)
344 tree op1a, op1b, op2a, op2b;
345 enum tree_code code1 = parse_predicate (c1, &op1a, &op1b);
346 enum tree_code code2 = parse_predicate (c2, &op2a, &op2b);
348 if (code1 != ERROR_MARK && code2 != ERROR_MARK)
350 tree t = maybe_fold_or_comparisons (code1, op1a, op1b,
351 code2, op2a, op2b);
352 if (t)
353 return t;
356 return fold_build2_loc (loc, TRUTH_OR_EXPR, boolean_type_node, c1, c2);
359 /* Returns true if N is either a constant or a SSA_NAME. */
361 static bool
362 constant_or_ssa_name (tree n)
364 switch (TREE_CODE (n))
366 case SSA_NAME:
367 case INTEGER_CST:
368 case REAL_CST:
369 case COMPLEX_CST:
370 case VECTOR_CST:
371 return true;
372 default:
373 return false;
377 /* Returns either a COND_EXPR or the folded expression if the folded
378 expression is a MIN_EXPR, a MAX_EXPR, an ABS_EXPR,
379 a constant or a SSA_NAME. */
381 static tree
382 fold_build_cond_expr (tree type, tree cond, tree rhs, tree lhs)
384 tree rhs1, lhs1, cond_expr;
386 /* If COND is comparison r != 0 and r has boolean type, convert COND
387 to SSA_NAME to accept by vect bool pattern. */
388 if (TREE_CODE (cond) == NE_EXPR)
390 tree op0 = TREE_OPERAND (cond, 0);
391 tree op1 = TREE_OPERAND (cond, 1);
392 if (TREE_CODE (op0) == SSA_NAME
393 && TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
394 && (integer_zerop (op1)))
395 cond = op0;
397 cond_expr = fold_ternary (COND_EXPR, type, cond,
398 rhs, lhs);
400 if (cond_expr == NULL_TREE)
401 return build3 (COND_EXPR, type, cond, rhs, lhs);
403 STRIP_USELESS_TYPE_CONVERSION (cond_expr);
405 if (constant_or_ssa_name (cond_expr))
406 return cond_expr;
408 if (TREE_CODE (cond_expr) == ABS_EXPR)
410 rhs1 = TREE_OPERAND (cond_expr, 1);
411 STRIP_USELESS_TYPE_CONVERSION (rhs1);
412 if (constant_or_ssa_name (rhs1))
413 return build1 (ABS_EXPR, type, rhs1);
416 if (TREE_CODE (cond_expr) == MIN_EXPR
417 || TREE_CODE (cond_expr) == MAX_EXPR)
419 lhs1 = TREE_OPERAND (cond_expr, 0);
420 STRIP_USELESS_TYPE_CONVERSION (lhs1);
421 rhs1 = TREE_OPERAND (cond_expr, 1);
422 STRIP_USELESS_TYPE_CONVERSION (rhs1);
423 if (constant_or_ssa_name (rhs1)
424 && constant_or_ssa_name (lhs1))
425 return build2 (TREE_CODE (cond_expr), type, lhs1, rhs1);
427 return build3 (COND_EXPR, type, cond, rhs, lhs);
430 /* Add condition NC to the predicate list of basic block BB. LOOP is
431 the loop to be if-converted. Use predicate of cd-equivalent block
432 for join bb if it exists: we call basic blocks bb1 and bb2
433 cd-equivalent if they are executed under the same condition. */
435 static inline void
436 add_to_predicate_list (struct loop *loop, basic_block bb, tree nc)
438 tree bc, *tp;
439 basic_block dom_bb;
441 if (is_true_predicate (nc))
442 return;
444 /* If dominance tells us this basic block is always executed,
445 don't record any predicates for it. */
446 if (dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
447 return;
449 dom_bb = get_immediate_dominator (CDI_DOMINATORS, bb);
450 /* We use notion of cd equivalence to get simpler predicate for
451 join block, e.g. if join block has 2 predecessors with predicates
452 p1 & p2 and p1 & !p2, we'd like to get p1 for it instead of
453 p1 & p2 | p1 & !p2. */
454 if (dom_bb != loop->header
455 && get_immediate_dominator (CDI_POST_DOMINATORS, dom_bb) == bb)
457 gcc_assert (flow_bb_inside_loop_p (loop, dom_bb));
458 bc = bb_predicate (dom_bb);
459 if (!is_true_predicate (bc))
460 set_bb_predicate (bb, bc);
461 else
462 gcc_assert (is_true_predicate (bb_predicate (bb)));
463 if (dump_file && (dump_flags & TDF_DETAILS))
464 fprintf (dump_file, "Use predicate of bb#%d for bb#%d\n",
465 dom_bb->index, bb->index);
466 return;
469 if (!is_predicated (bb))
470 bc = nc;
471 else
473 bc = bb_predicate (bb);
474 bc = fold_or_predicates (EXPR_LOCATION (bc), nc, bc);
475 if (is_true_predicate (bc))
477 reset_bb_predicate (bb);
478 return;
482 /* Allow a TRUTH_NOT_EXPR around the main predicate. */
483 if (TREE_CODE (bc) == TRUTH_NOT_EXPR)
484 tp = &TREE_OPERAND (bc, 0);
485 else
486 tp = &bc;
487 if (!is_gimple_condexpr (*tp))
489 gimple_seq stmts;
490 *tp = force_gimple_operand_1 (*tp, &stmts, is_gimple_condexpr, NULL_TREE);
491 add_bb_predicate_gimplified_stmts (bb, stmts);
493 set_bb_predicate (bb, bc);
496 /* Add the condition COND to the previous condition PREV_COND, and add
497 this to the predicate list of the destination of edge E. LOOP is
498 the loop to be if-converted. */
500 static void
501 add_to_dst_predicate_list (struct loop *loop, edge e,
502 tree prev_cond, tree cond)
504 if (!flow_bb_inside_loop_p (loop, e->dest))
505 return;
507 if (!is_true_predicate (prev_cond))
508 cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
509 prev_cond, cond);
511 if (!dominated_by_p (CDI_DOMINATORS, loop->latch, e->dest))
512 add_to_predicate_list (loop, e->dest, cond);
515 /* Return true if one of the successor edges of BB exits LOOP. */
517 static bool
518 bb_with_exit_edge_p (struct loop *loop, basic_block bb)
520 edge e;
521 edge_iterator ei;
523 FOR_EACH_EDGE (e, ei, bb->succs)
524 if (loop_exit_edge_p (loop, e))
525 return true;
527 return false;
530 /* Return true when PHI is if-convertible. PHI is part of loop LOOP
531 and it belongs to basic block BB.
533 PHI is not if-convertible if:
534 - it has more than 2 arguments.
536 When the flag_tree_loop_if_convert_stores is not set, PHI is not
537 if-convertible if:
538 - a virtual PHI is immediately used in another PHI node,
539 - there is a virtual PHI in a BB other than the loop->header.
540 When the aggressive_if_conv is set, PHI can have more than
541 two arguments. */
543 static bool
544 if_convertible_phi_p (struct loop *loop, basic_block bb, gphi *phi,
545 bool any_mask_load_store)
547 if (dump_file && (dump_flags & TDF_DETAILS))
549 fprintf (dump_file, "-------------------------\n");
550 print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
553 if (bb != loop->header)
555 if (gimple_phi_num_args (phi) != 2
556 && !aggressive_if_conv)
558 if (dump_file && (dump_flags & TDF_DETAILS))
559 fprintf (dump_file, "More than two phi node args.\n");
560 return false;
564 if (flag_tree_loop_if_convert_stores || any_mask_load_store)
565 return true;
567 /* When the flag_tree_loop_if_convert_stores is not set, check
568 that there are no memory writes in the branches of the loop to be
569 if-converted. */
570 if (virtual_operand_p (gimple_phi_result (phi)))
572 imm_use_iterator imm_iter;
573 use_operand_p use_p;
575 if (bb != loop->header)
577 if (dump_file && (dump_flags & TDF_DETAILS))
578 fprintf (dump_file, "Virtual phi not on loop->header.\n");
579 return false;
582 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, gimple_phi_result (phi))
584 if (gimple_code (USE_STMT (use_p)) == GIMPLE_PHI
585 && USE_STMT (use_p) != (gimple) phi)
587 if (dump_file && (dump_flags & TDF_DETAILS))
588 fprintf (dump_file, "Difficult to handle this virtual phi.\n");
589 return false;
594 return true;
597 /* Records the status of a data reference. This struct is attached to
598 each DR->aux field. */
600 struct ifc_dr {
601 /* -1 when not initialized, 0 when false, 1 when true. */
602 int written_at_least_once;
604 /* -1 when not initialized, 0 when false, 1 when true. */
605 int rw_unconditionally;
608 #define IFC_DR(DR) ((struct ifc_dr *) (DR)->aux)
609 #define DR_WRITTEN_AT_LEAST_ONCE(DR) (IFC_DR (DR)->written_at_least_once)
610 #define DR_RW_UNCONDITIONALLY(DR) (IFC_DR (DR)->rw_unconditionally)
612 /* Returns true when the memory references of STMT are read or written
613 unconditionally. In other words, this function returns true when
614 for every data reference A in STMT there exist other accesses to
615 a data reference with the same base with predicates that add up (OR-up) to
616 the true predicate: this ensures that the data reference A is touched
617 (read or written) on every iteration of the if-converted loop. */
619 static bool
620 memrefs_read_or_written_unconditionally (gimple stmt,
621 vec<data_reference_p> drs)
623 int i, j;
624 data_reference_p a, b;
625 tree ca = bb_predicate (gimple_bb (stmt));
627 for (i = 0; drs.iterate (i, &a); i++)
628 if (DR_STMT (a) == stmt)
630 bool found = false;
631 int x = DR_RW_UNCONDITIONALLY (a);
633 if (x == 0)
634 return false;
636 if (x == 1)
637 continue;
639 for (j = 0; drs.iterate (j, &b); j++)
641 tree ref_base_a = DR_REF (a);
642 tree ref_base_b = DR_REF (b);
644 if (DR_STMT (b) == stmt)
645 continue;
647 while (TREE_CODE (ref_base_a) == COMPONENT_REF
648 || TREE_CODE (ref_base_a) == IMAGPART_EXPR
649 || TREE_CODE (ref_base_a) == REALPART_EXPR)
650 ref_base_a = TREE_OPERAND (ref_base_a, 0);
652 while (TREE_CODE (ref_base_b) == COMPONENT_REF
653 || TREE_CODE (ref_base_b) == IMAGPART_EXPR
654 || TREE_CODE (ref_base_b) == REALPART_EXPR)
655 ref_base_b = TREE_OPERAND (ref_base_b, 0);
657 if (!operand_equal_p (ref_base_a, ref_base_b, 0))
659 tree cb = bb_predicate (gimple_bb (DR_STMT (b)));
661 if (DR_RW_UNCONDITIONALLY (b) == 1
662 || is_true_predicate (cb)
663 || is_true_predicate (ca
664 = fold_or_predicates (EXPR_LOCATION (cb), ca, cb)))
666 DR_RW_UNCONDITIONALLY (a) = 1;
667 DR_RW_UNCONDITIONALLY (b) = 1;
668 found = true;
669 break;
674 if (!found)
676 DR_RW_UNCONDITIONALLY (a) = 0;
677 return false;
681 return true;
684 /* Returns true when the memory references of STMT are unconditionally
685 written. In other words, this function returns true when for every
686 data reference A written in STMT, there exist other writes to the
687 same data reference with predicates that add up (OR-up) to the true
688 predicate: this ensures that the data reference A is written on
689 every iteration of the if-converted loop. */
691 static bool
692 write_memrefs_written_at_least_once (gimple stmt,
693 vec<data_reference_p> drs)
695 int i, j;
696 data_reference_p a, b;
697 tree ca = bb_predicate (gimple_bb (stmt));
699 for (i = 0; drs.iterate (i, &a); i++)
700 if (DR_STMT (a) == stmt
701 && DR_IS_WRITE (a))
703 bool found = false;
704 int x = DR_WRITTEN_AT_LEAST_ONCE (a);
706 if (x == 0)
707 return false;
709 if (x == 1)
710 continue;
712 for (j = 0; drs.iterate (j, &b); j++)
713 if (DR_STMT (b) != stmt
714 && DR_IS_WRITE (b)
715 && same_data_refs_base_objects (a, b))
717 tree cb = bb_predicate (gimple_bb (DR_STMT (b)));
719 if (DR_WRITTEN_AT_LEAST_ONCE (b) == 1
720 || is_true_predicate (cb)
721 || is_true_predicate (ca = fold_or_predicates (EXPR_LOCATION (cb),
722 ca, cb)))
724 DR_WRITTEN_AT_LEAST_ONCE (a) = 1;
725 DR_WRITTEN_AT_LEAST_ONCE (b) = 1;
726 found = true;
727 break;
731 if (!found)
733 DR_WRITTEN_AT_LEAST_ONCE (a) = 0;
734 return false;
738 return true;
741 /* Return true when the memory references of STMT won't trap in the
742 if-converted code. There are two things that we have to check for:
744 - writes to memory occur to writable memory: if-conversion of
745 memory writes transforms the conditional memory writes into
746 unconditional writes, i.e. "if (cond) A[i] = foo" is transformed
747 into "A[i] = cond ? foo : A[i]", and as the write to memory may not
748 be executed at all in the original code, it may be a readonly
749 memory. To check that A is not const-qualified, we check that
750 there exists at least an unconditional write to A in the current
751 function.
753 - reads or writes to memory are valid memory accesses for every
754 iteration. To check that the memory accesses are correctly formed
755 and that we are allowed to read and write in these locations, we
756 check that the memory accesses to be if-converted occur at every
757 iteration unconditionally. */
759 static bool
760 ifcvt_memrefs_wont_trap (gimple stmt, vec<data_reference_p> refs)
762 return write_memrefs_written_at_least_once (stmt, refs)
763 && memrefs_read_or_written_unconditionally (stmt, refs);
766 /* Wrapper around gimple_could_trap_p refined for the needs of the
767 if-conversion. Try to prove that the memory accesses of STMT could
768 not trap in the innermost loop containing STMT. */
770 static bool
771 ifcvt_could_trap_p (gimple stmt, vec<data_reference_p> refs)
773 if (gimple_vuse (stmt)
774 && !gimple_could_trap_p_1 (stmt, false, false)
775 && ifcvt_memrefs_wont_trap (stmt, refs))
776 return false;
778 return gimple_could_trap_p (stmt);
781 /* Return true if STMT could be converted into a masked load or store
782 (conditional load or store based on a mask computed from bb predicate). */
784 static bool
785 ifcvt_can_use_mask_load_store (gimple stmt)
787 tree lhs, ref;
788 machine_mode mode;
789 basic_block bb = gimple_bb (stmt);
790 bool is_load;
792 if (!(flag_tree_loop_vectorize || bb->loop_father->force_vectorize)
793 || bb->loop_father->dont_vectorize
794 || !gimple_assign_single_p (stmt)
795 || gimple_has_volatile_ops (stmt))
796 return false;
798 /* Check whether this is a load or store. */
799 lhs = gimple_assign_lhs (stmt);
800 if (gimple_store_p (stmt))
802 if (!is_gimple_val (gimple_assign_rhs1 (stmt)))
803 return false;
804 is_load = false;
805 ref = lhs;
807 else if (gimple_assign_load_p (stmt))
809 is_load = true;
810 ref = gimple_assign_rhs1 (stmt);
812 else
813 return false;
815 if (may_be_nonaddressable_p (ref))
816 return false;
818 /* Mask should be integer mode of the same size as the load/store
819 mode. */
820 mode = TYPE_MODE (TREE_TYPE (lhs));
821 if (int_mode_for_mode (mode) == BLKmode
822 || VECTOR_MODE_P (mode))
823 return false;
825 if (can_vec_mask_load_store_p (mode, is_load))
826 return true;
828 return false;
831 /* Return true when STMT is if-convertible.
833 GIMPLE_ASSIGN statement is not if-convertible if,
834 - it is not movable,
835 - it could trap,
836 - LHS is not var decl. */
838 static bool
839 if_convertible_gimple_assign_stmt_p (gimple stmt,
840 vec<data_reference_p> refs,
841 bool *any_mask_load_store)
843 tree lhs = gimple_assign_lhs (stmt);
844 basic_block bb;
846 if (dump_file && (dump_flags & TDF_DETAILS))
848 fprintf (dump_file, "-------------------------\n");
849 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
852 if (!is_gimple_reg_type (TREE_TYPE (lhs)))
853 return false;
855 /* Some of these constrains might be too conservative. */
856 if (stmt_ends_bb_p (stmt)
857 || gimple_has_volatile_ops (stmt)
858 || (TREE_CODE (lhs) == SSA_NAME
859 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
860 || gimple_has_side_effects (stmt))
862 if (dump_file && (dump_flags & TDF_DETAILS))
863 fprintf (dump_file, "stmt not suitable for ifcvt\n");
864 return false;
867 /* tree-into-ssa.c uses GF_PLF_1, so avoid it, because
868 in between if_convertible_loop_p and combine_blocks
869 we can perform loop versioning. */
870 gimple_set_plf (stmt, GF_PLF_2, false);
872 if (flag_tree_loop_if_convert_stores)
874 if (ifcvt_could_trap_p (stmt, refs))
876 if (ifcvt_can_use_mask_load_store (stmt))
878 gimple_set_plf (stmt, GF_PLF_2, true);
879 *any_mask_load_store = true;
880 return true;
882 if (dump_file && (dump_flags & TDF_DETAILS))
883 fprintf (dump_file, "tree could trap...\n");
884 return false;
886 return true;
889 if (gimple_assign_rhs_could_trap_p (stmt))
891 if (ifcvt_can_use_mask_load_store (stmt))
893 gimple_set_plf (stmt, GF_PLF_2, true);
894 *any_mask_load_store = true;
895 return true;
897 if (dump_file && (dump_flags & TDF_DETAILS))
898 fprintf (dump_file, "tree could trap...\n");
899 return false;
902 bb = gimple_bb (stmt);
904 if (TREE_CODE (lhs) != SSA_NAME
905 && bb != bb->loop_father->header
906 && !bb_with_exit_edge_p (bb->loop_father, bb))
908 if (ifcvt_can_use_mask_load_store (stmt))
910 gimple_set_plf (stmt, GF_PLF_2, true);
911 *any_mask_load_store = true;
912 return true;
914 if (dump_file && (dump_flags & TDF_DETAILS))
916 fprintf (dump_file, "LHS is not var\n");
917 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
919 return false;
922 return true;
925 /* Return true when STMT is if-convertible.
927 A statement is if-convertible if:
928 - it is an if-convertible GIMPLE_ASSIGN,
929 - it is a GIMPLE_LABEL or a GIMPLE_COND,
930 - it is builtins call. */
932 static bool
933 if_convertible_stmt_p (gimple stmt, vec<data_reference_p> refs,
934 bool *any_mask_load_store)
936 switch (gimple_code (stmt))
938 case GIMPLE_LABEL:
939 case GIMPLE_DEBUG:
940 case GIMPLE_COND:
941 return true;
943 case GIMPLE_ASSIGN:
944 return if_convertible_gimple_assign_stmt_p (stmt, refs,
945 any_mask_load_store);
947 case GIMPLE_CALL:
949 tree fndecl = gimple_call_fndecl (stmt);
950 if (fndecl)
952 int flags = gimple_call_flags (stmt);
953 if ((flags & ECF_CONST)
954 && !(flags & ECF_LOOPING_CONST_OR_PURE)
955 /* We can only vectorize some builtins at the moment,
956 so restrict if-conversion to those. */
957 && DECL_BUILT_IN (fndecl))
958 return true;
960 return false;
963 default:
964 /* Don't know what to do with 'em so don't do anything. */
965 if (dump_file && (dump_flags & TDF_DETAILS))
967 fprintf (dump_file, "don't know what to do\n");
968 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
970 return false;
971 break;
974 return true;
977 /* Assumes that BB has more than 1 predecessors.
978 Returns false if at least one successor is not on critical edge
979 and true otherwise. */
981 static inline bool
982 all_preds_critical_p (basic_block bb)
984 edge e;
985 edge_iterator ei;
987 FOR_EACH_EDGE (e, ei, bb->preds)
988 if (EDGE_COUNT (e->src->succs) == 1)
989 return false;
990 return true;
993 /* Returns true if at least one successor in on critical edge. */
994 static inline bool
995 has_pred_critical_p (basic_block bb)
997 edge e;
998 edge_iterator ei;
1000 FOR_EACH_EDGE (e, ei, bb->preds)
1001 if (EDGE_COUNT (e->src->succs) > 1)
1002 return true;
1003 return false;
1006 /* Return true when BB is if-convertible. This routine does not check
1007 basic block's statements and phis.
1009 A basic block is not if-convertible if:
1010 - it is non-empty and it is after the exit block (in BFS order),
1011 - it is after the exit block but before the latch,
1012 - its edges are not normal.
1014 Last restriction is valid if aggressive_if_conv is false.
1016 EXIT_BB is the basic block containing the exit of the LOOP. BB is
1017 inside LOOP. */
1019 static bool
1020 if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb)
1022 edge e;
1023 edge_iterator ei;
1025 if (dump_file && (dump_flags & TDF_DETAILS))
1026 fprintf (dump_file, "----------[%d]-------------\n", bb->index);
1028 if (EDGE_COUNT (bb->succs) > 2)
1029 return false;
1031 if (EDGE_COUNT (bb->preds) > 2
1032 && !aggressive_if_conv)
1033 return false;
1035 if (exit_bb)
1037 if (bb != loop->latch)
1039 if (dump_file && (dump_flags & TDF_DETAILS))
1040 fprintf (dump_file, "basic block after exit bb but before latch\n");
1041 return false;
1043 else if (!empty_block_p (bb))
1045 if (dump_file && (dump_flags & TDF_DETAILS))
1046 fprintf (dump_file, "non empty basic block after exit bb\n");
1047 return false;
1049 else if (bb == loop->latch
1050 && bb != exit_bb
1051 && !dominated_by_p (CDI_DOMINATORS, bb, exit_bb))
1053 if (dump_file && (dump_flags & TDF_DETAILS))
1054 fprintf (dump_file, "latch is not dominated by exit_block\n");
1055 return false;
1059 /* Be less adventurous and handle only normal edges. */
1060 FOR_EACH_EDGE (e, ei, bb->succs)
1061 if (e->flags & (EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP))
1063 if (dump_file && (dump_flags & TDF_DETAILS))
1064 fprintf (dump_file, "Difficult to handle edges\n");
1065 return false;
1068 /* At least one incoming edge has to be non-critical as otherwise edge
1069 predicates are not equal to basic-block predicates of the edge
1070 source. This check is skipped if aggressive_if_conv is true. */
1071 if (!aggressive_if_conv
1072 && EDGE_COUNT (bb->preds) > 1
1073 && bb != loop->header
1074 && all_preds_critical_p (bb))
1076 if (dump_file && (dump_flags & TDF_DETAILS))
1077 fprintf (dump_file, "only critical predecessors\n");
1078 return false;
1081 return true;
1084 /* Return true when all predecessor blocks of BB are visited. The
1085 VISITED bitmap keeps track of the visited blocks. */
1087 static bool
1088 pred_blocks_visited_p (basic_block bb, bitmap *visited)
1090 edge e;
1091 edge_iterator ei;
1092 FOR_EACH_EDGE (e, ei, bb->preds)
1093 if (!bitmap_bit_p (*visited, e->src->index))
1094 return false;
1096 return true;
1099 /* Get body of a LOOP in suitable order for if-conversion. It is
1100 caller's responsibility to deallocate basic block list.
1101 If-conversion suitable order is, breadth first sort (BFS) order
1102 with an additional constraint: select a block only if all its
1103 predecessors are already selected. */
1105 static basic_block *
1106 get_loop_body_in_if_conv_order (const struct loop *loop)
1108 basic_block *blocks, *blocks_in_bfs_order;
1109 basic_block bb;
1110 bitmap visited;
1111 unsigned int index = 0;
1112 unsigned int visited_count = 0;
1114 gcc_assert (loop->num_nodes);
1115 gcc_assert (loop->latch != EXIT_BLOCK_PTR_FOR_FN (cfun));
1117 blocks = XCNEWVEC (basic_block, loop->num_nodes);
1118 visited = BITMAP_ALLOC (NULL);
1120 blocks_in_bfs_order = get_loop_body_in_bfs_order (loop);
1122 index = 0;
1123 while (index < loop->num_nodes)
1125 bb = blocks_in_bfs_order [index];
1127 if (bb->flags & BB_IRREDUCIBLE_LOOP)
1129 free (blocks_in_bfs_order);
1130 BITMAP_FREE (visited);
1131 free (blocks);
1132 return NULL;
1135 if (!bitmap_bit_p (visited, bb->index))
1137 if (pred_blocks_visited_p (bb, &visited)
1138 || bb == loop->header)
1140 /* This block is now visited. */
1141 bitmap_set_bit (visited, bb->index);
1142 blocks[visited_count++] = bb;
1146 index++;
1148 if (index == loop->num_nodes
1149 && visited_count != loop->num_nodes)
1150 /* Not done yet. */
1151 index = 0;
1153 free (blocks_in_bfs_order);
1154 BITMAP_FREE (visited);
1155 return blocks;
1158 /* Returns true when the analysis of the predicates for all the basic
1159 blocks in LOOP succeeded.
1161 predicate_bbs first allocates the predicates of the basic blocks.
1162 These fields are then initialized with the tree expressions
1163 representing the predicates under which a basic block is executed
1164 in the LOOP. As the loop->header is executed at each iteration, it
1165 has the "true" predicate. Other statements executed under a
1166 condition are predicated with that condition, for example
1168 | if (x)
1169 | S1;
1170 | else
1171 | S2;
1173 S1 will be predicated with "x", and
1174 S2 will be predicated with "!x". */
1176 static void
1177 predicate_bbs (loop_p loop)
1179 unsigned int i;
1181 for (i = 0; i < loop->num_nodes; i++)
1182 init_bb_predicate (ifc_bbs[i]);
1184 for (i = 0; i < loop->num_nodes; i++)
1186 basic_block bb = ifc_bbs[i];
1187 tree cond;
1188 gimple stmt;
1190 /* The loop latch and loop exit block are always executed and
1191 have no extra conditions to be processed: skip them. */
1192 if (bb == loop->latch
1193 || bb_with_exit_edge_p (loop, bb))
1195 reset_bb_predicate (bb);
1196 continue;
1199 cond = bb_predicate (bb);
1200 stmt = last_stmt (bb);
1201 if (stmt && gimple_code (stmt) == GIMPLE_COND)
1203 tree c2;
1204 edge true_edge, false_edge;
1205 location_t loc = gimple_location (stmt);
1206 tree c = build2_loc (loc, gimple_cond_code (stmt),
1207 boolean_type_node,
1208 gimple_cond_lhs (stmt),
1209 gimple_cond_rhs (stmt));
1211 /* Add new condition into destination's predicate list. */
1212 extract_true_false_edges_from_block (gimple_bb (stmt),
1213 &true_edge, &false_edge);
1215 /* If C is true, then TRUE_EDGE is taken. */
1216 add_to_dst_predicate_list (loop, true_edge, unshare_expr (cond),
1217 unshare_expr (c));
1219 /* If C is false, then FALSE_EDGE is taken. */
1220 c2 = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node,
1221 unshare_expr (c));
1222 add_to_dst_predicate_list (loop, false_edge,
1223 unshare_expr (cond), c2);
1225 cond = NULL_TREE;
1228 /* If current bb has only one successor, then consider it as an
1229 unconditional goto. */
1230 if (single_succ_p (bb))
1232 basic_block bb_n = single_succ (bb);
1234 /* The successor bb inherits the predicate of its
1235 predecessor. If there is no predicate in the predecessor
1236 bb, then consider the successor bb as always executed. */
1237 if (cond == NULL_TREE)
1238 cond = boolean_true_node;
1240 add_to_predicate_list (loop, bb_n, cond);
1244 /* The loop header is always executed. */
1245 reset_bb_predicate (loop->header);
1246 gcc_assert (bb_predicate_gimplified_stmts (loop->header) == NULL
1247 && bb_predicate_gimplified_stmts (loop->latch) == NULL);
1250 /* Return true when LOOP is if-convertible. This is a helper function
1251 for if_convertible_loop_p. REFS and DDRS are initialized and freed
1252 in if_convertible_loop_p. */
1254 static bool
1255 if_convertible_loop_p_1 (struct loop *loop,
1256 vec<loop_p> *loop_nest,
1257 vec<data_reference_p> *refs,
1258 vec<ddr_p> *ddrs, bool *any_mask_load_store)
1260 bool res;
1261 unsigned int i;
1262 basic_block exit_bb = NULL;
1264 /* Don't if-convert the loop when the data dependences cannot be
1265 computed: the loop won't be vectorized in that case. */
1266 res = compute_data_dependences_for_loop (loop, true, loop_nest, refs, ddrs);
1267 if (!res)
1268 return false;
1270 calculate_dominance_info (CDI_DOMINATORS);
1271 calculate_dominance_info (CDI_POST_DOMINATORS);
1273 /* Allow statements that can be handled during if-conversion. */
1274 ifc_bbs = get_loop_body_in_if_conv_order (loop);
1275 if (!ifc_bbs)
1277 if (dump_file && (dump_flags & TDF_DETAILS))
1278 fprintf (dump_file, "Irreducible loop\n");
1279 return false;
1282 for (i = 0; i < loop->num_nodes; i++)
1284 basic_block bb = ifc_bbs[i];
1286 if (!if_convertible_bb_p (loop, bb, exit_bb))
1287 return false;
1289 if (bb_with_exit_edge_p (loop, bb))
1290 exit_bb = bb;
1293 for (i = 0; i < loop->num_nodes; i++)
1295 basic_block bb = ifc_bbs[i];
1296 gimple_stmt_iterator gsi;
1298 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1299 switch (gimple_code (gsi_stmt (gsi)))
1301 case GIMPLE_LABEL:
1302 case GIMPLE_ASSIGN:
1303 case GIMPLE_CALL:
1304 case GIMPLE_DEBUG:
1305 case GIMPLE_COND:
1306 break;
1307 default:
1308 return false;
1312 if (flag_tree_loop_if_convert_stores)
1314 data_reference_p dr;
1316 for (i = 0; refs->iterate (i, &dr); i++)
1318 dr->aux = XNEW (struct ifc_dr);
1319 DR_WRITTEN_AT_LEAST_ONCE (dr) = -1;
1320 DR_RW_UNCONDITIONALLY (dr) = -1;
1322 predicate_bbs (loop);
1325 for (i = 0; i < loop->num_nodes; i++)
1327 basic_block bb = ifc_bbs[i];
1328 gimple_stmt_iterator itr;
1330 /* Check the if-convertibility of statements in predicated BBs. */
1331 if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
1332 for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr))
1333 if (!if_convertible_stmt_p (gsi_stmt (itr), *refs,
1334 any_mask_load_store))
1335 return false;
1338 if (flag_tree_loop_if_convert_stores)
1339 for (i = 0; i < loop->num_nodes; i++)
1340 free_bb_predicate (ifc_bbs[i]);
1342 /* Checking PHIs needs to be done after stmts, as the fact whether there
1343 are any masked loads or stores affects the tests. */
1344 for (i = 0; i < loop->num_nodes; i++)
1346 basic_block bb = ifc_bbs[i];
1347 gphi_iterator itr;
1349 for (itr = gsi_start_phis (bb); !gsi_end_p (itr); gsi_next (&itr))
1350 if (!if_convertible_phi_p (loop, bb, itr.phi (),
1351 *any_mask_load_store))
1352 return false;
1355 if (dump_file)
1356 fprintf (dump_file, "Applying if-conversion\n");
1358 return true;
1361 /* Return true when LOOP is if-convertible.
1362 LOOP is if-convertible if:
1363 - it is innermost,
1364 - it has two or more basic blocks,
1365 - it has only one exit,
1366 - loop header is not the exit edge,
1367 - if its basic blocks and phi nodes are if convertible. */
1369 static bool
1370 if_convertible_loop_p (struct loop *loop, bool *any_mask_load_store)
1372 edge e;
1373 edge_iterator ei;
1374 bool res = false;
1375 vec<data_reference_p> refs;
1376 vec<ddr_p> ddrs;
1378 /* Handle only innermost loop. */
1379 if (!loop || loop->inner)
1381 if (dump_file && (dump_flags & TDF_DETAILS))
1382 fprintf (dump_file, "not innermost loop\n");
1383 return false;
1386 /* If only one block, no need for if-conversion. */
1387 if (loop->num_nodes <= 2)
1389 if (dump_file && (dump_flags & TDF_DETAILS))
1390 fprintf (dump_file, "less than 2 basic blocks\n");
1391 return false;
1394 /* More than one loop exit is too much to handle. */
1395 if (!single_exit (loop))
1397 if (dump_file && (dump_flags & TDF_DETAILS))
1398 fprintf (dump_file, "multiple exits\n");
1399 return false;
1402 /* If one of the loop header's edge is an exit edge then do not
1403 apply if-conversion. */
1404 FOR_EACH_EDGE (e, ei, loop->header->succs)
1405 if (loop_exit_edge_p (loop, e))
1406 return false;
1408 refs.create (5);
1409 ddrs.create (25);
1410 auto_vec<loop_p, 3> loop_nest;
1411 res = if_convertible_loop_p_1 (loop, &loop_nest, &refs, &ddrs,
1412 any_mask_load_store);
1414 if (flag_tree_loop_if_convert_stores)
1416 data_reference_p dr;
1417 unsigned int i;
1419 for (i = 0; refs.iterate (i, &dr); i++)
1420 free (dr->aux);
1423 free_data_refs (refs);
1424 free_dependence_relations (ddrs);
1425 return res;
1428 /* Returns true if def-stmt for phi argument ARG is simple increment/decrement
1429 which is in predicated basic block.
1430 In fact, the following PHI pattern is searching:
1431 loop-header:
1432 reduc_1 = PHI <..., reduc_2>
1434 if (...)
1435 reduc_3 = ...
1436 reduc_2 = PHI <reduc_1, reduc_3>
1438 ARG_0 and ARG_1 are correspondent PHI arguments.
1439 REDUC, OP0 and OP1 contain reduction stmt and its operands.
1440 EXTENDED is true if PHI has > 2 arguments. */
1442 static bool
1443 is_cond_scalar_reduction (gimple phi, gimple *reduc, tree arg_0, tree arg_1,
1444 tree *op0, tree *op1, bool extended)
1446 tree lhs, r_op1, r_op2;
1447 gimple stmt;
1448 gimple header_phi = NULL;
1449 enum tree_code reduction_op;
1450 basic_block bb = gimple_bb (phi);
1451 struct loop *loop = bb->loop_father;
1452 edge latch_e = loop_latch_edge (loop);
1453 imm_use_iterator imm_iter;
1454 use_operand_p use_p;
1455 edge e;
1456 edge_iterator ei;
1457 bool result = false;
1458 if (TREE_CODE (arg_0) != SSA_NAME || TREE_CODE (arg_1) != SSA_NAME)
1459 return false;
1461 if (!extended && gimple_code (SSA_NAME_DEF_STMT (arg_0)) == GIMPLE_PHI)
1463 lhs = arg_1;
1464 header_phi = SSA_NAME_DEF_STMT (arg_0);
1465 stmt = SSA_NAME_DEF_STMT (arg_1);
1467 else if (gimple_code (SSA_NAME_DEF_STMT (arg_1)) == GIMPLE_PHI)
1469 lhs = arg_0;
1470 header_phi = SSA_NAME_DEF_STMT (arg_1);
1471 stmt = SSA_NAME_DEF_STMT (arg_0);
1473 else
1474 return false;
1475 if (gimple_bb (header_phi) != loop->header)
1476 return false;
1478 if (PHI_ARG_DEF_FROM_EDGE (header_phi, latch_e) != PHI_RESULT (phi))
1479 return false;
1481 if (gimple_code (stmt) != GIMPLE_ASSIGN
1482 || gimple_has_volatile_ops (stmt))
1483 return false;
1485 if (!flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
1486 return false;
1488 if (!is_predicated (gimple_bb (stmt)))
1489 return false;
1491 /* Check that stmt-block is predecessor of phi-block. */
1492 FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
1493 if (e->dest == bb)
1495 result = true;
1496 break;
1498 if (!result)
1499 return false;
1501 if (!has_single_use (lhs))
1502 return false;
1504 reduction_op = gimple_assign_rhs_code (stmt);
1505 if (reduction_op != PLUS_EXPR && reduction_op != MINUS_EXPR)
1506 return false;
1507 r_op1 = gimple_assign_rhs1 (stmt);
1508 r_op2 = gimple_assign_rhs2 (stmt);
1510 /* Make R_OP1 to hold reduction variable. */
1511 if (r_op2 == PHI_RESULT (header_phi)
1512 && reduction_op == PLUS_EXPR)
1513 std::swap (r_op1, r_op2);
1514 else if (r_op1 != PHI_RESULT (header_phi))
1515 return false;
1517 /* Check that R_OP1 is used in reduction stmt or in PHI only. */
1518 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, r_op1)
1520 gimple use_stmt = USE_STMT (use_p);
1521 if (is_gimple_debug (use_stmt))
1522 continue;
1523 if (use_stmt == stmt)
1524 continue;
1525 if (gimple_code (use_stmt) != GIMPLE_PHI)
1526 return false;
1529 *op0 = r_op1; *op1 = r_op2;
1530 *reduc = stmt;
1531 return true;
1534 /* Converts conditional scalar reduction into unconditional form, e.g.
1535 bb_4
1536 if (_5 != 0) goto bb_5 else goto bb_6
1537 end_bb_4
1538 bb_5
1539 res_6 = res_13 + 1;
1540 end_bb_5
1541 bb_6
1542 # res_2 = PHI <res_13(4), res_6(5)>
1543 end_bb_6
1545 will be converted into sequence
1546 _ifc__1 = _5 != 0 ? 1 : 0;
1547 res_2 = res_13 + _ifc__1;
1548 Argument SWAP tells that arguments of conditional expression should be
1549 swapped.
1550 Returns rhs of resulting PHI assignment. */
1552 static tree
1553 convert_scalar_cond_reduction (gimple reduc, gimple_stmt_iterator *gsi,
1554 tree cond, tree op0, tree op1, bool swap)
1556 gimple_stmt_iterator stmt_it;
1557 gimple new_assign;
1558 tree rhs;
1559 tree rhs1 = gimple_assign_rhs1 (reduc);
1560 tree tmp = make_temp_ssa_name (TREE_TYPE (rhs1), NULL, "_ifc_");
1561 tree c;
1562 tree zero = build_zero_cst (TREE_TYPE (rhs1));
1564 if (dump_file && (dump_flags & TDF_DETAILS))
1566 fprintf (dump_file, "Found cond scalar reduction.\n");
1567 print_gimple_stmt (dump_file, reduc, 0, TDF_SLIM);
1570 /* Build cond expression using COND and constant operand
1571 of reduction rhs. */
1572 c = fold_build_cond_expr (TREE_TYPE (rhs1),
1573 unshare_expr (cond),
1574 swap ? zero : op1,
1575 swap ? op1 : zero);
1577 /* Create assignment stmt and insert it at GSI. */
1578 new_assign = gimple_build_assign (tmp, c);
1579 gsi_insert_before (gsi, new_assign, GSI_SAME_STMT);
1580 /* Build rhs for unconditional increment/decrement. */
1581 rhs = fold_build2 (gimple_assign_rhs_code (reduc),
1582 TREE_TYPE (rhs1), op0, tmp);
1584 /* Delete original reduction stmt. */
1585 stmt_it = gsi_for_stmt (reduc);
1586 gsi_remove (&stmt_it, true);
1587 release_defs (reduc);
1588 return rhs;
1591 /* Helpers for PHI arguments hashtable map. */
1593 struct phi_args_hash_traits : default_hashmap_traits
1595 static inline hashval_t hash (tree);
1596 static inline bool equal_keys (tree, tree);
1599 inline hashval_t
1600 phi_args_hash_traits::hash (tree value)
1602 return iterative_hash_expr (value, 0);
1605 inline bool
1606 phi_args_hash_traits::equal_keys (tree value1, tree value2)
1608 return operand_equal_p (value1, value2, 0);
1611 /* Produce condition for all occurrences of ARG in PHI node. */
1613 static tree
1614 gen_phi_arg_condition (gphi *phi, vec<int> *occur,
1615 gimple_stmt_iterator *gsi)
1617 int len;
1618 int i;
1619 tree cond = NULL_TREE;
1620 tree c;
1621 edge e;
1623 len = occur->length ();
1624 gcc_assert (len > 0);
1625 for (i = 0; i < len; i++)
1627 e = gimple_phi_arg_edge (phi, (*occur)[i]);
1628 c = bb_predicate (e->src);
1629 if (is_true_predicate (c))
1630 continue;
1631 c = force_gimple_operand_gsi_1 (gsi, unshare_expr (c),
1632 is_gimple_condexpr, NULL_TREE,
1633 true, GSI_SAME_STMT);
1634 if (cond != NULL_TREE)
1636 /* Must build OR expression. */
1637 cond = fold_or_predicates (EXPR_LOCATION (c), c, cond);
1638 cond = force_gimple_operand_gsi_1 (gsi, unshare_expr (cond),
1639 is_gimple_condexpr, NULL_TREE,
1640 true, GSI_SAME_STMT);
1642 else
1643 cond = c;
1645 gcc_assert (cond != NULL_TREE);
1646 return cond;
1649 /* Replace a scalar PHI node with a COND_EXPR using COND as condition.
1650 This routine can handle PHI nodes with more than two arguments.
1652 For example,
1653 S1: A = PHI <x1(1), x2(5)>
1654 is converted into,
1655 S2: A = cond ? x1 : x2;
1657 The generated code is inserted at GSI that points to the top of
1658 basic block's statement list.
1659 If PHI node has more than two arguments a chain of conditional
1660 expression is produced. */
1663 static void
1664 predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi)
1666 gimple new_stmt = NULL, reduc;
1667 tree rhs, res, arg0, arg1, op0, op1, scev;
1668 tree cond;
1669 unsigned int index0;
1670 unsigned int max, args_len;
1671 edge e;
1672 basic_block bb;
1673 unsigned int i;
1675 res = gimple_phi_result (phi);
1676 if (virtual_operand_p (res))
1677 return;
1679 if ((rhs = degenerate_phi_result (phi))
1680 || ((scev = analyze_scalar_evolution (gimple_bb (phi)->loop_father,
1681 res))
1682 && !chrec_contains_undetermined (scev)
1683 && scev != res
1684 && (rhs = gimple_phi_arg_def (phi, 0))))
1686 if (dump_file && (dump_flags & TDF_DETAILS))
1688 fprintf (dump_file, "Degenerate phi!\n");
1689 print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
1691 new_stmt = gimple_build_assign (res, rhs);
1692 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1693 update_stmt (new_stmt);
1694 return;
1697 bb = gimple_bb (phi);
1698 if (EDGE_COUNT (bb->preds) == 2)
1700 /* Predicate ordinary PHI node with 2 arguments. */
1701 edge first_edge, second_edge;
1702 basic_block true_bb;
1703 first_edge = EDGE_PRED (bb, 0);
1704 second_edge = EDGE_PRED (bb, 1);
1705 cond = bb_predicate (first_edge->src);
1706 if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
1707 std::swap (first_edge, second_edge);
1708 if (EDGE_COUNT (first_edge->src->succs) > 1)
1710 cond = bb_predicate (second_edge->src);
1711 if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
1712 cond = TREE_OPERAND (cond, 0);
1713 else
1714 first_edge = second_edge;
1716 else
1717 cond = bb_predicate (first_edge->src);
1718 /* Gimplify the condition to a valid cond-expr conditonal operand. */
1719 cond = force_gimple_operand_gsi_1 (gsi, unshare_expr (cond),
1720 is_gimple_condexpr, NULL_TREE,
1721 true, GSI_SAME_STMT);
1722 true_bb = first_edge->src;
1723 if (EDGE_PRED (bb, 1)->src == true_bb)
1725 arg0 = gimple_phi_arg_def (phi, 1);
1726 arg1 = gimple_phi_arg_def (phi, 0);
1728 else
1730 arg0 = gimple_phi_arg_def (phi, 0);
1731 arg1 = gimple_phi_arg_def (phi, 1);
1733 if (is_cond_scalar_reduction (phi, &reduc, arg0, arg1,
1734 &op0, &op1, false))
1735 /* Convert reduction stmt into vectorizable form. */
1736 rhs = convert_scalar_cond_reduction (reduc, gsi, cond, op0, op1,
1737 true_bb != gimple_bb (reduc));
1738 else
1739 /* Build new RHS using selected condition and arguments. */
1740 rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond),
1741 arg0, arg1);
1742 new_stmt = gimple_build_assign (res, rhs);
1743 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1744 update_stmt (new_stmt);
1746 if (dump_file && (dump_flags & TDF_DETAILS))
1748 fprintf (dump_file, "new phi replacement stmt\n");
1749 print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
1751 return;
1754 /* Create hashmap for PHI node which contain vector of argument indexes
1755 having the same value. */
1756 bool swap = false;
1757 hash_map<tree, auto_vec<int>, phi_args_hash_traits> phi_arg_map;
1758 unsigned int num_args = gimple_phi_num_args (phi);
1759 int max_ind = -1;
1760 /* Vector of different PHI argument values. */
1761 auto_vec<tree> args (num_args);
1763 /* Compute phi_arg_map. */
1764 for (i = 0; i < num_args; i++)
1766 tree arg;
1768 arg = gimple_phi_arg_def (phi, i);
1769 if (!phi_arg_map.get (arg))
1770 args.quick_push (arg);
1771 phi_arg_map.get_or_insert (arg).safe_push (i);
1774 /* Determine element with max number of occurrences. */
1775 max_ind = -1;
1776 max = 1;
1777 args_len = args.length ();
1778 for (i = 0; i < args_len; i++)
1780 unsigned int len;
1781 if ((len = phi_arg_map.get (args[i])->length ()) > max)
1783 max_ind = (int) i;
1784 max = len;
1788 /* Put element with max number of occurences to the end of ARGS. */
1789 if (max_ind != -1 && max_ind +1 != (int) args_len)
1790 std::swap (args[args_len - 1], args[max_ind]);
1792 /* Handle one special case when number of arguments with different values
1793 is equal 2 and one argument has the only occurrence. Such PHI can be
1794 handled as if would have only 2 arguments. */
1795 if (args_len == 2 && phi_arg_map.get (args[0])->length () == 1)
1797 vec<int> *indexes;
1798 indexes = phi_arg_map.get (args[0]);
1799 index0 = (*indexes)[0];
1800 arg0 = args[0];
1801 arg1 = args[1];
1802 e = gimple_phi_arg_edge (phi, index0);
1803 cond = bb_predicate (e->src);
1804 if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
1806 swap = true;
1807 cond = TREE_OPERAND (cond, 0);
1809 /* Gimplify the condition to a valid cond-expr conditonal operand. */
1810 cond = force_gimple_operand_gsi_1 (gsi, unshare_expr (cond),
1811 is_gimple_condexpr, NULL_TREE,
1812 true, GSI_SAME_STMT);
1813 if (!(is_cond_scalar_reduction (phi, &reduc, arg0 , arg1,
1814 &op0, &op1, true)))
1815 rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond),
1816 swap? arg1 : arg0,
1817 swap? arg0 : arg1);
1818 else
1819 /* Convert reduction stmt into vectorizable form. */
1820 rhs = convert_scalar_cond_reduction (reduc, gsi, cond, op0, op1,
1821 swap);
1822 new_stmt = gimple_build_assign (res, rhs);
1823 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1824 update_stmt (new_stmt);
1826 else
1828 /* Common case. */
1829 vec<int> *indexes;
1830 tree type = TREE_TYPE (gimple_phi_result (phi));
1831 tree lhs;
1832 arg1 = args[1];
1833 for (i = 0; i < args_len; i++)
1835 arg0 = args[i];
1836 indexes = phi_arg_map.get (args[i]);
1837 if (i != args_len - 1)
1838 lhs = make_temp_ssa_name (type, NULL, "_ifc_");
1839 else
1840 lhs = res;
1841 cond = gen_phi_arg_condition (phi, indexes, gsi);
1842 rhs = fold_build_cond_expr (type, unshare_expr (cond),
1843 arg0, arg1);
1844 new_stmt = gimple_build_assign (lhs, rhs);
1845 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1846 update_stmt (new_stmt);
1847 arg1 = lhs;
1851 if (dump_file && (dump_flags & TDF_DETAILS))
1853 fprintf (dump_file, "new extended phi replacement stmt\n");
1854 print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
1858 /* Replaces in LOOP all the scalar phi nodes other than those in the
1859 LOOP->header block with conditional modify expressions. */
1861 static void
1862 predicate_all_scalar_phis (struct loop *loop)
1864 basic_block bb;
1865 unsigned int orig_loop_num_nodes = loop->num_nodes;
1866 unsigned int i;
1868 for (i = 1; i < orig_loop_num_nodes; i++)
1870 gphi *phi;
1871 gimple_stmt_iterator gsi;
1872 gphi_iterator phi_gsi;
1873 bb = ifc_bbs[i];
1875 if (bb == loop->header)
1876 continue;
1878 if (EDGE_COUNT (bb->preds) == 1)
1879 continue;
1881 phi_gsi = gsi_start_phis (bb);
1882 if (gsi_end_p (phi_gsi))
1883 continue;
1885 gsi = gsi_after_labels (bb);
1886 while (!gsi_end_p (phi_gsi))
1888 phi = phi_gsi.phi ();
1889 predicate_scalar_phi (phi, &gsi);
1890 release_phi_node (phi);
1891 gsi_next (&phi_gsi);
1894 set_phi_nodes (bb, NULL);
1898 /* Insert in each basic block of LOOP the statements produced by the
1899 gimplification of the predicates. */
1901 static void
1902 insert_gimplified_predicates (loop_p loop, bool any_mask_load_store)
1904 unsigned int i;
1906 for (i = 0; i < loop->num_nodes; i++)
1908 basic_block bb = ifc_bbs[i];
1909 gimple_seq stmts;
1910 if (!is_predicated (bb))
1911 gcc_assert (bb_predicate_gimplified_stmts (bb) == NULL);
1912 if (!is_predicated (bb))
1914 /* Do not insert statements for a basic block that is not
1915 predicated. Also make sure that the predicate of the
1916 basic block is set to true. */
1917 reset_bb_predicate (bb);
1918 continue;
1921 stmts = bb_predicate_gimplified_stmts (bb);
1922 if (stmts)
1924 if (flag_tree_loop_if_convert_stores
1925 || any_mask_load_store)
1927 /* Insert the predicate of the BB just after the label,
1928 as the if-conversion of memory writes will use this
1929 predicate. */
1930 gimple_stmt_iterator gsi = gsi_after_labels (bb);
1931 gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
1933 else
1935 /* Insert the predicate of the BB at the end of the BB
1936 as this would reduce the register pressure: the only
1937 use of this predicate will be in successor BBs. */
1938 gimple_stmt_iterator gsi = gsi_last_bb (bb);
1940 if (gsi_end_p (gsi)
1941 || stmt_ends_bb_p (gsi_stmt (gsi)))
1942 gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
1943 else
1944 gsi_insert_seq_after (&gsi, stmts, GSI_SAME_STMT);
1947 /* Once the sequence is code generated, set it to NULL. */
1948 set_bb_predicate_gimplified_stmts (bb, NULL);
1953 /* Helper function for predicate_mem_writes. Returns index of existent
1954 mask if it was created for given SIZE and -1 otherwise. */
1956 static int
1957 mask_exists (int size, vec<int> vec)
1959 unsigned int ix;
1960 int v;
1961 FOR_EACH_VEC_ELT (vec, ix, v)
1962 if (v == size)
1963 return (int) ix;
1964 return -1;
1967 /* Predicate each write to memory in LOOP.
1969 This function transforms control flow constructs containing memory
1970 writes of the form:
1972 | for (i = 0; i < N; i++)
1973 | if (cond)
1974 | A[i] = expr;
1976 into the following form that does not contain control flow:
1978 | for (i = 0; i < N; i++)
1979 | A[i] = cond ? expr : A[i];
1981 The original CFG looks like this:
1983 | bb_0
1984 | i = 0
1985 | end_bb_0
1987 | bb_1
1988 | if (i < N) goto bb_5 else goto bb_2
1989 | end_bb_1
1991 | bb_2
1992 | cond = some_computation;
1993 | if (cond) goto bb_3 else goto bb_4
1994 | end_bb_2
1996 | bb_3
1997 | A[i] = expr;
1998 | goto bb_4
1999 | end_bb_3
2001 | bb_4
2002 | goto bb_1
2003 | end_bb_4
2005 insert_gimplified_predicates inserts the computation of the COND
2006 expression at the beginning of the destination basic block:
2008 | bb_0
2009 | i = 0
2010 | end_bb_0
2012 | bb_1
2013 | if (i < N) goto bb_5 else goto bb_2
2014 | end_bb_1
2016 | bb_2
2017 | cond = some_computation;
2018 | if (cond) goto bb_3 else goto bb_4
2019 | end_bb_2
2021 | bb_3
2022 | cond = some_computation;
2023 | A[i] = expr;
2024 | goto bb_4
2025 | end_bb_3
2027 | bb_4
2028 | goto bb_1
2029 | end_bb_4
2031 predicate_mem_writes is then predicating the memory write as follows:
2033 | bb_0
2034 | i = 0
2035 | end_bb_0
2037 | bb_1
2038 | if (i < N) goto bb_5 else goto bb_2
2039 | end_bb_1
2041 | bb_2
2042 | if (cond) goto bb_3 else goto bb_4
2043 | end_bb_2
2045 | bb_3
2046 | cond = some_computation;
2047 | A[i] = cond ? expr : A[i];
2048 | goto bb_4
2049 | end_bb_3
2051 | bb_4
2052 | goto bb_1
2053 | end_bb_4
2055 and finally combine_blocks removes the basic block boundaries making
2056 the loop vectorizable:
2058 | bb_0
2059 | i = 0
2060 | if (i < N) goto bb_5 else goto bb_1
2061 | end_bb_0
2063 | bb_1
2064 | cond = some_computation;
2065 | A[i] = cond ? expr : A[i];
2066 | if (i < N) goto bb_5 else goto bb_4
2067 | end_bb_1
2069 | bb_4
2070 | goto bb_1
2071 | end_bb_4
2074 static void
2075 predicate_mem_writes (loop_p loop)
2077 unsigned int i, orig_loop_num_nodes = loop->num_nodes;
2078 auto_vec<int, 1> vect_sizes;
2079 auto_vec<tree, 1> vect_masks;
2081 for (i = 1; i < orig_loop_num_nodes; i++)
2083 gimple_stmt_iterator gsi;
2084 basic_block bb = ifc_bbs[i];
2085 tree cond = bb_predicate (bb);
2086 bool swap;
2087 gimple stmt;
2088 int index;
2090 if (is_true_predicate (cond))
2091 continue;
2093 swap = false;
2094 if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
2096 swap = true;
2097 cond = TREE_OPERAND (cond, 0);
2100 vect_sizes.truncate (0);
2101 vect_masks.truncate (0);
2103 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2104 if (!gimple_assign_single_p (stmt = gsi_stmt (gsi)))
2105 continue;
2106 else if (gimple_plf (stmt, GF_PLF_2))
2108 tree lhs = gimple_assign_lhs (stmt);
2109 tree rhs = gimple_assign_rhs1 (stmt);
2110 tree ref, addr, ptr, masktype, mask_op0, mask_op1, mask;
2111 gimple new_stmt;
2112 int bitsize = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (lhs)));
2113 ref = TREE_CODE (lhs) == SSA_NAME ? rhs : lhs;
2114 mark_addressable (ref);
2115 addr = force_gimple_operand_gsi (&gsi, build_fold_addr_expr (ref),
2116 true, NULL_TREE, true,
2117 GSI_SAME_STMT);
2118 if (!vect_sizes.is_empty ()
2119 && (index = mask_exists (bitsize, vect_sizes)) != -1)
2120 /* Use created mask. */
2121 mask = vect_masks[index];
2122 else
2124 masktype = build_nonstandard_integer_type (bitsize, 1);
2125 mask_op0 = build_int_cst (masktype, swap ? 0 : -1);
2126 mask_op1 = build_int_cst (masktype, swap ? -1 : 0);
2127 cond = force_gimple_operand_gsi_1 (&gsi, unshare_expr (cond),
2128 is_gimple_condexpr,
2129 NULL_TREE,
2130 true, GSI_SAME_STMT);
2131 mask = fold_build_cond_expr (masktype, unshare_expr (cond),
2132 mask_op0, mask_op1);
2133 mask = ifc_temp_var (masktype, mask, &gsi);
2134 /* Save mask and its size for further use. */
2135 vect_sizes.safe_push (bitsize);
2136 vect_masks.safe_push (mask);
2138 ptr = build_int_cst (reference_alias_ptr_type (ref), 0);
2139 /* Copy points-to info if possible. */
2140 if (TREE_CODE (addr) == SSA_NAME && !SSA_NAME_PTR_INFO (addr))
2141 copy_ref_info (build2 (MEM_REF, TREE_TYPE (ref), addr, ptr),
2142 ref);
2143 if (TREE_CODE (lhs) == SSA_NAME)
2145 new_stmt
2146 = gimple_build_call_internal (IFN_MASK_LOAD, 3, addr,
2147 ptr, mask);
2148 gimple_call_set_lhs (new_stmt, lhs);
2150 else
2151 new_stmt
2152 = gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr,
2153 mask, rhs);
2154 gsi_replace (&gsi, new_stmt, true);
2156 else if (gimple_vdef (stmt))
2158 tree lhs = gimple_assign_lhs (stmt);
2159 tree rhs = gimple_assign_rhs1 (stmt);
2160 tree type = TREE_TYPE (lhs);
2162 lhs = ifc_temp_var (type, unshare_expr (lhs), &gsi);
2163 rhs = ifc_temp_var (type, unshare_expr (rhs), &gsi);
2164 if (swap)
2165 std::swap (lhs, rhs);
2166 cond = force_gimple_operand_gsi_1 (&gsi, unshare_expr (cond),
2167 is_gimple_condexpr, NULL_TREE,
2168 true, GSI_SAME_STMT);
2169 rhs = fold_build_cond_expr (type, unshare_expr (cond), rhs, lhs);
2170 gimple_assign_set_rhs1 (stmt, ifc_temp_var (type, rhs, &gsi));
2171 update_stmt (stmt);
2176 /* Remove all GIMPLE_CONDs and GIMPLE_LABELs of all the basic blocks
2177 other than the exit and latch of the LOOP. Also resets the
2178 GIMPLE_DEBUG information. */
2180 static void
2181 remove_conditions_and_labels (loop_p loop)
2183 gimple_stmt_iterator gsi;
2184 unsigned int i;
2186 for (i = 0; i < loop->num_nodes; i++)
2188 basic_block bb = ifc_bbs[i];
2190 if (bb_with_exit_edge_p (loop, bb)
2191 || bb == loop->latch)
2192 continue;
2194 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
2195 switch (gimple_code (gsi_stmt (gsi)))
2197 case GIMPLE_COND:
2198 case GIMPLE_LABEL:
2199 gsi_remove (&gsi, true);
2200 break;
2202 case GIMPLE_DEBUG:
2203 /* ??? Should there be conditional GIMPLE_DEBUG_BINDs? */
2204 if (gimple_debug_bind_p (gsi_stmt (gsi)))
2206 gimple_debug_bind_reset_value (gsi_stmt (gsi));
2207 update_stmt (gsi_stmt (gsi));
2209 gsi_next (&gsi);
2210 break;
2212 default:
2213 gsi_next (&gsi);
2218 /* Combine all the basic blocks from LOOP into one or two super basic
2219 blocks. Replace PHI nodes with conditional modify expressions. */
2221 static void
2222 combine_blocks (struct loop *loop, bool any_mask_load_store)
2224 basic_block bb, exit_bb, merge_target_bb;
2225 unsigned int orig_loop_num_nodes = loop->num_nodes;
2226 unsigned int i;
2227 edge e;
2228 edge_iterator ei;
2230 predicate_bbs (loop);
2231 remove_conditions_and_labels (loop);
2232 insert_gimplified_predicates (loop, any_mask_load_store);
2233 predicate_all_scalar_phis (loop);
2235 if (flag_tree_loop_if_convert_stores || any_mask_load_store)
2236 predicate_mem_writes (loop);
2238 /* Merge basic blocks: first remove all the edges in the loop,
2239 except for those from the exit block. */
2240 exit_bb = NULL;
2241 for (i = 0; i < orig_loop_num_nodes; i++)
2243 bb = ifc_bbs[i];
2244 free_bb_predicate (bb);
2245 if (bb_with_exit_edge_p (loop, bb))
2247 gcc_assert (exit_bb == NULL);
2248 exit_bb = bb;
2251 gcc_assert (exit_bb != loop->latch);
2253 for (i = 1; i < orig_loop_num_nodes; i++)
2255 bb = ifc_bbs[i];
2257 for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei));)
2259 if (e->src == exit_bb)
2260 ei_next (&ei);
2261 else
2262 remove_edge (e);
2266 if (exit_bb != NULL)
2268 if (exit_bb != loop->header)
2270 /* Connect this node to loop header. */
2271 make_edge (loop->header, exit_bb, EDGE_FALLTHRU);
2272 set_immediate_dominator (CDI_DOMINATORS, exit_bb, loop->header);
2275 /* Redirect non-exit edges to loop->latch. */
2276 FOR_EACH_EDGE (e, ei, exit_bb->succs)
2278 if (!loop_exit_edge_p (loop, e))
2279 redirect_edge_and_branch (e, loop->latch);
2281 set_immediate_dominator (CDI_DOMINATORS, loop->latch, exit_bb);
2283 else
2285 /* If the loop does not have an exit, reconnect header and latch. */
2286 make_edge (loop->header, loop->latch, EDGE_FALLTHRU);
2287 set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header);
2290 merge_target_bb = loop->header;
2291 for (i = 1; i < orig_loop_num_nodes; i++)
2293 gimple_stmt_iterator gsi;
2294 gimple_stmt_iterator last;
2296 bb = ifc_bbs[i];
2298 if (bb == exit_bb || bb == loop->latch)
2299 continue;
2301 /* Make stmts member of loop->header. */
2302 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2303 gimple_set_bb (gsi_stmt (gsi), merge_target_bb);
2305 /* Update stmt list. */
2306 last = gsi_last_bb (merge_target_bb);
2307 gsi_insert_seq_after (&last, bb_seq (bb), GSI_NEW_STMT);
2308 set_bb_seq (bb, NULL);
2310 delete_basic_block (bb);
2313 /* If possible, merge loop header to the block with the exit edge.
2314 This reduces the number of basic blocks to two, to please the
2315 vectorizer that handles only loops with two nodes. */
2316 if (exit_bb
2317 && exit_bb != loop->header
2318 && can_merge_blocks_p (loop->header, exit_bb))
2319 merge_blocks (loop->header, exit_bb);
2321 free (ifc_bbs);
2322 ifc_bbs = NULL;
2325 /* Version LOOP before if-converting it, the original loop
2326 will be then if-converted, the new copy of the loop will not,
2327 and the LOOP_VECTORIZED internal call will be guarding which
2328 loop to execute. The vectorizer pass will fold this
2329 internal call into either true or false. */
2331 static bool
2332 version_loop_for_if_conversion (struct loop *loop)
2334 basic_block cond_bb;
2335 tree cond = make_ssa_name (boolean_type_node);
2336 struct loop *new_loop;
2337 gimple g;
2338 gimple_stmt_iterator gsi;
2340 g = gimple_build_call_internal (IFN_LOOP_VECTORIZED, 2,
2341 build_int_cst (integer_type_node, loop->num),
2342 integer_zero_node);
2343 gimple_call_set_lhs (g, cond);
2345 initialize_original_copy_tables ();
2346 new_loop = loop_version (loop, cond, &cond_bb,
2347 REG_BR_PROB_BASE, REG_BR_PROB_BASE,
2348 REG_BR_PROB_BASE, true);
2349 free_original_copy_tables ();
2350 if (new_loop == NULL)
2351 return false;
2352 new_loop->dont_vectorize = true;
2353 new_loop->force_vectorize = false;
2354 gsi = gsi_last_bb (cond_bb);
2355 gimple_call_set_arg (g, 1, build_int_cst (integer_type_node, new_loop->num));
2356 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2357 update_ssa (TODO_update_ssa);
2358 return true;
2361 /* Performs splitting of critical edges if aggressive_if_conv is true.
2362 Returns false if loop won't be if converted and true otherwise. */
2364 static bool
2365 ifcvt_split_critical_edges (struct loop *loop)
2367 basic_block *body;
2368 basic_block bb;
2369 unsigned int num = loop->num_nodes;
2370 unsigned int i;
2371 gimple stmt;
2372 edge e;
2373 edge_iterator ei;
2375 if (num <= 2)
2376 return false;
2377 if (loop->inner)
2378 return false;
2379 if (!single_exit (loop))
2380 return false;
2382 body = get_loop_body (loop);
2383 for (i = 0; i < num; i++)
2385 bb = body[i];
2386 if (bb == loop->latch
2387 || bb_with_exit_edge_p (loop, bb))
2388 continue;
2389 stmt = last_stmt (bb);
2390 /* Skip basic blocks not ending with conditional branch. */
2391 if (!(stmt && gimple_code (stmt) == GIMPLE_COND))
2392 continue;
2393 FOR_EACH_EDGE (e, ei, bb->succs)
2394 if (EDGE_CRITICAL_P (e) && e->dest->loop_father == loop)
2395 split_edge (e);
2397 free (body);
2398 return true;
2401 /* Assumes that lhs of DEF_STMT have multiple uses.
2402 Delete one use by (1) creation of copy DEF_STMT with
2403 unique lhs; (2) change original use of lhs in one
2404 use statement with newly created lhs. */
2406 static void
2407 ifcvt_split_def_stmt (gimple def_stmt, gimple use_stmt)
2409 tree var;
2410 tree lhs;
2411 gimple copy_stmt;
2412 gimple_stmt_iterator gsi;
2413 use_operand_p use_p;
2414 imm_use_iterator imm_iter;
2416 var = gimple_assign_lhs (def_stmt);
2417 copy_stmt = gimple_copy (def_stmt);
2418 lhs = make_temp_ssa_name (TREE_TYPE (var), NULL, "_ifc_");
2419 gimple_assign_set_lhs (copy_stmt, lhs);
2420 SSA_NAME_DEF_STMT (lhs) = copy_stmt;
2421 /* Insert copy of DEF_STMT. */
2422 gsi = gsi_for_stmt (def_stmt);
2423 gsi_insert_after (&gsi, copy_stmt, GSI_SAME_STMT);
2424 /* Change use of var to lhs in use_stmt. */
2425 if (dump_file && (dump_flags & TDF_DETAILS))
2427 fprintf (dump_file, "Change use of var ");
2428 print_generic_expr (dump_file, var, TDF_SLIM);
2429 fprintf (dump_file, " to ");
2430 print_generic_expr (dump_file, lhs, TDF_SLIM);
2431 fprintf (dump_file, "\n");
2433 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var)
2435 if (USE_STMT (use_p) != use_stmt)
2436 continue;
2437 SET_USE (use_p, lhs);
2438 break;
2442 /* Traverse bool pattern recursively starting from VAR.
2443 Save its def and use statements to defuse_list if VAR does
2444 not have single use. */
2446 static void
2447 ifcvt_walk_pattern_tree (tree var, vec<gimple> *defuse_list,
2448 gimple use_stmt)
2450 tree rhs1, rhs2;
2451 enum tree_code code;
2452 gimple def_stmt;
2454 def_stmt = SSA_NAME_DEF_STMT (var);
2455 if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
2456 return;
2457 if (!has_single_use (var))
2459 /* Put def and use stmts into defuse_list. */
2460 defuse_list->safe_push (def_stmt);
2461 defuse_list->safe_push (use_stmt);
2462 if (dump_file && (dump_flags & TDF_DETAILS))
2464 fprintf (dump_file, "Multiple lhs uses in stmt\n");
2465 print_gimple_stmt (dump_file, def_stmt, 0, TDF_SLIM);
2468 rhs1 = gimple_assign_rhs1 (def_stmt);
2469 code = gimple_assign_rhs_code (def_stmt);
2470 switch (code)
2472 case SSA_NAME:
2473 ifcvt_walk_pattern_tree (rhs1, defuse_list, def_stmt);
2474 break;
2475 CASE_CONVERT:
2476 if ((TYPE_PRECISION (TREE_TYPE (rhs1)) != 1
2477 || !TYPE_UNSIGNED (TREE_TYPE (rhs1)))
2478 && TREE_CODE (TREE_TYPE (rhs1)) != BOOLEAN_TYPE)
2479 break;
2480 ifcvt_walk_pattern_tree (rhs1, defuse_list, def_stmt);
2481 break;
2482 case BIT_NOT_EXPR:
2483 ifcvt_walk_pattern_tree (rhs1, defuse_list, def_stmt);
2484 break;
2485 case BIT_AND_EXPR:
2486 case BIT_IOR_EXPR:
2487 case BIT_XOR_EXPR:
2488 ifcvt_walk_pattern_tree (rhs1, defuse_list, def_stmt);
2489 rhs2 = gimple_assign_rhs2 (def_stmt);
2490 ifcvt_walk_pattern_tree (rhs2, defuse_list, def_stmt);
2491 break;
2492 default:
2493 break;
2495 return;
2498 /* Returns true if STMT can be a root of bool pattern apllied
2499 by vectorizer. */
2501 static bool
2502 stmt_is_root_of_bool_pattern (gimple stmt)
2504 enum tree_code code;
2505 tree lhs, rhs;
2507 code = gimple_assign_rhs_code (stmt);
2508 if (CONVERT_EXPR_CODE_P (code))
2510 lhs = gimple_assign_lhs (stmt);
2511 rhs = gimple_assign_rhs1 (stmt);
2512 if (TREE_CODE (TREE_TYPE (rhs)) != BOOLEAN_TYPE)
2513 return false;
2514 if (TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE)
2515 return false;
2516 return true;
2518 else if (code == COND_EXPR)
2520 rhs = gimple_assign_rhs1 (stmt);
2521 if (TREE_CODE (rhs) != SSA_NAME)
2522 return false;
2523 return true;
2525 return false;
2528 /* Traverse all statements in BB which correspondent to loop header to
2529 find out all statements which can start bool pattern applied by
2530 vectorizer and convert multiple uses in it to conform pattern
2531 restrictions. Such case can occur if the same predicate is used both
2532 for phi node conversion and load/store mask. */
2534 static void
2535 ifcvt_repair_bool_pattern (basic_block bb)
2537 tree rhs;
2538 gimple stmt;
2539 gimple_stmt_iterator gsi;
2540 vec<gimple> defuse_list = vNULL;
2541 vec<gimple> pattern_roots = vNULL;
2542 bool repeat = true;
2543 int niter = 0;
2544 unsigned int ix;
2546 /* Collect all root pattern statements. */
2547 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2549 stmt = gsi_stmt (gsi);
2550 if (gimple_code (stmt) != GIMPLE_ASSIGN)
2551 continue;
2552 if (!stmt_is_root_of_bool_pattern (stmt))
2553 continue;
2554 pattern_roots.safe_push (stmt);
2557 if (pattern_roots.is_empty ())
2558 return;
2560 /* Split all statements with multiple uses iteratively since splitting
2561 may create new multiple uses. */
2562 while (repeat)
2564 repeat = false;
2565 niter++;
2566 FOR_EACH_VEC_ELT (pattern_roots, ix, stmt)
2568 rhs = gimple_assign_rhs1 (stmt);
2569 ifcvt_walk_pattern_tree (rhs, &defuse_list, stmt);
2570 while (defuse_list.length () > 0)
2572 repeat = true;
2573 gimple def_stmt, use_stmt;
2574 use_stmt = defuse_list.pop ();
2575 def_stmt = defuse_list.pop ();
2576 ifcvt_split_def_stmt (def_stmt, use_stmt);
2581 if (dump_file && (dump_flags & TDF_DETAILS))
2582 fprintf (dump_file, "Repair bool pattern takes %d iterations. \n",
2583 niter);
2586 /* Delete redundant statements produced by predication which prevents
2587 loop vectorization. */
2589 static void
2590 ifcvt_local_dce (basic_block bb)
2592 gimple stmt;
2593 gimple stmt1;
2594 gimple phi;
2595 gimple_stmt_iterator gsi;
2596 vec<gimple> worklist;
2597 enum gimple_code code;
2598 use_operand_p use_p;
2599 imm_use_iterator imm_iter;
2601 worklist.create (64);
2602 /* Consider all phi as live statements. */
2603 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2605 phi = gsi_stmt (gsi);
2606 gimple_set_plf (phi, GF_PLF_2, true);
2607 worklist.safe_push (phi);
2609 /* Consider load/store statemnts, CALL and COND as live. */
2610 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2612 stmt = gsi_stmt (gsi);
2613 if (gimple_store_p (stmt)
2614 || gimple_assign_load_p (stmt)
2615 || is_gimple_debug (stmt))
2617 gimple_set_plf (stmt, GF_PLF_2, true);
2618 worklist.safe_push (stmt);
2619 continue;
2621 code = gimple_code (stmt);
2622 if (code == GIMPLE_COND || code == GIMPLE_CALL)
2624 gimple_set_plf (stmt, GF_PLF_2, true);
2625 worklist.safe_push (stmt);
2626 continue;
2628 gimple_set_plf (stmt, GF_PLF_2, false);
2630 if (code == GIMPLE_ASSIGN)
2632 tree lhs = gimple_assign_lhs (stmt);
2633 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
2635 stmt1 = USE_STMT (use_p);
2636 if (gimple_bb (stmt1) != bb)
2638 gimple_set_plf (stmt, GF_PLF_2, true);
2639 worklist.safe_push (stmt);
2640 break;
2645 /* Propagate liveness through arguments of live stmt. */
2646 while (worklist.length () > 0)
2648 ssa_op_iter iter;
2649 use_operand_p use_p;
2650 tree use;
2652 stmt = worklist.pop ();
2653 FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
2655 use = USE_FROM_PTR (use_p);
2656 if (TREE_CODE (use) != SSA_NAME)
2657 continue;
2658 stmt1 = SSA_NAME_DEF_STMT (use);
2659 if (gimple_bb (stmt1) != bb
2660 || gimple_plf (stmt1, GF_PLF_2))
2661 continue;
2662 gimple_set_plf (stmt1, GF_PLF_2, true);
2663 worklist.safe_push (stmt1);
2666 /* Delete dead statements. */
2667 gsi = gsi_start_bb (bb);
2668 while (!gsi_end_p (gsi))
2670 stmt = gsi_stmt (gsi);
2671 if (gimple_plf (stmt, GF_PLF_2))
2673 gsi_next (&gsi);
2674 continue;
2676 if (dump_file && (dump_flags & TDF_DETAILS))
2678 fprintf (dump_file, "Delete dead stmt in bb#%d\n", bb->index);
2679 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
2681 gsi_remove (&gsi, true);
2682 release_defs (stmt);
2686 /* If-convert LOOP when it is legal. For the moment this pass has no
2687 profitability analysis. Returns non-zero todo flags when something
2688 changed. */
2690 static unsigned int
2691 tree_if_conversion (struct loop *loop)
2693 unsigned int todo = 0;
2694 ifc_bbs = NULL;
2695 bool any_mask_load_store = false;
2697 /* Set-up aggressive if-conversion for loops marked with simd pragma. */
2698 aggressive_if_conv = loop->force_vectorize;
2699 /* Check either outer loop was marked with simd pragma. */
2700 if (!aggressive_if_conv)
2702 struct loop *outer_loop = loop_outer (loop);
2703 if (outer_loop && outer_loop->force_vectorize)
2704 aggressive_if_conv = true;
2707 if (aggressive_if_conv)
2708 if (!ifcvt_split_critical_edges (loop))
2709 goto cleanup;
2711 if (!if_convertible_loop_p (loop, &any_mask_load_store)
2712 || !dbg_cnt (if_conversion_tree))
2713 goto cleanup;
2715 if (any_mask_load_store
2716 && ((!flag_tree_loop_vectorize && !loop->force_vectorize)
2717 || loop->dont_vectorize))
2718 goto cleanup;
2720 if (any_mask_load_store && !version_loop_for_if_conversion (loop))
2721 goto cleanup;
2723 /* Now all statements are if-convertible. Combine all the basic
2724 blocks into one huge basic block doing the if-conversion
2725 on-the-fly. */
2726 combine_blocks (loop, any_mask_load_store);
2728 /* Delete dead predicate computations and repair tree correspondent
2729 to bool pattern to delete multiple uses of preidcates. */
2730 if (aggressive_if_conv)
2732 ifcvt_local_dce (loop->header);
2733 ifcvt_repair_bool_pattern (loop->header);
2736 todo |= TODO_cleanup_cfg;
2737 if (flag_tree_loop_if_convert_stores || any_mask_load_store)
2739 mark_virtual_operands_for_renaming (cfun);
2740 todo |= TODO_update_ssa_only_virtuals;
2743 cleanup:
2744 if (ifc_bbs)
2746 unsigned int i;
2748 for (i = 0; i < loop->num_nodes; i++)
2749 free_bb_predicate (ifc_bbs[i]);
2751 free (ifc_bbs);
2752 ifc_bbs = NULL;
2754 free_dominance_info (CDI_POST_DOMINATORS);
2756 return todo;
2759 /* Tree if-conversion pass management. */
2761 namespace {
2763 const pass_data pass_data_if_conversion =
2765 GIMPLE_PASS, /* type */
2766 "ifcvt", /* name */
2767 OPTGROUP_NONE, /* optinfo_flags */
2768 TV_NONE, /* tv_id */
2769 ( PROP_cfg | PROP_ssa ), /* properties_required */
2770 0, /* properties_provided */
2771 0, /* properties_destroyed */
2772 0, /* todo_flags_start */
2773 0, /* todo_flags_finish */
2776 class pass_if_conversion : public gimple_opt_pass
2778 public:
2779 pass_if_conversion (gcc::context *ctxt)
2780 : gimple_opt_pass (pass_data_if_conversion, ctxt)
2783 /* opt_pass methods: */
2784 virtual bool gate (function *);
2785 virtual unsigned int execute (function *);
2787 }; // class pass_if_conversion
2789 bool
2790 pass_if_conversion::gate (function *fun)
2792 return (((flag_tree_loop_vectorize || fun->has_force_vectorize_loops)
2793 && flag_tree_loop_if_convert != 0)
2794 || flag_tree_loop_if_convert == 1
2795 || flag_tree_loop_if_convert_stores == 1);
2798 unsigned int
2799 pass_if_conversion::execute (function *fun)
2801 struct loop *loop;
2802 unsigned todo = 0;
2804 if (number_of_loops (fun) <= 1)
2805 return 0;
2807 FOR_EACH_LOOP (loop, 0)
2808 if (flag_tree_loop_if_convert == 1
2809 || flag_tree_loop_if_convert_stores == 1
2810 || ((flag_tree_loop_vectorize || loop->force_vectorize)
2811 && !loop->dont_vectorize))
2812 todo |= tree_if_conversion (loop);
2814 #ifdef ENABLE_CHECKING
2816 basic_block bb;
2817 FOR_EACH_BB_FN (bb, fun)
2818 gcc_assert (!bb->aux);
2820 #endif
2822 return todo;
2825 } // anon namespace
2827 gimple_opt_pass *
2828 make_pass_if_conversion (gcc::context *ctxt)
2830 return new pass_if_conversion (ctxt);