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