[PATCH] RISC-V: Move UNSPEC_SSP_SET and UNSPEC_SSP_TEST to correct enum
[gcc.git] / gcc / tree-if-conv.cc
blob5b63bf67fe0e1d691eae03712b99a32fa37fed7a
1 /* If-conversion for vectorizer.
2 Copyright (C) 2004-2025 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 "backend.h"
87 #include "rtl.h"
88 #include "tree.h"
89 #include "gimple.h"
90 #include "cfghooks.h"
91 #include "tree-pass.h"
92 #include "ssa.h"
93 #include "expmed.h"
94 #include "expr.h"
95 #include "optabs-tree.h"
96 #include "gimple-pretty-print.h"
97 #include "alias.h"
98 #include "fold-const.h"
99 #include "stor-layout.h"
100 #include "gimple-iterator.h"
101 #include "gimple-fold.h"
102 #include "gimplify.h"
103 #include "gimplify-me.h"
104 #include "tree-cfg.h"
105 #include "tree-into-ssa.h"
106 #include "tree-ssa.h"
107 #include "cfgloop.h"
108 #include "tree-data-ref.h"
109 #include "tree-scalar-evolution.h"
110 #include "tree-ssa-loop.h"
111 #include "tree-ssa-loop-niter.h"
112 #include "tree-ssa-loop-ivopts.h"
113 #include "tree-ssa-address.h"
114 #include "dbgcnt.h"
115 #include "tree-hash-traits.h"
116 #include "varasm.h"
117 #include "builtins.h"
118 #include "cfganal.h"
119 #include "internal-fn.h"
120 #include "fold-const.h"
121 #include "tree-ssa-sccvn.h"
122 #include "tree-cfgcleanup.h"
123 #include "tree-ssa-dse.h"
124 #include "tree-vectorizer.h"
125 #include "tree-eh.h"
126 #include "cgraph.h"
128 /* For lang_hooks.types.type_for_mode. */
129 #include "langhooks.h"
131 /* Only handle PHIs with no more arguments unless we are asked to by
132 simd pragma. */
133 #define MAX_PHI_ARG_NUM \
134 ((unsigned) param_max_tree_if_conversion_phi_args)
136 /* True if we've converted a statement that was only executed when some
137 condition C was true, and if for correctness we need to predicate the
138 statement to ensure that it is a no-op when C is false. See
139 predicate_statements for the kinds of predication we support. */
140 static bool need_to_predicate;
142 /* True if we have to rewrite stmts that may invoke undefined behavior
143 when a condition C was false so it doesn't if it is always executed.
144 See predicate_statements for the kinds of predication we support. */
145 static bool need_to_rewrite_undefined;
147 /* Indicate if there are any complicated PHIs that need to be handled in
148 if-conversion. Complicated PHI has more than two arguments and can't
149 be degenerated to two arguments PHI. See more information in comment
150 before phi_convertible_by_degenerating_args. */
151 static bool any_complicated_phi;
153 /* True if we have bitfield accesses we can lower. */
154 static bool need_to_lower_bitfields;
156 /* True if there is any ifcvting to be done. */
157 static bool need_to_ifcvt;
159 /* Hash for struct innermost_loop_behavior. It depends on the user to
160 free the memory. */
162 struct innermost_loop_behavior_hash : nofree_ptr_hash <innermost_loop_behavior>
164 static inline hashval_t hash (const value_type &);
165 static inline bool equal (const value_type &,
166 const compare_type &);
169 inline hashval_t
170 innermost_loop_behavior_hash::hash (const value_type &e)
172 hashval_t hash;
174 hash = iterative_hash_expr (e->base_address, 0);
175 hash = iterative_hash_expr (e->offset, hash);
176 hash = iterative_hash_expr (e->init, hash);
177 return iterative_hash_expr (e->step, hash);
180 inline bool
181 innermost_loop_behavior_hash::equal (const value_type &e1,
182 const compare_type &e2)
184 if ((e1->base_address && !e2->base_address)
185 || (!e1->base_address && e2->base_address)
186 || (!e1->offset && e2->offset)
187 || (e1->offset && !e2->offset)
188 || (!e1->init && e2->init)
189 || (e1->init && !e2->init)
190 || (!e1->step && e2->step)
191 || (e1->step && !e2->step))
192 return false;
194 if (e1->base_address && e2->base_address
195 && !operand_equal_p (e1->base_address, e2->base_address, 0))
196 return false;
197 if (e1->offset && e2->offset
198 && !operand_equal_p (e1->offset, e2->offset, 0))
199 return false;
200 if (e1->init && e2->init
201 && !operand_equal_p (e1->init, e2->init, 0))
202 return false;
203 if (e1->step && e2->step
204 && !operand_equal_p (e1->step, e2->step, 0))
205 return false;
207 return true;
210 /* List of basic blocks in if-conversion-suitable order. */
211 static basic_block *ifc_bbs;
213 /* Hash table to store <DR's innermost loop behavior, DR> pairs. */
214 static hash_map<innermost_loop_behavior_hash,
215 data_reference_p> *innermost_DR_map;
217 /* Hash table to store <base reference, DR> pairs. */
218 static hash_map<tree_operand_hash, data_reference_p> *baseref_DR_map;
220 /* List of redundant SSA names: the first should be replaced by the second. */
221 static vec< std::pair<tree, tree> > redundant_ssa_names;
223 /* Structure used to predicate basic blocks. This is attached to the
224 ->aux field of the BBs in the loop to be if-converted. */
225 struct bb_predicate {
227 /* The condition under which this basic block is executed. */
228 tree predicate;
230 /* PREDICATE is gimplified, and the sequence of statements is
231 recorded here, in order to avoid the duplication of computations
232 that occur in previous conditions. See PR44483. */
233 gimple_seq predicate_gimplified_stmts;
235 /* Records the number of statements recorded into
236 PREDICATE_GIMPLIFIED_STMTS. */
237 unsigned no_predicate_stmts;
240 /* Returns true when the basic block BB has a predicate. */
242 static inline bool
243 bb_has_predicate (basic_block bb)
245 return bb->aux != NULL;
248 /* Returns the gimplified predicate for basic block BB. */
250 static inline tree
251 bb_predicate (basic_block bb)
253 return ((struct bb_predicate *) bb->aux)->predicate;
256 /* Sets the gimplified predicate COND for basic block BB. */
258 static inline void
259 set_bb_predicate (basic_block bb, tree cond)
261 auto aux = (struct bb_predicate *) bb->aux;
262 gcc_assert ((TREE_CODE (cond) == TRUTH_NOT_EXPR
263 && is_gimple_val (TREE_OPERAND (cond, 0)))
264 || is_gimple_val (cond));
265 aux->predicate = cond;
266 aux->no_predicate_stmts++;
268 if (dump_file && (dump_flags & TDF_DETAILS))
269 fprintf (dump_file, "Recording block %d value %d\n", bb->index,
270 aux->no_predicate_stmts);
273 /* Returns the sequence of statements of the gimplification of the
274 predicate for basic block BB. */
276 static inline gimple_seq
277 bb_predicate_gimplified_stmts (basic_block bb)
279 return ((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts;
282 /* Sets the sequence of statements STMTS of the gimplification of the
283 predicate for basic block BB. If PRESERVE_COUNTS then don't clear the predicate
284 counts. */
286 static inline void
287 set_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts,
288 bool preserve_counts)
290 ((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts = stmts;
291 if (stmts == NULL && !preserve_counts)
292 ((struct bb_predicate *) bb->aux)->no_predicate_stmts = 0;
295 /* Adds the sequence of statements STMTS to the sequence of statements
296 of the predicate for basic block BB. */
298 static inline void
299 add_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts)
301 /* We might have updated some stmts in STMTS via force_gimple_operand
302 calling fold_stmt and that producing multiple stmts. Delink immediate
303 uses so update_ssa after loop versioning doesn't get confused for
304 the not yet inserted predicates.
305 ??? This should go away once we reliably avoid updating stmts
306 not in any BB. */
307 for (gimple_stmt_iterator gsi = gsi_start (stmts);
308 !gsi_end_p (gsi); gsi_next (&gsi))
310 gimple *stmt = gsi_stmt (gsi);
311 delink_stmt_imm_use (stmt);
312 gimple_set_modified (stmt, true);
313 ((struct bb_predicate *) bb->aux)->no_predicate_stmts++;
315 gimple_seq_add_seq_without_update
316 (&(((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts), stmts);
319 /* Return the number of statements the predicate of the basic block consists
320 of. */
322 static inline unsigned
323 get_bb_num_predicate_stmts (basic_block bb)
325 return ((struct bb_predicate *) bb->aux)->no_predicate_stmts;
328 /* Initializes to TRUE the predicate of basic block BB. */
330 static inline void
331 init_bb_predicate (basic_block bb)
333 bb->aux = XNEW (struct bb_predicate);
334 set_bb_predicate_gimplified_stmts (bb, NULL, false);
335 set_bb_predicate (bb, boolean_true_node);
338 /* Release the SSA_NAMEs associated with the predicate of basic block BB. */
340 static inline void
341 release_bb_predicate (basic_block bb)
343 gimple_seq stmts = bb_predicate_gimplified_stmts (bb);
344 if (stmts)
346 /* Ensure that these stmts haven't yet been added to a bb. */
347 if (flag_checking)
348 for (gimple_stmt_iterator i = gsi_start (stmts);
349 !gsi_end_p (i); gsi_next (&i))
350 gcc_assert (! gimple_bb (gsi_stmt (i)));
352 /* Discard them. */
353 gimple_seq_discard (stmts);
354 set_bb_predicate_gimplified_stmts (bb, NULL, false);
358 /* Free the predicate of basic block BB. */
360 static inline void
361 free_bb_predicate (basic_block bb)
363 if (!bb_has_predicate (bb))
364 return;
366 release_bb_predicate (bb);
367 free (bb->aux);
368 bb->aux = NULL;
371 /* Reinitialize predicate of BB with the true predicate. */
373 static inline void
374 reset_bb_predicate (basic_block bb)
376 if (!bb_has_predicate (bb))
377 init_bb_predicate (bb);
378 else
380 release_bb_predicate (bb);
381 set_bb_predicate (bb, boolean_true_node);
385 /* Returns a new SSA_NAME of type TYPE that is assigned the value of
386 the expression EXPR. Inserts the statement created for this
387 computation before GSI and leaves the iterator GSI at the same
388 statement. */
390 static tree
391 ifc_temp_var (tree type, tree expr, gimple_stmt_iterator *gsi)
393 tree new_name = make_temp_ssa_name (type, NULL, "_ifc_");
394 gimple *stmt = gimple_build_assign (new_name, expr);
395 gimple_set_vuse (stmt, gimple_vuse (gsi_stmt (*gsi)));
396 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
397 return new_name;
400 /* Return true when COND is a false predicate. */
402 static inline bool
403 is_false_predicate (tree cond)
405 return (cond != NULL_TREE
406 && (cond == boolean_false_node
407 || integer_zerop (cond)));
410 /* Return true when COND is a true predicate. */
412 static inline bool
413 is_true_predicate (tree cond)
415 return (cond == NULL_TREE
416 || cond == boolean_true_node
417 || integer_onep (cond));
420 /* Returns true when BB has a predicate that is not trivial: true or
421 NULL_TREE. */
423 static inline bool
424 is_predicated (basic_block bb)
426 return !is_true_predicate (bb_predicate (bb));
429 /* Parses the predicate COND and returns its comparison code and
430 operands OP0 and OP1. */
432 static enum tree_code
433 parse_predicate (tree cond, tree *op0, tree *op1)
435 gimple *s;
437 if (TREE_CODE (cond) == SSA_NAME
438 && is_gimple_assign (s = SSA_NAME_DEF_STMT (cond)))
440 if (TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison)
442 *op0 = gimple_assign_rhs1 (s);
443 *op1 = gimple_assign_rhs2 (s);
444 return gimple_assign_rhs_code (s);
447 else if (gimple_assign_rhs_code (s) == TRUTH_NOT_EXPR)
449 tree op = gimple_assign_rhs1 (s);
450 tree type = TREE_TYPE (op);
451 enum tree_code code = parse_predicate (op, op0, op1);
453 return code == ERROR_MARK ? ERROR_MARK
454 : invert_tree_comparison (code, HONOR_NANS (type));
457 return ERROR_MARK;
460 if (COMPARISON_CLASS_P (cond))
462 *op0 = TREE_OPERAND (cond, 0);
463 *op1 = TREE_OPERAND (cond, 1);
464 return TREE_CODE (cond);
467 return ERROR_MARK;
470 /* Returns the fold of predicate C1 OR C2 at location LOC. */
472 static tree
473 fold_or_predicates (location_t loc, tree c1, tree c2)
475 tree op1a, op1b, op2a, op2b;
476 enum tree_code code1 = parse_predicate (c1, &op1a, &op1b);
477 enum tree_code code2 = parse_predicate (c2, &op2a, &op2b);
479 if (code1 != ERROR_MARK && code2 != ERROR_MARK)
481 tree t = maybe_fold_or_comparisons (boolean_type_node, code1, op1a, op1b,
482 code2, op2a, op2b);
483 if (t)
484 return t;
487 return fold_build2_loc (loc, TRUTH_OR_EXPR, boolean_type_node, c1, c2);
490 /* Returns either a COND_EXPR or the folded expression if the folded
491 expression is a MIN_EXPR, a MAX_EXPR, an ABS_EXPR,
492 a constant or a SSA_NAME. */
494 static tree
495 fold_build_cond_expr (tree type, tree cond, tree rhs, tree lhs)
497 /* If COND is comparison r != 0 and r has boolean type, convert COND
498 to SSA_NAME to accept by vect bool pattern. */
499 if (TREE_CODE (cond) == NE_EXPR)
501 tree op0 = TREE_OPERAND (cond, 0);
502 tree op1 = TREE_OPERAND (cond, 1);
503 if (TREE_CODE (op0) == SSA_NAME
504 && TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
505 && (integer_zerop (op1)))
506 cond = op0;
509 gimple_match_op cexpr (gimple_match_cond::UNCOND, COND_EXPR,
510 type, cond, rhs, lhs);
511 if (cexpr.resimplify (NULL, follow_all_ssa_edges))
513 if (gimple_simplified_result_is_gimple_val (&cexpr))
514 return cexpr.ops[0];
515 else if (cexpr.code == ABS_EXPR)
516 return build1 (ABS_EXPR, type, cexpr.ops[0]);
517 else if (cexpr.code == MIN_EXPR
518 || cexpr.code == MAX_EXPR)
519 return build2 ((tree_code)cexpr.code, type, cexpr.ops[0], cexpr.ops[1]);
522 return build3 (COND_EXPR, type, cond, rhs, lhs);
525 /* Add condition NC to the predicate list of basic block BB. LOOP is
526 the loop to be if-converted. Use predicate of cd-equivalent block
527 for join bb if it exists: we call basic blocks bb1 and bb2
528 cd-equivalent if they are executed under the same condition. */
530 static inline void
531 add_to_predicate_list (class loop *loop, basic_block bb, tree nc)
533 tree bc, *tp;
534 basic_block dom_bb;
536 if (is_true_predicate (nc))
537 return;
539 /* If dominance tells us this basic block is always executed,
540 don't record any predicates for it. */
541 if (dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
542 return;
544 dom_bb = get_immediate_dominator (CDI_DOMINATORS, bb);
545 /* We use notion of cd equivalence to get simpler predicate for
546 join block, e.g. if join block has 2 predecessors with predicates
547 p1 & p2 and p1 & !p2, we'd like to get p1 for it instead of
548 p1 & p2 | p1 & !p2. */
549 if (dom_bb != loop->header
550 && get_immediate_dominator (CDI_POST_DOMINATORS, dom_bb) == bb)
552 gcc_assert (flow_bb_inside_loop_p (loop, dom_bb));
553 bc = bb_predicate (dom_bb);
554 if (!is_true_predicate (bc))
555 set_bb_predicate (bb, bc);
556 else
557 gcc_assert (is_true_predicate (bb_predicate (bb)));
558 if (dump_file && (dump_flags & TDF_DETAILS))
559 fprintf (dump_file, "Use predicate of bb#%d for bb#%d\n",
560 dom_bb->index, bb->index);
561 return;
564 if (!is_predicated (bb))
565 bc = nc;
566 else
568 bc = bb_predicate (bb);
569 bc = fold_or_predicates (EXPR_LOCATION (bc), nc, bc);
570 if (is_true_predicate (bc))
572 reset_bb_predicate (bb);
573 return;
577 /* Allow a TRUTH_NOT_EXPR around the main predicate. */
578 if (TREE_CODE (bc) == TRUTH_NOT_EXPR)
579 tp = &TREE_OPERAND (bc, 0);
580 else
581 tp = &bc;
582 if (!is_gimple_val (*tp))
584 gimple_seq stmts;
585 *tp = force_gimple_operand (*tp, &stmts, true, NULL_TREE);
586 add_bb_predicate_gimplified_stmts (bb, stmts);
588 set_bb_predicate (bb, bc);
591 /* Add the condition COND to the previous condition PREV_COND, and add
592 this to the predicate list of the destination of edge E. LOOP is
593 the loop to be if-converted. */
595 static void
596 add_to_dst_predicate_list (class loop *loop, edge e,
597 tree prev_cond, tree cond)
599 if (!flow_bb_inside_loop_p (loop, e->dest))
600 return;
602 if (!is_true_predicate (prev_cond))
603 cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
604 prev_cond, cond);
606 if (!dominated_by_p (CDI_DOMINATORS, loop->latch, e->dest))
607 add_to_predicate_list (loop, e->dest, cond);
610 /* Return true if one of the successor edges of BB exits LOOP. */
612 static bool
613 bb_with_exit_edge_p (const class loop *loop, basic_block bb)
615 edge e;
616 edge_iterator ei;
618 FOR_EACH_EDGE (e, ei, bb->succs)
619 if (loop_exit_edge_p (loop, e))
620 return true;
622 return false;
625 /* Given PHI which has more than two arguments, this function checks if
626 it's if-convertible by degenerating its arguments. Specifically, if
627 below two conditions are satisfied:
629 1) Number of PHI arguments with different values equals to 2 and one
630 argument has the only occurrence.
631 2) The edge corresponding to the unique argument isn't critical edge.
633 Such PHI can be handled as PHIs have only two arguments. For example,
634 below PHI:
636 res = PHI <A_1(e1), A_1(e2), A_2(e3)>;
638 can be transformed into:
640 res = (predicate of e3) ? A_2 : A_1;
642 Return TRUE if it is the case, FALSE otherwise. */
644 static bool
645 phi_convertible_by_degenerating_args (gphi *phi)
647 edge e;
648 tree arg, t1 = NULL, t2 = NULL;
649 unsigned int i, i1 = 0, i2 = 0, n1 = 0, n2 = 0;
650 unsigned int num_args = gimple_phi_num_args (phi);
652 gcc_assert (num_args > 2);
654 for (i = 0; i < num_args; i++)
656 arg = gimple_phi_arg_def (phi, i);
657 if (t1 == NULL || operand_equal_p (t1, arg, 0))
659 n1++;
660 i1 = i;
661 t1 = arg;
663 else if (t2 == NULL || operand_equal_p (t2, arg, 0))
665 n2++;
666 i2 = i;
667 t2 = arg;
669 else
670 return false;
673 if (n1 != 1 && n2 != 1)
674 return false;
676 /* Check if the edge corresponding to the unique arg is critical. */
677 e = gimple_phi_arg_edge (phi, (n1 == 1) ? i1 : i2);
678 if (EDGE_COUNT (e->src->succs) > 1)
679 return false;
681 return true;
684 /* Return true when PHI is if-convertible. PHI is part of loop LOOP
685 and it belongs to basic block BB. Note at this point, it is sure
686 that PHI is if-convertible. This function updates global variable
687 ANY_COMPLICATED_PHI if PHI is complicated. */
689 static bool
690 if_convertible_phi_p (class loop *loop, basic_block bb, gphi *phi)
692 if (dump_file && (dump_flags & TDF_DETAILS))
694 fprintf (dump_file, "-------------------------\n");
695 print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
698 if (bb != loop->header
699 && gimple_phi_num_args (phi) > 2
700 && !phi_convertible_by_degenerating_args (phi))
701 any_complicated_phi = true;
703 return true;
706 /* Records the status of a data reference. This struct is attached to
707 each DR->aux field. */
709 struct ifc_dr {
710 bool rw_unconditionally;
711 bool w_unconditionally;
712 bool written_at_least_once;
714 tree rw_predicate;
715 tree w_predicate;
716 tree base_w_predicate;
719 #define IFC_DR(DR) ((struct ifc_dr *) (DR)->aux)
720 #define DR_BASE_W_UNCONDITIONALLY(DR) (IFC_DR (DR)->written_at_least_once)
721 #define DR_RW_UNCONDITIONALLY(DR) (IFC_DR (DR)->rw_unconditionally)
722 #define DR_W_UNCONDITIONALLY(DR) (IFC_DR (DR)->w_unconditionally)
724 /* Iterates over DR's and stores refs, DR and base refs, DR pairs in
725 HASH tables. While storing them in HASH table, it checks if the
726 reference is unconditionally read or written and stores that as a flag
727 information. For base reference it checks if it is written atlest once
728 unconditionally and stores it as flag information along with DR.
729 In other words for every data reference A in STMT there exist other
730 accesses to a data reference with the same base with predicates that
731 add up (OR-up) to the true predicate: this ensures that the data
732 reference A is touched (read or written) on every iteration of the
733 if-converted loop. */
734 static void
735 hash_memrefs_baserefs_and_store_DRs_read_written_info (data_reference_p a)
738 data_reference_p *master_dr, *base_master_dr;
739 tree base_ref = DR_BASE_OBJECT (a);
740 innermost_loop_behavior *innermost = &DR_INNERMOST (a);
741 tree ca = bb_predicate (gimple_bb (DR_STMT (a)));
742 bool exist1, exist2;
744 master_dr = &innermost_DR_map->get_or_insert (innermost, &exist1);
745 if (!exist1)
746 *master_dr = a;
748 if (DR_IS_WRITE (a))
750 IFC_DR (*master_dr)->w_predicate
751 = fold_or_predicates (UNKNOWN_LOCATION, ca,
752 IFC_DR (*master_dr)->w_predicate);
753 if (is_true_predicate (IFC_DR (*master_dr)->w_predicate))
754 DR_W_UNCONDITIONALLY (*master_dr) = true;
756 IFC_DR (*master_dr)->rw_predicate
757 = fold_or_predicates (UNKNOWN_LOCATION, ca,
758 IFC_DR (*master_dr)->rw_predicate);
759 if (is_true_predicate (IFC_DR (*master_dr)->rw_predicate))
760 DR_RW_UNCONDITIONALLY (*master_dr) = true;
762 if (DR_IS_WRITE (a))
764 base_master_dr = &baseref_DR_map->get_or_insert (base_ref, &exist2);
765 if (!exist2)
766 *base_master_dr = a;
767 IFC_DR (*base_master_dr)->base_w_predicate
768 = fold_or_predicates (UNKNOWN_LOCATION, ca,
769 IFC_DR (*base_master_dr)->base_w_predicate);
770 if (is_true_predicate (IFC_DR (*base_master_dr)->base_w_predicate))
771 DR_BASE_W_UNCONDITIONALLY (*base_master_dr) = true;
775 /* Return TRUE if can prove the index IDX of an array reference REF is
776 within array bound. Return false otherwise. */
778 static bool
779 idx_within_array_bound (tree ref, tree *idx, void *dta)
781 wi::overflow_type overflow;
782 widest_int niter, valid_niter, delta, wi_step;
783 tree ev, init, step;
784 tree low, high;
785 class loop *loop = (class loop*) dta;
787 /* Only support within-bound access for array references. */
788 if (TREE_CODE (ref) != ARRAY_REF)
789 return false;
791 /* For arrays that might have flexible sizes, it is not guaranteed that they
792 do not extend over their declared size. */
793 if (array_ref_flexible_size_p (ref))
794 return false;
796 ev = analyze_scalar_evolution (loop, *idx);
797 ev = instantiate_parameters (loop, ev);
798 init = initial_condition (ev);
799 step = evolution_part_in_loop_num (ev, loop->num);
801 if (!init || TREE_CODE (init) != INTEGER_CST
802 || (step && TREE_CODE (step) != INTEGER_CST))
803 return false;
805 low = array_ref_low_bound (ref);
806 high = array_ref_up_bound (ref);
808 /* The case of nonconstant bounds could be handled, but it would be
809 complicated. */
810 if (TREE_CODE (low) != INTEGER_CST
811 || !high || TREE_CODE (high) != INTEGER_CST)
812 return false;
814 /* Check if the intial idx is within bound. */
815 if (wi::to_widest (init) < wi::to_widest (low)
816 || wi::to_widest (init) > wi::to_widest (high))
817 return false;
819 /* The idx is always within bound. */
820 if (!step || integer_zerop (step))
821 return true;
823 if (!max_loop_iterations (loop, &niter))
824 return false;
826 if (wi::to_widest (step) < 0)
828 delta = wi::to_widest (init) - wi::to_widest (low);
829 wi_step = -wi::to_widest (step);
831 else
833 delta = wi::to_widest (high) - wi::to_widest (init);
834 wi_step = wi::to_widest (step);
837 valid_niter = wi::div_floor (delta, wi_step, SIGNED, &overflow);
838 /* The iteration space of idx is within array bound. */
839 if (!overflow && niter <= valid_niter)
840 return true;
842 return false;
845 /* Return TRUE if ref is a within bound array reference. */
847 bool
848 ref_within_array_bound (gimple *stmt, tree ref)
850 class loop *loop = loop_containing_stmt (stmt);
852 gcc_assert (loop != NULL);
853 return for_each_index (&ref, idx_within_array_bound, loop);
857 /* Given a memory reference expression T, return TRUE if base object
858 it refers to is writable. The base object of a memory reference
859 is the main object being referenced, which is returned by function
860 get_base_address. */
862 static bool
863 base_object_writable (tree ref)
865 tree base_tree = get_base_address (ref);
867 return (base_tree
868 && DECL_P (base_tree)
869 && decl_binds_to_current_def_p (base_tree)
870 && !TREE_READONLY (base_tree));
873 /* Return true when the memory references of STMT won't trap in the
874 if-converted code. There are two things that we have to check for:
876 - writes to memory occur to writable memory: if-conversion of
877 memory writes transforms the conditional memory writes into
878 unconditional writes, i.e. "if (cond) A[i] = foo" is transformed
879 into "A[i] = cond ? foo : A[i]", and as the write to memory may not
880 be executed at all in the original code, it may be a readonly
881 memory. To check that A is not const-qualified, we check that
882 there exists at least an unconditional write to A in the current
883 function.
885 - reads or writes to memory are valid memory accesses for every
886 iteration. To check that the memory accesses are correctly formed
887 and that we are allowed to read and write in these locations, we
888 check that the memory accesses to be if-converted occur at every
889 iteration unconditionally.
891 Returns true for the memory reference in STMT, same memory reference
892 is read or written unconditionally atleast once and the base memory
893 reference is written unconditionally once. This is to check reference
894 will not write fault. Also retuns true if the memory reference is
895 unconditionally read once then we are conditionally writing to memory
896 which is defined as read and write and is bound to the definition
897 we are seeing. */
898 static bool
899 ifcvt_memrefs_wont_trap (gimple *stmt, vec<data_reference_p> drs)
901 /* If DR didn't see a reference here we can't use it to tell
902 whether the ref traps or not. */
903 if (gimple_uid (stmt) == 0)
904 return false;
906 data_reference_p *master_dr, *base_master_dr;
907 data_reference_p a = drs[gimple_uid (stmt) - 1];
909 tree base = DR_BASE_OBJECT (a);
910 innermost_loop_behavior *innermost = &DR_INNERMOST (a);
912 gcc_assert (DR_STMT (a) == stmt);
913 gcc_assert (DR_BASE_ADDRESS (a) || DR_OFFSET (a)
914 || DR_INIT (a) || DR_STEP (a));
916 master_dr = innermost_DR_map->get (innermost);
917 gcc_assert (master_dr != NULL);
919 base_master_dr = baseref_DR_map->get (base);
921 /* If a is unconditionally written to it doesn't trap. */
922 if (DR_W_UNCONDITIONALLY (*master_dr))
923 return true;
925 /* If a is unconditionally accessed then ...
927 Even a is conditional access, we can treat it as an unconditional
928 one if it's an array reference and all its index are within array
929 bound. */
930 if (DR_RW_UNCONDITIONALLY (*master_dr)
931 || ref_within_array_bound (stmt, DR_REF (a)))
933 /* an unconditional read won't trap. */
934 if (DR_IS_READ (a))
935 return true;
937 /* an unconditionaly write won't trap if the base is written
938 to unconditionally. */
939 if ((base_master_dr
940 && DR_BASE_W_UNCONDITIONALLY (*base_master_dr))
941 /* or the base is known to be not readonly. */
942 || base_object_writable (DR_REF (a)))
943 return !ref_can_have_store_data_races (base);
946 return false;
949 /* Return true if STMT could be converted into a masked load or store
950 (conditional load or store based on a mask computed from bb predicate). */
952 static bool
953 ifcvt_can_use_mask_load_store (gimple *stmt)
955 /* Check whether this is a load or store. */
956 tree lhs = gimple_assign_lhs (stmt);
957 bool is_load;
958 tree ref;
959 if (gimple_store_p (stmt))
961 if (!is_gimple_val (gimple_assign_rhs1 (stmt)))
962 return false;
963 is_load = false;
964 ref = lhs;
966 else if (gimple_assign_load_p (stmt))
968 is_load = true;
969 ref = gimple_assign_rhs1 (stmt);
971 else
972 return false;
974 if (may_be_nonaddressable_p (ref))
975 return false;
977 /* Mask should be integer mode of the same size as the load/store
978 mode. */
979 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
980 if (!int_mode_for_mode (mode).exists () || VECTOR_MODE_P (mode))
981 return false;
983 if (can_vec_mask_load_store_p (mode, VOIDmode, is_load))
984 return true;
986 return false;
989 /* Return true if STMT could be converted from an operation that is
990 unconditional to one that is conditional on a bb predicate mask. */
992 static bool
993 ifcvt_can_predicate (gimple *stmt)
995 basic_block bb = gimple_bb (stmt);
997 if (!(flag_tree_loop_vectorize || bb->loop_father->force_vectorize)
998 || bb->loop_father->dont_vectorize
999 || gimple_has_volatile_ops (stmt))
1000 return false;
1002 if (gimple_assign_single_p (stmt))
1003 return ifcvt_can_use_mask_load_store (stmt);
1005 tree_code code = gimple_assign_rhs_code (stmt);
1006 tree lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
1007 tree rhs_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
1008 if (!types_compatible_p (lhs_type, rhs_type))
1009 return false;
1010 internal_fn cond_fn = get_conditional_internal_fn (code);
1011 return (cond_fn != IFN_LAST
1012 && vectorized_internal_fn_supported_p (cond_fn, lhs_type));
1015 /* Return true when STMT is if-convertible.
1017 GIMPLE_ASSIGN statement is not if-convertible if,
1018 - it is not movable,
1019 - it could trap,
1020 - LHS is not var decl. */
1022 static bool
1023 if_convertible_gimple_assign_stmt_p (gimple *stmt,
1024 vec<data_reference_p> refs)
1026 tree lhs = gimple_assign_lhs (stmt);
1028 if (dump_file && (dump_flags & TDF_DETAILS))
1030 fprintf (dump_file, "-------------------------\n");
1031 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1034 if (!is_gimple_reg_type (TREE_TYPE (lhs)))
1035 return false;
1037 /* Some of these constrains might be too conservative. */
1038 if (stmt_ends_bb_p (stmt)
1039 || gimple_has_volatile_ops (stmt)
1040 || (TREE_CODE (lhs) == SSA_NAME
1041 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
1042 || gimple_has_side_effects (stmt))
1044 if (dump_file && (dump_flags & TDF_DETAILS))
1045 fprintf (dump_file, "stmt not suitable for ifcvt\n");
1046 return false;
1049 /* tree-into-ssa.cc uses GF_PLF_1, so avoid it, because
1050 in between if_convertible_loop_p and combine_blocks
1051 we can perform loop versioning. */
1052 gimple_set_plf (stmt, GF_PLF_2, false);
1054 if ((! gimple_vuse (stmt)
1055 || gimple_could_trap_p_1 (stmt, false, false)
1056 || ! ifcvt_memrefs_wont_trap (stmt, refs))
1057 && gimple_could_trap_p (stmt))
1059 if (ifcvt_can_predicate (stmt))
1061 gimple_set_plf (stmt, GF_PLF_2, true);
1062 need_to_predicate = true;
1063 return true;
1065 if (dump_file && (dump_flags & TDF_DETAILS))
1066 fprintf (dump_file, "tree could trap...\n");
1067 return false;
1069 else if ((INTEGRAL_TYPE_P (TREE_TYPE (lhs))
1070 || POINTER_TYPE_P (TREE_TYPE (lhs)))
1071 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (lhs))
1072 && arith_code_with_undefined_signed_overflow
1073 (gimple_assign_rhs_code (stmt)))
1074 /* We have to rewrite stmts with undefined overflow. */
1075 need_to_rewrite_undefined = true;
1077 /* When if-converting stores force versioning, likewise if we
1078 ended up generating store data races. */
1079 if (gimple_vdef (stmt))
1080 need_to_predicate = true;
1082 return true;
1085 /* Return true when SW switch statement is equivalent to cond, that
1086 all non default labels point to the same label.
1088 Fallthrough is not checked for and could even happen
1089 with cond (using goto), so is handled.
1091 This is intended for switches created by the if-switch-conversion
1092 pass, but can handle some programmer supplied cases too. */
1094 static bool
1095 if_convertible_switch_p (gswitch *sw)
1097 if (gimple_switch_num_labels (sw) <= 1)
1098 return false;
1099 tree label = CASE_LABEL (gimple_switch_label (sw, 1));
1100 for (unsigned i = 1; i < gimple_switch_num_labels (sw); i++)
1102 if (CASE_LABEL (gimple_switch_label (sw, i)) != label)
1103 return false;
1105 return true;
1108 /* Return true when STMT is if-convertible.
1110 A statement is if-convertible if:
1111 - it is an if-convertible GIMPLE_ASSIGN,
1112 - it is a GIMPLE_LABEL or a GIMPLE_COND,
1113 - it is a switch equivalent to COND
1114 - it is builtins call,
1115 - it is a call to a function with a SIMD clone. */
1117 static bool
1118 if_convertible_stmt_p (gimple *stmt, vec<data_reference_p> refs)
1120 switch (gimple_code (stmt))
1122 case GIMPLE_LABEL:
1123 case GIMPLE_DEBUG:
1124 case GIMPLE_COND:
1125 return true;
1127 case GIMPLE_SWITCH:
1128 return if_convertible_switch_p (as_a <gswitch *> (stmt));
1130 case GIMPLE_ASSIGN:
1131 return if_convertible_gimple_assign_stmt_p (stmt, refs);
1133 case GIMPLE_CALL:
1135 tree fndecl = gimple_call_fndecl (stmt);
1136 if (fndecl)
1138 /* We can vectorize some builtins and functions with SIMD
1139 "inbranch" clones. */
1140 struct cgraph_node *node = cgraph_node::get (fndecl);
1141 if (node && node->simd_clones != NULL)
1142 /* Ensure that at least one clone can be "inbranch". */
1143 for (struct cgraph_node *n = node->simd_clones; n != NULL;
1144 n = n->simdclone->next_clone)
1145 if (n->simdclone->inbranch)
1147 gimple_set_plf (stmt, GF_PLF_2, true);
1148 need_to_predicate = true;
1149 return true;
1153 /* There are some IFN_s that are used to replace builtins but have the
1154 same semantics. Even if MASK_CALL cannot handle them vectorable_call
1155 will insert the proper selection, so do not block conversion. */
1156 int flags = gimple_call_flags (stmt);
1157 if ((flags & ECF_CONST)
1158 && !(flags & ECF_LOOPING_CONST_OR_PURE)
1159 && gimple_call_combined_fn (stmt) != CFN_LAST)
1160 return true;
1162 return false;
1165 default:
1166 /* Don't know what to do with 'em so don't do anything. */
1167 if (dump_file && (dump_flags & TDF_DETAILS))
1169 fprintf (dump_file, "don't know what to do\n");
1170 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1172 return false;
1176 /* Assumes that BB has more than 1 predecessors.
1177 Returns false if at least one successor is not on critical edge
1178 and true otherwise. */
1180 static inline bool
1181 all_preds_critical_p (basic_block bb)
1183 edge e;
1184 edge_iterator ei;
1186 FOR_EACH_EDGE (e, ei, bb->preds)
1187 if (EDGE_COUNT (e->src->succs) == 1)
1188 return false;
1189 return true;
1192 /* Return true when BB is if-convertible. This routine does not check
1193 basic block's statements and phis.
1195 A basic block is not if-convertible if:
1196 - it is non-empty and it is after the exit block (in BFS order),
1197 - it is after the exit block but before the latch,
1198 - its edges are not normal.
1200 EXIT_BB is the basic block containing the exit of the LOOP. BB is
1201 inside LOOP. */
1203 static bool
1204 if_convertible_bb_p (class loop *loop, basic_block bb, basic_block exit_bb)
1206 edge e;
1207 edge_iterator ei;
1209 if (dump_file && (dump_flags & TDF_DETAILS))
1210 fprintf (dump_file, "----------[%d]-------------\n", bb->index);
1212 if (EDGE_COUNT (bb->succs) > 2)
1213 return false;
1215 if (gcall *call = safe_dyn_cast <gcall *> (*gsi_last_bb (bb)))
1216 if (gimple_call_ctrl_altering_p (call))
1217 return false;
1219 if (exit_bb)
1221 if (bb != loop->latch)
1223 if (dump_file && (dump_flags & TDF_DETAILS))
1224 fprintf (dump_file, "basic block after exit bb but before latch\n");
1225 return false;
1227 else if (!empty_block_p (bb))
1229 if (dump_file && (dump_flags & TDF_DETAILS))
1230 fprintf (dump_file, "non empty basic block after exit bb\n");
1231 return false;
1233 else if (bb == loop->latch
1234 && bb != exit_bb
1235 && !dominated_by_p (CDI_DOMINATORS, bb, exit_bb))
1237 if (dump_file && (dump_flags & TDF_DETAILS))
1238 fprintf (dump_file, "latch is not dominated by exit_block\n");
1239 return false;
1243 /* Be less adventurous and handle only normal edges. */
1244 FOR_EACH_EDGE (e, ei, bb->succs)
1245 if (e->flags & (EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP))
1247 if (dump_file && (dump_flags & TDF_DETAILS))
1248 fprintf (dump_file, "Difficult to handle edges\n");
1249 return false;
1252 return true;
1255 /* Return true when all predecessor blocks of BB are visited. The
1256 VISITED bitmap keeps track of the visited blocks. */
1258 static bool
1259 pred_blocks_visited_p (basic_block bb, bitmap *visited)
1261 edge e;
1262 edge_iterator ei;
1263 FOR_EACH_EDGE (e, ei, bb->preds)
1264 if (!bitmap_bit_p (*visited, e->src->index))
1265 return false;
1267 return true;
1270 /* Get body of a LOOP in suitable order for if-conversion. It is
1271 caller's responsibility to deallocate basic block list.
1272 If-conversion suitable order is, breadth first sort (BFS) order
1273 with an additional constraint: select a block only if all its
1274 predecessors are already selected. */
1276 static basic_block *
1277 get_loop_body_in_if_conv_order (const class loop *loop)
1279 basic_block *blocks, *blocks_in_bfs_order;
1280 basic_block bb;
1281 bitmap visited;
1282 unsigned int index = 0;
1283 unsigned int visited_count = 0;
1285 gcc_assert (loop->num_nodes);
1286 gcc_assert (loop->latch != EXIT_BLOCK_PTR_FOR_FN (cfun));
1288 blocks = XCNEWVEC (basic_block, loop->num_nodes);
1289 visited = BITMAP_ALLOC (NULL);
1291 blocks_in_bfs_order = get_loop_body_in_bfs_order (loop);
1293 index = 0;
1294 while (index < loop->num_nodes)
1296 bb = blocks_in_bfs_order [index];
1298 if (bb->flags & BB_IRREDUCIBLE_LOOP)
1300 free (blocks_in_bfs_order);
1301 BITMAP_FREE (visited);
1302 free (blocks);
1303 return NULL;
1306 if (!bitmap_bit_p (visited, bb->index))
1308 if (pred_blocks_visited_p (bb, &visited)
1309 || bb == loop->header)
1311 /* This block is now visited. */
1312 bitmap_set_bit (visited, bb->index);
1313 blocks[visited_count++] = bb;
1317 index++;
1319 if (index == loop->num_nodes
1320 && visited_count != loop->num_nodes)
1321 /* Not done yet. */
1322 index = 0;
1324 free (blocks_in_bfs_order);
1325 BITMAP_FREE (visited);
1327 /* Go through loop and reject if-conversion or lowering of bitfields if we
1328 encounter statements we do not believe the vectorizer will be able to
1329 handle. If adding a new type of statement here, make sure
1330 'ifcvt_local_dce' is also able to handle it propertly. */
1331 for (index = 0; index < loop->num_nodes; index++)
1333 basic_block bb = blocks[index];
1334 gimple_stmt_iterator gsi;
1336 bool may_have_nonlocal_labels
1337 = bb_with_exit_edge_p (loop, bb) || bb == loop->latch;
1338 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1339 switch (gimple_code (gsi_stmt (gsi)))
1341 case GIMPLE_LABEL:
1342 if (!may_have_nonlocal_labels)
1344 tree label
1345 = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi)));
1346 if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
1348 free (blocks);
1349 return NULL;
1352 /* Fallthru. */
1353 case GIMPLE_ASSIGN:
1354 case GIMPLE_CALL:
1355 case GIMPLE_DEBUG:
1356 case GIMPLE_COND:
1357 case GIMPLE_SWITCH:
1358 gimple_set_uid (gsi_stmt (gsi), 0);
1359 break;
1360 default:
1361 free (blocks);
1362 return NULL;
1365 return blocks;
1368 /* Returns true when the analysis of the predicates for all the basic
1369 blocks in LOOP succeeded.
1371 predicate_bbs first allocates the predicates of the basic blocks.
1372 These fields are then initialized with the tree expressions
1373 representing the predicates under which a basic block is executed
1374 in the LOOP. As the loop->header is executed at each iteration, it
1375 has the "true" predicate. Other statements executed under a
1376 condition are predicated with that condition, for example
1378 | if (x)
1379 | S1;
1380 | else
1381 | S2;
1383 S1 will be predicated with "x", and
1384 S2 will be predicated with "!x". */
1386 static void
1387 predicate_bbs (loop_p loop)
1389 unsigned int i;
1391 for (i = 0; i < loop->num_nodes; i++)
1392 init_bb_predicate (ifc_bbs[i]);
1394 for (i = 0; i < loop->num_nodes; i++)
1396 basic_block bb = ifc_bbs[i];
1397 tree cond;
1399 /* The loop latch and loop exit block are always executed and
1400 have no extra conditions to be processed: skip them. */
1401 if (bb == loop->latch
1402 || bb_with_exit_edge_p (loop, bb))
1404 reset_bb_predicate (bb);
1405 continue;
1408 cond = bb_predicate (bb);
1409 if (gcond *stmt = safe_dyn_cast <gcond *> (*gsi_last_bb (bb)))
1411 tree c2;
1412 edge true_edge, false_edge;
1413 location_t loc = gimple_location (stmt);
1414 tree c;
1415 /* gcc.dg/fold-bopcond-1.c shows that despite all forwprop passes
1416 conditions can remain unfolded because of multiple uses so
1417 try to re-fold here, especially to get precision changing
1418 conversions sorted out. Do not simply fold the stmt since
1419 this is analysis only. When conditions were embedded in
1420 COND_EXPRs those were folded separately before folding the
1421 COND_EXPR but as they are now outside we have to make sure
1422 to fold them. Do it here - another opportunity would be to
1423 fold predicates as they are inserted. */
1424 gimple_match_op cexpr (gimple_match_cond::UNCOND,
1425 gimple_cond_code (stmt),
1426 boolean_type_node,
1427 gimple_cond_lhs (stmt),
1428 gimple_cond_rhs (stmt));
1429 if (cexpr.resimplify (NULL, follow_all_ssa_edges)
1430 && cexpr.code.is_tree_code ()
1431 && TREE_CODE_CLASS ((tree_code)cexpr.code) == tcc_comparison)
1432 c = build2_loc (loc, (tree_code)cexpr.code, boolean_type_node,
1433 cexpr.ops[0], cexpr.ops[1]);
1434 else
1435 c = build2_loc (loc, gimple_cond_code (stmt),
1436 boolean_type_node,
1437 gimple_cond_lhs (stmt),
1438 gimple_cond_rhs (stmt));
1440 /* Add new condition into destination's predicate list. */
1441 extract_true_false_edges_from_block (gimple_bb (stmt),
1442 &true_edge, &false_edge);
1444 /* If C is true, then TRUE_EDGE is taken. */
1445 add_to_dst_predicate_list (loop, true_edge, unshare_expr (cond),
1446 unshare_expr (c));
1448 /* If C is false, then FALSE_EDGE is taken. */
1449 c2 = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node,
1450 unshare_expr (c));
1451 add_to_dst_predicate_list (loop, false_edge,
1452 unshare_expr (cond), c2);
1454 cond = NULL_TREE;
1457 /* Assumes the limited COND like switches checked for earlier. */
1458 else if (gswitch *sw = safe_dyn_cast <gswitch *> (*gsi_last_bb (bb)))
1460 location_t loc = gimple_location (*gsi_last_bb (bb));
1462 tree default_label = CASE_LABEL (gimple_switch_default_label (sw));
1463 tree cond_label = CASE_LABEL (gimple_switch_label (sw, 1));
1465 edge false_edge = find_edge (bb, label_to_block (cfun, default_label));
1466 edge true_edge = find_edge (bb, label_to_block (cfun, cond_label));
1468 /* Create chain of switch tests for each case. */
1469 tree switch_cond = NULL_TREE;
1470 tree index = gimple_switch_index (sw);
1471 for (unsigned i = 1; i < gimple_switch_num_labels (sw); i++)
1473 tree label = gimple_switch_label (sw, i);
1474 tree case_cond;
1475 if (CASE_HIGH (label))
1477 tree low = build2_loc (loc, GE_EXPR,
1478 boolean_type_node,
1479 index, fold_convert_loc (loc, TREE_TYPE (index),
1480 CASE_LOW (label)));
1481 tree high = build2_loc (loc, LE_EXPR,
1482 boolean_type_node,
1483 index, fold_convert_loc (loc, TREE_TYPE (index),
1484 CASE_HIGH (label)));
1485 case_cond = build2_loc (loc, TRUTH_AND_EXPR,
1486 boolean_type_node,
1487 low, high);
1489 else
1490 case_cond = build2_loc (loc, EQ_EXPR,
1491 boolean_type_node,
1492 index,
1493 fold_convert_loc (loc, TREE_TYPE (index),
1494 CASE_LOW (label)));
1495 if (i > 1)
1496 switch_cond = build2_loc (loc, TRUTH_OR_EXPR,
1497 boolean_type_node,
1498 case_cond, switch_cond);
1499 else
1500 switch_cond = case_cond;
1503 add_to_dst_predicate_list (loop, true_edge, unshare_expr (cond),
1504 unshare_expr (switch_cond));
1505 switch_cond = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node,
1506 unshare_expr (switch_cond));
1507 add_to_dst_predicate_list (loop, false_edge,
1508 unshare_expr (cond), switch_cond);
1509 cond = NULL_TREE;
1512 /* If current bb has only one successor, then consider it as an
1513 unconditional goto. */
1514 if (single_succ_p (bb))
1516 basic_block bb_n = single_succ (bb);
1518 /* The successor bb inherits the predicate of its
1519 predecessor. If there is no predicate in the predecessor
1520 bb, then consider the successor bb as always executed. */
1521 if (cond == NULL_TREE)
1522 cond = boolean_true_node;
1524 add_to_predicate_list (loop, bb_n, cond);
1528 /* The loop header is always executed. */
1529 reset_bb_predicate (loop->header);
1530 gcc_assert (bb_predicate_gimplified_stmts (loop->header) == NULL
1531 && bb_predicate_gimplified_stmts (loop->latch) == NULL);
1534 /* Build region by adding loop pre-header and post-header blocks. */
1536 static vec<basic_block>
1537 build_region (class loop *loop)
1539 vec<basic_block> region = vNULL;
1540 basic_block exit_bb = NULL;
1542 gcc_assert (ifc_bbs);
1543 /* The first element is loop pre-header. */
1544 region.safe_push (loop_preheader_edge (loop)->src);
1546 for (unsigned int i = 0; i < loop->num_nodes; i++)
1548 basic_block bb = ifc_bbs[i];
1549 region.safe_push (bb);
1550 /* Find loop postheader. */
1551 edge e;
1552 edge_iterator ei;
1553 FOR_EACH_EDGE (e, ei, bb->succs)
1554 if (loop_exit_edge_p (loop, e))
1556 exit_bb = e->dest;
1557 break;
1560 /* The last element is loop post-header. */
1561 gcc_assert (exit_bb);
1562 region.safe_push (exit_bb);
1563 return region;
1566 /* Return true when LOOP is if-convertible. This is a helper function
1567 for if_convertible_loop_p. REFS and DDRS are initialized and freed
1568 in if_convertible_loop_p. */
1570 static bool
1571 if_convertible_loop_p_1 (class loop *loop, vec<data_reference_p> *refs)
1573 unsigned int i;
1574 basic_block exit_bb = NULL;
1575 vec<basic_block> region;
1577 calculate_dominance_info (CDI_DOMINATORS);
1579 for (i = 0; i < loop->num_nodes; i++)
1581 basic_block bb = ifc_bbs[i];
1583 if (!if_convertible_bb_p (loop, bb, exit_bb))
1584 return false;
1586 if (bb_with_exit_edge_p (loop, bb))
1587 exit_bb = bb;
1590 data_reference_p dr;
1592 innermost_DR_map
1593 = new hash_map<innermost_loop_behavior_hash, data_reference_p>;
1594 baseref_DR_map = new hash_map<tree_operand_hash, data_reference_p>;
1596 /* Compute post-dominator tree locally. */
1597 region = build_region (loop);
1598 calculate_dominance_info_for_region (CDI_POST_DOMINATORS, region);
1600 predicate_bbs (loop);
1602 /* Free post-dominator tree since it is not used after predication. */
1603 free_dominance_info_for_region (cfun, CDI_POST_DOMINATORS, region);
1604 region.release ();
1606 for (i = 0; refs->iterate (i, &dr); i++)
1608 tree ref = DR_REF (dr);
1610 dr->aux = XNEW (struct ifc_dr);
1611 DR_BASE_W_UNCONDITIONALLY (dr) = false;
1612 DR_RW_UNCONDITIONALLY (dr) = false;
1613 DR_W_UNCONDITIONALLY (dr) = false;
1614 IFC_DR (dr)->rw_predicate = boolean_false_node;
1615 IFC_DR (dr)->w_predicate = boolean_false_node;
1616 IFC_DR (dr)->base_w_predicate = boolean_false_node;
1617 if (gimple_uid (DR_STMT (dr)) == 0)
1618 gimple_set_uid (DR_STMT (dr), i + 1);
1620 /* If DR doesn't have innermost loop behavior or it's a compound
1621 memory reference, we synthesize its innermost loop behavior
1622 for hashing. */
1623 if (TREE_CODE (ref) == COMPONENT_REF
1624 || TREE_CODE (ref) == IMAGPART_EXPR
1625 || TREE_CODE (ref) == REALPART_EXPR
1626 || !(DR_BASE_ADDRESS (dr) || DR_OFFSET (dr)
1627 || DR_INIT (dr) || DR_STEP (dr)))
1629 while (TREE_CODE (ref) == COMPONENT_REF
1630 || TREE_CODE (ref) == IMAGPART_EXPR
1631 || TREE_CODE (ref) == REALPART_EXPR)
1632 ref = TREE_OPERAND (ref, 0);
1634 memset (&DR_INNERMOST (dr), 0, sizeof (DR_INNERMOST (dr)));
1635 DR_BASE_ADDRESS (dr) = ref;
1637 hash_memrefs_baserefs_and_store_DRs_read_written_info (dr);
1640 for (i = 0; i < loop->num_nodes; i++)
1642 basic_block bb = ifc_bbs[i];
1643 gimple_stmt_iterator itr;
1645 /* Check the if-convertibility of statements in predicated BBs. */
1646 if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
1647 for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr))
1648 if (!if_convertible_stmt_p (gsi_stmt (itr), *refs))
1649 return false;
1652 /* Checking PHIs needs to be done after stmts, as the fact whether there
1653 are any masked loads or stores affects the tests. */
1654 for (i = 0; i < loop->num_nodes; i++)
1656 basic_block bb = ifc_bbs[i];
1657 gphi_iterator itr;
1659 for (itr = gsi_start_phis (bb); !gsi_end_p (itr); gsi_next (&itr))
1660 if (!if_convertible_phi_p (loop, bb, itr.phi ()))
1661 return false;
1664 if (dump_file)
1665 fprintf (dump_file, "Applying if-conversion\n");
1667 return true;
1670 /* Return true when LOOP is if-convertible.
1671 LOOP is if-convertible if:
1672 - it is innermost,
1673 - it has two or more basic blocks,
1674 - it has only one exit,
1675 - loop header is not the exit edge,
1676 - if its basic blocks and phi nodes are if convertible. */
1678 static bool
1679 if_convertible_loop_p (class loop *loop, vec<data_reference_p> *refs)
1681 edge e;
1682 edge_iterator ei;
1683 bool res = false;
1685 /* Handle only innermost loop. */
1686 if (!loop || loop->inner)
1688 if (dump_file && (dump_flags & TDF_DETAILS))
1689 fprintf (dump_file, "not innermost loop\n");
1690 return false;
1693 /* If only one block, no need for if-conversion. */
1694 if (loop->num_nodes <= 2)
1696 if (dump_file && (dump_flags & TDF_DETAILS))
1697 fprintf (dump_file, "less than 2 basic blocks\n");
1698 return false;
1701 /* If one of the loop header's edge is an exit edge then do not
1702 apply if-conversion. */
1703 FOR_EACH_EDGE (e, ei, loop->header->succs)
1704 if (loop_exit_edge_p (loop, e))
1705 return false;
1707 res = if_convertible_loop_p_1 (loop, refs);
1709 delete innermost_DR_map;
1710 innermost_DR_map = NULL;
1712 delete baseref_DR_map;
1713 baseref_DR_map = NULL;
1715 return res;
1718 /* Return reduc_1 if has_nop.
1720 if (...)
1721 tmp1 = (unsigned type) reduc_1;
1722 tmp2 = tmp1 + rhs2;
1723 reduc_3 = (signed type) tmp2. */
1724 static tree
1725 strip_nop_cond_scalar_reduction (bool has_nop, tree op)
1727 if (!has_nop)
1728 return op;
1730 if (TREE_CODE (op) != SSA_NAME)
1731 return NULL_TREE;
1733 gassign *stmt = safe_dyn_cast <gassign *> (SSA_NAME_DEF_STMT (op));
1734 if (!stmt
1735 || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
1736 || !tree_nop_conversion_p (TREE_TYPE (op), TREE_TYPE
1737 (gimple_assign_rhs1 (stmt))))
1738 return NULL_TREE;
1740 return gimple_assign_rhs1 (stmt);
1743 /* Returns true if def-stmt for phi argument ARG is simple increment/decrement
1744 which is in predicated basic block.
1745 In fact, the following PHI pattern is searching:
1746 loop-header:
1747 reduc_1 = PHI <..., reduc_2>
1749 if (...)
1750 reduc_3 = ...
1751 reduc_2 = PHI <reduc_1, reduc_3>
1753 ARG_0 and ARG_1 are correspondent PHI arguments.
1754 REDUC, OP0 and OP1 contain reduction stmt and its operands.
1755 EXTENDED is true if PHI has > 2 arguments. */
1757 static bool
1758 is_cond_scalar_reduction (gimple *phi, gimple **reduc, tree arg_0, tree arg_1,
1759 tree *op0, tree *op1, bool extended, bool* has_nop,
1760 gimple **nop_reduc)
1762 tree lhs, r_op1, r_op2, r_nop1, r_nop2;
1763 gimple *stmt;
1764 gimple *header_phi = NULL;
1765 enum tree_code reduction_op;
1766 basic_block bb = gimple_bb (phi);
1767 class loop *loop = bb->loop_father;
1768 edge latch_e = loop_latch_edge (loop);
1769 imm_use_iterator imm_iter;
1770 use_operand_p use_p;
1771 edge e;
1772 edge_iterator ei;
1773 bool result = *has_nop = false;
1774 if (TREE_CODE (arg_0) != SSA_NAME || TREE_CODE (arg_1) != SSA_NAME)
1775 return false;
1777 if (!extended && gimple_code (SSA_NAME_DEF_STMT (arg_0)) == GIMPLE_PHI)
1779 lhs = arg_1;
1780 header_phi = SSA_NAME_DEF_STMT (arg_0);
1781 stmt = SSA_NAME_DEF_STMT (arg_1);
1783 else if (gimple_code (SSA_NAME_DEF_STMT (arg_1)) == GIMPLE_PHI)
1785 lhs = arg_0;
1786 header_phi = SSA_NAME_DEF_STMT (arg_1);
1787 stmt = SSA_NAME_DEF_STMT (arg_0);
1789 else
1790 return false;
1791 if (gimple_bb (header_phi) != loop->header)
1792 return false;
1794 if (PHI_ARG_DEF_FROM_EDGE (header_phi, latch_e) != PHI_RESULT (phi))
1795 return false;
1797 if (gimple_code (stmt) != GIMPLE_ASSIGN
1798 || gimple_has_volatile_ops (stmt))
1799 return false;
1801 if (!flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
1802 return false;
1804 if (!is_predicated (gimple_bb (stmt)))
1805 return false;
1807 /* Check that stmt-block is predecessor of phi-block. */
1808 FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
1809 if (e->dest == bb)
1811 result = true;
1812 break;
1814 if (!result)
1815 return false;
1817 if (!has_single_use (lhs))
1818 return false;
1820 reduction_op = gimple_assign_rhs_code (stmt);
1822 /* Catch something like below
1824 loop-header:
1825 reduc_1 = PHI <..., reduc_2>
1827 if (...)
1828 tmp1 = (unsigned type) reduc_1;
1829 tmp2 = tmp1 + rhs2;
1830 reduc_3 = (signed type) tmp2;
1832 reduc_2 = PHI <reduc_1, reduc_3>
1834 and convert to
1836 reduc_2 = PHI <0, reduc_1>
1837 tmp1 = (unsigned type)reduc_1;
1838 ifcvt = cond_expr ? rhs2 : 0
1839 tmp2 = tmp1 +/- ifcvt;
1840 reduc_1 = (signed type)tmp2; */
1842 if (CONVERT_EXPR_CODE_P (reduction_op))
1844 lhs = gimple_assign_rhs1 (stmt);
1845 if (TREE_CODE (lhs) != SSA_NAME
1846 || !has_single_use (lhs))
1847 return false;
1849 *nop_reduc = stmt;
1850 stmt = SSA_NAME_DEF_STMT (lhs);
1851 if (gimple_bb (stmt) != gimple_bb (*nop_reduc)
1852 || !is_gimple_assign (stmt))
1853 return false;
1855 *has_nop = true;
1856 reduction_op = gimple_assign_rhs_code (stmt);
1859 if (reduction_op != PLUS_EXPR
1860 && reduction_op != MINUS_EXPR
1861 && reduction_op != MULT_EXPR
1862 && reduction_op != BIT_IOR_EXPR
1863 && reduction_op != BIT_XOR_EXPR
1864 && reduction_op != BIT_AND_EXPR)
1865 return false;
1866 r_op1 = gimple_assign_rhs1 (stmt);
1867 r_op2 = gimple_assign_rhs2 (stmt);
1869 r_nop1 = strip_nop_cond_scalar_reduction (*has_nop, r_op1);
1870 r_nop2 = strip_nop_cond_scalar_reduction (*has_nop, r_op2);
1872 /* Make R_OP1 to hold reduction variable. */
1873 if (r_nop2 == PHI_RESULT (header_phi)
1874 && commutative_tree_code (reduction_op))
1876 std::swap (r_op1, r_op2);
1877 std::swap (r_nop1, r_nop2);
1879 else if (r_nop1 != PHI_RESULT (header_phi))
1880 return false;
1882 if (*has_nop)
1884 /* Check that R_NOP1 is used in nop_stmt or in PHI only. */
1885 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, r_nop1)
1887 gimple *use_stmt = USE_STMT (use_p);
1888 if (is_gimple_debug (use_stmt))
1889 continue;
1890 if (use_stmt == SSA_NAME_DEF_STMT (r_op1))
1891 continue;
1892 if (use_stmt != phi)
1893 return false;
1897 /* Check that R_OP1 is used in reduction stmt or in PHI only. */
1898 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, r_op1)
1900 gimple *use_stmt = USE_STMT (use_p);
1901 if (is_gimple_debug (use_stmt))
1902 continue;
1903 if (use_stmt == stmt)
1904 continue;
1905 if (gimple_code (use_stmt) != GIMPLE_PHI)
1906 return false;
1909 *op0 = r_op1; *op1 = r_op2;
1910 *reduc = stmt;
1911 return true;
1914 /* Converts conditional scalar reduction into unconditional form, e.g.
1915 bb_4
1916 if (_5 != 0) goto bb_5 else goto bb_6
1917 end_bb_4
1918 bb_5
1919 res_6 = res_13 + 1;
1920 end_bb_5
1921 bb_6
1922 # res_2 = PHI <res_13(4), res_6(5)>
1923 end_bb_6
1925 will be converted into sequence
1926 _ifc__1 = _5 != 0 ? 1 : 0;
1927 res_2 = res_13 + _ifc__1;
1928 Argument SWAP tells that arguments of conditional expression should be
1929 swapped.
1930 If LOOP_VERSIONED is true if we assume that we versioned the loop for
1931 vectorization. In that case we can create a COND_OP.
1932 Returns rhs of resulting PHI assignment. */
1934 static tree
1935 convert_scalar_cond_reduction (gimple *reduc, gimple_stmt_iterator *gsi,
1936 tree cond, tree op0, tree op1, bool swap,
1937 bool has_nop, gimple* nop_reduc,
1938 bool loop_versioned)
1940 gimple_stmt_iterator stmt_it;
1941 gimple *new_assign;
1942 tree rhs;
1943 tree rhs1 = gimple_assign_rhs1 (reduc);
1944 tree lhs = gimple_assign_lhs (reduc);
1945 tree tmp = make_temp_ssa_name (TREE_TYPE (rhs1), NULL, "_ifc_");
1946 tree c;
1947 enum tree_code reduction_op = gimple_assign_rhs_code (reduc);
1948 tree op_nochange = neutral_op_for_reduction (TREE_TYPE (rhs1), reduction_op,
1949 NULL, false);
1950 gimple_seq stmts = NULL;
1952 if (dump_file && (dump_flags & TDF_DETAILS))
1954 fprintf (dump_file, "Found cond scalar reduction.\n");
1955 print_gimple_stmt (dump_file, reduc, 0, TDF_SLIM);
1958 /* If possible create a COND_OP instead of a COND_EXPR and an OP_EXPR.
1959 The COND_OP will have a neutral_op else value. */
1960 internal_fn ifn;
1961 ifn = get_conditional_internal_fn (reduction_op);
1962 if (loop_versioned && ifn != IFN_LAST
1963 && vectorized_internal_fn_supported_p (ifn, TREE_TYPE (lhs))
1964 && !swap)
1966 gcall *cond_call = gimple_build_call_internal (ifn, 4,
1967 unshare_expr (cond),
1968 op0, op1, op0);
1969 gsi_insert_before (gsi, cond_call, GSI_SAME_STMT);
1970 gimple_call_set_lhs (cond_call, tmp);
1971 rhs = tmp;
1973 else
1975 /* Build cond expression using COND and constant operand
1976 of reduction rhs. */
1977 c = fold_build_cond_expr (TREE_TYPE (rhs1),
1978 unshare_expr (cond),
1979 swap ? op_nochange : op1,
1980 swap ? op1 : op_nochange);
1981 /* Create assignment stmt and insert it at GSI. */
1982 new_assign = gimple_build_assign (tmp, c);
1983 gsi_insert_before (gsi, new_assign, GSI_SAME_STMT);
1984 /* Build rhs for unconditional increment/decrement/logic_operation. */
1985 rhs = gimple_build (&stmts, reduction_op,
1986 TREE_TYPE (rhs1), op0, tmp);
1989 if (has_nop)
1991 rhs = gimple_convert (&stmts,
1992 TREE_TYPE (gimple_assign_lhs (nop_reduc)), rhs);
1993 stmt_it = gsi_for_stmt (nop_reduc);
1994 gsi_remove (&stmt_it, true);
1995 release_defs (nop_reduc);
1997 gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1999 /* Delete original reduction stmt. */
2000 stmt_it = gsi_for_stmt (reduc);
2001 gsi_remove (&stmt_it, true);
2002 release_defs (reduc);
2003 return rhs;
2006 /* Generate a simplified conditional. */
2008 static tree
2009 gen_simplified_condition (tree cond, scalar_cond_masked_set_type &cond_set)
2011 /* Check if the value is already live in a previous branch. This resolves
2012 nested conditionals from diamond PHI reductions. */
2013 if (TREE_CODE (cond) == SSA_NAME)
2015 gimple *stmt = SSA_NAME_DEF_STMT (cond);
2016 gassign *assign = NULL;
2017 if ((assign = as_a <gassign *> (stmt))
2018 && gimple_assign_rhs_code (assign) == BIT_AND_EXPR)
2020 tree arg1 = gimple_assign_rhs1 (assign);
2021 tree arg2 = gimple_assign_rhs2 (assign);
2022 if (cond_set.contains ({ arg1, 1 }))
2023 arg1 = boolean_true_node;
2024 else
2025 arg1 = gen_simplified_condition (arg1, cond_set);
2027 if (cond_set.contains ({ arg2, 1 }))
2028 arg2 = boolean_true_node;
2029 else
2030 arg2 = gen_simplified_condition (arg2, cond_set);
2032 cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, arg1, arg2);
2035 return cond;
2038 /* Structure used to track meta-data on PHI arguments used to generate
2039 most efficient comparison sequence to slatten a PHI node. */
2041 typedef struct ifcvt_arg_entry
2043 /* The PHI node argument value. */
2044 tree arg;
2046 /* The number of compares required to reach this PHI node from start of the
2047 BB being if-converted. */
2048 unsigned num_compares;
2050 /* The number of times this PHI node argument appears in the current PHI
2051 node. */
2052 unsigned occurs;
2054 /* The indices at which this PHI arg occurs inside the PHI node. */
2055 vec <int> *indexes;
2056 } ifcvt_arg_entry_t;
2058 /* Produce condition for all occurrences of ARG in PHI node. Set *INVERT
2059 as to whether the condition is inverted. */
2061 static tree
2062 gen_phi_arg_condition (gphi *phi, ifcvt_arg_entry_t &arg,
2063 gimple_stmt_iterator *gsi,
2064 scalar_cond_masked_set_type &cond_set, bool *invert)
2066 int len;
2067 int i;
2068 tree cond = NULL_TREE;
2069 tree c;
2070 edge e;
2072 *invert = false;
2073 len = arg.indexes->length ();
2074 gcc_assert (len > 0);
2075 for (i = 0; i < len; i++)
2077 e = gimple_phi_arg_edge (phi, (*arg.indexes)[i]);
2078 c = bb_predicate (e->src);
2079 if (is_true_predicate (c))
2081 cond = c;
2082 break;
2084 /* If we have just a single inverted predicate, signal that and
2085 instead invert the COND_EXPR arms. */
2086 if (len == 1 && TREE_CODE (c) == TRUTH_NOT_EXPR)
2088 c = TREE_OPERAND (c, 0);
2089 *invert = true;
2092 c = gen_simplified_condition (c, cond_set);
2093 c = force_gimple_operand_gsi (gsi, unshare_expr (c),
2094 true, NULL_TREE, true, GSI_SAME_STMT);
2095 if (cond != NULL_TREE)
2097 /* Must build OR expression. */
2098 cond = fold_or_predicates (EXPR_LOCATION (c), c, cond);
2099 cond = force_gimple_operand_gsi (gsi, unshare_expr (cond), true,
2100 NULL_TREE, true, GSI_SAME_STMT);
2102 else
2103 cond = c;
2105 /* Register the new possibly simplified conditional. When more than 2
2106 entries in a phi node we chain entries in the false branch, so the
2107 inverted condition is active. */
2108 scalar_cond_masked_key pred_cond ({ cond, 1 });
2109 if (!*invert)
2110 pred_cond.inverted_p = !pred_cond.inverted_p;
2111 cond_set.add (pred_cond);
2113 gcc_assert (cond != NULL_TREE);
2114 return cond;
2117 /* Create the smallest nested conditional possible. On pre-order we record
2118 which conditionals are live, and on post-order rewrite the chain by removing
2119 already active conditions.
2121 As an example we simplify:
2123 _7 = a_10 < 0;
2124 _21 = a_10 >= 0;
2125 _22 = a_10 < e_11(D);
2126 _23 = _21 & _22;
2127 _ifc__42 = _23 ? t_13 : 0;
2128 t_6 = _7 ? 1 : _ifc__42
2130 into
2132 _7 = a_10 < 0;
2133 _22 = a_10 < e_11(D);
2134 _ifc__42 = _22 ? t_13 : 0;
2135 t_6 = _7 ? 1 : _ifc__42;
2137 which produces better code. */
2139 static tree
2140 gen_phi_nest_statement (gphi *phi, gimple_stmt_iterator *gsi,
2141 scalar_cond_masked_set_type &cond_set, tree type,
2142 gimple **res_stmt, tree lhs0,
2143 vec<struct ifcvt_arg_entry> &args, unsigned idx)
2145 if (idx == args.length ())
2146 return args[idx - 1].arg;
2148 bool invert;
2149 tree cond = gen_phi_arg_condition (phi, args[idx - 1], gsi, cond_set,
2150 &invert);
2151 tree arg1 = gen_phi_nest_statement (phi, gsi, cond_set, type, res_stmt, lhs0,
2152 args, idx + 1);
2154 unsigned prev = idx;
2155 unsigned curr = prev - 1;
2156 tree arg0 = args[curr].arg;
2157 tree rhs, lhs;
2158 if (idx > 1)
2159 lhs = make_temp_ssa_name (type, NULL, "_ifc_");
2160 else
2161 lhs = lhs0;
2163 if (invert)
2164 rhs = fold_build_cond_expr (type, unshare_expr (cond),
2165 arg1, arg0);
2166 else
2167 rhs = fold_build_cond_expr (type, unshare_expr (cond),
2168 arg0, arg1);
2169 gassign *new_stmt = gimple_build_assign (lhs, rhs);
2170 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
2171 update_stmt (new_stmt);
2172 *res_stmt = new_stmt;
2173 return lhs;
2176 /* When flattening a PHI node we have a choice of which conditions to test to
2177 for all the paths from the start of the dominator block of the BB with the
2178 PHI node. If the PHI node has X arguments we have to only test X - 1
2179 conditions as the last one is implicit. It does matter which conditions we
2180 test first. We should test the shortest condition first (distance here is
2181 measures in the number of logical operators in the condition) and the
2182 longest one last. This allows us to skip testing the most expensive
2183 condition. To accomplish this we need to sort the conditions. P1 and P2
2184 are sorted first based on the number of logical operations (num_compares)
2185 and then by how often they occur in the PHI node. */
2187 static int
2188 cmp_arg_entry (const void *p1, const void *p2, void * /* data. */)
2190 const ifcvt_arg_entry sval1 = *(const ifcvt_arg_entry *)p1;
2191 const ifcvt_arg_entry sval2 = *(const ifcvt_arg_entry *)p2;
2193 if (sval1.num_compares < sval2.num_compares)
2194 return -1;
2195 else if (sval1.num_compares > sval2.num_compares)
2196 return 1;
2198 if (sval1.occurs < sval2.occurs)
2199 return -1;
2200 else if (sval1.occurs > sval2.occurs)
2201 return 1;
2203 return 0;
2206 /* Replace a scalar PHI node with a COND_EXPR using COND as condition.
2207 This routine can handle PHI nodes with more than two arguments.
2209 For example,
2210 S1: A = PHI <x1(1), x2(5)>
2211 is converted into,
2212 S2: A = cond ? x1 : x2;
2214 The generated code is inserted at GSI that points to the top of
2215 basic block's statement list.
2216 If PHI node has more than two arguments a chain of conditional
2217 expression is produced.
2218 LOOP_VERSIONED should be true if we know that the loop was versioned for
2219 vectorization. */
2222 static void
2223 predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi, bool loop_versioned)
2225 gimple *new_stmt = NULL, *reduc, *nop_reduc;
2226 tree rhs, res, arg0, arg1, op0, op1, scev;
2227 tree cond;
2228 unsigned int index0;
2229 edge e;
2230 basic_block bb;
2231 unsigned int i;
2232 bool has_nop;
2234 res = gimple_phi_result (phi);
2235 if (virtual_operand_p (res))
2236 return;
2238 if ((rhs = degenerate_phi_result (phi))
2239 || ((scev = analyze_scalar_evolution (gimple_bb (phi)->loop_father,
2240 res))
2241 && !chrec_contains_undetermined (scev)
2242 && scev != res
2243 && (rhs = gimple_phi_arg_def (phi, 0))))
2245 if (dump_file && (dump_flags & TDF_DETAILS))
2247 fprintf (dump_file, "Degenerate phi!\n");
2248 print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
2250 new_stmt = gimple_build_assign (res, rhs);
2251 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
2252 update_stmt (new_stmt);
2253 return;
2256 bb = gimple_bb (phi);
2257 /* Keep track of conditionals already seen. */
2258 scalar_cond_masked_set_type cond_set;
2259 if (EDGE_COUNT (bb->preds) == 2)
2261 /* Predicate ordinary PHI node with 2 arguments. */
2262 edge first_edge, second_edge;
2263 basic_block true_bb;
2264 first_edge = EDGE_PRED (bb, 0);
2265 second_edge = EDGE_PRED (bb, 1);
2266 cond = bb_predicate (first_edge->src);
2267 cond_set.add ({ cond, 1 });
2268 if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
2269 std::swap (first_edge, second_edge);
2270 if (EDGE_COUNT (first_edge->src->succs) > 1)
2272 cond = bb_predicate (second_edge->src);
2273 if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
2274 cond = TREE_OPERAND (cond, 0);
2275 else
2276 first_edge = second_edge;
2278 else
2279 cond = bb_predicate (first_edge->src);
2281 /* Gimplify the condition to a valid cond-expr conditonal operand. */
2282 cond = gen_simplified_condition (cond, cond_set);
2283 cond = force_gimple_operand_gsi (gsi, unshare_expr (cond), true,
2284 NULL_TREE, true, GSI_SAME_STMT);
2285 true_bb = first_edge->src;
2286 if (EDGE_PRED (bb, 1)->src == true_bb)
2288 arg0 = gimple_phi_arg_def (phi, 1);
2289 arg1 = gimple_phi_arg_def (phi, 0);
2291 else
2293 arg0 = gimple_phi_arg_def (phi, 0);
2294 arg1 = gimple_phi_arg_def (phi, 1);
2296 if (is_cond_scalar_reduction (phi, &reduc, arg0, arg1,
2297 &op0, &op1, false, &has_nop,
2298 &nop_reduc))
2300 /* Convert reduction stmt into vectorizable form. */
2301 rhs = convert_scalar_cond_reduction (reduc, gsi, cond, op0, op1,
2302 true_bb != gimple_bb (reduc),
2303 has_nop, nop_reduc,
2304 loop_versioned);
2305 redundant_ssa_names.safe_push (std::make_pair (res, rhs));
2307 else
2308 /* Build new RHS using selected condition and arguments. */
2309 rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond),
2310 arg0, arg1);
2311 new_stmt = gimple_build_assign (res, rhs);
2312 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
2313 gimple_stmt_iterator new_gsi = gsi_for_stmt (new_stmt);
2314 if (fold_stmt (&new_gsi, follow_all_ssa_edges))
2316 new_stmt = gsi_stmt (new_gsi);
2317 update_stmt (new_stmt);
2320 if (dump_file && (dump_flags & TDF_DETAILS))
2322 fprintf (dump_file, "new phi replacement stmt\n");
2323 print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
2325 return;
2328 /* Create hashmap for PHI node which contain vector of argument indexes
2329 having the same value. */
2330 bool swap = false;
2331 hash_map<tree_operand_hash, auto_vec<int> > phi_arg_map;
2332 unsigned int num_args = gimple_phi_num_args (phi);
2333 /* Vector of different PHI argument values. */
2334 auto_vec<ifcvt_arg_entry_t> args;
2336 /* Compute phi_arg_map, determine the list of unique PHI args and the indices
2337 where they are in the PHI node. The indices will be used to determine
2338 the conditions to apply and their complexity. */
2339 for (i = 0; i < num_args; i++)
2341 tree arg;
2343 arg = gimple_phi_arg_def (phi, i);
2344 if (!phi_arg_map.get (arg))
2345 args.safe_push ({ arg, 0, 0, NULL });
2346 phi_arg_map.get_or_insert (arg).safe_push (i);
2349 /* Determine element with max number of occurrences and complexity. Looking
2350 at only number of occurrences as a measure for complexity isn't enough as
2351 all usages can be unique but the comparisons to reach the PHI node differ
2352 per branch. */
2353 for (unsigned i = 0; i < args.length (); i++)
2355 unsigned int len = 0;
2356 vec<int> *indices = phi_arg_map.get (args[i].arg);
2357 for (int index : *indices)
2359 edge e = gimple_phi_arg_edge (phi, index);
2360 len += get_bb_num_predicate_stmts (e->src);
2363 unsigned occur = indices->length ();
2364 if (dump_file && (dump_flags & TDF_DETAILS))
2365 fprintf (dump_file, "Ranking %d as len=%d, idx=%d\n", i, len, occur);
2366 args[i].num_compares = len;
2367 args[i].occurs = occur;
2368 args[i].indexes = indices;
2371 /* Sort elements based on rankings ARGS. */
2372 args.stablesort (cmp_arg_entry, NULL);
2374 /* Handle one special case when number of arguments with different values
2375 is equal 2 and one argument has the only occurrence. Such PHI can be
2376 handled as if would have only 2 arguments. */
2377 if (args.length () == 2
2378 && args[0].indexes->length () == 1)
2380 index0 = (*args[0].indexes)[0];
2381 arg0 = args[0].arg;
2382 arg1 = args[1].arg;
2383 e = gimple_phi_arg_edge (phi, index0);
2384 cond = bb_predicate (e->src);
2385 if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
2387 swap = true;
2388 cond = TREE_OPERAND (cond, 0);
2390 /* Gimplify the condition to a valid cond-expr conditonal operand. */
2391 cond = force_gimple_operand_gsi (gsi, unshare_expr (cond), true,
2392 NULL_TREE, true, GSI_SAME_STMT);
2393 if (!(is_cond_scalar_reduction (phi, &reduc, arg0 , arg1,
2394 &op0, &op1, true, &has_nop, &nop_reduc)))
2395 rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond),
2396 swap ? arg1 : arg0,
2397 swap ? arg0 : arg1);
2398 else
2400 /* Convert reduction stmt into vectorizable form. */
2401 rhs = convert_scalar_cond_reduction (reduc, gsi, cond, op0, op1,
2402 swap, has_nop, nop_reduc,
2403 loop_versioned);
2404 redundant_ssa_names.safe_push (std::make_pair (res, rhs));
2406 new_stmt = gimple_build_assign (res, rhs);
2407 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
2408 update_stmt (new_stmt);
2410 else
2412 /* Common case. */
2413 tree type = TREE_TYPE (gimple_phi_result (phi));
2414 gen_phi_nest_statement (phi, gsi, cond_set, type, &new_stmt, res,
2415 args, 1);
2418 if (dump_file && (dump_flags & TDF_DETAILS))
2420 fprintf (dump_file, "new extended phi replacement stmt\n");
2421 print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
2425 /* Replaces in LOOP all the scalar phi nodes other than those in the
2426 LOOP->header block with conditional modify expressions.
2427 LOOP_VERSIONED should be true if we know that the loop was versioned for
2428 vectorization. */
2430 static void
2431 predicate_all_scalar_phis (class loop *loop, bool loop_versioned)
2433 basic_block bb;
2434 unsigned int orig_loop_num_nodes = loop->num_nodes;
2435 unsigned int i;
2437 for (i = 1; i < orig_loop_num_nodes; i++)
2439 gphi *phi;
2440 gimple_stmt_iterator gsi;
2441 gphi_iterator phi_gsi;
2442 bb = ifc_bbs[i];
2444 if (bb == loop->header)
2445 continue;
2447 phi_gsi = gsi_start_phis (bb);
2448 if (gsi_end_p (phi_gsi))
2449 continue;
2451 gsi = gsi_after_labels (bb);
2452 while (!gsi_end_p (phi_gsi))
2454 phi = phi_gsi.phi ();
2455 if (virtual_operand_p (gimple_phi_result (phi)))
2456 gsi_next (&phi_gsi);
2457 else
2459 predicate_scalar_phi (phi, &gsi, loop_versioned);
2460 remove_phi_node (&phi_gsi, false);
2466 /* Insert in each basic block of LOOP the statements produced by the
2467 gimplification of the predicates. */
2469 static void
2470 insert_gimplified_predicates (loop_p loop)
2472 unsigned int i;
2474 for (i = 0; i < loop->num_nodes; i++)
2476 basic_block bb = ifc_bbs[i];
2477 gimple_seq stmts;
2478 if (!is_predicated (bb))
2479 gcc_assert (bb_predicate_gimplified_stmts (bb) == NULL);
2480 if (!is_predicated (bb))
2482 /* Do not insert statements for a basic block that is not
2483 predicated. Also make sure that the predicate of the
2484 basic block is set to true. */
2485 reset_bb_predicate (bb);
2486 continue;
2489 stmts = bb_predicate_gimplified_stmts (bb);
2490 if (stmts)
2492 if (need_to_predicate)
2494 /* Insert the predicate of the BB just after the label,
2495 as the if-conversion of memory writes will use this
2496 predicate. */
2497 gimple_stmt_iterator gsi = gsi_after_labels (bb);
2498 gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
2500 else
2502 /* Insert the predicate of the BB at the end of the BB
2503 as this would reduce the register pressure: the only
2504 use of this predicate will be in successor BBs. */
2505 gimple_stmt_iterator gsi = gsi_last_bb (bb);
2507 if (gsi_end_p (gsi)
2508 || stmt_ends_bb_p (gsi_stmt (gsi)))
2509 gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
2510 else
2511 gsi_insert_seq_after (&gsi, stmts, GSI_SAME_STMT);
2514 /* Once the sequence is code generated, set it to NULL. */
2515 set_bb_predicate_gimplified_stmts (bb, NULL, true);
2520 /* Helper function for predicate_statements. Returns index of existent
2521 mask if it was created for given SIZE and -1 otherwise. */
2523 static int
2524 mask_exists (int size, const vec<int> &vec)
2526 unsigned int ix;
2527 int v;
2528 FOR_EACH_VEC_ELT (vec, ix, v)
2529 if (v == size)
2530 return (int) ix;
2531 return -1;
2534 /* Helper function for predicate_statements. STMT is a memory read or
2535 write and it needs to be predicated by MASK. Return a statement
2536 that does so. */
2538 static gimple *
2539 predicate_load_or_store (gimple_stmt_iterator *gsi, gassign *stmt, tree mask)
2541 gcall *new_stmt;
2543 tree lhs = gimple_assign_lhs (stmt);
2544 tree rhs = gimple_assign_rhs1 (stmt);
2545 tree ref = TREE_CODE (lhs) == SSA_NAME ? rhs : lhs;
2546 mark_addressable (ref);
2547 tree addr = force_gimple_operand_gsi (gsi, build_fold_addr_expr (ref),
2548 true, NULL_TREE, true, GSI_SAME_STMT);
2549 tree ptr = build_int_cst (reference_alias_ptr_type (ref),
2550 get_object_alignment (ref));
2551 /* Copy points-to info if possible. */
2552 if (TREE_CODE (addr) == SSA_NAME && !SSA_NAME_PTR_INFO (addr))
2553 copy_ref_info (build2 (MEM_REF, TREE_TYPE (ref), addr, ptr),
2554 ref);
2555 if (TREE_CODE (lhs) == SSA_NAME)
2557 /* Get a zero else value. This might not be what a target actually uses
2558 but we cannot be sure about which vector mode the vectorizer will
2559 choose. Therefore, leave the decision whether we need to force the
2560 inactive elements to zero to the vectorizer. */
2561 tree els = vect_get_mask_load_else (MASK_LOAD_ELSE_ZERO,
2562 TREE_TYPE (lhs));
2564 new_stmt
2565 = gimple_build_call_internal (IFN_MASK_LOAD, 4, addr,
2566 ptr, mask, els);
2568 gimple_call_set_lhs (new_stmt, lhs);
2569 gimple_set_vuse (new_stmt, gimple_vuse (stmt));
2571 else
2573 new_stmt
2574 = gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr,
2575 mask, rhs);
2576 gimple_move_vops (new_stmt, stmt);
2578 gimple_call_set_nothrow (new_stmt, true);
2579 return new_stmt;
2582 /* STMT uses OP_LHS. Check whether it is equivalent to:
2584 ... = OP_MASK ? OP_LHS : X;
2586 Return X if so, otherwise return null. OP_MASK is an SSA_NAME that is
2587 known to have value OP_COND. */
2589 static tree
2590 check_redundant_cond_expr (gimple *stmt, tree op_mask, tree op_cond,
2591 tree op_lhs)
2593 gassign *assign = dyn_cast <gassign *> (stmt);
2594 if (!assign || gimple_assign_rhs_code (assign) != COND_EXPR)
2595 return NULL_TREE;
2597 tree use_cond = gimple_assign_rhs1 (assign);
2598 tree if_true = gimple_assign_rhs2 (assign);
2599 tree if_false = gimple_assign_rhs3 (assign);
2601 if ((use_cond == op_mask || operand_equal_p (use_cond, op_cond, 0))
2602 && if_true == op_lhs)
2603 return if_false;
2605 if (inverse_conditions_p (use_cond, op_cond) && if_false == op_lhs)
2606 return if_true;
2608 return NULL_TREE;
2611 /* Return true if VALUE is available for use at STMT. SSA_NAMES is
2612 the set of SSA names defined earlier in STMT's block. */
2614 static bool
2615 value_available_p (gimple *stmt, hash_set<tree_ssa_name_hash> *ssa_names,
2616 tree value)
2618 if (is_gimple_min_invariant (value))
2619 return true;
2621 if (TREE_CODE (value) == SSA_NAME)
2623 if (SSA_NAME_IS_DEFAULT_DEF (value))
2624 return true;
2626 basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (value));
2627 basic_block use_bb = gimple_bb (stmt);
2628 return (def_bb == use_bb
2629 ? ssa_names->contains (value)
2630 : dominated_by_p (CDI_DOMINATORS, use_bb, def_bb));
2633 return false;
2636 /* Helper function for predicate_statements. STMT is a potentially-trapping
2637 arithmetic operation that needs to be predicated by MASK, an SSA_NAME that
2638 has value COND. Return a statement that does so. SSA_NAMES is the set of
2639 SSA names defined earlier in STMT's block. */
2641 static gimple *
2642 predicate_rhs_code (gassign *stmt, tree mask, tree cond,
2643 hash_set<tree_ssa_name_hash> *ssa_names)
2645 tree lhs = gimple_assign_lhs (stmt);
2646 tree_code code = gimple_assign_rhs_code (stmt);
2647 unsigned int nops = gimple_num_ops (stmt);
2648 internal_fn cond_fn = get_conditional_internal_fn (code);
2650 /* Construct the arguments to the conditional internal function. */
2651 auto_vec<tree, 8> args;
2652 args.safe_grow (nops + 1, true);
2653 args[0] = mask;
2654 for (unsigned int i = 1; i < nops; ++i)
2655 args[i] = gimple_op (stmt, i);
2656 args[nops] = NULL_TREE;
2658 /* Look for uses of the result to see whether they are COND_EXPRs that can
2659 be folded into the conditional call. */
2660 imm_use_iterator imm_iter;
2661 gimple *use_stmt;
2662 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, lhs)
2664 tree new_else = check_redundant_cond_expr (use_stmt, mask, cond, lhs);
2665 if (new_else && value_available_p (stmt, ssa_names, new_else))
2667 if (!args[nops])
2668 args[nops] = new_else;
2669 if (operand_equal_p (new_else, args[nops], 0))
2671 /* We have:
2673 LHS = IFN_COND (MASK, ..., ELSE);
2674 X = MASK ? LHS : ELSE;
2676 which makes X equivalent to LHS. */
2677 tree use_lhs = gimple_assign_lhs (use_stmt);
2678 redundant_ssa_names.safe_push (std::make_pair (use_lhs, lhs));
2682 if (!args[nops])
2683 args[nops] = targetm.preferred_else_value (cond_fn, TREE_TYPE (lhs),
2684 nops - 1, &args[1]);
2686 /* Create and insert the call. */
2687 gcall *new_stmt = gimple_build_call_internal_vec (cond_fn, args);
2688 gimple_call_set_lhs (new_stmt, lhs);
2689 gimple_call_set_nothrow (new_stmt, true);
2691 return new_stmt;
2694 /* Predicate each write to memory in LOOP.
2696 This function transforms control flow constructs containing memory
2697 writes of the form:
2699 | for (i = 0; i < N; i++)
2700 | if (cond)
2701 | A[i] = expr;
2703 into the following form that does not contain control flow:
2705 | for (i = 0; i < N; i++)
2706 | A[i] = cond ? expr : A[i];
2708 The original CFG looks like this:
2710 | bb_0
2711 | i = 0
2712 | end_bb_0
2714 | bb_1
2715 | if (i < N) goto bb_5 else goto bb_2
2716 | end_bb_1
2718 | bb_2
2719 | cond = some_computation;
2720 | if (cond) goto bb_3 else goto bb_4
2721 | end_bb_2
2723 | bb_3
2724 | A[i] = expr;
2725 | goto bb_4
2726 | end_bb_3
2728 | bb_4
2729 | goto bb_1
2730 | end_bb_4
2732 insert_gimplified_predicates inserts the computation of the COND
2733 expression at the beginning of the destination basic block:
2735 | bb_0
2736 | i = 0
2737 | end_bb_0
2739 | bb_1
2740 | if (i < N) goto bb_5 else goto bb_2
2741 | end_bb_1
2743 | bb_2
2744 | cond = some_computation;
2745 | if (cond) goto bb_3 else goto bb_4
2746 | end_bb_2
2748 | bb_3
2749 | cond = some_computation;
2750 | A[i] = expr;
2751 | goto bb_4
2752 | end_bb_3
2754 | bb_4
2755 | goto bb_1
2756 | end_bb_4
2758 predicate_statements is then predicating the memory write as follows:
2760 | bb_0
2761 | i = 0
2762 | end_bb_0
2764 | bb_1
2765 | if (i < N) goto bb_5 else goto bb_2
2766 | end_bb_1
2768 | bb_2
2769 | if (cond) goto bb_3 else goto bb_4
2770 | end_bb_2
2772 | bb_3
2773 | cond = some_computation;
2774 | A[i] = cond ? expr : A[i];
2775 | goto bb_4
2776 | end_bb_3
2778 | bb_4
2779 | goto bb_1
2780 | end_bb_4
2782 and finally combine_blocks removes the basic block boundaries making
2783 the loop vectorizable:
2785 | bb_0
2786 | i = 0
2787 | if (i < N) goto bb_5 else goto bb_1
2788 | end_bb_0
2790 | bb_1
2791 | cond = some_computation;
2792 | A[i] = cond ? expr : A[i];
2793 | if (i < N) goto bb_5 else goto bb_4
2794 | end_bb_1
2796 | bb_4
2797 | goto bb_1
2798 | end_bb_4
2801 static void
2802 predicate_statements (loop_p loop)
2804 unsigned int i, orig_loop_num_nodes = loop->num_nodes;
2805 auto_vec<int, 1> vect_sizes;
2806 auto_vec<tree, 1> vect_masks;
2807 hash_set<tree_ssa_name_hash> ssa_names;
2809 for (i = 1; i < orig_loop_num_nodes; i++)
2811 gimple_stmt_iterator gsi;
2812 basic_block bb = ifc_bbs[i];
2813 tree cond = bb_predicate (bb);
2814 bool swap;
2815 int index;
2817 if (is_true_predicate (cond))
2818 continue;
2820 swap = false;
2821 if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
2823 swap = true;
2824 cond = TREE_OPERAND (cond, 0);
2827 vect_sizes.truncate (0);
2828 vect_masks.truncate (0);
2830 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
2832 gassign *stmt = dyn_cast <gassign *> (gsi_stmt (gsi));
2833 tree lhs;
2834 if (!stmt)
2836 else if (is_false_predicate (cond)
2837 && gimple_vdef (stmt))
2839 unlink_stmt_vdef (stmt);
2840 gsi_remove (&gsi, true);
2841 release_defs (stmt);
2842 continue;
2844 else if (gimple_plf (stmt, GF_PLF_2)
2845 && is_gimple_assign (stmt))
2847 tree lhs = gimple_assign_lhs (stmt);
2848 tree mask;
2849 gimple *new_stmt;
2850 gimple_seq stmts = NULL;
2851 machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
2852 /* We checked before setting GF_PLF_2 that an equivalent
2853 integer mode exists. */
2854 int bitsize = GET_MODE_BITSIZE (mode).to_constant ();
2855 if (!vect_sizes.is_empty ()
2856 && (index = mask_exists (bitsize, vect_sizes)) != -1)
2857 /* Use created mask. */
2858 mask = vect_masks[index];
2859 else
2861 if (COMPARISON_CLASS_P (cond))
2862 mask = gimple_build (&stmts, TREE_CODE (cond),
2863 boolean_type_node,
2864 TREE_OPERAND (cond, 0),
2865 TREE_OPERAND (cond, 1));
2866 else
2867 mask = cond;
2869 if (swap)
2871 tree true_val
2872 = constant_boolean_node (true, TREE_TYPE (mask));
2873 mask = gimple_build (&stmts, BIT_XOR_EXPR,
2874 TREE_TYPE (mask), mask, true_val);
2876 gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
2878 /* Save mask and its size for further use. */
2879 vect_sizes.safe_push (bitsize);
2880 vect_masks.safe_push (mask);
2882 if (gimple_assign_single_p (stmt))
2883 new_stmt = predicate_load_or_store (&gsi, stmt, mask);
2884 else
2885 new_stmt = predicate_rhs_code (stmt, mask, cond, &ssa_names);
2887 gsi_replace (&gsi, new_stmt, true);
2889 else if (((lhs = gimple_assign_lhs (stmt)), true)
2890 && (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
2891 || POINTER_TYPE_P (TREE_TYPE (lhs)))
2892 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (lhs))
2893 && arith_code_with_undefined_signed_overflow
2894 (gimple_assign_rhs_code (stmt)))
2895 rewrite_to_defined_overflow (&gsi);
2896 else if (gimple_vdef (stmt))
2898 tree lhs = gimple_assign_lhs (stmt);
2899 tree rhs = gimple_assign_rhs1 (stmt);
2900 tree type = TREE_TYPE (lhs);
2902 lhs = ifc_temp_var (type, unshare_expr (lhs), &gsi);
2903 rhs = ifc_temp_var (type, unshare_expr (rhs), &gsi);
2904 if (swap)
2905 std::swap (lhs, rhs);
2906 cond = force_gimple_operand_gsi (&gsi, unshare_expr (cond), true,
2907 NULL_TREE, true, GSI_SAME_STMT);
2908 rhs = fold_build_cond_expr (type, unshare_expr (cond), rhs, lhs);
2909 gimple_assign_set_rhs1 (stmt, ifc_temp_var (type, rhs, &gsi));
2910 update_stmt (stmt);
2913 if (gimple_plf (gsi_stmt (gsi), GF_PLF_2)
2914 && is_gimple_call (gsi_stmt (gsi)))
2916 /* Convert functions that have a SIMD clone to IFN_MASK_CALL.
2917 This will cause the vectorizer to match the "in branch"
2918 clone variants, and serves to build the mask vector
2919 in a natural way. */
2920 tree mask = cond;
2921 gcall *call = dyn_cast <gcall *> (gsi_stmt (gsi));
2922 tree orig_fn = gimple_call_fn (call);
2923 int orig_nargs = gimple_call_num_args (call);
2924 auto_vec<tree> args;
2925 args.safe_push (orig_fn);
2926 for (int i = 0; i < orig_nargs; i++)
2927 args.safe_push (gimple_call_arg (call, i));
2928 /* If `swap', we invert the mask used for the if branch for use
2929 when masking the function call. */
2930 if (swap)
2932 gimple_seq stmts = NULL;
2933 tree true_val
2934 = constant_boolean_node (true, TREE_TYPE (mask));
2935 mask = gimple_build (&stmts, BIT_XOR_EXPR,
2936 TREE_TYPE (mask), mask, true_val);
2937 gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
2939 args.safe_push (mask);
2941 /* Replace the call with a IFN_MASK_CALL that has the extra
2942 condition parameter. */
2943 gcall *new_call = gimple_build_call_internal_vec (IFN_MASK_CALL,
2944 args);
2945 gimple_call_set_lhs (new_call, gimple_call_lhs (call));
2946 gsi_replace (&gsi, new_call, true);
2949 lhs = gimple_get_lhs (gsi_stmt (gsi));
2950 if (lhs && TREE_CODE (lhs) == SSA_NAME)
2951 ssa_names.add (lhs);
2952 gsi_next (&gsi);
2954 ssa_names.empty ();
2958 /* Remove all GIMPLE_CONDs and GIMPLE_LABELs and GIMPLE_SWITCH of all
2959 the basic blocks other than the exit and latch of the LOOP. Also
2960 resets the GIMPLE_DEBUG information. */
2962 static void
2963 remove_conditions_and_labels (loop_p loop)
2965 gimple_stmt_iterator gsi;
2966 unsigned int i;
2968 for (i = 0; i < loop->num_nodes; i++)
2970 basic_block bb = ifc_bbs[i];
2972 if (bb_with_exit_edge_p (loop, bb)
2973 || bb == loop->latch)
2974 continue;
2976 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
2977 switch (gimple_code (gsi_stmt (gsi)))
2979 case GIMPLE_COND:
2980 case GIMPLE_LABEL:
2981 case GIMPLE_SWITCH:
2982 gsi_remove (&gsi, true);
2983 break;
2985 case GIMPLE_DEBUG:
2986 /* ??? Should there be conditional GIMPLE_DEBUG_BINDs? */
2987 if (gimple_debug_bind_p (gsi_stmt (gsi)))
2989 gimple_debug_bind_reset_value (gsi_stmt (gsi));
2990 update_stmt (gsi_stmt (gsi));
2992 gsi_next (&gsi);
2993 break;
2995 default:
2996 gsi_next (&gsi);
3001 /* Combine all the basic blocks from LOOP into one or two super basic
3002 blocks. Replace PHI nodes with conditional modify expressions.
3003 LOOP_VERSIONED should be true if we know that the loop was versioned for
3004 vectorization. */
3006 static void
3007 combine_blocks (class loop *loop, bool loop_versioned)
3009 basic_block bb, exit_bb, merge_target_bb;
3010 unsigned int orig_loop_num_nodes = loop->num_nodes;
3011 unsigned int i;
3012 edge e;
3013 edge_iterator ei;
3015 /* Reset flow-sensitive info before predicating stmts or PHIs we
3016 might fold. */
3017 bool *predicated = XNEWVEC (bool, orig_loop_num_nodes);
3018 for (i = 0; i < orig_loop_num_nodes; i++)
3020 bb = ifc_bbs[i];
3021 predicated[i] = is_predicated (bb);
3022 if (predicated[i])
3024 for (auto gsi = gsi_start_phis (bb);
3025 !gsi_end_p (gsi); gsi_next (&gsi))
3026 reset_flow_sensitive_info (gimple_phi_result (*gsi));
3027 for (auto gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3029 gimple *stmt = gsi_stmt (gsi);
3030 ssa_op_iter i;
3031 tree op;
3032 FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF)
3033 reset_flow_sensitive_info (op);
3038 remove_conditions_and_labels (loop);
3039 insert_gimplified_predicates (loop);
3040 predicate_all_scalar_phis (loop, loop_versioned);
3042 if (need_to_predicate || need_to_rewrite_undefined)
3043 predicate_statements (loop);
3045 /* Merge basic blocks. */
3046 exit_bb = single_exit (loop)->src;
3047 gcc_assert (exit_bb != loop->latch);
3048 for (i = 0; i < orig_loop_num_nodes; i++)
3050 bb = ifc_bbs[i];
3051 free_bb_predicate (bb);
3054 merge_target_bb = loop->header;
3056 /* Get at the virtual def valid for uses starting at the first block
3057 we merge into the header. Without a virtual PHI the loop has the
3058 same virtual use on all stmts. */
3059 gphi *vphi = get_virtual_phi (loop->header);
3060 tree last_vdef = NULL_TREE;
3061 if (vphi)
3063 last_vdef = gimple_phi_result (vphi);
3064 for (gimple_stmt_iterator gsi = gsi_start_bb (loop->header);
3065 ! gsi_end_p (gsi); gsi_next (&gsi))
3066 if (gimple_vdef (gsi_stmt (gsi)))
3067 last_vdef = gimple_vdef (gsi_stmt (gsi));
3069 for (i = 1; i < orig_loop_num_nodes; i++)
3071 gimple_stmt_iterator gsi;
3072 gimple_stmt_iterator last;
3074 bb = ifc_bbs[i];
3076 if (bb == exit_bb || bb == loop->latch)
3077 continue;
3079 /* We release virtual PHIs late because we have to propagate them
3080 out using the current VUSE. The def might be the one used
3081 after the loop. */
3082 vphi = get_virtual_phi (bb);
3083 if (vphi)
3085 /* When there's just loads inside the loop a stray virtual
3086 PHI merging the uses can appear, update last_vdef from
3087 it. */
3088 if (!last_vdef)
3089 last_vdef = gimple_phi_arg_def (vphi, 0);
3090 imm_use_iterator iter;
3091 use_operand_p use_p;
3092 gimple *use_stmt;
3093 FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_phi_result (vphi))
3095 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
3096 SET_USE (use_p, last_vdef);
3098 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (vphi)))
3099 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (last_vdef) = 1;
3100 gsi = gsi_for_stmt (vphi);
3101 remove_phi_node (&gsi, true);
3104 /* Make stmts member of loop->header and clear range info from all stmts
3105 in BB which is now no longer executed conditional on a predicate we
3106 could have derived it from. */
3107 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3109 gimple *stmt = gsi_stmt (gsi);
3110 gimple_set_bb (stmt, merge_target_bb);
3111 /* Update virtual operands. */
3112 if (last_vdef)
3114 use_operand_p use_p = ssa_vuse_operand (stmt);
3115 if (use_p
3116 && USE_FROM_PTR (use_p) != last_vdef)
3117 SET_USE (use_p, last_vdef);
3118 if (gimple_vdef (stmt))
3119 last_vdef = gimple_vdef (stmt);
3121 else
3122 /* If this is the first load we arrive at update last_vdef
3123 so we handle stray PHIs correctly. */
3124 last_vdef = gimple_vuse (stmt);
3127 /* Update stmt list. */
3128 last = gsi_last_bb (merge_target_bb);
3129 gsi_insert_seq_after_without_update (&last, bb_seq (bb), GSI_NEW_STMT);
3130 set_bb_seq (bb, NULL);
3133 /* Fixup virtual operands in the exit block. */
3134 if (exit_bb
3135 && exit_bb != loop->header)
3137 /* We release virtual PHIs late because we have to propagate them
3138 out using the current VUSE. The def might be the one used
3139 after the loop. */
3140 vphi = get_virtual_phi (exit_bb);
3141 if (vphi)
3143 /* When there's just loads inside the loop a stray virtual
3144 PHI merging the uses can appear, update last_vdef from
3145 it. */
3146 if (!last_vdef)
3147 last_vdef = gimple_phi_arg_def (vphi, 0);
3148 imm_use_iterator iter;
3149 use_operand_p use_p;
3150 gimple *use_stmt;
3151 FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_phi_result (vphi))
3153 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
3154 SET_USE (use_p, last_vdef);
3156 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (vphi)))
3157 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (last_vdef) = 1;
3158 gimple_stmt_iterator gsi = gsi_for_stmt (vphi);
3159 remove_phi_node (&gsi, true);
3163 /* Now remove all the edges in the loop, except for those from the exit
3164 block and delete the blocks we elided. */
3165 for (i = 1; i < orig_loop_num_nodes; i++)
3167 bb = ifc_bbs[i];
3169 for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei));)
3171 if (e->src == exit_bb)
3172 ei_next (&ei);
3173 else
3174 remove_edge (e);
3177 for (i = 1; i < orig_loop_num_nodes; i++)
3179 bb = ifc_bbs[i];
3181 if (bb == exit_bb || bb == loop->latch)
3182 continue;
3184 delete_basic_block (bb);
3187 /* Re-connect the exit block. */
3188 if (exit_bb != NULL)
3190 if (exit_bb != loop->header)
3192 /* Connect this node to loop header. */
3193 make_single_succ_edge (loop->header, exit_bb, EDGE_FALLTHRU);
3194 set_immediate_dominator (CDI_DOMINATORS, exit_bb, loop->header);
3197 /* Redirect non-exit edges to loop->latch. */
3198 FOR_EACH_EDGE (e, ei, exit_bb->succs)
3200 if (!loop_exit_edge_p (loop, e))
3201 redirect_edge_and_branch (e, loop->latch);
3203 set_immediate_dominator (CDI_DOMINATORS, loop->latch, exit_bb);
3205 else
3207 /* If the loop does not have an exit, reconnect header and latch. */
3208 make_edge (loop->header, loop->latch, EDGE_FALLTHRU);
3209 set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header);
3212 /* If possible, merge loop header to the block with the exit edge.
3213 This reduces the number of basic blocks to two, to please the
3214 vectorizer that handles only loops with two nodes. */
3215 if (exit_bb
3216 && exit_bb != loop->header)
3218 if (can_merge_blocks_p (loop->header, exit_bb))
3219 merge_blocks (loop->header, exit_bb);
3222 free (ifc_bbs);
3223 ifc_bbs = NULL;
3224 free (predicated);
3227 /* Version LOOP before if-converting it; the original loop
3228 will be if-converted, the new copy of the loop will not,
3229 and the LOOP_VECTORIZED internal call will be guarding which
3230 loop to execute. The vectorizer pass will fold this
3231 internal call into either true or false.
3233 Note that this function intentionally invalidates profile. Both edges
3234 out of LOOP_VECTORIZED must have 100% probability so the profile remains
3235 consistent after the condition is folded in the vectorizer. */
3237 static class loop *
3238 version_loop_for_if_conversion (class loop *loop, vec<gimple *> *preds)
3240 basic_block cond_bb;
3241 tree cond = make_ssa_name (boolean_type_node);
3242 class loop *new_loop;
3243 gimple *g;
3244 gimple_stmt_iterator gsi;
3245 unsigned int save_length = 0;
3247 g = gimple_build_call_internal (IFN_LOOP_VECTORIZED, 2,
3248 build_int_cst (integer_type_node, loop->num),
3249 integer_zero_node);
3250 gimple_call_set_lhs (g, cond);
3252 void **saved_preds = NULL;
3253 if (any_complicated_phi || need_to_predicate)
3255 /* Save BB->aux around loop_version as that uses the same field. */
3256 save_length = loop->inner ? loop->inner->num_nodes : loop->num_nodes;
3257 saved_preds = XALLOCAVEC (void *, save_length);
3258 for (unsigned i = 0; i < save_length; i++)
3259 saved_preds[i] = ifc_bbs[i]->aux;
3262 initialize_original_copy_tables ();
3263 /* At this point we invalidate porfile confistency until IFN_LOOP_VECTORIZED
3264 is re-merged in the vectorizer. */
3265 new_loop = loop_version (loop, cond, &cond_bb,
3266 profile_probability::always (),
3267 profile_probability::always (),
3268 profile_probability::always (),
3269 profile_probability::always (), true);
3270 free_original_copy_tables ();
3272 if (any_complicated_phi || need_to_predicate)
3273 for (unsigned i = 0; i < save_length; i++)
3274 ifc_bbs[i]->aux = saved_preds[i];
3276 if (new_loop == NULL)
3277 return NULL;
3279 new_loop->dont_vectorize = true;
3280 new_loop->force_vectorize = false;
3281 gsi = gsi_last_bb (cond_bb);
3282 gimple_call_set_arg (g, 1, build_int_cst (integer_type_node, new_loop->num));
3283 if (preds)
3284 preds->safe_push (g);
3285 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
3286 update_ssa (TODO_update_ssa_no_phi);
3287 return new_loop;
3290 /* Return true when LOOP satisfies the follow conditions that will
3291 allow it to be recognized by the vectorizer for outer-loop
3292 vectorization:
3293 - The loop is not the root node of the loop tree.
3294 - The loop has exactly one inner loop.
3295 - The loop has a single exit.
3296 - The loop header has a single successor, which is the inner
3297 loop header.
3298 - Each of the inner and outer loop latches have a single
3299 predecessor.
3300 - The loop exit block has a single predecessor, which is the
3301 inner loop's exit block. */
3303 static bool
3304 versionable_outer_loop_p (class loop *loop)
3306 if (!loop_outer (loop)
3307 || loop->dont_vectorize
3308 || !loop->inner
3309 || loop->inner->next
3310 || !single_exit (loop)
3311 || !single_succ_p (loop->header)
3312 || single_succ (loop->header) != loop->inner->header
3313 || !single_pred_p (loop->latch)
3314 || !single_pred_p (loop->inner->latch))
3315 return false;
3317 basic_block outer_exit = single_pred (loop->latch);
3318 basic_block inner_exit = single_pred (loop->inner->latch);
3320 if (!single_pred_p (outer_exit) || single_pred (outer_exit) != inner_exit)
3321 return false;
3323 if (dump_file)
3324 fprintf (dump_file, "Found vectorizable outer loop for versioning\n");
3326 return true;
3329 /* Performs splitting of critical edges. Skip splitting and return false
3330 if LOOP will not be converted because:
3332 - LOOP is not well formed.
3333 - LOOP has PHI with more than MAX_PHI_ARG_NUM arguments.
3335 Last restriction is valid only if AGGRESSIVE_IF_CONV is false. */
3337 static bool
3338 ifcvt_split_critical_edges (class loop *loop, bool aggressive_if_conv)
3340 basic_block *body;
3341 basic_block bb;
3342 unsigned int num = loop->num_nodes;
3343 unsigned int i;
3344 edge e;
3345 edge_iterator ei;
3346 auto_vec<edge> critical_edges;
3348 /* Loop is not well formed. */
3349 if (loop->inner)
3350 return false;
3352 body = get_loop_body (loop);
3353 for (i = 0; i < num; i++)
3355 bb = body[i];
3356 if (!aggressive_if_conv
3357 && phi_nodes (bb)
3358 && EDGE_COUNT (bb->preds) > MAX_PHI_ARG_NUM)
3360 if (dump_file && (dump_flags & TDF_DETAILS))
3361 fprintf (dump_file,
3362 "BB %d has complicated PHI with more than %u args.\n",
3363 bb->index, MAX_PHI_ARG_NUM);
3365 free (body);
3366 return false;
3368 if (bb == loop->latch || bb_with_exit_edge_p (loop, bb))
3369 continue;
3371 /* Skip basic blocks not ending with conditional branch. */
3372 if (!safe_is_a <gcond *> (*gsi_last_bb (bb))
3373 && !safe_is_a <gswitch *> (*gsi_last_bb (bb)))
3374 continue;
3376 FOR_EACH_EDGE (e, ei, bb->succs)
3377 if (EDGE_CRITICAL_P (e) && e->dest->loop_father == loop)
3378 critical_edges.safe_push (e);
3380 free (body);
3382 while (critical_edges.length () > 0)
3384 e = critical_edges.pop ();
3385 /* Don't split if bb can be predicated along non-critical edge. */
3386 if (EDGE_COUNT (e->dest->preds) > 2 || all_preds_critical_p (e->dest))
3387 split_edge (e);
3390 return true;
3393 /* Delete redundant statements produced by predication which prevents
3394 loop vectorization. */
3396 static void
3397 ifcvt_local_dce (class loop *loop)
3399 gimple *stmt;
3400 gimple *stmt1;
3401 gimple *phi;
3402 gimple_stmt_iterator gsi;
3403 auto_vec<gimple *> worklist;
3404 enum gimple_code code;
3405 use_operand_p use_p;
3406 imm_use_iterator imm_iter;
3408 /* The loop has a single BB only. */
3409 basic_block bb = loop->header;
3410 tree latch_vdef = NULL_TREE;
3412 worklist.create (64);
3413 /* Consider all phi as live statements. */
3414 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3416 phi = gsi_stmt (gsi);
3417 gimple_set_plf (phi, GF_PLF_2, true);
3418 worklist.safe_push (phi);
3419 if (virtual_operand_p (gimple_phi_result (phi)))
3420 latch_vdef = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
3422 /* Consider load/store statements, CALL and COND as live. */
3423 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3425 stmt = gsi_stmt (gsi);
3426 if (is_gimple_debug (stmt))
3428 gimple_set_plf (stmt, GF_PLF_2, true);
3429 continue;
3431 if (gimple_store_p (stmt) || gimple_assign_load_p (stmt))
3433 gimple_set_plf (stmt, GF_PLF_2, true);
3434 worklist.safe_push (stmt);
3435 continue;
3437 code = gimple_code (stmt);
3438 if (code == GIMPLE_COND || code == GIMPLE_CALL || code == GIMPLE_SWITCH)
3440 gimple_set_plf (stmt, GF_PLF_2, true);
3441 worklist.safe_push (stmt);
3442 continue;
3444 gimple_set_plf (stmt, GF_PLF_2, false);
3446 if (code == GIMPLE_ASSIGN)
3448 tree lhs = gimple_assign_lhs (stmt);
3449 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
3451 stmt1 = USE_STMT (use_p);
3452 if (!is_gimple_debug (stmt1) && gimple_bb (stmt1) != bb)
3454 gimple_set_plf (stmt, GF_PLF_2, true);
3455 worklist.safe_push (stmt);
3456 break;
3461 /* Propagate liveness through arguments of live stmt. */
3462 while (worklist.length () > 0)
3464 ssa_op_iter iter;
3465 use_operand_p use_p;
3466 tree use;
3468 stmt = worklist.pop ();
3469 FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
3471 use = USE_FROM_PTR (use_p);
3472 if (TREE_CODE (use) != SSA_NAME)
3473 continue;
3474 stmt1 = SSA_NAME_DEF_STMT (use);
3475 if (gimple_bb (stmt1) != bb || gimple_plf (stmt1, GF_PLF_2))
3476 continue;
3477 gimple_set_plf (stmt1, GF_PLF_2, true);
3478 worklist.safe_push (stmt1);
3481 /* Delete dead statements. */
3482 gsi = gsi_last_bb (bb);
3483 while (!gsi_end_p (gsi))
3485 gimple_stmt_iterator gsiprev = gsi;
3486 gsi_prev (&gsiprev);
3487 stmt = gsi_stmt (gsi);
3488 if (!gimple_has_volatile_ops (stmt)
3489 && gimple_store_p (stmt)
3490 && gimple_vdef (stmt))
3492 tree lhs = gimple_get_lhs (stmt);
3493 ao_ref write;
3494 ao_ref_init (&write, lhs);
3496 if (dse_classify_store (&write, stmt, false, NULL, NULL, latch_vdef)
3497 == DSE_STORE_DEAD)
3498 delete_dead_or_redundant_assignment (&gsi, "dead");
3499 gsi = gsiprev;
3500 continue;
3503 if (gimple_plf (stmt, GF_PLF_2))
3505 gsi = gsiprev;
3506 continue;
3508 if (dump_file && (dump_flags & TDF_DETAILS))
3510 fprintf (dump_file, "Delete dead stmt in bb#%d\n", bb->index);
3511 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
3513 gsi_remove (&gsi, true);
3514 release_defs (stmt);
3515 gsi = gsiprev;
3519 /* Return true if VALUE is already available on edge PE. */
3521 static bool
3522 ifcvt_available_on_edge_p (edge pe, tree value)
3524 if (is_gimple_min_invariant (value))
3525 return true;
3527 if (TREE_CODE (value) == SSA_NAME)
3529 basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (value));
3530 if (!def_bb || dominated_by_p (CDI_DOMINATORS, pe->dest, def_bb))
3531 return true;
3534 return false;
3537 /* Return true if STMT can be hoisted from if-converted loop LOOP to
3538 edge PE. */
3540 static bool
3541 ifcvt_can_hoist (class loop *loop, edge pe, gimple *stmt)
3543 if (auto *call = dyn_cast<gcall *> (stmt))
3545 if (gimple_call_internal_p (call)
3546 && internal_fn_mask_index (gimple_call_internal_fn (call)) >= 0)
3547 return false;
3549 else if (auto *assign = dyn_cast<gassign *> (stmt))
3551 if (gimple_assign_rhs_code (assign) == COND_EXPR)
3552 return false;
3554 else
3555 return false;
3557 if (gimple_has_side_effects (stmt)
3558 || gimple_could_trap_p (stmt)
3559 || stmt_could_throw_p (cfun, stmt)
3560 || gimple_vdef (stmt)
3561 || gimple_vuse (stmt))
3562 return false;
3564 int num_args = gimple_num_args (stmt);
3565 if (pe != loop_preheader_edge (loop))
3567 for (int i = 0; i < num_args; ++i)
3568 if (!ifcvt_available_on_edge_p (pe, gimple_arg (stmt, i)))
3569 return false;
3571 else
3573 for (int i = 0; i < num_args; ++i)
3574 if (!expr_invariant_in_loop_p (loop, gimple_arg (stmt, i)))
3575 return false;
3578 return true;
3581 /* Hoist invariant statements from LOOP to edge PE. */
3583 static void
3584 ifcvt_hoist_invariants (class loop *loop, edge pe)
3586 /* Only hoist from the now unconditionally executed part of the loop. */
3587 basic_block bb = loop->header;
3588 gimple_stmt_iterator hoist_gsi = {};
3589 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
3591 gimple *stmt = gsi_stmt (gsi);
3592 if (ifcvt_can_hoist (loop, pe, stmt))
3594 /* Once we've hoisted one statement, insert other statements
3595 after it. */
3596 gsi_remove (&gsi, false);
3597 if (hoist_gsi.ptr)
3598 gsi_insert_after (&hoist_gsi, stmt, GSI_NEW_STMT);
3599 else
3601 gsi_insert_on_edge_immediate (pe, stmt);
3602 hoist_gsi = gsi_for_stmt (stmt);
3604 continue;
3606 gsi_next (&gsi);
3610 /* Returns the DECL_FIELD_BIT_OFFSET of the bitfield accesse in stmt iff its
3611 type mode is not BLKmode. If BITPOS is not NULL it will hold the poly_int64
3612 value of the DECL_FIELD_BIT_OFFSET of the bitfield access and STRUCT_EXPR,
3613 if not NULL, will hold the tree representing the base struct of this
3614 bitfield. */
3616 static tree
3617 get_bitfield_rep (gassign *stmt, bool write, tree *bitpos,
3618 tree *struct_expr)
3620 tree comp_ref = write ? gimple_assign_lhs (stmt)
3621 : gimple_assign_rhs1 (stmt);
3623 tree field_decl = TREE_OPERAND (comp_ref, 1);
3624 tree ref_offset = component_ref_field_offset (comp_ref);
3625 tree rep_decl = DECL_BIT_FIELD_REPRESENTATIVE (field_decl);
3627 /* Bail out if the representative is not a suitable type for a scalar
3628 register variable. */
3629 if (!is_gimple_reg_type (TREE_TYPE (rep_decl)))
3630 return NULL_TREE;
3632 /* Bail out if the DECL_SIZE of the field_decl isn't the same as the BF's
3633 precision. */
3634 unsigned HOST_WIDE_INT bf_prec
3635 = TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (stmt)));
3636 if (compare_tree_int (DECL_SIZE (field_decl), bf_prec) != 0)
3637 return NULL_TREE;
3639 if (TREE_CODE (DECL_FIELD_OFFSET (rep_decl)) != INTEGER_CST
3640 || TREE_CODE (ref_offset) != INTEGER_CST)
3642 if (dump_file && (dump_flags & TDF_DETAILS))
3643 fprintf (dump_file, "\t Bitfield NOT OK to lower,"
3644 " offset is non-constant.\n");
3645 return NULL_TREE;
3648 if (struct_expr)
3649 *struct_expr = TREE_OPERAND (comp_ref, 0);
3651 if (bitpos)
3653 /* To calculate the bitposition of the BITFIELD_REF we have to determine
3654 where our bitfield starts in relation to the container REP_DECL. The
3655 DECL_FIELD_OFFSET of the original bitfield's member FIELD_DECL tells
3656 us how many bytes from the start of the structure there are until the
3657 start of the group of bitfield members the FIELD_DECL belongs to,
3658 whereas DECL_FIELD_BIT_OFFSET will tell us how many bits from that
3659 position our actual bitfield member starts. For the container
3660 REP_DECL adding DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET will tell
3661 us the distance between the start of the structure and the start of
3662 the container, though the first is in bytes and the later other in
3663 bits. With this in mind we calculate the bit position of our new
3664 BITFIELD_REF by subtracting the number of bits between the start of
3665 the structure and the container from the number of bits from the start
3666 of the structure and the actual bitfield member. */
3667 tree bf_pos = fold_build2 (MULT_EXPR, bitsizetype,
3668 ref_offset,
3669 build_int_cst (bitsizetype, BITS_PER_UNIT));
3670 bf_pos = fold_build2 (PLUS_EXPR, bitsizetype, bf_pos,
3671 DECL_FIELD_BIT_OFFSET (field_decl));
3672 tree rep_pos = fold_build2 (MULT_EXPR, bitsizetype,
3673 DECL_FIELD_OFFSET (rep_decl),
3674 build_int_cst (bitsizetype, BITS_PER_UNIT));
3675 rep_pos = fold_build2 (PLUS_EXPR, bitsizetype, rep_pos,
3676 DECL_FIELD_BIT_OFFSET (rep_decl));
3678 *bitpos = fold_build2 (MINUS_EXPR, bitsizetype, bf_pos, rep_pos);
3681 return rep_decl;
3685 /* Lowers the bitfield described by DATA.
3686 For a write like:
3688 struct.bf = _1;
3690 lower to:
3692 __ifc_1 = struct.<representative>;
3693 __ifc_2 = BIT_INSERT_EXPR (__ifc_1, _1, bitpos);
3694 struct.<representative> = __ifc_2;
3696 For a read:
3698 _1 = struct.bf;
3700 lower to:
3702 __ifc_1 = struct.<representative>;
3703 _1 = BIT_FIELD_REF (__ifc_1, bitsize, bitpos);
3705 where representative is a legal load that contains the bitfield value,
3706 bitsize is the size of the bitfield and bitpos the offset to the start of
3707 the bitfield within the representative. */
3709 static void
3710 lower_bitfield (gassign *stmt, bool write)
3712 tree struct_expr;
3713 tree bitpos;
3714 tree rep_decl = get_bitfield_rep (stmt, write, &bitpos, &struct_expr);
3715 tree rep_type = TREE_TYPE (rep_decl);
3716 tree bf_type = TREE_TYPE (gimple_assign_lhs (stmt));
3718 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
3719 if (dump_file && (dump_flags & TDF_DETAILS))
3721 fprintf (dump_file, "Lowering:\n");
3722 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
3723 fprintf (dump_file, "to:\n");
3726 /* REP_COMP_REF is a COMPONENT_REF for the representative. NEW_VAL is it's
3727 defining SSA_NAME. */
3728 tree rep_comp_ref = build3 (COMPONENT_REF, rep_type, struct_expr, rep_decl,
3729 NULL_TREE);
3730 tree new_val = ifc_temp_var (rep_type, rep_comp_ref, &gsi);
3732 if (dump_file && (dump_flags & TDF_DETAILS))
3733 print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (new_val), 0, TDF_SLIM);
3735 if (write)
3737 new_val = ifc_temp_var (rep_type,
3738 build3 (BIT_INSERT_EXPR, rep_type, new_val,
3739 unshare_expr (gimple_assign_rhs1 (stmt)),
3740 bitpos), &gsi);
3742 if (dump_file && (dump_flags & TDF_DETAILS))
3743 print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (new_val), 0, TDF_SLIM);
3745 gimple *new_stmt = gimple_build_assign (unshare_expr (rep_comp_ref),
3746 new_val);
3747 gimple_move_vops (new_stmt, stmt);
3748 gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
3750 if (dump_file && (dump_flags & TDF_DETAILS))
3751 print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
3753 else
3755 tree bfr = build3 (BIT_FIELD_REF, bf_type, new_val,
3756 build_int_cst (bitsizetype, TYPE_PRECISION (bf_type)),
3757 bitpos);
3758 new_val = ifc_temp_var (bf_type, bfr, &gsi);
3760 gimple *new_stmt = gimple_build_assign (gimple_assign_lhs (stmt),
3761 new_val);
3762 gimple_move_vops (new_stmt, stmt);
3763 gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
3765 if (dump_file && (dump_flags & TDF_DETAILS))
3766 print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
3769 gsi_remove (&gsi, true);
3772 /* Return TRUE if there are bitfields to lower in this LOOP. Fill TO_LOWER
3773 with data structures representing these bitfields. */
3775 static bool
3776 bitfields_to_lower_p (class loop *loop,
3777 vec <gassign *> &reads_to_lower,
3778 vec <gassign *> &writes_to_lower)
3780 gimple_stmt_iterator gsi;
3782 if (dump_file && (dump_flags & TDF_DETAILS))
3784 fprintf (dump_file, "Analyzing loop %d for bitfields:\n", loop->num);
3787 for (unsigned i = 0; i < loop->num_nodes; ++i)
3789 basic_block bb = ifc_bbs[i];
3790 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3792 gassign *stmt = dyn_cast<gassign*> (gsi_stmt (gsi));
3793 if (!stmt)
3794 continue;
3796 tree op = gimple_assign_lhs (stmt);
3797 bool write = TREE_CODE (op) == COMPONENT_REF;
3799 if (!write)
3800 op = gimple_assign_rhs1 (stmt);
3802 if (TREE_CODE (op) != COMPONENT_REF)
3803 continue;
3805 if (DECL_BIT_FIELD_TYPE (TREE_OPERAND (op, 1)))
3807 if (dump_file && (dump_flags & TDF_DETAILS))
3808 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
3810 if (TREE_THIS_VOLATILE (op))
3812 if (dump_file && (dump_flags & TDF_DETAILS))
3813 fprintf (dump_file, "\t Bitfield NO OK to lower,"
3814 " the access is volatile.\n");
3815 return false;
3818 if (!INTEGRAL_TYPE_P (TREE_TYPE (op)))
3820 if (dump_file && (dump_flags & TDF_DETAILS))
3821 fprintf (dump_file, "\t Bitfield NO OK to lower,"
3822 " field type is not Integral.\n");
3823 return false;
3826 if (!get_bitfield_rep (stmt, write, NULL, NULL))
3828 if (dump_file && (dump_flags & TDF_DETAILS))
3829 fprintf (dump_file, "\t Bitfield NOT OK to lower,"
3830 " representative is BLKmode.\n");
3831 return false;
3834 if (dump_file && (dump_flags & TDF_DETAILS))
3835 fprintf (dump_file, "\tBitfield OK to lower.\n");
3836 if (write)
3837 writes_to_lower.safe_push (stmt);
3838 else
3839 reads_to_lower.safe_push (stmt);
3843 return !reads_to_lower.is_empty () || !writes_to_lower.is_empty ();
3847 /* If-convert LOOP when it is legal. For the moment this pass has no
3848 profitability analysis. Returns non-zero todo flags when something
3849 changed. */
3851 unsigned int
3852 tree_if_conversion (class loop *loop, vec<gimple *> *preds)
3854 unsigned int todo = 0;
3855 bool aggressive_if_conv;
3856 class loop *rloop;
3857 auto_vec <gassign *, 4> reads_to_lower;
3858 auto_vec <gassign *, 4> writes_to_lower;
3859 bitmap exit_bbs;
3860 edge pe;
3861 auto_vec<data_reference_p, 10> refs;
3862 bool loop_versioned;
3864 again:
3865 rloop = NULL;
3866 ifc_bbs = NULL;
3867 need_to_lower_bitfields = false;
3868 need_to_ifcvt = false;
3869 need_to_predicate = false;
3870 need_to_rewrite_undefined = false;
3871 any_complicated_phi = false;
3872 loop_versioned = false;
3874 /* Apply more aggressive if-conversion when loop or its outer loop were
3875 marked with simd pragma. When that's the case, we try to if-convert
3876 loop containing PHIs with more than MAX_PHI_ARG_NUM arguments. */
3877 aggressive_if_conv = loop->force_vectorize;
3878 if (!aggressive_if_conv)
3880 class loop *outer_loop = loop_outer (loop);
3881 if (outer_loop && outer_loop->force_vectorize)
3882 aggressive_if_conv = true;
3885 /* If there are more than two BBs in the loop then there is at least one if
3886 to convert. */
3887 if (loop->num_nodes > 2
3888 && !ifcvt_split_critical_edges (loop, aggressive_if_conv))
3889 goto cleanup;
3891 ifc_bbs = get_loop_body_in_if_conv_order (loop);
3892 if (!ifc_bbs)
3894 if (dump_file && (dump_flags & TDF_DETAILS))
3895 fprintf (dump_file, "Irreducible loop\n");
3896 goto cleanup;
3899 if (find_data_references_in_loop (loop, &refs) == chrec_dont_know)
3900 goto cleanup;
3902 if (loop->num_nodes > 2)
3904 /* More than one loop exit is too much to handle. */
3905 if (!single_exit (loop))
3907 if (dump_file && (dump_flags & TDF_DETAILS))
3908 fprintf (dump_file, "Can not ifcvt due to multiple exits\n");
3910 else
3912 need_to_ifcvt = true;
3914 if (!if_convertible_loop_p (loop, &refs)
3915 || !dbg_cnt (if_conversion_tree))
3916 goto cleanup;
3918 if ((need_to_predicate || any_complicated_phi)
3919 && ((!flag_tree_loop_vectorize && !loop->force_vectorize)
3920 || loop->dont_vectorize))
3921 goto cleanup;
3925 if ((flag_tree_loop_vectorize || loop->force_vectorize)
3926 && !loop->dont_vectorize)
3927 need_to_lower_bitfields = bitfields_to_lower_p (loop, reads_to_lower,
3928 writes_to_lower);
3930 if (!need_to_ifcvt && !need_to_lower_bitfields)
3931 goto cleanup;
3933 /* The edge to insert invariant stmts on. */
3934 pe = loop_preheader_edge (loop);
3936 /* Since we have no cost model, always version loops unless the user
3937 specified -ftree-loop-if-convert or unless versioning is required.
3938 Either version this loop, or if the pattern is right for outer-loop
3939 vectorization, version the outer loop. In the latter case we will
3940 still if-convert the original inner loop. */
3941 if (need_to_lower_bitfields
3942 || need_to_predicate
3943 || any_complicated_phi
3944 || flag_tree_loop_if_convert != 1)
3946 class loop *vloop
3947 = (versionable_outer_loop_p (loop_outer (loop))
3948 ? loop_outer (loop) : loop);
3949 class loop *nloop = version_loop_for_if_conversion (vloop, preds);
3950 if (nloop == NULL)
3951 goto cleanup;
3952 if (vloop != loop)
3954 /* If versionable_outer_loop_p decided to version the
3955 outer loop, version also the inner loop of the non-vectorized
3956 loop copy. So we transform:
3957 loop1
3958 loop2
3959 into:
3960 if (LOOP_VECTORIZED (1, 3))
3962 loop1
3963 loop2
3965 else
3966 loop3 (copy of loop1)
3967 if (LOOP_VECTORIZED (4, 5))
3968 loop4 (copy of loop2)
3969 else
3970 loop5 (copy of loop4) */
3971 gcc_assert (nloop->inner && nloop->inner->next == NULL);
3972 rloop = nloop->inner;
3974 else
3975 /* If we versioned loop then make sure to insert invariant
3976 stmts before the .LOOP_VECTORIZED check since the vectorizer
3977 will re-use that for things like runtime alias versioning
3978 whose condition can end up using those invariants. */
3979 pe = single_pred_edge (gimple_bb (preds->last ()));
3981 loop_versioned = true;
3984 if (need_to_lower_bitfields)
3986 if (dump_file && (dump_flags & TDF_DETAILS))
3988 fprintf (dump_file, "-------------------------\n");
3989 fprintf (dump_file, "Start lowering bitfields\n");
3991 while (!reads_to_lower.is_empty ())
3992 lower_bitfield (reads_to_lower.pop (), false);
3993 while (!writes_to_lower.is_empty ())
3994 lower_bitfield (writes_to_lower.pop (), true);
3996 if (dump_file && (dump_flags & TDF_DETAILS))
3998 fprintf (dump_file, "Done lowering bitfields\n");
3999 fprintf (dump_file, "-------------------------\n");
4002 if (need_to_ifcvt)
4004 /* Before we rewrite edges we'll record their original position in the
4005 edge map such that we can map the edges between the ifcvt and the
4006 non-ifcvt loop during peeling. */
4007 uintptr_t idx = 0;
4008 for (edge exit : get_loop_exit_edges (loop))
4009 exit->aux = (void*)idx++;
4011 /* Now all statements are if-convertible. Combine all the basic
4012 blocks into one huge basic block doing the if-conversion
4013 on-the-fly. */
4014 combine_blocks (loop, loop_versioned);
4017 std::pair <tree, tree> *name_pair;
4018 unsigned ssa_names_idx;
4019 FOR_EACH_VEC_ELT (redundant_ssa_names, ssa_names_idx, name_pair)
4020 replace_uses_by (name_pair->first, name_pair->second);
4021 redundant_ssa_names.release ();
4023 /* Perform local CSE, this esp. helps the vectorizer analysis if loads
4024 and stores are involved. CSE only the loop body, not the entry
4025 PHIs, those are to be kept in sync with the non-if-converted copy.
4026 ??? We'll still keep dead stores though. */
4027 exit_bbs = BITMAP_ALLOC (NULL);
4028 for (edge exit : get_loop_exit_edges (loop))
4029 bitmap_set_bit (exit_bbs, exit->dest->index);
4030 todo |= do_rpo_vn (cfun, loop_preheader_edge (loop), exit_bbs,
4031 false, true, true);
4033 /* Delete dead predicate computations. */
4034 ifcvt_local_dce (loop);
4035 BITMAP_FREE (exit_bbs);
4037 ifcvt_hoist_invariants (loop, pe);
4039 todo |= TODO_cleanup_cfg;
4041 cleanup:
4042 data_reference_p dr;
4043 unsigned int i;
4044 for (i = 0; refs.iterate (i, &dr); i++)
4046 free (dr->aux);
4047 free_data_ref (dr);
4049 refs.truncate (0);
4051 if (ifc_bbs)
4053 unsigned int i;
4055 for (i = 0; i < loop->num_nodes; i++)
4056 free_bb_predicate (ifc_bbs[i]);
4058 free (ifc_bbs);
4059 ifc_bbs = NULL;
4061 if (rloop != NULL)
4063 loop = rloop;
4064 reads_to_lower.truncate (0);
4065 writes_to_lower.truncate (0);
4066 goto again;
4069 return todo;
4072 /* Tree if-conversion pass management. */
4074 namespace {
4076 const pass_data pass_data_if_conversion =
4078 GIMPLE_PASS, /* type */
4079 "ifcvt", /* name */
4080 OPTGROUP_NONE, /* optinfo_flags */
4081 TV_TREE_LOOP_IFCVT, /* tv_id */
4082 ( PROP_cfg | PROP_ssa ), /* properties_required */
4083 0, /* properties_provided */
4084 0, /* properties_destroyed */
4085 0, /* todo_flags_start */
4086 0, /* todo_flags_finish */
4089 class pass_if_conversion : public gimple_opt_pass
4091 public:
4092 pass_if_conversion (gcc::context *ctxt)
4093 : gimple_opt_pass (pass_data_if_conversion, ctxt)
4096 /* opt_pass methods: */
4097 bool gate (function *) final override;
4098 unsigned int execute (function *) final override;
4100 }; // class pass_if_conversion
4102 bool
4103 pass_if_conversion::gate (function *fun)
4105 return (((flag_tree_loop_vectorize || fun->has_force_vectorize_loops)
4106 && flag_tree_loop_if_convert != 0)
4107 || flag_tree_loop_if_convert == 1);
4110 unsigned int
4111 pass_if_conversion::execute (function *fun)
4113 unsigned todo = 0;
4115 if (number_of_loops (fun) <= 1)
4116 return 0;
4118 auto_vec<gimple *> preds;
4119 for (auto loop : loops_list (cfun, 0))
4120 if (flag_tree_loop_if_convert == 1
4121 || ((flag_tree_loop_vectorize || loop->force_vectorize)
4122 && !loop->dont_vectorize))
4123 todo |= tree_if_conversion (loop, &preds);
4125 if (todo)
4127 free_numbers_of_iterations_estimates (fun);
4128 scev_reset ();
4131 if (flag_checking)
4133 basic_block bb;
4134 FOR_EACH_BB_FN (bb, fun)
4135 gcc_assert (!bb->aux);
4138 /* Perform IL update now, it might elide some loops. */
4139 if (todo & TODO_cleanup_cfg)
4141 cleanup_tree_cfg ();
4142 if (need_ssa_update_p (fun))
4143 todo |= TODO_update_ssa;
4145 if (todo & TODO_update_ssa_any)
4146 update_ssa (todo & TODO_update_ssa_any);
4148 /* If if-conversion elided the loop fall back to the original one. Likewise
4149 if the loops are not nested in the same outer loop. */
4150 for (unsigned i = 0; i < preds.length (); ++i)
4152 gimple *g = preds[i];
4153 if (!gimple_bb (g))
4154 continue;
4155 auto ifcvt_loop = get_loop (fun, tree_to_uhwi (gimple_call_arg (g, 0)));
4156 auto orig_loop = get_loop (fun, tree_to_uhwi (gimple_call_arg (g, 1)));
4157 if (!ifcvt_loop || !orig_loop)
4159 if (dump_file)
4160 fprintf (dump_file, "If-converted loop vanished\n");
4161 fold_loop_internal_call (g, boolean_false_node);
4163 else if (loop_outer (ifcvt_loop) != loop_outer (orig_loop))
4165 if (dump_file)
4166 fprintf (dump_file, "If-converted loop in different outer loop\n");
4167 fold_loop_internal_call (g, boolean_false_node);
4171 return 0;
4174 } // anon namespace
4176 gimple_opt_pass *
4177 make_pass_if_conversion (gcc::context *ctxt)
4179 return new pass_if_conversion (ctxt);