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