1 /* If-conversion for vectorizer.
2 Copyright (C) 2004-2015 Free Software Foundation, Inc.
3 Contributed by Devang Patel <dpatel@apple.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
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
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
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'
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:
43 # i_23 = PHI <0(0), i_18(10)>;
46 if (j_15 > 41) goto <L1>; else goto <L17>;
53 # iftmp.2_4 = PHI <0(8), 42(2)>;
57 if (i_18 <= 15) goto <L19>; else goto <L18>;
67 # i_23 = PHI <0(0), i_18(10)>;
72 iftmp.2_4 = j_15 > 41 ? 42 : 0;
75 if (i_18 <= 15) goto <L19>; else goto <L18>;
85 #include "coretypes.h"
90 #include "double-int.h"
97 #include "fold-const.h"
98 #include "stor-layout.h"
101 #include "hard-reg-set.h"
102 #include "function.h"
103 #include "dominance.h"
105 #include "basic-block.h"
106 #include "gimple-pretty-print.h"
107 #include "tree-ssa-alias.h"
108 #include "internal-fn.h"
109 #include "gimple-fold.h"
110 #include "gimple-expr.h"
113 #include "gimplify.h"
114 #include "gimple-iterator.h"
115 #include "gimplify-me.h"
116 #include "gimple-ssa.h"
117 #include "tree-cfg.h"
118 #include "tree-phinodes.h"
119 #include "ssa-iterators.h"
120 #include "stringpool.h"
121 #include "tree-ssanames.h"
122 #include "tree-into-ssa.h"
123 #include "tree-ssa.h"
125 #include "tree-chrec.h"
126 #include "tree-data-ref.h"
127 #include "tree-scalar-evolution.h"
128 #include "tree-ssa-loop-ivopts.h"
129 #include "tree-ssa-address.h"
130 #include "tree-pass.h"
134 #include "statistics.h"
136 #include "fixed-value.h"
137 #include "insn-config.h"
142 #include "emit-rtl.h"
146 #include "insn-codes.h"
148 #include "hash-map.h"
150 /* List of basic blocks in if-conversion-suitable order. */
151 static basic_block
*ifc_bbs
;
153 /* Apply more aggressive (extended) if-conversion if true. */
154 static bool aggressive_if_conv
;
156 /* Structure used to predicate basic blocks. This is attached to the
157 ->aux field of the BBs in the loop to be if-converted. */
158 typedef struct bb_predicate_s
{
160 /* The condition under which this basic block is executed. */
163 /* PREDICATE is gimplified, and the sequence of statements is
164 recorded here, in order to avoid the duplication of computations
165 that occur in previous conditions. See PR44483. */
166 gimple_seq predicate_gimplified_stmts
;
169 /* Returns true when the basic block BB has a predicate. */
172 bb_has_predicate (basic_block bb
)
174 return bb
->aux
!= NULL
;
177 /* Returns the gimplified predicate for basic block BB. */
180 bb_predicate (basic_block bb
)
182 return ((bb_predicate_p
) bb
->aux
)->predicate
;
185 /* Sets the gimplified predicate COND for basic block BB. */
188 set_bb_predicate (basic_block bb
, tree cond
)
190 gcc_assert ((TREE_CODE (cond
) == TRUTH_NOT_EXPR
191 && is_gimple_condexpr (TREE_OPERAND (cond
, 0)))
192 || is_gimple_condexpr (cond
));
193 ((bb_predicate_p
) bb
->aux
)->predicate
= cond
;
196 /* Returns the sequence of statements of the gimplification of the
197 predicate for basic block BB. */
199 static inline gimple_seq
200 bb_predicate_gimplified_stmts (basic_block bb
)
202 return ((bb_predicate_p
) bb
->aux
)->predicate_gimplified_stmts
;
205 /* Sets the sequence of statements STMTS of the gimplification of the
206 predicate for basic block BB. */
209 set_bb_predicate_gimplified_stmts (basic_block bb
, gimple_seq stmts
)
211 ((bb_predicate_p
) bb
->aux
)->predicate_gimplified_stmts
= stmts
;
214 /* Adds the sequence of statements STMTS to the sequence of statements
215 of the predicate for basic block BB. */
218 add_bb_predicate_gimplified_stmts (basic_block bb
, gimple_seq stmts
)
221 (&(((bb_predicate_p
) bb
->aux
)->predicate_gimplified_stmts
), stmts
);
224 /* Initializes to TRUE the predicate of basic block BB. */
227 init_bb_predicate (basic_block bb
)
229 bb
->aux
= XNEW (struct bb_predicate_s
);
230 set_bb_predicate_gimplified_stmts (bb
, NULL
);
231 set_bb_predicate (bb
, boolean_true_node
);
234 /* Release the SSA_NAMEs associated with the predicate of basic block BB,
235 but don't actually free it. */
238 release_bb_predicate (basic_block bb
)
240 gimple_seq stmts
= bb_predicate_gimplified_stmts (bb
);
243 gimple_stmt_iterator i
;
245 for (i
= gsi_start (stmts
); !gsi_end_p (i
); gsi_next (&i
))
246 free_stmt_operands (cfun
, gsi_stmt (i
));
247 set_bb_predicate_gimplified_stmts (bb
, NULL
);
251 /* Free the predicate of basic block BB. */
254 free_bb_predicate (basic_block bb
)
256 if (!bb_has_predicate (bb
))
259 release_bb_predicate (bb
);
264 /* Reinitialize predicate of BB with the true predicate. */
267 reset_bb_predicate (basic_block bb
)
269 if (!bb_has_predicate (bb
))
270 init_bb_predicate (bb
);
273 release_bb_predicate (bb
);
274 set_bb_predicate (bb
, boolean_true_node
);
278 /* Returns a new SSA_NAME of type TYPE that is assigned the value of
279 the expression EXPR. Inserts the statement created for this
280 computation before GSI and leaves the iterator GSI at the same
284 ifc_temp_var (tree type
, tree expr
, gimple_stmt_iterator
*gsi
)
286 tree new_name
= make_temp_ssa_name (type
, NULL
, "_ifc_");
287 gimple stmt
= gimple_build_assign (new_name
, expr
);
288 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
292 /* Return true when COND is a true predicate. */
295 is_true_predicate (tree cond
)
297 return (cond
== NULL_TREE
298 || cond
== boolean_true_node
299 || integer_onep (cond
));
302 /* Returns true when BB has a predicate that is not trivial: true or
306 is_predicated (basic_block bb
)
308 return !is_true_predicate (bb_predicate (bb
));
311 /* Parses the predicate COND and returns its comparison code and
312 operands OP0 and OP1. */
314 static enum tree_code
315 parse_predicate (tree cond
, tree
*op0
, tree
*op1
)
319 if (TREE_CODE (cond
) == SSA_NAME
320 && is_gimple_assign (s
= SSA_NAME_DEF_STMT (cond
)))
322 if (TREE_CODE_CLASS (gimple_assign_rhs_code (s
)) == tcc_comparison
)
324 *op0
= gimple_assign_rhs1 (s
);
325 *op1
= gimple_assign_rhs2 (s
);
326 return gimple_assign_rhs_code (s
);
329 else if (gimple_assign_rhs_code (s
) == TRUTH_NOT_EXPR
)
331 tree op
= gimple_assign_rhs1 (s
);
332 tree type
= TREE_TYPE (op
);
333 enum tree_code code
= parse_predicate (op
, op0
, op1
);
335 return code
== ERROR_MARK
? ERROR_MARK
336 : invert_tree_comparison (code
, HONOR_NANS (type
));
342 if (TREE_CODE_CLASS (TREE_CODE (cond
)) == tcc_comparison
)
344 *op0
= TREE_OPERAND (cond
, 0);
345 *op1
= TREE_OPERAND (cond
, 1);
346 return TREE_CODE (cond
);
352 /* Returns the fold of predicate C1 OR C2 at location LOC. */
355 fold_or_predicates (location_t loc
, tree c1
, tree c2
)
357 tree op1a
, op1b
, op2a
, op2b
;
358 enum tree_code code1
= parse_predicate (c1
, &op1a
, &op1b
);
359 enum tree_code code2
= parse_predicate (c2
, &op2a
, &op2b
);
361 if (code1
!= ERROR_MARK
&& code2
!= ERROR_MARK
)
363 tree t
= maybe_fold_or_comparisons (code1
, op1a
, op1b
,
369 return fold_build2_loc (loc
, TRUTH_OR_EXPR
, boolean_type_node
, c1
, c2
);
372 /* Returns true if N is either a constant or a SSA_NAME. */
375 constant_or_ssa_name (tree n
)
377 switch (TREE_CODE (n
))
390 /* Returns either a COND_EXPR or the folded expression if the folded
391 expression is a MIN_EXPR, a MAX_EXPR, an ABS_EXPR,
392 a constant or a SSA_NAME. */
395 fold_build_cond_expr (tree type
, tree cond
, tree rhs
, tree lhs
)
397 tree rhs1
, lhs1
, cond_expr
;
399 /* If COND is comparison r != 0 and r has boolean type, convert COND
400 to SSA_NAME to accept by vect bool pattern. */
401 if (TREE_CODE (cond
) == NE_EXPR
)
403 tree op0
= TREE_OPERAND (cond
, 0);
404 tree op1
= TREE_OPERAND (cond
, 1);
405 if (TREE_CODE (op0
) == SSA_NAME
406 && TREE_CODE (TREE_TYPE (op0
)) == BOOLEAN_TYPE
407 && (integer_zerop (op1
)))
410 cond_expr
= fold_ternary (COND_EXPR
, type
, cond
,
413 if (cond_expr
== NULL_TREE
)
414 return build3 (COND_EXPR
, type
, cond
, rhs
, lhs
);
416 STRIP_USELESS_TYPE_CONVERSION (cond_expr
);
418 if (constant_or_ssa_name (cond_expr
))
421 if (TREE_CODE (cond_expr
) == ABS_EXPR
)
423 rhs1
= TREE_OPERAND (cond_expr
, 1);
424 STRIP_USELESS_TYPE_CONVERSION (rhs1
);
425 if (constant_or_ssa_name (rhs1
))
426 return build1 (ABS_EXPR
, type
, rhs1
);
429 if (TREE_CODE (cond_expr
) == MIN_EXPR
430 || TREE_CODE (cond_expr
) == MAX_EXPR
)
432 lhs1
= TREE_OPERAND (cond_expr
, 0);
433 STRIP_USELESS_TYPE_CONVERSION (lhs1
);
434 rhs1
= TREE_OPERAND (cond_expr
, 1);
435 STRIP_USELESS_TYPE_CONVERSION (rhs1
);
436 if (constant_or_ssa_name (rhs1
)
437 && constant_or_ssa_name (lhs1
))
438 return build2 (TREE_CODE (cond_expr
), type
, lhs1
, rhs1
);
440 return build3 (COND_EXPR
, type
, cond
, rhs
, lhs
);
443 /* Add condition NC to the predicate list of basic block BB. LOOP is
444 the loop to be if-converted. Use predicate of cd-equivalent block
445 for join bb if it exists: we call basic blocks bb1 and bb2
446 cd-equivalent if they are executed under the same condition. */
449 add_to_predicate_list (struct loop
*loop
, basic_block bb
, tree nc
)
454 if (is_true_predicate (nc
))
457 /* If dominance tells us this basic block is always executed,
458 don't record any predicates for it. */
459 if (dominated_by_p (CDI_DOMINATORS
, loop
->latch
, bb
))
462 dom_bb
= get_immediate_dominator (CDI_DOMINATORS
, bb
);
463 /* We use notion of cd equivalence to get simpler predicate for
464 join block, e.g. if join block has 2 predecessors with predicates
465 p1 & p2 and p1 & !p2, we'd like to get p1 for it instead of
466 p1 & p2 | p1 & !p2. */
467 if (dom_bb
!= loop
->header
468 && get_immediate_dominator (CDI_POST_DOMINATORS
, dom_bb
) == bb
)
470 gcc_assert (flow_bb_inside_loop_p (loop
, dom_bb
));
471 bc
= bb_predicate (dom_bb
);
472 if (!is_true_predicate (bc
))
473 set_bb_predicate (bb
, bc
);
475 gcc_assert (is_true_predicate (bb_predicate (bb
)));
476 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
477 fprintf (dump_file
, "Use predicate of bb#%d for bb#%d\n",
478 dom_bb
->index
, bb
->index
);
482 if (!is_predicated (bb
))
486 bc
= bb_predicate (bb
);
487 bc
= fold_or_predicates (EXPR_LOCATION (bc
), nc
, bc
);
488 if (is_true_predicate (bc
))
490 reset_bb_predicate (bb
);
495 /* Allow a TRUTH_NOT_EXPR around the main predicate. */
496 if (TREE_CODE (bc
) == TRUTH_NOT_EXPR
)
497 tp
= &TREE_OPERAND (bc
, 0);
500 if (!is_gimple_condexpr (*tp
))
503 *tp
= force_gimple_operand_1 (*tp
, &stmts
, is_gimple_condexpr
, NULL_TREE
);
504 add_bb_predicate_gimplified_stmts (bb
, stmts
);
506 set_bb_predicate (bb
, bc
);
509 /* Add the condition COND to the previous condition PREV_COND, and add
510 this to the predicate list of the destination of edge E. LOOP is
511 the loop to be if-converted. */
514 add_to_dst_predicate_list (struct loop
*loop
, edge e
,
515 tree prev_cond
, tree cond
)
517 if (!flow_bb_inside_loop_p (loop
, e
->dest
))
520 if (!is_true_predicate (prev_cond
))
521 cond
= fold_build2 (TRUTH_AND_EXPR
, boolean_type_node
,
524 if (!dominated_by_p (CDI_DOMINATORS
, loop
->latch
, e
->dest
))
525 add_to_predicate_list (loop
, e
->dest
, cond
);
528 /* Return true if one of the successor edges of BB exits LOOP. */
531 bb_with_exit_edge_p (struct loop
*loop
, basic_block bb
)
536 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
537 if (loop_exit_edge_p (loop
, e
))
543 /* Return true when PHI is if-convertible. PHI is part of loop LOOP
544 and it belongs to basic block BB.
546 PHI is not if-convertible if:
547 - it has more than 2 arguments.
549 When the flag_tree_loop_if_convert_stores is not set, PHI is not
551 - a virtual PHI is immediately used in another PHI node,
552 - there is a virtual PHI in a BB other than the loop->header.
553 When the aggressive_if_conv is set, PHI can have more than
557 if_convertible_phi_p (struct loop
*loop
, basic_block bb
, gphi
*phi
,
558 bool any_mask_load_store
)
560 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
562 fprintf (dump_file
, "-------------------------\n");
563 print_gimple_stmt (dump_file
, phi
, 0, TDF_SLIM
);
566 if (bb
!= loop
->header
)
568 if (gimple_phi_num_args (phi
) != 2
569 && !aggressive_if_conv
)
571 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
572 fprintf (dump_file
, "More than two phi node args.\n");
577 if (flag_tree_loop_if_convert_stores
|| any_mask_load_store
)
580 /* When the flag_tree_loop_if_convert_stores is not set, check
581 that there are no memory writes in the branches of the loop to be
583 if (virtual_operand_p (gimple_phi_result (phi
)))
585 imm_use_iterator imm_iter
;
588 if (bb
!= loop
->header
)
590 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
591 fprintf (dump_file
, "Virtual phi not on loop->header.\n");
595 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, gimple_phi_result (phi
))
597 if (gimple_code (USE_STMT (use_p
)) == GIMPLE_PHI
)
599 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
600 fprintf (dump_file
, "Difficult to handle this virtual phi.\n");
609 /* Records the status of a data reference. This struct is attached to
610 each DR->aux field. */
613 /* -1 when not initialized, 0 when false, 1 when true. */
614 int written_at_least_once
;
616 /* -1 when not initialized, 0 when false, 1 when true. */
617 int rw_unconditionally
;
620 #define IFC_DR(DR) ((struct ifc_dr *) (DR)->aux)
621 #define DR_WRITTEN_AT_LEAST_ONCE(DR) (IFC_DR (DR)->written_at_least_once)
622 #define DR_RW_UNCONDITIONALLY(DR) (IFC_DR (DR)->rw_unconditionally)
624 /* Returns true when the memory references of STMT are read or written
625 unconditionally. In other words, this function returns true when
626 for every data reference A in STMT there exist other accesses to
627 a data reference with the same base with predicates that add up (OR-up) to
628 the true predicate: this ensures that the data reference A is touched
629 (read or written) on every iteration of the if-converted loop. */
632 memrefs_read_or_written_unconditionally (gimple stmt
,
633 vec
<data_reference_p
> drs
)
636 data_reference_p a
, b
;
637 tree ca
= bb_predicate (gimple_bb (stmt
));
639 for (i
= 0; drs
.iterate (i
, &a
); i
++)
640 if (DR_STMT (a
) == stmt
)
643 int x
= DR_RW_UNCONDITIONALLY (a
);
651 for (j
= 0; drs
.iterate (j
, &b
); j
++)
653 tree ref_base_a
= DR_REF (a
);
654 tree ref_base_b
= DR_REF (b
);
656 if (DR_STMT (b
) == stmt
)
659 while (TREE_CODE (ref_base_a
) == COMPONENT_REF
660 || TREE_CODE (ref_base_a
) == IMAGPART_EXPR
661 || TREE_CODE (ref_base_a
) == REALPART_EXPR
)
662 ref_base_a
= TREE_OPERAND (ref_base_a
, 0);
664 while (TREE_CODE (ref_base_b
) == COMPONENT_REF
665 || TREE_CODE (ref_base_b
) == IMAGPART_EXPR
666 || TREE_CODE (ref_base_b
) == REALPART_EXPR
)
667 ref_base_b
= TREE_OPERAND (ref_base_b
, 0);
669 if (!operand_equal_p (ref_base_a
, ref_base_b
, 0))
671 tree cb
= bb_predicate (gimple_bb (DR_STMT (b
)));
673 if (DR_RW_UNCONDITIONALLY (b
) == 1
674 || is_true_predicate (cb
)
675 || is_true_predicate (ca
676 = fold_or_predicates (EXPR_LOCATION (cb
), ca
, cb
)))
678 DR_RW_UNCONDITIONALLY (a
) = 1;
679 DR_RW_UNCONDITIONALLY (b
) = 1;
688 DR_RW_UNCONDITIONALLY (a
) = 0;
696 /* Returns true when the memory references of STMT are unconditionally
697 written. In other words, this function returns true when for every
698 data reference A written in STMT, there exist other writes to the
699 same data reference with predicates that add up (OR-up) to the true
700 predicate: this ensures that the data reference A is written on
701 every iteration of the if-converted loop. */
704 write_memrefs_written_at_least_once (gimple stmt
,
705 vec
<data_reference_p
> drs
)
708 data_reference_p a
, b
;
709 tree ca
= bb_predicate (gimple_bb (stmt
));
711 for (i
= 0; drs
.iterate (i
, &a
); i
++)
712 if (DR_STMT (a
) == stmt
716 int x
= DR_WRITTEN_AT_LEAST_ONCE (a
);
724 for (j
= 0; drs
.iterate (j
, &b
); j
++)
725 if (DR_STMT (b
) != stmt
727 && same_data_refs_base_objects (a
, b
))
729 tree cb
= bb_predicate (gimple_bb (DR_STMT (b
)));
731 if (DR_WRITTEN_AT_LEAST_ONCE (b
) == 1
732 || is_true_predicate (cb
)
733 || is_true_predicate (ca
= fold_or_predicates (EXPR_LOCATION (cb
),
736 DR_WRITTEN_AT_LEAST_ONCE (a
) = 1;
737 DR_WRITTEN_AT_LEAST_ONCE (b
) = 1;
745 DR_WRITTEN_AT_LEAST_ONCE (a
) = 0;
753 /* Return true when the memory references of STMT won't trap in the
754 if-converted code. There are two things that we have to check for:
756 - writes to memory occur to writable memory: if-conversion of
757 memory writes transforms the conditional memory writes into
758 unconditional writes, i.e. "if (cond) A[i] = foo" is transformed
759 into "A[i] = cond ? foo : A[i]", and as the write to memory may not
760 be executed at all in the original code, it may be a readonly
761 memory. To check that A is not const-qualified, we check that
762 there exists at least an unconditional write to A in the current
765 - reads or writes to memory are valid memory accesses for every
766 iteration. To check that the memory accesses are correctly formed
767 and that we are allowed to read and write in these locations, we
768 check that the memory accesses to be if-converted occur at every
769 iteration unconditionally. */
772 ifcvt_memrefs_wont_trap (gimple stmt
, vec
<data_reference_p
> refs
)
774 return write_memrefs_written_at_least_once (stmt
, refs
)
775 && memrefs_read_or_written_unconditionally (stmt
, refs
);
778 /* Wrapper around gimple_could_trap_p refined for the needs of the
779 if-conversion. Try to prove that the memory accesses of STMT could
780 not trap in the innermost loop containing STMT. */
783 ifcvt_could_trap_p (gimple stmt
, vec
<data_reference_p
> refs
)
785 if (gimple_vuse (stmt
)
786 && !gimple_could_trap_p_1 (stmt
, false, false)
787 && ifcvt_memrefs_wont_trap (stmt
, refs
))
790 return gimple_could_trap_p (stmt
);
793 /* Return true if STMT could be converted into a masked load or store
794 (conditional load or store based on a mask computed from bb predicate). */
797 ifcvt_can_use_mask_load_store (gimple stmt
)
801 basic_block bb
= gimple_bb (stmt
);
804 if (!(flag_tree_loop_vectorize
|| bb
->loop_father
->force_vectorize
)
805 || bb
->loop_father
->dont_vectorize
806 || !gimple_assign_single_p (stmt
)
807 || gimple_has_volatile_ops (stmt
))
810 /* Check whether this is a load or store. */
811 lhs
= gimple_assign_lhs (stmt
);
812 if (gimple_store_p (stmt
))
814 if (!is_gimple_val (gimple_assign_rhs1 (stmt
)))
819 else if (gimple_assign_load_p (stmt
))
822 ref
= gimple_assign_rhs1 (stmt
);
827 if (may_be_nonaddressable_p (ref
))
830 /* Mask should be integer mode of the same size as the load/store
832 mode
= TYPE_MODE (TREE_TYPE (lhs
));
833 if (int_mode_for_mode (mode
) == BLKmode
834 || VECTOR_MODE_P (mode
))
837 if (can_vec_mask_load_store_p (mode
, is_load
))
843 /* Return true when STMT is if-convertible.
845 GIMPLE_ASSIGN statement is not if-convertible if,
848 - LHS is not var decl. */
851 if_convertible_gimple_assign_stmt_p (gimple stmt
,
852 vec
<data_reference_p
> refs
,
853 bool *any_mask_load_store
)
855 tree lhs
= gimple_assign_lhs (stmt
);
858 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
860 fprintf (dump_file
, "-------------------------\n");
861 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
864 if (!is_gimple_reg_type (TREE_TYPE (lhs
)))
867 /* Some of these constrains might be too conservative. */
868 if (stmt_ends_bb_p (stmt
)
869 || gimple_has_volatile_ops (stmt
)
870 || (TREE_CODE (lhs
) == SSA_NAME
871 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs
))
872 || gimple_has_side_effects (stmt
))
874 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
875 fprintf (dump_file
, "stmt not suitable for ifcvt\n");
879 /* tree-into-ssa.c uses GF_PLF_1, so avoid it, because
880 in between if_convertible_loop_p and combine_blocks
881 we can perform loop versioning. */
882 gimple_set_plf (stmt
, GF_PLF_2
, false);
884 if (flag_tree_loop_if_convert_stores
)
886 if (ifcvt_could_trap_p (stmt
, refs
))
888 if (ifcvt_can_use_mask_load_store (stmt
))
890 gimple_set_plf (stmt
, GF_PLF_2
, true);
891 *any_mask_load_store
= true;
894 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
895 fprintf (dump_file
, "tree could trap...\n");
901 if (gimple_assign_rhs_could_trap_p (stmt
))
903 if (ifcvt_can_use_mask_load_store (stmt
))
905 gimple_set_plf (stmt
, GF_PLF_2
, true);
906 *any_mask_load_store
= true;
909 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
910 fprintf (dump_file
, "tree could trap...\n");
914 bb
= gimple_bb (stmt
);
916 if (TREE_CODE (lhs
) != SSA_NAME
917 && bb
!= bb
->loop_father
->header
918 && !bb_with_exit_edge_p (bb
->loop_father
, bb
))
920 if (ifcvt_can_use_mask_load_store (stmt
))
922 gimple_set_plf (stmt
, GF_PLF_2
, true);
923 *any_mask_load_store
= true;
926 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
928 fprintf (dump_file
, "LHS is not var\n");
929 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
937 /* Return true when STMT is if-convertible.
939 A statement is if-convertible if:
940 - it is an if-convertible GIMPLE_ASSIGN,
941 - it is a GIMPLE_LABEL or a GIMPLE_COND,
942 - it is builtins call. */
945 if_convertible_stmt_p (gimple stmt
, vec
<data_reference_p
> refs
,
946 bool *any_mask_load_store
)
948 switch (gimple_code (stmt
))
956 return if_convertible_gimple_assign_stmt_p (stmt
, refs
,
957 any_mask_load_store
);
961 tree fndecl
= gimple_call_fndecl (stmt
);
964 int flags
= gimple_call_flags (stmt
);
965 if ((flags
& ECF_CONST
)
966 && !(flags
& ECF_LOOPING_CONST_OR_PURE
)
967 /* We can only vectorize some builtins at the moment,
968 so restrict if-conversion to those. */
969 && DECL_BUILT_IN (fndecl
))
976 /* Don't know what to do with 'em so don't do anything. */
977 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
979 fprintf (dump_file
, "don't know what to do\n");
980 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
989 /* Assumes that BB has more than 1 predecessors.
990 Returns false if at least one successor is not on critical edge
991 and true otherwise. */
994 all_preds_critical_p (basic_block bb
)
999 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
1000 if (EDGE_COUNT (e
->src
->succs
) == 1)
1005 /* Returns true if at least one successor in on critical edge. */
1007 has_pred_critical_p (basic_block bb
)
1012 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
1013 if (EDGE_COUNT (e
->src
->succs
) > 1)
1018 /* Return true when BB is if-convertible. This routine does not check
1019 basic block's statements and phis.
1021 A basic block is not if-convertible if:
1022 - it is non-empty and it is after the exit block (in BFS order),
1023 - it is after the exit block but before the latch,
1024 - its edges are not normal.
1026 Last restriction is valid if aggressive_if_conv is false.
1028 EXIT_BB is the basic block containing the exit of the LOOP. BB is
1032 if_convertible_bb_p (struct loop
*loop
, basic_block bb
, basic_block exit_bb
)
1037 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1038 fprintf (dump_file
, "----------[%d]-------------\n", bb
->index
);
1040 if (EDGE_COUNT (bb
->succs
) > 2)
1043 if (EDGE_COUNT (bb
->preds
) > 2
1044 && !aggressive_if_conv
)
1049 if (bb
!= loop
->latch
)
1051 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1052 fprintf (dump_file
, "basic block after exit bb but before latch\n");
1055 else if (!empty_block_p (bb
))
1057 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1058 fprintf (dump_file
, "non empty basic block after exit bb\n");
1061 else if (bb
== loop
->latch
1063 && !dominated_by_p (CDI_DOMINATORS
, bb
, exit_bb
))
1065 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1066 fprintf (dump_file
, "latch is not dominated by exit_block\n");
1071 /* Be less adventurous and handle only normal edges. */
1072 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1073 if (e
->flags
& (EDGE_EH
| EDGE_ABNORMAL
| EDGE_IRREDUCIBLE_LOOP
))
1075 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1076 fprintf (dump_file
, "Difficult to handle edges\n");
1080 /* At least one incoming edge has to be non-critical as otherwise edge
1081 predicates are not equal to basic-block predicates of the edge
1082 source. This check is skipped if aggressive_if_conv is true. */
1083 if (!aggressive_if_conv
1084 && EDGE_COUNT (bb
->preds
) > 1
1085 && bb
!= loop
->header
1086 && all_preds_critical_p (bb
))
1088 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1089 fprintf (dump_file
, "only critical predecessors\n");
1096 /* Return true when all predecessor blocks of BB are visited. The
1097 VISITED bitmap keeps track of the visited blocks. */
1100 pred_blocks_visited_p (basic_block bb
, bitmap
*visited
)
1104 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
1105 if (!bitmap_bit_p (*visited
, e
->src
->index
))
1111 /* Get body of a LOOP in suitable order for if-conversion. It is
1112 caller's responsibility to deallocate basic block list.
1113 If-conversion suitable order is, breadth first sort (BFS) order
1114 with an additional constraint: select a block only if all its
1115 predecessors are already selected. */
1117 static basic_block
*
1118 get_loop_body_in_if_conv_order (const struct loop
*loop
)
1120 basic_block
*blocks
, *blocks_in_bfs_order
;
1123 unsigned int index
= 0;
1124 unsigned int visited_count
= 0;
1126 gcc_assert (loop
->num_nodes
);
1127 gcc_assert (loop
->latch
!= EXIT_BLOCK_PTR_FOR_FN (cfun
));
1129 blocks
= XCNEWVEC (basic_block
, loop
->num_nodes
);
1130 visited
= BITMAP_ALLOC (NULL
);
1132 blocks_in_bfs_order
= get_loop_body_in_bfs_order (loop
);
1135 while (index
< loop
->num_nodes
)
1137 bb
= blocks_in_bfs_order
[index
];
1139 if (bb
->flags
& BB_IRREDUCIBLE_LOOP
)
1141 free (blocks_in_bfs_order
);
1142 BITMAP_FREE (visited
);
1147 if (!bitmap_bit_p (visited
, bb
->index
))
1149 if (pred_blocks_visited_p (bb
, &visited
)
1150 || bb
== loop
->header
)
1152 /* This block is now visited. */
1153 bitmap_set_bit (visited
, bb
->index
);
1154 blocks
[visited_count
++] = bb
;
1160 if (index
== loop
->num_nodes
1161 && visited_count
!= loop
->num_nodes
)
1165 free (blocks_in_bfs_order
);
1166 BITMAP_FREE (visited
);
1170 /* Returns true when the analysis of the predicates for all the basic
1171 blocks in LOOP succeeded.
1173 predicate_bbs first allocates the predicates of the basic blocks.
1174 These fields are then initialized with the tree expressions
1175 representing the predicates under which a basic block is executed
1176 in the LOOP. As the loop->header is executed at each iteration, it
1177 has the "true" predicate. Other statements executed under a
1178 condition are predicated with that condition, for example
1185 S1 will be predicated with "x", and
1186 S2 will be predicated with "!x". */
1189 predicate_bbs (loop_p loop
)
1193 for (i
= 0; i
< loop
->num_nodes
; i
++)
1194 init_bb_predicate (ifc_bbs
[i
]);
1196 for (i
= 0; i
< loop
->num_nodes
; i
++)
1198 basic_block bb
= ifc_bbs
[i
];
1202 /* The loop latch and loop exit block are always executed and
1203 have no extra conditions to be processed: skip them. */
1204 if (bb
== loop
->latch
1205 || bb_with_exit_edge_p (loop
, bb
))
1207 reset_bb_predicate (bb
);
1211 cond
= bb_predicate (bb
);
1212 stmt
= last_stmt (bb
);
1213 if (stmt
&& gimple_code (stmt
) == GIMPLE_COND
)
1216 edge true_edge
, false_edge
;
1217 location_t loc
= gimple_location (stmt
);
1218 tree c
= build2_loc (loc
, gimple_cond_code (stmt
),
1220 gimple_cond_lhs (stmt
),
1221 gimple_cond_rhs (stmt
));
1223 /* Add new condition into destination's predicate list. */
1224 extract_true_false_edges_from_block (gimple_bb (stmt
),
1225 &true_edge
, &false_edge
);
1227 /* If C is true, then TRUE_EDGE is taken. */
1228 add_to_dst_predicate_list (loop
, true_edge
, unshare_expr (cond
),
1231 /* If C is false, then FALSE_EDGE is taken. */
1232 c2
= build1_loc (loc
, TRUTH_NOT_EXPR
, boolean_type_node
,
1234 add_to_dst_predicate_list (loop
, false_edge
,
1235 unshare_expr (cond
), c2
);
1240 /* If current bb has only one successor, then consider it as an
1241 unconditional goto. */
1242 if (single_succ_p (bb
))
1244 basic_block bb_n
= single_succ (bb
);
1246 /* The successor bb inherits the predicate of its
1247 predecessor. If there is no predicate in the predecessor
1248 bb, then consider the successor bb as always executed. */
1249 if (cond
== NULL_TREE
)
1250 cond
= boolean_true_node
;
1252 add_to_predicate_list (loop
, bb_n
, cond
);
1256 /* The loop header is always executed. */
1257 reset_bb_predicate (loop
->header
);
1258 gcc_assert (bb_predicate_gimplified_stmts (loop
->header
) == NULL
1259 && bb_predicate_gimplified_stmts (loop
->latch
) == NULL
);
1262 /* Return true when LOOP is if-convertible. This is a helper function
1263 for if_convertible_loop_p. REFS and DDRS are initialized and freed
1264 in if_convertible_loop_p. */
1267 if_convertible_loop_p_1 (struct loop
*loop
,
1268 vec
<loop_p
> *loop_nest
,
1269 vec
<data_reference_p
> *refs
,
1270 vec
<ddr_p
> *ddrs
, bool *any_mask_load_store
)
1274 basic_block exit_bb
= NULL
;
1276 /* Don't if-convert the loop when the data dependences cannot be
1277 computed: the loop won't be vectorized in that case. */
1278 res
= compute_data_dependences_for_loop (loop
, true, loop_nest
, refs
, ddrs
);
1282 calculate_dominance_info (CDI_DOMINATORS
);
1283 calculate_dominance_info (CDI_POST_DOMINATORS
);
1285 /* Allow statements that can be handled during if-conversion. */
1286 ifc_bbs
= get_loop_body_in_if_conv_order (loop
);
1289 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1290 fprintf (dump_file
, "Irreducible loop\n");
1294 for (i
= 0; i
< loop
->num_nodes
; i
++)
1296 basic_block bb
= ifc_bbs
[i
];
1298 if (!if_convertible_bb_p (loop
, bb
, exit_bb
))
1301 if (bb_with_exit_edge_p (loop
, bb
))
1305 for (i
= 0; i
< loop
->num_nodes
; i
++)
1307 basic_block bb
= ifc_bbs
[i
];
1308 gimple_stmt_iterator gsi
;
1310 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1311 switch (gimple_code (gsi_stmt (gsi
)))
1324 if (flag_tree_loop_if_convert_stores
)
1326 data_reference_p dr
;
1328 for (i
= 0; refs
->iterate (i
, &dr
); i
++)
1330 dr
->aux
= XNEW (struct ifc_dr
);
1331 DR_WRITTEN_AT_LEAST_ONCE (dr
) = -1;
1332 DR_RW_UNCONDITIONALLY (dr
) = -1;
1334 predicate_bbs (loop
);
1337 for (i
= 0; i
< loop
->num_nodes
; i
++)
1339 basic_block bb
= ifc_bbs
[i
];
1340 gimple_stmt_iterator itr
;
1342 /* Check the if-convertibility of statements in predicated BBs. */
1343 if (!dominated_by_p (CDI_DOMINATORS
, loop
->latch
, bb
))
1344 for (itr
= gsi_start_bb (bb
); !gsi_end_p (itr
); gsi_next (&itr
))
1345 if (!if_convertible_stmt_p (gsi_stmt (itr
), *refs
,
1346 any_mask_load_store
))
1350 if (flag_tree_loop_if_convert_stores
)
1351 for (i
= 0; i
< loop
->num_nodes
; i
++)
1352 free_bb_predicate (ifc_bbs
[i
]);
1354 /* Checking PHIs needs to be done after stmts, as the fact whether there
1355 are any masked loads or stores affects the tests. */
1356 for (i
= 0; i
< loop
->num_nodes
; i
++)
1358 basic_block bb
= ifc_bbs
[i
];
1361 for (itr
= gsi_start_phis (bb
); !gsi_end_p (itr
); gsi_next (&itr
))
1362 if (!if_convertible_phi_p (loop
, bb
, itr
.phi (),
1363 *any_mask_load_store
))
1368 fprintf (dump_file
, "Applying if-conversion\n");
1373 /* Return true when LOOP is if-convertible.
1374 LOOP is if-convertible if:
1376 - it has two or more basic blocks,
1377 - it has only one exit,
1378 - loop header is not the exit edge,
1379 - if its basic blocks and phi nodes are if convertible. */
1382 if_convertible_loop_p (struct loop
*loop
, bool *any_mask_load_store
)
1387 vec
<data_reference_p
> refs
;
1390 /* Handle only innermost loop. */
1391 if (!loop
|| loop
->inner
)
1393 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1394 fprintf (dump_file
, "not innermost loop\n");
1398 /* If only one block, no need for if-conversion. */
1399 if (loop
->num_nodes
<= 2)
1401 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1402 fprintf (dump_file
, "less than 2 basic blocks\n");
1406 /* More than one loop exit is too much to handle. */
1407 if (!single_exit (loop
))
1409 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1410 fprintf (dump_file
, "multiple exits\n");
1414 /* If one of the loop header's edge is an exit edge then do not
1415 apply if-conversion. */
1416 FOR_EACH_EDGE (e
, ei
, loop
->header
->succs
)
1417 if (loop_exit_edge_p (loop
, e
))
1422 auto_vec
<loop_p
, 3> loop_nest
;
1423 res
= if_convertible_loop_p_1 (loop
, &loop_nest
, &refs
, &ddrs
,
1424 any_mask_load_store
);
1426 if (flag_tree_loop_if_convert_stores
)
1428 data_reference_p dr
;
1431 for (i
= 0; refs
.iterate (i
, &dr
); i
++)
1435 free_data_refs (refs
);
1436 free_dependence_relations (ddrs
);
1440 /* Returns true if def-stmt for phi argument ARG is simple increment/decrement
1441 which is in predicated basic block.
1442 In fact, the following PHI pattern is searching:
1444 reduc_1 = PHI <..., reduc_2>
1448 reduc_2 = PHI <reduc_1, reduc_3>
1450 ARG_0 and ARG_1 are correspondent PHI arguments.
1451 REDUC, OP0 and OP1 contain reduction stmt and its operands.
1452 EXTENDED is true if PHI has > 2 arguments. */
1455 is_cond_scalar_reduction (gimple phi
, gimple
*reduc
, tree arg_0
, tree arg_1
,
1456 tree
*op0
, tree
*op1
, bool extended
)
1458 tree lhs
, r_op1
, r_op2
;
1460 gimple header_phi
= NULL
;
1461 enum tree_code reduction_op
;
1462 basic_block bb
= gimple_bb (phi
);
1463 struct loop
*loop
= bb
->loop_father
;
1464 edge latch_e
= loop_latch_edge (loop
);
1465 imm_use_iterator imm_iter
;
1466 use_operand_p use_p
;
1469 bool result
= false;
1470 if (TREE_CODE (arg_0
) != SSA_NAME
|| TREE_CODE (arg_1
) != SSA_NAME
)
1473 if (!extended
&& gimple_code (SSA_NAME_DEF_STMT (arg_0
)) == GIMPLE_PHI
)
1476 header_phi
= SSA_NAME_DEF_STMT (arg_0
);
1477 stmt
= SSA_NAME_DEF_STMT (arg_1
);
1479 else if (gimple_code (SSA_NAME_DEF_STMT (arg_1
)) == GIMPLE_PHI
)
1482 header_phi
= SSA_NAME_DEF_STMT (arg_1
);
1483 stmt
= SSA_NAME_DEF_STMT (arg_0
);
1487 if (gimple_bb (header_phi
) != loop
->header
)
1490 if (PHI_ARG_DEF_FROM_EDGE (header_phi
, latch_e
) != PHI_RESULT (phi
))
1493 if (gimple_code (stmt
) != GIMPLE_ASSIGN
1494 || gimple_has_volatile_ops (stmt
))
1497 if (!flow_bb_inside_loop_p (loop
, gimple_bb (stmt
)))
1500 if (!is_predicated (gimple_bb (stmt
)))
1503 /* Check that stmt-block is predecessor of phi-block. */
1504 FOR_EACH_EDGE (e
, ei
, gimple_bb (stmt
)->succs
)
1513 if (!has_single_use (lhs
))
1516 reduction_op
= gimple_assign_rhs_code (stmt
);
1517 if (reduction_op
!= PLUS_EXPR
&& reduction_op
!= MINUS_EXPR
)
1519 r_op1
= gimple_assign_rhs1 (stmt
);
1520 r_op2
= gimple_assign_rhs2 (stmt
);
1522 /* Make R_OP1 to hold reduction variable. */
1523 if (r_op2
== PHI_RESULT (header_phi
)
1524 && reduction_op
== PLUS_EXPR
)
1530 else if (r_op1
!= PHI_RESULT (header_phi
))
1533 /* Check that R_OP1 is used in reduction stmt or in PHI only. */
1534 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, r_op1
)
1536 gimple use_stmt
= USE_STMT (use_p
);
1537 if (is_gimple_debug (use_stmt
))
1539 if (use_stmt
== stmt
)
1541 if (gimple_code (use_stmt
) != GIMPLE_PHI
)
1545 *op0
= r_op1
; *op1
= r_op2
;
1550 /* Converts conditional scalar reduction into unconditional form, e.g.
1552 if (_5 != 0) goto bb_5 else goto bb_6
1558 # res_2 = PHI <res_13(4), res_6(5)>
1561 will be converted into sequence
1562 _ifc__1 = _5 != 0 ? 1 : 0;
1563 res_2 = res_13 + _ifc__1;
1564 Argument SWAP tells that arguments of conditional expression should be
1566 Returns rhs of resulting PHI assignment. */
1569 convert_scalar_cond_reduction (gimple reduc
, gimple_stmt_iterator
*gsi
,
1570 tree cond
, tree op0
, tree op1
, bool swap
)
1572 gimple_stmt_iterator stmt_it
;
1575 tree rhs1
= gimple_assign_rhs1 (reduc
);
1576 tree tmp
= make_temp_ssa_name (TREE_TYPE (rhs1
), NULL
, "_ifc_");
1578 tree zero
= build_zero_cst (TREE_TYPE (rhs1
));
1580 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1582 fprintf (dump_file
, "Found cond scalar reduction.\n");
1583 print_gimple_stmt (dump_file
, reduc
, 0, TDF_SLIM
);
1586 /* Build cond expression using COND and constant operand
1587 of reduction rhs. */
1588 c
= fold_build_cond_expr (TREE_TYPE (rhs1
),
1589 unshare_expr (cond
),
1593 /* Create assignment stmt and insert it at GSI. */
1594 new_assign
= gimple_build_assign (tmp
, c
);
1595 gsi_insert_before (gsi
, new_assign
, GSI_SAME_STMT
);
1596 /* Build rhs for unconditional increment/decrement. */
1597 rhs
= fold_build2 (gimple_assign_rhs_code (reduc
),
1598 TREE_TYPE (rhs1
), op0
, tmp
);
1600 /* Delete original reduction stmt. */
1601 stmt_it
= gsi_for_stmt (reduc
);
1602 gsi_remove (&stmt_it
, true);
1603 release_defs (reduc
);
1607 /* Helpers for PHI arguments hashtable map. */
1609 struct phi_args_hash_traits
: default_hashmap_traits
1611 static inline hashval_t
hash (tree
);
1612 static inline bool equal_keys (tree
, tree
);
1616 phi_args_hash_traits::hash (tree value
)
1618 return iterative_hash_expr (value
, 0);
1622 phi_args_hash_traits::equal_keys (tree value1
, tree value2
)
1624 return operand_equal_p (value1
, value2
, 0);
1627 /* Produce condition for all occurrences of ARG in PHI node. */
1630 gen_phi_arg_condition (gphi
*phi
, vec
<int> *occur
,
1631 gimple_stmt_iterator
*gsi
)
1635 tree cond
= NULL_TREE
;
1639 len
= occur
->length ();
1640 gcc_assert (len
> 0);
1641 for (i
= 0; i
< len
; i
++)
1643 e
= gimple_phi_arg_edge (phi
, (*occur
)[i
]);
1644 c
= bb_predicate (e
->src
);
1645 if (is_true_predicate (c
))
1647 c
= force_gimple_operand_gsi_1 (gsi
, unshare_expr (c
),
1648 is_gimple_condexpr
, NULL_TREE
,
1649 true, GSI_SAME_STMT
);
1650 if (cond
!= NULL_TREE
)
1652 /* Must build OR expression. */
1653 cond
= fold_or_predicates (EXPR_LOCATION (c
), c
, cond
);
1654 cond
= force_gimple_operand_gsi_1 (gsi
, unshare_expr (cond
),
1655 is_gimple_condexpr
, NULL_TREE
,
1656 true, GSI_SAME_STMT
);
1661 gcc_assert (cond
!= NULL_TREE
);
1665 /* Replace a scalar PHI node with a COND_EXPR using COND as condition.
1666 This routine can handle PHI nodes with more than two arguments.
1669 S1: A = PHI <x1(1), x2(5)>
1671 S2: A = cond ? x1 : x2;
1673 The generated code is inserted at GSI that points to the top of
1674 basic block's statement list.
1675 If PHI node has more than two arguments a chain of conditional
1676 expression is produced. */
1680 predicate_scalar_phi (gphi
*phi
, gimple_stmt_iterator
*gsi
)
1682 gimple new_stmt
= NULL
, reduc
;
1683 tree rhs
, res
, arg0
, arg1
, op0
, op1
, scev
;
1685 unsigned int index0
;
1686 unsigned int max
, args_len
;
1691 res
= gimple_phi_result (phi
);
1692 if (virtual_operand_p (res
))
1695 if ((rhs
= degenerate_phi_result (phi
))
1696 || ((scev
= analyze_scalar_evolution (gimple_bb (phi
)->loop_father
,
1698 && !chrec_contains_undetermined (scev
)
1700 && (rhs
= gimple_phi_arg_def (phi
, 0))))
1702 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1704 fprintf (dump_file
, "Degenerate phi!\n");
1705 print_gimple_stmt (dump_file
, phi
, 0, TDF_SLIM
);
1707 new_stmt
= gimple_build_assign (res
, rhs
);
1708 gsi_insert_before (gsi
, new_stmt
, GSI_SAME_STMT
);
1709 update_stmt (new_stmt
);
1713 bb
= gimple_bb (phi
);
1714 if (EDGE_COUNT (bb
->preds
) == 2)
1716 /* Predicate ordinary PHI node with 2 arguments. */
1717 edge first_edge
, second_edge
;
1718 basic_block true_bb
;
1719 first_edge
= EDGE_PRED (bb
, 0);
1720 second_edge
= EDGE_PRED (bb
, 1);
1721 cond
= bb_predicate (first_edge
->src
);
1722 if (TREE_CODE (cond
) == TRUTH_NOT_EXPR
)
1724 edge tmp_edge
= first_edge
;
1725 first_edge
= second_edge
;
1726 second_edge
= tmp_edge
;
1728 if (EDGE_COUNT (first_edge
->src
->succs
) > 1)
1730 cond
= bb_predicate (second_edge
->src
);
1731 if (TREE_CODE (cond
) == TRUTH_NOT_EXPR
)
1732 cond
= TREE_OPERAND (cond
, 0);
1734 first_edge
= second_edge
;
1737 cond
= bb_predicate (first_edge
->src
);
1738 /* Gimplify the condition to a valid cond-expr conditonal operand. */
1739 cond
= force_gimple_operand_gsi_1 (gsi
, unshare_expr (cond
),
1740 is_gimple_condexpr
, NULL_TREE
,
1741 true, GSI_SAME_STMT
);
1742 true_bb
= first_edge
->src
;
1743 if (EDGE_PRED (bb
, 1)->src
== true_bb
)
1745 arg0
= gimple_phi_arg_def (phi
, 1);
1746 arg1
= gimple_phi_arg_def (phi
, 0);
1750 arg0
= gimple_phi_arg_def (phi
, 0);
1751 arg1
= gimple_phi_arg_def (phi
, 1);
1753 if (is_cond_scalar_reduction (phi
, &reduc
, arg0
, arg1
,
1755 /* Convert reduction stmt into vectorizable form. */
1756 rhs
= convert_scalar_cond_reduction (reduc
, gsi
, cond
, op0
, op1
,
1757 true_bb
!= gimple_bb (reduc
));
1759 /* Build new RHS using selected condition and arguments. */
1760 rhs
= fold_build_cond_expr (TREE_TYPE (res
), unshare_expr (cond
),
1762 new_stmt
= gimple_build_assign (res
, rhs
);
1763 gsi_insert_before (gsi
, new_stmt
, GSI_SAME_STMT
);
1764 update_stmt (new_stmt
);
1766 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1768 fprintf (dump_file
, "new phi replacement stmt\n");
1769 print_gimple_stmt (dump_file
, new_stmt
, 0, TDF_SLIM
);
1774 /* Create hashmap for PHI node which contain vector of argument indexes
1775 having the same value. */
1777 hash_map
<tree
, auto_vec
<int>, phi_args_hash_traits
> phi_arg_map
;
1778 unsigned int num_args
= gimple_phi_num_args (phi
);
1780 /* Vector of different PHI argument values. */
1781 auto_vec
<tree
> args (num_args
);
1783 /* Compute phi_arg_map. */
1784 for (i
= 0; i
< num_args
; i
++)
1788 arg
= gimple_phi_arg_def (phi
, i
);
1789 if (!phi_arg_map
.get (arg
))
1790 args
.quick_push (arg
);
1791 phi_arg_map
.get_or_insert (arg
).safe_push (i
);
1794 /* Determine element with max number of occurrences. */
1797 args_len
= args
.length ();
1798 for (i
= 0; i
< args_len
; i
++)
1801 if ((len
= phi_arg_map
.get (args
[i
])->length ()) > max
)
1808 /* Put element with max number of occurences to the end of ARGS. */
1809 if (max_ind
!= -1 && max_ind
+1 != (int) args_len
)
1811 tree tmp
= args
[args_len
- 1];
1812 args
[args_len
- 1] = args
[max_ind
];
1813 args
[max_ind
] = tmp
;
1816 /* Handle one special case when number of arguments with different values
1817 is equal 2 and one argument has the only occurrence. Such PHI can be
1818 handled as if would have only 2 arguments. */
1819 if (args_len
== 2 && phi_arg_map
.get (args
[0])->length () == 1)
1822 indexes
= phi_arg_map
.get (args
[0]);
1823 index0
= (*indexes
)[0];
1826 e
= gimple_phi_arg_edge (phi
, index0
);
1827 cond
= bb_predicate (e
->src
);
1828 if (TREE_CODE (cond
) == TRUTH_NOT_EXPR
)
1831 cond
= TREE_OPERAND (cond
, 0);
1833 /* Gimplify the condition to a valid cond-expr conditonal operand. */
1834 cond
= force_gimple_operand_gsi_1 (gsi
, unshare_expr (cond
),
1835 is_gimple_condexpr
, NULL_TREE
,
1836 true, GSI_SAME_STMT
);
1837 if (!(is_cond_scalar_reduction (phi
, &reduc
, arg0
, arg1
,
1839 rhs
= fold_build_cond_expr (TREE_TYPE (res
), unshare_expr (cond
),
1843 /* Convert reduction stmt into vectorizable form. */
1844 rhs
= convert_scalar_cond_reduction (reduc
, gsi
, cond
, op0
, op1
,
1846 new_stmt
= gimple_build_assign (res
, rhs
);
1847 gsi_insert_before (gsi
, new_stmt
, GSI_SAME_STMT
);
1848 update_stmt (new_stmt
);
1854 tree type
= TREE_TYPE (gimple_phi_result (phi
));
1857 for (i
= 0; i
< args_len
; i
++)
1860 indexes
= phi_arg_map
.get (args
[i
]);
1861 if (i
!= args_len
- 1)
1862 lhs
= make_temp_ssa_name (type
, NULL
, "_ifc_");
1865 cond
= gen_phi_arg_condition (phi
, indexes
, gsi
);
1866 rhs
= fold_build_cond_expr (type
, unshare_expr (cond
),
1868 new_stmt
= gimple_build_assign (lhs
, rhs
);
1869 gsi_insert_before (gsi
, new_stmt
, GSI_SAME_STMT
);
1870 update_stmt (new_stmt
);
1875 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1877 fprintf (dump_file
, "new extended phi replacement stmt\n");
1878 print_gimple_stmt (dump_file
, new_stmt
, 0, TDF_SLIM
);
1882 /* Replaces in LOOP all the scalar phi nodes other than those in the
1883 LOOP->header block with conditional modify expressions. */
1886 predicate_all_scalar_phis (struct loop
*loop
)
1889 unsigned int orig_loop_num_nodes
= loop
->num_nodes
;
1892 for (i
= 1; i
< orig_loop_num_nodes
; i
++)
1895 gimple_stmt_iterator gsi
;
1896 gphi_iterator phi_gsi
;
1899 if (bb
== loop
->header
)
1902 if (EDGE_COUNT (bb
->preds
) == 1)
1905 phi_gsi
= gsi_start_phis (bb
);
1906 if (gsi_end_p (phi_gsi
))
1909 gsi
= gsi_after_labels (bb
);
1910 while (!gsi_end_p (phi_gsi
))
1912 phi
= phi_gsi
.phi ();
1913 predicate_scalar_phi (phi
, &gsi
);
1914 release_phi_node (phi
);
1915 gsi_next (&phi_gsi
);
1918 set_phi_nodes (bb
, NULL
);
1922 /* Insert in each basic block of LOOP the statements produced by the
1923 gimplification of the predicates. */
1926 insert_gimplified_predicates (loop_p loop
, bool any_mask_load_store
)
1930 for (i
= 0; i
< loop
->num_nodes
; i
++)
1932 basic_block bb
= ifc_bbs
[i
];
1934 if (!is_predicated (bb
))
1935 gcc_assert (bb_predicate_gimplified_stmts (bb
) == NULL
);
1936 if (!is_predicated (bb
))
1938 /* Do not insert statements for a basic block that is not
1939 predicated. Also make sure that the predicate of the
1940 basic block is set to true. */
1941 reset_bb_predicate (bb
);
1945 stmts
= bb_predicate_gimplified_stmts (bb
);
1948 if (flag_tree_loop_if_convert_stores
1949 || any_mask_load_store
)
1951 /* Insert the predicate of the BB just after the label,
1952 as the if-conversion of memory writes will use this
1954 gimple_stmt_iterator gsi
= gsi_after_labels (bb
);
1955 gsi_insert_seq_before (&gsi
, stmts
, GSI_SAME_STMT
);
1959 /* Insert the predicate of the BB at the end of the BB
1960 as this would reduce the register pressure: the only
1961 use of this predicate will be in successor BBs. */
1962 gimple_stmt_iterator gsi
= gsi_last_bb (bb
);
1965 || stmt_ends_bb_p (gsi_stmt (gsi
)))
1966 gsi_insert_seq_before (&gsi
, stmts
, GSI_SAME_STMT
);
1968 gsi_insert_seq_after (&gsi
, stmts
, GSI_SAME_STMT
);
1971 /* Once the sequence is code generated, set it to NULL. */
1972 set_bb_predicate_gimplified_stmts (bb
, NULL
);
1977 /* Helper function for predicate_mem_writes. Returns index of existent
1978 mask if it was created for given SIZE and -1 otherwise. */
1981 mask_exists (int size
, vec
<int> vec
)
1985 FOR_EACH_VEC_ELT (vec
, ix
, v
)
1991 /* Predicate each write to memory in LOOP.
1993 This function transforms control flow constructs containing memory
1996 | for (i = 0; i < N; i++)
2000 into the following form that does not contain control flow:
2002 | for (i = 0; i < N; i++)
2003 | A[i] = cond ? expr : A[i];
2005 The original CFG looks like this:
2012 | if (i < N) goto bb_5 else goto bb_2
2016 | cond = some_computation;
2017 | if (cond) goto bb_3 else goto bb_4
2029 insert_gimplified_predicates inserts the computation of the COND
2030 expression at the beginning of the destination basic block:
2037 | if (i < N) goto bb_5 else goto bb_2
2041 | cond = some_computation;
2042 | if (cond) goto bb_3 else goto bb_4
2046 | cond = some_computation;
2055 predicate_mem_writes is then predicating the memory write as follows:
2062 | if (i < N) goto bb_5 else goto bb_2
2066 | if (cond) goto bb_3 else goto bb_4
2070 | cond = some_computation;
2071 | A[i] = cond ? expr : A[i];
2079 and finally combine_blocks removes the basic block boundaries making
2080 the loop vectorizable:
2084 | if (i < N) goto bb_5 else goto bb_1
2088 | cond = some_computation;
2089 | A[i] = cond ? expr : A[i];
2090 | if (i < N) goto bb_5 else goto bb_4
2099 predicate_mem_writes (loop_p loop
)
2101 unsigned int i
, orig_loop_num_nodes
= loop
->num_nodes
;
2102 auto_vec
<int, 1> vect_sizes
;
2103 auto_vec
<tree
, 1> vect_masks
;
2105 for (i
= 1; i
< orig_loop_num_nodes
; i
++)
2107 gimple_stmt_iterator gsi
;
2108 basic_block bb
= ifc_bbs
[i
];
2109 tree cond
= bb_predicate (bb
);
2114 if (is_true_predicate (cond
))
2118 if (TREE_CODE (cond
) == TRUTH_NOT_EXPR
)
2121 cond
= TREE_OPERAND (cond
, 0);
2124 vect_sizes
.truncate (0);
2125 vect_masks
.truncate (0);
2127 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2128 if (!gimple_assign_single_p (stmt
= gsi_stmt (gsi
)))
2130 else if (gimple_plf (stmt
, GF_PLF_2
))
2132 tree lhs
= gimple_assign_lhs (stmt
);
2133 tree rhs
= gimple_assign_rhs1 (stmt
);
2134 tree ref
, addr
, ptr
, masktype
, mask_op0
, mask_op1
, mask
;
2136 int bitsize
= GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (lhs
)));
2137 ref
= TREE_CODE (lhs
) == SSA_NAME
? rhs
: lhs
;
2138 mark_addressable (ref
);
2139 addr
= force_gimple_operand_gsi (&gsi
, build_fold_addr_expr (ref
),
2140 true, NULL_TREE
, true,
2142 if (!vect_sizes
.is_empty ()
2143 && (index
= mask_exists (bitsize
, vect_sizes
)) != -1)
2144 /* Use created mask. */
2145 mask
= vect_masks
[index
];
2148 masktype
= build_nonstandard_integer_type (bitsize
, 1);
2149 mask_op0
= build_int_cst (masktype
, swap
? 0 : -1);
2150 mask_op1
= build_int_cst (masktype
, swap
? -1 : 0);
2151 cond
= force_gimple_operand_gsi_1 (&gsi
, unshare_expr (cond
),
2154 true, GSI_SAME_STMT
);
2155 mask
= fold_build_cond_expr (masktype
, unshare_expr (cond
),
2156 mask_op0
, mask_op1
);
2157 mask
= ifc_temp_var (masktype
, mask
, &gsi
);
2158 /* Save mask and its size for further use. */
2159 vect_sizes
.safe_push (bitsize
);
2160 vect_masks
.safe_push (mask
);
2162 ptr
= build_int_cst (reference_alias_ptr_type (ref
), 0);
2163 /* Copy points-to info if possible. */
2164 if (TREE_CODE (addr
) == SSA_NAME
&& !SSA_NAME_PTR_INFO (addr
))
2165 copy_ref_info (build2 (MEM_REF
, TREE_TYPE (ref
), addr
, ptr
),
2167 if (TREE_CODE (lhs
) == SSA_NAME
)
2170 = gimple_build_call_internal (IFN_MASK_LOAD
, 3, addr
,
2172 gimple_call_set_lhs (new_stmt
, lhs
);
2176 = gimple_build_call_internal (IFN_MASK_STORE
, 4, addr
, ptr
,
2178 gsi_replace (&gsi
, new_stmt
, true);
2180 else if (gimple_vdef (stmt
))
2182 tree lhs
= gimple_assign_lhs (stmt
);
2183 tree rhs
= gimple_assign_rhs1 (stmt
);
2184 tree type
= TREE_TYPE (lhs
);
2186 lhs
= ifc_temp_var (type
, unshare_expr (lhs
), &gsi
);
2187 rhs
= ifc_temp_var (type
, unshare_expr (rhs
), &gsi
);
2194 cond
= force_gimple_operand_gsi_1 (&gsi
, unshare_expr (cond
),
2195 is_gimple_condexpr
, NULL_TREE
,
2196 true, GSI_SAME_STMT
);
2197 rhs
= fold_build_cond_expr (type
, unshare_expr (cond
), rhs
, lhs
);
2198 gimple_assign_set_rhs1 (stmt
, ifc_temp_var (type
, rhs
, &gsi
));
2204 /* Remove all GIMPLE_CONDs and GIMPLE_LABELs of all the basic blocks
2205 other than the exit and latch of the LOOP. Also resets the
2206 GIMPLE_DEBUG information. */
2209 remove_conditions_and_labels (loop_p loop
)
2211 gimple_stmt_iterator gsi
;
2214 for (i
= 0; i
< loop
->num_nodes
; i
++)
2216 basic_block bb
= ifc_bbs
[i
];
2218 if (bb_with_exit_edge_p (loop
, bb
)
2219 || bb
== loop
->latch
)
2222 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); )
2223 switch (gimple_code (gsi_stmt (gsi
)))
2227 gsi_remove (&gsi
, true);
2231 /* ??? Should there be conditional GIMPLE_DEBUG_BINDs? */
2232 if (gimple_debug_bind_p (gsi_stmt (gsi
)))
2234 gimple_debug_bind_reset_value (gsi_stmt (gsi
));
2235 update_stmt (gsi_stmt (gsi
));
2246 /* Combine all the basic blocks from LOOP into one or two super basic
2247 blocks. Replace PHI nodes with conditional modify expressions. */
2250 combine_blocks (struct loop
*loop
, bool any_mask_load_store
)
2252 basic_block bb
, exit_bb
, merge_target_bb
;
2253 unsigned int orig_loop_num_nodes
= loop
->num_nodes
;
2258 predicate_bbs (loop
);
2259 remove_conditions_and_labels (loop
);
2260 insert_gimplified_predicates (loop
, any_mask_load_store
);
2261 predicate_all_scalar_phis (loop
);
2263 if (flag_tree_loop_if_convert_stores
|| any_mask_load_store
)
2264 predicate_mem_writes (loop
);
2266 /* Merge basic blocks: first remove all the edges in the loop,
2267 except for those from the exit block. */
2269 for (i
= 0; i
< orig_loop_num_nodes
; i
++)
2272 free_bb_predicate (bb
);
2273 if (bb_with_exit_edge_p (loop
, bb
))
2275 gcc_assert (exit_bb
== NULL
);
2279 gcc_assert (exit_bb
!= loop
->latch
);
2281 for (i
= 1; i
< orig_loop_num_nodes
; i
++)
2285 for (ei
= ei_start (bb
->preds
); (e
= ei_safe_edge (ei
));)
2287 if (e
->src
== exit_bb
)
2294 if (exit_bb
!= NULL
)
2296 if (exit_bb
!= loop
->header
)
2298 /* Connect this node to loop header. */
2299 make_edge (loop
->header
, exit_bb
, EDGE_FALLTHRU
);
2300 set_immediate_dominator (CDI_DOMINATORS
, exit_bb
, loop
->header
);
2303 /* Redirect non-exit edges to loop->latch. */
2304 FOR_EACH_EDGE (e
, ei
, exit_bb
->succs
)
2306 if (!loop_exit_edge_p (loop
, e
))
2307 redirect_edge_and_branch (e
, loop
->latch
);
2309 set_immediate_dominator (CDI_DOMINATORS
, loop
->latch
, exit_bb
);
2313 /* If the loop does not have an exit, reconnect header and latch. */
2314 make_edge (loop
->header
, loop
->latch
, EDGE_FALLTHRU
);
2315 set_immediate_dominator (CDI_DOMINATORS
, loop
->latch
, loop
->header
);
2318 merge_target_bb
= loop
->header
;
2319 for (i
= 1; i
< orig_loop_num_nodes
; i
++)
2321 gimple_stmt_iterator gsi
;
2322 gimple_stmt_iterator last
;
2326 if (bb
== exit_bb
|| bb
== loop
->latch
)
2329 /* Make stmts member of loop->header. */
2330 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2331 gimple_set_bb (gsi_stmt (gsi
), merge_target_bb
);
2333 /* Update stmt list. */
2334 last
= gsi_last_bb (merge_target_bb
);
2335 gsi_insert_seq_after (&last
, bb_seq (bb
), GSI_NEW_STMT
);
2336 set_bb_seq (bb
, NULL
);
2338 delete_basic_block (bb
);
2341 /* If possible, merge loop header to the block with the exit edge.
2342 This reduces the number of basic blocks to two, to please the
2343 vectorizer that handles only loops with two nodes. */
2345 && exit_bb
!= loop
->header
2346 && can_merge_blocks_p (loop
->header
, exit_bb
))
2347 merge_blocks (loop
->header
, exit_bb
);
2353 /* Version LOOP before if-converting it, the original loop
2354 will be then if-converted, the new copy of the loop will not,
2355 and the LOOP_VECTORIZED internal call will be guarding which
2356 loop to execute. The vectorizer pass will fold this
2357 internal call into either true or false. */
2360 version_loop_for_if_conversion (struct loop
*loop
)
2362 basic_block cond_bb
;
2363 tree cond
= make_ssa_name (boolean_type_node
);
2364 struct loop
*new_loop
;
2366 gimple_stmt_iterator gsi
;
2368 g
= gimple_build_call_internal (IFN_LOOP_VECTORIZED
, 2,
2369 build_int_cst (integer_type_node
, loop
->num
),
2371 gimple_call_set_lhs (g
, cond
);
2373 initialize_original_copy_tables ();
2374 new_loop
= loop_version (loop
, cond
, &cond_bb
,
2375 REG_BR_PROB_BASE
, REG_BR_PROB_BASE
,
2376 REG_BR_PROB_BASE
, true);
2377 free_original_copy_tables ();
2378 if (new_loop
== NULL
)
2380 new_loop
->dont_vectorize
= true;
2381 new_loop
->force_vectorize
= false;
2382 gsi
= gsi_last_bb (cond_bb
);
2383 gimple_call_set_arg (g
, 1, build_int_cst (integer_type_node
, new_loop
->num
));
2384 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
2385 update_ssa (TODO_update_ssa
);
2389 /* Performs splitting of critical edges if aggressive_if_conv is true.
2390 Returns false if loop won't be if converted and true otherwise. */
2393 ifcvt_split_critical_edges (struct loop
*loop
)
2397 unsigned int num
= loop
->num_nodes
;
2407 if (!single_exit (loop
))
2410 body
= get_loop_body (loop
);
2411 for (i
= 0; i
< num
; i
++)
2414 if (bb
== loop
->latch
2415 || bb_with_exit_edge_p (loop
, bb
))
2417 stmt
= last_stmt (bb
);
2418 /* Skip basic blocks not ending with conditional branch. */
2419 if (!(stmt
&& gimple_code (stmt
) == GIMPLE_COND
))
2421 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
2422 if (EDGE_CRITICAL_P (e
) && e
->dest
->loop_father
== loop
)
2429 /* Assumes that lhs of DEF_STMT have multiple uses.
2430 Delete one use by (1) creation of copy DEF_STMT with
2431 unique lhs; (2) change original use of lhs in one
2432 use statement with newly created lhs. */
2435 ifcvt_split_def_stmt (gimple def_stmt
, gimple use_stmt
)
2440 gimple_stmt_iterator gsi
;
2441 use_operand_p use_p
;
2442 imm_use_iterator imm_iter
;
2444 var
= gimple_assign_lhs (def_stmt
);
2445 copy_stmt
= gimple_copy (def_stmt
);
2446 lhs
= make_temp_ssa_name (TREE_TYPE (var
), NULL
, "_ifc_");
2447 gimple_assign_set_lhs (copy_stmt
, lhs
);
2448 SSA_NAME_DEF_STMT (lhs
) = copy_stmt
;
2449 /* Insert copy of DEF_STMT. */
2450 gsi
= gsi_for_stmt (def_stmt
);
2451 gsi_insert_after (&gsi
, copy_stmt
, GSI_SAME_STMT
);
2452 /* Change use of var to lhs in use_stmt. */
2453 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2455 fprintf (dump_file
, "Change use of var ");
2456 print_generic_expr (dump_file
, var
, TDF_SLIM
);
2457 fprintf (dump_file
, " to ");
2458 print_generic_expr (dump_file
, lhs
, TDF_SLIM
);
2459 fprintf (dump_file
, "\n");
2461 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, var
)
2463 if (USE_STMT (use_p
) != use_stmt
)
2465 SET_USE (use_p
, lhs
);
2470 /* Traverse bool pattern recursively starting from VAR.
2471 Save its def and use statements to defuse_list if VAR does
2472 not have single use. */
2475 ifcvt_walk_pattern_tree (tree var
, vec
<gimple
> *defuse_list
,
2479 enum tree_code code
;
2482 def_stmt
= SSA_NAME_DEF_STMT (var
);
2483 if (gimple_code (def_stmt
) != GIMPLE_ASSIGN
)
2485 if (!has_single_use (var
))
2487 /* Put def and use stmts into defuse_list. */
2488 defuse_list
->safe_push (def_stmt
);
2489 defuse_list
->safe_push (use_stmt
);
2490 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2492 fprintf (dump_file
, "Multiple lhs uses in stmt\n");
2493 print_gimple_stmt (dump_file
, def_stmt
, 0, TDF_SLIM
);
2496 rhs1
= gimple_assign_rhs1 (def_stmt
);
2497 code
= gimple_assign_rhs_code (def_stmt
);
2501 ifcvt_walk_pattern_tree (rhs1
, defuse_list
, def_stmt
);
2504 if ((TYPE_PRECISION (TREE_TYPE (rhs1
)) != 1
2505 || !TYPE_UNSIGNED (TREE_TYPE (rhs1
)))
2506 && TREE_CODE (TREE_TYPE (rhs1
)) != BOOLEAN_TYPE
)
2508 ifcvt_walk_pattern_tree (rhs1
, defuse_list
, def_stmt
);
2511 ifcvt_walk_pattern_tree (rhs1
, defuse_list
, def_stmt
);
2516 ifcvt_walk_pattern_tree (rhs1
, defuse_list
, def_stmt
);
2517 rhs2
= gimple_assign_rhs2 (def_stmt
);
2518 ifcvt_walk_pattern_tree (rhs2
, defuse_list
, def_stmt
);
2526 /* Returns true if STMT can be a root of bool pattern apllied
2530 stmt_is_root_of_bool_pattern (gimple stmt
)
2532 enum tree_code code
;
2535 code
= gimple_assign_rhs_code (stmt
);
2536 if (CONVERT_EXPR_CODE_P (code
))
2538 lhs
= gimple_assign_lhs (stmt
);
2539 rhs
= gimple_assign_rhs1 (stmt
);
2540 if (TREE_CODE (TREE_TYPE (rhs
)) != BOOLEAN_TYPE
)
2542 if (TREE_CODE (TREE_TYPE (lhs
)) == BOOLEAN_TYPE
)
2546 else if (code
== COND_EXPR
)
2548 rhs
= gimple_assign_rhs1 (stmt
);
2549 if (TREE_CODE (rhs
) != SSA_NAME
)
2556 /* Traverse all statements in BB which correspondent to loop header to
2557 find out all statements which can start bool pattern applied by
2558 vectorizer and convert multiple uses in it to conform pattern
2559 restrictions. Such case can occur if the same predicate is used both
2560 for phi node conversion and load/store mask. */
2563 ifcvt_repair_bool_pattern (basic_block bb
)
2567 gimple_stmt_iterator gsi
;
2568 vec
<gimple
> defuse_list
= vNULL
;
2569 vec
<gimple
> pattern_roots
= vNULL
;
2574 /* Collect all root pattern statements. */
2575 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2577 stmt
= gsi_stmt (gsi
);
2578 if (gimple_code (stmt
) != GIMPLE_ASSIGN
)
2580 if (!stmt_is_root_of_bool_pattern (stmt
))
2582 pattern_roots
.safe_push (stmt
);
2585 if (pattern_roots
.is_empty ())
2588 /* Split all statements with multiple uses iteratively since splitting
2589 may create new multiple uses. */
2594 FOR_EACH_VEC_ELT (pattern_roots
, ix
, stmt
)
2596 rhs
= gimple_assign_rhs1 (stmt
);
2597 ifcvt_walk_pattern_tree (rhs
, &defuse_list
, stmt
);
2598 while (defuse_list
.length () > 0)
2601 gimple def_stmt
, use_stmt
;
2602 use_stmt
= defuse_list
.pop ();
2603 def_stmt
= defuse_list
.pop ();
2604 ifcvt_split_def_stmt (def_stmt
, use_stmt
);
2609 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2610 fprintf (dump_file
, "Repair bool pattern takes %d iterations. \n",
2614 /* Delete redundant statements produced by predication which prevents
2615 loop vectorization. */
2618 ifcvt_local_dce (basic_block bb
)
2623 gimple_stmt_iterator gsi
;
2624 vec
<gimple
> worklist
;
2625 enum gimple_code code
;
2626 use_operand_p use_p
;
2627 imm_use_iterator imm_iter
;
2629 worklist
.create (64);
2630 /* Consider all phi as live statements. */
2631 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2633 phi
= gsi_stmt (gsi
);
2634 gimple_set_plf (phi
, GF_PLF_2
, true);
2635 worklist
.safe_push (phi
);
2637 /* Consider load/store statemnts, CALL and COND as live. */
2638 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2640 stmt
= gsi_stmt (gsi
);
2641 if (gimple_store_p (stmt
)
2642 || gimple_assign_load_p (stmt
)
2643 || is_gimple_debug (stmt
))
2645 gimple_set_plf (stmt
, GF_PLF_2
, true);
2646 worklist
.safe_push (stmt
);
2649 code
= gimple_code (stmt
);
2650 if (code
== GIMPLE_COND
|| code
== GIMPLE_CALL
)
2652 gimple_set_plf (stmt
, GF_PLF_2
, true);
2653 worklist
.safe_push (stmt
);
2656 gimple_set_plf (stmt
, GF_PLF_2
, false);
2658 if (code
== GIMPLE_ASSIGN
)
2660 tree lhs
= gimple_assign_lhs (stmt
);
2661 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, lhs
)
2663 stmt1
= USE_STMT (use_p
);
2664 if (gimple_bb (stmt1
) != bb
)
2666 gimple_set_plf (stmt
, GF_PLF_2
, true);
2667 worklist
.safe_push (stmt
);
2673 /* Propagate liveness through arguments of live stmt. */
2674 while (worklist
.length () > 0)
2677 use_operand_p use_p
;
2680 stmt
= worklist
.pop ();
2681 FOR_EACH_PHI_OR_STMT_USE (use_p
, stmt
, iter
, SSA_OP_USE
)
2683 use
= USE_FROM_PTR (use_p
);
2684 if (TREE_CODE (use
) != SSA_NAME
)
2686 stmt1
= SSA_NAME_DEF_STMT (use
);
2687 if (gimple_bb (stmt1
) != bb
2688 || gimple_plf (stmt1
, GF_PLF_2
))
2690 gimple_set_plf (stmt1
, GF_PLF_2
, true);
2691 worklist
.safe_push (stmt1
);
2694 /* Delete dead statements. */
2695 gsi
= gsi_start_bb (bb
);
2696 while (!gsi_end_p (gsi
))
2698 stmt
= gsi_stmt (gsi
);
2699 if (gimple_plf (stmt
, GF_PLF_2
))
2704 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2706 fprintf (dump_file
, "Delete dead stmt in bb#%d\n", bb
->index
);
2707 print_gimple_stmt (dump_file
, stmt
, 0, TDF_SLIM
);
2709 gsi_remove (&gsi
, true);
2710 release_defs (stmt
);
2714 /* If-convert LOOP when it is legal. For the moment this pass has no
2715 profitability analysis. Returns non-zero todo flags when something
2719 tree_if_conversion (struct loop
*loop
)
2721 unsigned int todo
= 0;
2723 bool any_mask_load_store
= false;
2725 /* Set-up aggressive if-conversion for loops marked with simd pragma. */
2726 aggressive_if_conv
= loop
->force_vectorize
;
2727 /* Check either outer loop was marked with simd pragma. */
2728 if (!aggressive_if_conv
)
2730 struct loop
*outer_loop
= loop_outer (loop
);
2731 if (outer_loop
&& outer_loop
->force_vectorize
)
2732 aggressive_if_conv
= true;
2735 if (aggressive_if_conv
)
2736 if (!ifcvt_split_critical_edges (loop
))
2739 if (!if_convertible_loop_p (loop
, &any_mask_load_store
)
2740 || !dbg_cnt (if_conversion_tree
))
2743 if (any_mask_load_store
2744 && ((!flag_tree_loop_vectorize
&& !loop
->force_vectorize
)
2745 || loop
->dont_vectorize
))
2748 if (any_mask_load_store
&& !version_loop_for_if_conversion (loop
))
2751 /* Now all statements are if-convertible. Combine all the basic
2752 blocks into one huge basic block doing the if-conversion
2754 combine_blocks (loop
, any_mask_load_store
);
2756 /* Delete dead predicate computations and repair tree correspondent
2757 to bool pattern to delete multiple uses of preidcates. */
2758 if (aggressive_if_conv
)
2760 ifcvt_local_dce (loop
->header
);
2761 ifcvt_repair_bool_pattern (loop
->header
);
2764 todo
|= TODO_cleanup_cfg
;
2765 if (flag_tree_loop_if_convert_stores
|| any_mask_load_store
)
2767 mark_virtual_operands_for_renaming (cfun
);
2768 todo
|= TODO_update_ssa_only_virtuals
;
2776 for (i
= 0; i
< loop
->num_nodes
; i
++)
2777 free_bb_predicate (ifc_bbs
[i
]);
2782 free_dominance_info (CDI_POST_DOMINATORS
);
2787 /* Tree if-conversion pass management. */
2791 const pass_data pass_data_if_conversion
=
2793 GIMPLE_PASS
, /* type */
2795 OPTGROUP_NONE
, /* optinfo_flags */
2796 TV_NONE
, /* tv_id */
2797 ( PROP_cfg
| PROP_ssa
), /* properties_required */
2798 0, /* properties_provided */
2799 0, /* properties_destroyed */
2800 0, /* todo_flags_start */
2801 0, /* todo_flags_finish */
2804 class pass_if_conversion
: public gimple_opt_pass
2807 pass_if_conversion (gcc::context
*ctxt
)
2808 : gimple_opt_pass (pass_data_if_conversion
, ctxt
)
2811 /* opt_pass methods: */
2812 virtual bool gate (function
*);
2813 virtual unsigned int execute (function
*);
2815 }; // class pass_if_conversion
2818 pass_if_conversion::gate (function
*fun
)
2820 return (((flag_tree_loop_vectorize
|| fun
->has_force_vectorize_loops
)
2821 && flag_tree_loop_if_convert
!= 0)
2822 || flag_tree_loop_if_convert
== 1
2823 || flag_tree_loop_if_convert_stores
== 1);
2827 pass_if_conversion::execute (function
*fun
)
2832 if (number_of_loops (fun
) <= 1)
2835 FOR_EACH_LOOP (loop
, 0)
2836 if (flag_tree_loop_if_convert
== 1
2837 || flag_tree_loop_if_convert_stores
== 1
2838 || ((flag_tree_loop_vectorize
|| loop
->force_vectorize
)
2839 && !loop
->dont_vectorize
))
2840 todo
|= tree_if_conversion (loop
);
2842 #ifdef ENABLE_CHECKING
2845 FOR_EACH_BB_FN (bb
, fun
)
2846 gcc_assert (!bb
->aux
);
2856 make_pass_if_conversion (gcc::context
*ctxt
)
2858 return new pass_if_conversion (ctxt
);