Line data Source code
1 : /* If-conversion for vectorizer.
2 : Copyright (C) 2004-2026 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 "expr.h"
95 : #include "optabs-tree.h"
96 : #include "gimple-pretty-print.h"
97 : #include "alias.h"
98 : #include "fold-const.h"
99 : #include "stor-layout.h"
100 : #include "gimple-iterator.h"
101 : #include "gimple-fold.h"
102 : #include "gimplify.h"
103 : #include "gimplify-me.h"
104 : #include "tree-cfg.h"
105 : #include "tree-into-ssa.h"
106 : #include "tree-ssa.h"
107 : #include "cfgloop.h"
108 : #include "tree-data-ref.h"
109 : #include "tree-scalar-evolution.h"
110 : #include "tree-ssa-loop.h"
111 : #include "tree-ssa-loop-niter.h"
112 : #include "tree-ssa-loop-ivopts.h"
113 : #include "tree-ssa-address.h"
114 : #include "dbgcnt.h"
115 : #include "tree-hash-traits.h"
116 : #include "varasm.h"
117 : #include "builtins.h"
118 : #include "cfganal.h"
119 : #include "internal-fn.h"
120 : #include "fold-const.h"
121 : #include "tree-ssa-sccvn.h"
122 : #include "tree-cfgcleanup.h"
123 : #include "tree-ssa-dse.h"
124 : #include "tree-vectorizer.h"
125 : #include "tree-eh.h"
126 : #include "cgraph.h"
127 :
128 : /* For lang_hooks.types.type_for_mode. */
129 : #include "langhooks.h"
130 :
131 : /* Only handle PHIs with no more arguments unless we are asked to by
132 : simd pragma. */
133 : #define MAX_PHI_ARG_NUM \
134 : ((unsigned) param_max_tree_if_conversion_phi_args)
135 :
136 : /* True if we've converted a statement that was only executed when some
137 : condition C was true, and if for correctness we need to predicate the
138 : statement to ensure that it is a no-op when C is false. See
139 : predicate_statements for the kinds of predication we support. */
140 : static bool need_to_predicate;
141 :
142 : /* True if we have to rewrite stmts that may invoke undefined behavior
143 : when a condition C was false so it doesn't if it is always executed.
144 : See predicate_statements for the kinds of predication we support. */
145 : static bool need_to_rewrite_undefined;
146 :
147 : /* Indicate if there are any complicated PHIs that need to be handled in
148 : if-conversion. Complicated PHI has more than two arguments and can't
149 : be degenerated to two arguments PHI. See more information in comment
150 : before phi_convertible_by_degenerating_args. */
151 : static bool any_complicated_phi;
152 :
153 : /* True if we have bitfield accesses we can lower. */
154 : static bool need_to_lower_bitfields;
155 :
156 : /* True if there is any ifcvting to be done. */
157 : static bool need_to_ifcvt;
158 :
159 : /* Hash for struct innermost_loop_behavior. It depends on the user to
160 : free the memory. */
161 :
162 : struct innermost_loop_behavior_hash : nofree_ptr_hash <innermost_loop_behavior>
163 : {
164 : static inline hashval_t hash (const value_type &);
165 : static inline bool equal (const value_type &,
166 : const compare_type &);
167 : };
168 :
169 : inline hashval_t
170 400369 : innermost_loop_behavior_hash::hash (const value_type &e)
171 : {
172 400369 : hashval_t hash;
173 :
174 400369 : hash = iterative_hash_expr (e->base_address, 0);
175 400369 : hash = iterative_hash_expr (e->offset, hash);
176 400369 : hash = iterative_hash_expr (e->init, hash);
177 400369 : return iterative_hash_expr (e->step, hash);
178 : }
179 :
180 : inline bool
181 289050 : innermost_loop_behavior_hash::equal (const value_type &e1,
182 : const compare_type &e2)
183 : {
184 289050 : if ((e1->base_address && !e2->base_address)
185 289050 : || (!e1->base_address && e2->base_address)
186 289050 : || (!e1->offset && e2->offset)
187 272804 : || (e1->offset && !e2->offset)
188 245371 : || (!e1->init && e2->init)
189 245371 : || (e1->init && !e2->init)
190 245371 : || (!e1->step && e2->step)
191 245371 : || (e1->step && !e2->step))
192 : return false;
193 :
194 245371 : if (e1->base_address && e2->base_address
195 490742 : && !operand_equal_p (e1->base_address, e2->base_address, 0))
196 : return false;
197 47048 : if (e1->offset && e2->offset
198 124569 : && !operand_equal_p (e1->offset, e2->offset, 0))
199 : return false;
200 46785 : if (e1->init && e2->init
201 124043 : && !operand_equal_p (e1->init, e2->init, 0))
202 : return false;
203 17538 : if (e1->step && e2->step
204 65549 : && !operand_equal_p (e1->step, e2->step, 0))
205 : return false;
206 :
207 : return true;
208 : }
209 :
210 : /* List of basic blocks in if-conversion-suitable order. */
211 : static basic_block *ifc_bbs;
212 :
213 : /* Hash table to store <DR's innermost loop behavior, DR> pairs. */
214 : static hash_map<innermost_loop_behavior_hash,
215 : data_reference_p> *innermost_DR_map;
216 :
217 : /* Hash table to store <base reference, DR> pairs. */
218 : static hash_map<tree_operand_hash, data_reference_p> *baseref_DR_map;
219 :
220 : /* List of redundant SSA names: the first should be replaced by the second. */
221 : static vec< std::pair<tree, tree> > redundant_ssa_names;
222 :
223 : /* Structure used to predicate basic blocks. This is attached to the
224 : ->aux field of the BBs in the loop to be if-converted. */
225 : struct bb_predicate {
226 :
227 : /* The condition under which this basic block is executed. */
228 : tree predicate;
229 :
230 : /* PREDICATE is gimplified, and the sequence of statements is
231 : recorded here, in order to avoid the duplication of computations
232 : that occur in previous conditions. See PR44483. */
233 : gimple_seq predicate_gimplified_stmts;
234 :
235 : /* Records the number of statements recorded into
236 : PREDICATE_GIMPLIFIED_STMTS. */
237 : unsigned no_predicate_stmts;
238 : };
239 :
240 : /* Returns true when the basic block BB has a predicate. */
241 :
242 : static inline bool
243 1974191 : bb_has_predicate (basic_block bb)
244 : {
245 1974191 : return bb->aux != NULL;
246 : }
247 :
248 : /* Returns the gimplified predicate for basic block BB. */
249 :
250 : static inline tree
251 906220 : bb_predicate (basic_block bb)
252 : {
253 906220 : return ((struct bb_predicate *) bb->aux)->predicate;
254 : }
255 :
256 : /* Sets the gimplified predicate COND for basic block BB. */
257 :
258 : static inline void
259 488975 : set_bb_predicate (basic_block bb, tree cond)
260 : {
261 488975 : auto aux = (struct bb_predicate *) bb->aux;
262 488975 : gcc_assert ((TREE_CODE (cond) == TRUTH_NOT_EXPR
263 : && is_gimple_val (TREE_OPERAND (cond, 0)))
264 : || is_gimple_val (cond));
265 488975 : aux->predicate = cond;
266 488975 : aux->no_predicate_stmts++;
267 :
268 488975 : if (dump_file && (dump_flags & TDF_DETAILS))
269 222 : fprintf (dump_file, "Recording block %d value %d\n", bb->index,
270 : aux->no_predicate_stmts);
271 488975 : }
272 :
273 : /* Returns the sequence of statements of the gimplification of the
274 : predicate for basic block BB. */
275 :
276 : static inline gimple_seq
277 600347 : bb_predicate_gimplified_stmts (basic_block bb)
278 : {
279 600347 : return ((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts;
280 : }
281 :
282 : /* Sets the sequence of statements STMTS of the gimplification of the
283 : predicate for basic block BB. If PRESERVE_COUNTS then don't clear the predicate
284 : counts. */
285 :
286 : static inline void
287 291141 : set_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts,
288 : bool preserve_counts)
289 : {
290 291141 : ((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts = stmts;
291 291141 : if (stmts == NULL && !preserve_counts)
292 238361 : ((struct bb_predicate *) bb->aux)->no_predicate_stmts = 0;
293 : }
294 :
295 : /* Adds the sequence of statements STMTS to the sequence of statements
296 : of the predicate for basic block BB. */
297 :
298 : static inline void
299 89071 : add_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts)
300 : {
301 : /* We might have updated some stmts in STMTS via force_gimple_operand
302 : calling fold_stmt and that producing multiple stmts. Delink immediate
303 : uses so update_ssa after loop versioning doesn't get confused for
304 : the not yet inserted predicates.
305 : ??? This should go away once we reliably avoid updating stmts
306 : not in any BB. */
307 89071 : for (gimple_stmt_iterator gsi = gsi_start (stmts);
308 219990 : !gsi_end_p (gsi); gsi_next (&gsi))
309 : {
310 130919 : gimple *stmt = gsi_stmt (gsi);
311 130919 : delink_stmt_imm_use (stmt);
312 130919 : gimple_set_modified (stmt, true);
313 130919 : ((struct bb_predicate *) bb->aux)->no_predicate_stmts++;
314 : }
315 89071 : gimple_seq_add_seq_without_update
316 89071 : (&(((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts), stmts);
317 89071 : }
318 :
319 : /* Return the number of statements the predicate of the basic block consists
320 : of. */
321 :
322 : static inline unsigned
323 16307 : get_bb_num_predicate_stmts (basic_block bb)
324 : {
325 16307 : return ((struct bb_predicate *) bb->aux)->no_predicate_stmts;
326 : }
327 :
328 : /* Initializes to TRUE the predicate of basic block BB. */
329 :
330 : static inline void
331 204218 : init_bb_predicate (basic_block bb)
332 : {
333 204218 : bb->aux = XNEW (struct bb_predicate);
334 204218 : set_bb_predicate_gimplified_stmts (bb, NULL, false);
335 204218 : set_bb_predicate (bb, boolean_true_node);
336 204218 : }
337 :
338 : /* Release the SSA_NAMEs associated with the predicate of basic block BB. */
339 :
340 : static inline void
341 394020 : release_bb_predicate (basic_block bb)
342 : {
343 394020 : gimple_seq stmts = bb_predicate_gimplified_stmts (bb);
344 394020 : if (stmts)
345 : {
346 : /* Ensure that these stmts haven't yet been added to a bb. */
347 34143 : if (flag_checking)
348 94804 : for (gimple_stmt_iterator i = gsi_start (stmts);
349 94804 : !gsi_end_p (i); gsi_next (&i))
350 60661 : gcc_assert (! gimple_bb (gsi_stmt (i)));
351 :
352 : /* Discard them. */
353 34143 : gimple_seq_discard (stmts);
354 34143 : set_bb_predicate_gimplified_stmts (bb, NULL, false);
355 : }
356 394020 : }
357 :
358 : /* Free the predicate of basic block BB. */
359 :
360 : static inline void
361 1784389 : free_bb_predicate (basic_block bb)
362 : {
363 1784389 : if (!bb_has_predicate (bb))
364 : return;
365 :
366 204218 : release_bb_predicate (bb);
367 204218 : free (bb->aux);
368 204218 : bb->aux = NULL;
369 : }
370 :
371 : /* Reinitialize predicate of BB with the true predicate. */
372 :
373 : static inline void
374 189802 : reset_bb_predicate (basic_block bb)
375 : {
376 189802 : if (!bb_has_predicate (bb))
377 0 : init_bb_predicate (bb);
378 : else
379 : {
380 189802 : release_bb_predicate (bb);
381 189802 : set_bb_predicate (bb, boolean_true_node);
382 : }
383 189802 : }
384 :
385 : /* Returns a new SSA_NAME of type TYPE that is assigned the value of
386 : the expression EXPR. Inserts the statement created for this
387 : computation before GSI and leaves the iterator GSI at the same
388 : statement. */
389 :
390 : static tree
391 5395 : ifc_temp_var (tree type, tree expr, gimple_stmt_iterator *gsi)
392 : {
393 5395 : tree new_name = make_temp_ssa_name (type, NULL, "_ifc_");
394 5395 : gimple *stmt = gimple_build_assign (new_name, expr);
395 10790 : gimple_set_vuse (stmt, gimple_vuse (gsi_stmt (*gsi)));
396 5395 : gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
397 5395 : return new_name;
398 : }
399 :
400 : /* Return true when COND is a false predicate. */
401 :
402 : static inline bool
403 90012 : is_false_predicate (tree cond)
404 : {
405 90012 : return (cond != NULL_TREE
406 90012 : && (cond == boolean_false_node
407 90012 : || integer_zerop (cond)));
408 : }
409 :
410 : /* Return true when COND is a true predicate. */
411 :
412 : static inline bool
413 1031246 : is_true_predicate (tree cond)
414 : {
415 1031246 : return (cond == NULL_TREE
416 1031246 : || cond == boolean_true_node
417 1498045 : || integer_onep (cond));
418 : }
419 :
420 : /* Returns true when BB has a predicate that is not trivial: true or
421 : NULL_TREE. */
422 :
423 : static inline bool
424 502485 : is_predicated (basic_block bb)
425 : {
426 12663 : return !is_true_predicate (bb_predicate (bb));
427 : }
428 :
429 : /* Parses the predicate COND and returns its comparison code and
430 : operands OP0 and OP1. */
431 :
432 : static enum tree_code
433 398312 : parse_predicate (tree cond, tree *op0, tree *op1)
434 : {
435 398312 : gimple *s;
436 :
437 398312 : if (TREE_CODE (cond) == SSA_NAME
438 398312 : && is_gimple_assign (s = SSA_NAME_DEF_STMT (cond)))
439 : {
440 63891 : if (TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison)
441 : {
442 32739 : *op0 = gimple_assign_rhs1 (s);
443 32739 : *op1 = gimple_assign_rhs2 (s);
444 32739 : return gimple_assign_rhs_code (s);
445 : }
446 :
447 31152 : else if (gimple_assign_rhs_code (s) == TRUTH_NOT_EXPR)
448 : {
449 0 : tree op = gimple_assign_rhs1 (s);
450 0 : tree type = TREE_TYPE (op);
451 0 : enum tree_code code = parse_predicate (op, op0, op1);
452 :
453 0 : return code == ERROR_MARK ? ERROR_MARK
454 0 : : invert_tree_comparison (code, HONOR_NANS (type));
455 : }
456 :
457 : return ERROR_MARK;
458 : }
459 :
460 334421 : if (COMPARISON_CLASS_P (cond))
461 : {
462 483 : *op0 = TREE_OPERAND (cond, 0);
463 483 : *op1 = TREE_OPERAND (cond, 1);
464 483 : return TREE_CODE (cond);
465 : }
466 :
467 : return ERROR_MARK;
468 : }
469 :
470 : /* Returns the fold of predicate C1 OR C2 at location LOC. */
471 :
472 : static tree
473 199156 : fold_or_predicates (location_t loc, tree c1, tree c2)
474 : {
475 199156 : tree op1a, op1b, op2a, op2b;
476 199156 : enum tree_code code1 = parse_predicate (c1, &op1a, &op1b);
477 199156 : enum tree_code code2 = parse_predicate (c2, &op2a, &op2b);
478 :
479 199156 : if (code1 != ERROR_MARK && code2 != ERROR_MARK)
480 : {
481 2319 : tree t = maybe_fold_or_comparisons (boolean_type_node, code1, op1a, op1b,
482 : code2, op2a, op2b);
483 2319 : if (t)
484 : return t;
485 : }
486 :
487 196935 : return fold_build2_loc (loc, TRUTH_OR_EXPR, boolean_type_node, c1, c2);
488 : }
489 :
490 : /* Returns either a COND_EXPR or the folded expression if the folded
491 : expression is a MIN_EXPR, a MAX_EXPR, an ABS_EXPR,
492 : a constant or a SSA_NAME. */
493 :
494 : static tree
495 51104 : fold_build_cond_expr (tree type, tree cond, tree rhs, tree lhs)
496 : {
497 : /* Short cut the case where both rhs and lhs are the same. */
498 51104 : if (operand_equal_p (rhs, lhs))
499 : return rhs;
500 :
501 : /* If COND is comparison r != 0 and r has boolean type, convert COND
502 : to SSA_NAME to accept by vect bool pattern. */
503 51104 : if (TREE_CODE (cond) == NE_EXPR)
504 : {
505 0 : tree op0 = TREE_OPERAND (cond, 0);
506 0 : tree op1 = TREE_OPERAND (cond, 1);
507 0 : if (TREE_CODE (op0) == SSA_NAME
508 0 : && TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
509 0 : && (integer_zerop (op1)))
510 : cond = op0;
511 : }
512 :
513 51104 : gimple_match_op cexpr (gimple_match_cond::UNCOND, COND_EXPR,
514 51104 : type, cond, rhs, lhs);
515 51104 : if (cexpr.resimplify (NULL, follow_all_ssa_edges))
516 : {
517 6617 : if (gimple_simplified_result_is_gimple_val (&cexpr))
518 551 : return cexpr.ops[0];
519 6066 : else if (cexpr.code == ABS_EXPR)
520 2 : return build1 (ABS_EXPR, type, cexpr.ops[0]);
521 6064 : else if (cexpr.code == MIN_EXPR
522 6064 : || cexpr.code == MAX_EXPR)
523 3316 : return build2 ((tree_code)cexpr.code, type, cexpr.ops[0], cexpr.ops[1]);
524 : }
525 :
526 47235 : return build3 (COND_EXPR, type, cond, rhs, lhs);
527 : }
528 :
529 : /* Add condition NC to the predicate list of basic block BB. LOOP is
530 : the loop to be if-converted. Use predicate of cd-equivalent block
531 : for join bb if it exists: we call basic blocks bb1 and bb2
532 : cd-equivalent if they are executed under the same condition. */
533 :
534 : static inline void
535 164011 : add_to_predicate_list (class loop *loop, basic_block bb, tree nc)
536 : {
537 164011 : tree bc, *tp;
538 164011 : basic_block dom_bb;
539 :
540 164011 : if (is_true_predicate (nc))
541 73168 : return;
542 :
543 : /* If dominance tells us this basic block is always executed,
544 : don't record any predicates for it. */
545 163999 : if (dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
546 : return;
547 :
548 94955 : dom_bb = get_immediate_dominator (CDI_DOMINATORS, bb);
549 : /* We use notion of cd equivalence to get simpler predicate for
550 : join block, e.g. if join block has 2 predecessors with predicates
551 : p1 & p2 and p1 & !p2, we'd like to get p1 for it instead of
552 : p1 & p2 | p1 & !p2. */
553 94955 : if (dom_bb != loop->header
554 94955 : && get_immediate_dominator (CDI_POST_DOMINATORS, dom_bb) == bb)
555 : {
556 4112 : gcc_assert (flow_bb_inside_loop_p (loop, dom_bb));
557 4112 : bc = bb_predicate (dom_bb);
558 4112 : if (!is_true_predicate (bc))
559 4112 : set_bb_predicate (bb, bc);
560 : else
561 0 : gcc_assert (is_true_predicate (bb_predicate (bb)));
562 4112 : if (dump_file && (dump_flags & TDF_DETAILS))
563 4 : fprintf (dump_file, "Use predicate of bb#%d for bb#%d\n",
564 : dom_bb->index, bb->index);
565 : return;
566 : }
567 :
568 90843 : if (!is_predicated (bb))
569 86923 : bc = nc;
570 : else
571 : {
572 3920 : bc = bb_predicate (bb);
573 3920 : bc = fold_or_predicates (EXPR_LOCATION (bc), nc, bc);
574 3920 : if (is_true_predicate (bc))
575 : {
576 0 : reset_bb_predicate (bb);
577 0 : return;
578 : }
579 : }
580 :
581 : /* Allow a TRUTH_NOT_EXPR around the main predicate. */
582 90843 : if (TREE_CODE (bc) == TRUTH_NOT_EXPR)
583 32734 : tp = &TREE_OPERAND (bc, 0);
584 : else
585 : tp = &bc;
586 90843 : if (!is_gimple_val (*tp))
587 : {
588 89071 : gimple_seq stmts;
589 89071 : *tp = force_gimple_operand (*tp, &stmts, true, NULL_TREE);
590 89071 : add_bb_predicate_gimplified_stmts (bb, stmts);
591 : }
592 90843 : set_bb_predicate (bb, bc);
593 : }
594 :
595 : /* Add the condition COND to the previous condition PREV_COND, and add
596 : this to the predicate list of the destination of edge E. LOOP is
597 : the loop to be if-converted. */
598 :
599 : static void
600 106544 : add_to_dst_predicate_list (class loop *loop, edge e,
601 : tree prev_cond, tree cond)
602 : {
603 106544 : if (!flow_bb_inside_loop_p (loop, e->dest))
604 : return;
605 :
606 106544 : if (!is_true_predicate (prev_cond))
607 22678 : cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
608 : prev_cond, cond);
609 :
610 106544 : if (!dominated_by_p (CDI_DOMINATORS, loop->latch, e->dest))
611 86399 : add_to_predicate_list (loop, e->dest, cond);
612 : }
613 :
614 : /* Return true if one of the successor edges of BB exits LOOP. */
615 :
616 : static bool
617 3456050 : bb_with_exit_edge_p (const class loop *loop, basic_block bb)
618 : {
619 3456050 : edge e;
620 3456050 : edge_iterator ei;
621 :
622 6973778 : FOR_EACH_EDGE (e, ei, bb->succs)
623 4915273 : if (loop_exit_edge_p (loop, e))
624 : return true;
625 :
626 : return false;
627 : }
628 :
629 : /* Given PHI which has more than two arguments, this function checks if
630 : it's if-convertible by degenerating its arguments. Specifically, if
631 : below two conditions are satisfied:
632 :
633 : 1) Number of PHI arguments with different values equals to 2 and one
634 : argument has the only occurrence.
635 : 2) The edge corresponding to the unique argument isn't critical edge.
636 :
637 : Such PHI can be handled as PHIs have only two arguments. For example,
638 : below PHI:
639 :
640 : res = PHI <A_1(e1), A_1(e2), A_2(e3)>;
641 :
642 : can be transformed into:
643 :
644 : res = (predicate of e3) ? A_2 : A_1;
645 :
646 : Return TRUE if it is the case, FALSE otherwise. */
647 :
648 : static bool
649 5546 : phi_convertible_by_degenerating_args (gphi *phi)
650 : {
651 5546 : edge e;
652 5546 : tree arg, t1 = NULL, t2 = NULL;
653 5546 : unsigned int i, i1 = 0, i2 = 0, n1 = 0, n2 = 0;
654 5546 : unsigned int num_args = gimple_phi_num_args (phi);
655 :
656 5546 : gcc_assert (num_args > 2);
657 :
658 20147 : for (i = 0; i < num_args; i++)
659 : {
660 16824 : arg = gimple_phi_arg_def (phi, i);
661 16824 : if (t1 == NULL || operand_equal_p (t1, arg, 0))
662 : {
663 7599 : n1++;
664 7599 : i1 = i;
665 7599 : t1 = arg;
666 : }
667 9225 : else if (t2 == NULL || operand_equal_p (t2, arg, 0))
668 : {
669 7002 : n2++;
670 7002 : i2 = i;
671 7002 : t2 = arg;
672 : }
673 : else
674 : return false;
675 : }
676 :
677 3323 : if (n1 != 1 && n2 != 1)
678 : return false;
679 :
680 : /* Check if the edge corresponding to the unique arg is critical. */
681 3263 : e = gimple_phi_arg_edge (phi, (n1 == 1) ? i1 : i2);
682 3263 : if (EDGE_COUNT (e->src->succs) > 1)
683 0 : return false;
684 :
685 : return true;
686 : }
687 :
688 : /* Return true when PHI is if-convertible. PHI is part of loop LOOP
689 : and it belongs to basic block BB. Note at this point, it is sure
690 : that PHI is if-convertible. This function updates global variable
691 : ANY_COMPLICATED_PHI if PHI is complicated. */
692 :
693 : static bool
694 128113 : if_convertible_phi_p (class loop *loop, basic_block bb, gphi *phi)
695 : {
696 128113 : if (dump_file && (dump_flags & TDF_DETAILS))
697 : {
698 67 : fprintf (dump_file, "-------------------------\n");
699 67 : print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
700 : }
701 :
702 128113 : if (bb != loop->header
703 51341 : && gimple_phi_num_args (phi) > 2
704 133659 : && !phi_convertible_by_degenerating_args (phi))
705 2283 : any_complicated_phi = true;
706 :
707 128113 : return true;
708 : }
709 :
710 : /* Records the status of a data reference. This struct is attached to
711 : each DR->aux field. */
712 :
713 : struct ifc_dr {
714 : bool rw_unconditionally;
715 : bool w_unconditionally;
716 : bool written_at_least_once;
717 :
718 : tree rw_predicate;
719 : tree w_predicate;
720 : tree base_w_predicate;
721 : };
722 :
723 : #define IFC_DR(DR) ((struct ifc_dr *) (DR)->aux)
724 : #define DR_BASE_W_UNCONDITIONALLY(DR) (IFC_DR (DR)->written_at_least_once)
725 : #define DR_RW_UNCONDITIONALLY(DR) (IFC_DR (DR)->rw_unconditionally)
726 : #define DR_W_UNCONDITIONALLY(DR) (IFC_DR (DR)->w_unconditionally)
727 :
728 : /* Iterates over DR's and stores refs, DR and base refs, DR pairs in
729 : HASH tables. While storing them in HASH table, it checks if the
730 : reference is unconditionally read or written and stores that as a flag
731 : information. For base reference it checks if it is written atlest once
732 : unconditionally and stores it as flag information along with DR.
733 : In other words for every data reference A in STMT there exist other
734 : accesses to a data reference with the same base with predicates that
735 : add up (OR-up) to the true predicate: this ensures that the data
736 : reference A is touched (read or written) on every iteration of the
737 : if-converted loop. */
738 : static void
739 119422 : hash_memrefs_baserefs_and_store_DRs_read_written_info (data_reference_p a)
740 : {
741 :
742 119422 : data_reference_p *master_dr, *base_master_dr;
743 119422 : tree base_ref = DR_BASE_OBJECT (a);
744 119422 : innermost_loop_behavior *innermost = &DR_INNERMOST (a);
745 119422 : tree ca = bb_predicate (gimple_bb (DR_STMT (a)));
746 119422 : bool exist1, exist2;
747 :
748 119422 : master_dr = &innermost_DR_map->get_or_insert (innermost, &exist1);
749 119422 : if (!exist1)
750 91572 : *master_dr = a;
751 :
752 119422 : if (DR_IS_WRITE (a))
753 : {
754 37878 : IFC_DR (*master_dr)->w_predicate
755 75756 : = fold_or_predicates (UNKNOWN_LOCATION, ca,
756 37878 : IFC_DR (*master_dr)->w_predicate);
757 37878 : if (is_true_predicate (IFC_DR (*master_dr)->w_predicate))
758 21607 : DR_W_UNCONDITIONALLY (*master_dr) = true;
759 : }
760 119422 : IFC_DR (*master_dr)->rw_predicate
761 238844 : = fold_or_predicates (UNKNOWN_LOCATION, ca,
762 119422 : IFC_DR (*master_dr)->rw_predicate);
763 119422 : if (is_true_predicate (IFC_DR (*master_dr)->rw_predicate))
764 83343 : DR_RW_UNCONDITIONALLY (*master_dr) = true;
765 :
766 119422 : if (DR_IS_WRITE (a))
767 : {
768 37878 : base_master_dr = &baseref_DR_map->get_or_insert (base_ref, &exist2);
769 37878 : if (!exist2)
770 27718 : *base_master_dr = a;
771 37878 : IFC_DR (*base_master_dr)->base_w_predicate
772 75756 : = fold_or_predicates (UNKNOWN_LOCATION, ca,
773 37878 : IFC_DR (*base_master_dr)->base_w_predicate);
774 37878 : if (is_true_predicate (IFC_DR (*base_master_dr)->base_w_predicate))
775 21869 : DR_BASE_W_UNCONDITIONALLY (*base_master_dr) = true;
776 : }
777 119422 : }
778 :
779 : /* Return TRUE if can prove the index IDX of an array reference REF is
780 : within array bound. Return false otherwise. */
781 :
782 : static bool
783 259414 : idx_within_array_bound (tree ref, tree *idx, void *dta)
784 : {
785 259414 : wi::overflow_type overflow;
786 259414 : widest_int niter, valid_niter, delta, wi_step;
787 259414 : tree ev, init, step;
788 259414 : tree low, high;
789 259414 : class loop *loop = (class loop*) dta;
790 :
791 : /* Only support within-bound access for array references. */
792 259414 : if (TREE_CODE (ref) != ARRAY_REF)
793 : return false;
794 :
795 : /* For arrays that might have flexible sizes, it is not guaranteed that they
796 : do not extend over their declared size. */
797 146141 : if (array_ref_flexible_size_p (ref))
798 : return false;
799 :
800 93521 : ev = analyze_scalar_evolution (loop, *idx);
801 93521 : ev = instantiate_parameters (loop, ev);
802 93521 : init = initial_condition (ev);
803 93521 : step = evolution_part_in_loop_num (ev, loop->num);
804 :
805 93521 : if (!init || TREE_CODE (init) != INTEGER_CST
806 82969 : || (step && TREE_CODE (step) != INTEGER_CST))
807 : return false;
808 :
809 82963 : low = array_ref_low_bound (ref);
810 82963 : high = array_ref_up_bound (ref);
811 :
812 : /* The case of nonconstant bounds could be handled, but it would be
813 : complicated. */
814 82963 : if (TREE_CODE (low) != INTEGER_CST
815 82963 : || !high || TREE_CODE (high) != INTEGER_CST)
816 : return false;
817 :
818 : /* Check if the initial idx is within bound. */
819 82895 : if (wi::to_widest (init) < wi::to_widest (low)
820 165782 : || wi::to_widest (init) > wi::to_widest (high))
821 : return false;
822 :
823 : /* The idx is always within bound. */
824 82879 : if (!step || integer_zerop (step))
825 : return true;
826 :
827 80927 : if (!max_loop_iterations (loop, &niter))
828 : return false;
829 :
830 80927 : if (wi::to_widest (step) < 0)
831 : {
832 303 : delta = wi::to_widest (init) - wi::to_widest (low);
833 303 : wi_step = -wi::to_widest (step);
834 : }
835 : else
836 : {
837 80624 : delta = wi::to_widest (high) - wi::to_widest (init);
838 80624 : wi_step = wi::to_widest (step);
839 : }
840 :
841 80927 : valid_niter = wi::div_floor (delta, wi_step, SIGNED, &overflow);
842 : /* The iteration space of idx is within array bound. */
843 161854 : if (!overflow && niter <= valid_niter)
844 80446 : return true;
845 :
846 : return false;
847 259414 : }
848 :
849 : /* Return TRUE if ref is a within bound array reference. */
850 :
851 : bool
852 252560 : ref_within_array_bound (gimple *stmt, tree ref)
853 : {
854 252560 : class loop *loop = loop_containing_stmt (stmt);
855 :
856 252560 : gcc_assert (loop != NULL);
857 252560 : return for_each_index (&ref, idx_within_array_bound, loop);
858 : }
859 :
860 :
861 : /* Given a memory reference expression T, return TRUE if base object
862 : it refers to is writable. The base object of a memory reference
863 : is the main object being referenced, which is returned by function
864 : get_base_address. */
865 :
866 : static bool
867 2361 : base_object_writable (tree ref)
868 : {
869 2361 : tree base_tree = get_base_address (ref);
870 :
871 2361 : return (base_tree
872 2361 : && DECL_P (base_tree)
873 1468 : && decl_binds_to_current_def_p (base_tree)
874 3825 : && !TREE_READONLY (base_tree));
875 : }
876 :
877 : /* Return true when the memory references of STMT won't trap in the
878 : if-converted code. There are two things that we have to check for:
879 :
880 : - writes to memory occur to writable memory: if-conversion of
881 : memory writes transforms the conditional memory writes into
882 : unconditional writes, i.e. "if (cond) A[i] = foo" is transformed
883 : into "A[i] = cond ? foo : A[i]", and as the write to memory may not
884 : be executed at all in the original code, it may be a readonly
885 : memory. To check that A is not const-qualified, we check that
886 : there exists at least an unconditional write to A in the current
887 : function.
888 :
889 : - reads or writes to memory are valid memory accesses for every
890 : iteration. To check that the memory accesses are correctly formed
891 : and that we are allowed to read and write in these locations, we
892 : check that the memory accesses to be if-converted occur at every
893 : iteration unconditionally.
894 :
895 : Returns true for the memory reference in STMT, same memory reference
896 : is read or written unconditionally at least once and the base memory
897 : reference is written unconditionally once. This is to check reference
898 : will not write fault. Also returns true if the memory reference is
899 : unconditionally read once then we are conditionally writing to memory
900 : which is defined as read and write and is bound to the definition
901 : we are seeing. */
902 : static bool
903 19983 : ifcvt_memrefs_wont_trap (gimple *stmt, vec<data_reference_p> drs)
904 : {
905 : /* If DR didn't see a reference here we can't use it to tell
906 : whether the ref traps or not. */
907 19983 : if (gimple_uid (stmt) == 0)
908 : return false;
909 :
910 19982 : data_reference_p *master_dr, *base_master_dr;
911 19982 : data_reference_p a = drs[gimple_uid (stmt) - 1];
912 :
913 19982 : tree base = DR_BASE_OBJECT (a);
914 19982 : innermost_loop_behavior *innermost = &DR_INNERMOST (a);
915 :
916 19982 : gcc_assert (DR_STMT (a) == stmt);
917 19982 : gcc_assert (DR_BASE_ADDRESS (a) || DR_OFFSET (a)
918 : || DR_INIT (a) || DR_STEP (a));
919 :
920 19982 : master_dr = innermost_DR_map->get (innermost);
921 19982 : gcc_assert (master_dr != NULL);
922 :
923 19982 : base_master_dr = baseref_DR_map->get (base);
924 :
925 : /* If a is unconditionally written to it doesn't trap. */
926 19982 : if (DR_W_UNCONDITIONALLY (*master_dr))
927 : return true;
928 :
929 : /* If a is unconditionally accessed then ...
930 :
931 : Even a is conditional access, we can treat it as an unconditional
932 : one if it's an array reference and all its index are within array
933 : bound. */
934 18122 : if (DR_RW_UNCONDITIONALLY (*master_dr)
935 18122 : || ref_within_array_bound (stmt, DR_REF (a)))
936 : {
937 : /* an unconditional read won't trap. */
938 6492 : if (DR_IS_READ (a))
939 : return true;
940 :
941 : /* an unconditionally write won't trap if the base is written
942 : to unconditionally. */
943 2398 : if ((base_master_dr
944 2398 : && DR_BASE_W_UNCONDITIONALLY (*base_master_dr))
945 : /* or the base is known to be not readonly. */
946 4759 : || base_object_writable (DR_REF (a)))
947 1501 : return !ref_can_have_store_data_races (base);
948 : }
949 :
950 : return false;
951 : }
952 :
953 : /* Return true if STMT could be converted into a masked load or store
954 : (conditional load or store based on a mask computed from bb predicate). */
955 :
956 : static bool
957 11954 : ifcvt_can_use_mask_load_store (gimple *stmt)
958 : {
959 : /* Check whether this is a load or store. */
960 11954 : tree lhs = gimple_assign_lhs (stmt);
961 11954 : bool is_load;
962 11954 : tree ref;
963 11954 : if (gimple_store_p (stmt))
964 : {
965 2781 : if (!is_gimple_val (gimple_assign_rhs1 (stmt)))
966 : return false;
967 : is_load = false;
968 : ref = lhs;
969 : }
970 9173 : else if (gimple_assign_load_p (stmt))
971 : {
972 9172 : is_load = true;
973 9172 : ref = gimple_assign_rhs1 (stmt);
974 : }
975 : else
976 : return false;
977 :
978 11953 : if (may_be_nonaddressable_p (ref))
979 : return false;
980 :
981 : /* Mask should be integer mode of the same size as the load/store
982 : mode. */
983 11894 : machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
984 11894 : if (!int_mode_for_mode (mode).exists () || VECTOR_MODE_P (mode))
985 : return false;
986 :
987 11863 : if (can_vec_mask_load_store_p (mode, VOIDmode, is_load))
988 : return true;
989 :
990 : return false;
991 : }
992 :
993 : /* Return true if STMT could be converted from an operation that is
994 : unconditional to one that is conditional on a bb predicate mask. */
995 :
996 : static bool
997 13869 : ifcvt_can_predicate (gimple *stmt)
998 : {
999 13869 : basic_block bb = gimple_bb (stmt);
1000 :
1001 284 : if (!(flag_tree_loop_vectorize || bb->loop_father->force_vectorize)
1002 13869 : || bb->loop_father->dont_vectorize
1003 27738 : || gimple_has_volatile_ops (stmt))
1004 : return false;
1005 :
1006 13869 : if (gimple_assign_single_p (stmt))
1007 11954 : return ifcvt_can_use_mask_load_store (stmt);
1008 :
1009 1915 : tree callee;
1010 1915 : if (gimple_call_builtin_p (stmt))
1011 155 : if ((callee = gimple_call_fndecl (stmt))
1012 155 : && fndecl_built_in_p (callee, BUILT_IN_NORMAL))
1013 : {
1014 149 : auto ifn = associated_internal_fn (callee);
1015 149 : auto cond_ifn = get_conditional_internal_fn (ifn);
1016 149 : tree type = TREE_TYPE (gimple_call_fntype (stmt));
1017 149 : return (cond_ifn != IFN_LAST
1018 149 : && vectorized_internal_fn_supported_p (cond_ifn, type));
1019 : }
1020 :
1021 1766 : if (!is_gimple_assign (stmt))
1022 : return false;
1023 :
1024 1760 : tree_code code = gimple_assign_rhs_code (stmt);
1025 1760 : tree lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
1026 1760 : tree rhs_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
1027 1760 : if (!types_compatible_p (lhs_type, rhs_type))
1028 : return false;
1029 1104 : internal_fn cond_fn = get_conditional_internal_fn (code);
1030 1104 : return (cond_fn != IFN_LAST
1031 1104 : && vectorized_internal_fn_supported_p (cond_fn, lhs_type));
1032 : }
1033 :
1034 : /* Return true when STMT is if-convertible.
1035 :
1036 : GIMPLE_ASSIGN statement is not if-convertible if,
1037 : - it is not movable,
1038 : - it could trap,
1039 : - LHS is not var decl. */
1040 :
1041 : static bool
1042 76824 : if_convertible_gimple_assign_stmt_p (gimple *stmt,
1043 : vec<data_reference_p> refs)
1044 : {
1045 76824 : tree lhs = gimple_assign_lhs (stmt);
1046 :
1047 76824 : if (dump_file && (dump_flags & TDF_DETAILS))
1048 : {
1049 26 : fprintf (dump_file, "-------------------------\n");
1050 26 : print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1051 : }
1052 :
1053 76824 : if (!is_gimple_reg_type (TREE_TYPE (lhs)))
1054 : return false;
1055 :
1056 : /* Some of these constrains might be too conservative. */
1057 76545 : if (stmt_ends_bb_p (stmt)
1058 76545 : || gimple_has_volatile_ops (stmt)
1059 76470 : || (TREE_CODE (lhs) == SSA_NAME
1060 72172 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
1061 153015 : || gimple_has_side_effects (stmt))
1062 : {
1063 75 : if (dump_file && (dump_flags & TDF_DETAILS))
1064 0 : fprintf (dump_file, "stmt not suitable for ifcvt\n");
1065 : return false;
1066 : }
1067 :
1068 : /* tree-into-ssa.cc uses GF_PLF_1, so avoid it, because
1069 : in between if_convertible_loop_p and combine_blocks
1070 : we can perform loop versioning. */
1071 76470 : gimple_set_plf (stmt, GF_PLF_2, false);
1072 :
1073 76470 : if ((! gimple_vuse (stmt)
1074 19983 : || gimple_could_trap_p_1 (stmt, false, false)
1075 19983 : || ! ifcvt_memrefs_wont_trap (stmt, refs))
1076 89314 : && gimple_could_trap_p (stmt))
1077 : {
1078 13714 : if (ifcvt_can_predicate (stmt))
1079 : {
1080 2694 : gimple_set_plf (stmt, GF_PLF_2, true);
1081 2694 : need_to_predicate = true;
1082 2694 : return true;
1083 : }
1084 11020 : if (dump_file && (dump_flags & TDF_DETAILS))
1085 0 : fprintf (dump_file, "tree could trap...\n");
1086 : return false;
1087 : }
1088 62756 : else if (gimple_needing_rewrite_undefined (stmt))
1089 : /* We have to rewrite stmts with undefined overflow. */
1090 28158 : need_to_rewrite_undefined = true;
1091 :
1092 : /* When if-converting stores force versioning, likewise if we
1093 : ended up generating store data races. */
1094 125512 : if (gimple_vdef (stmt))
1095 1517 : need_to_predicate = true;
1096 :
1097 : return true;
1098 : }
1099 :
1100 : /* Return true when SW switch statement is equivalent to cond, that
1101 : all non default labels point to the same label.
1102 :
1103 : Fallthrough is not checked for and could even happen
1104 : with cond (using goto), so is handled.
1105 :
1106 : This is intended for switches created by the if-switch-conversion
1107 : pass, but can handle some programmer supplied cases too. */
1108 :
1109 : static bool
1110 70 : if_convertible_switch_p (gswitch *sw)
1111 : {
1112 70 : if (gimple_switch_num_labels (sw) <= 1)
1113 : return false;
1114 70 : tree label = CASE_LABEL (gimple_switch_label (sw, 1));
1115 762 : for (unsigned i = 1; i < gimple_switch_num_labels (sw); i++)
1116 : {
1117 698 : if (CASE_LABEL (gimple_switch_label (sw, i)) != label)
1118 : return false;
1119 : }
1120 : return true;
1121 : }
1122 :
1123 : /* Return true when STMT is an if-convertible SIMD clone stmts.
1124 :
1125 : A SIMD clone statement is if-convertible if:
1126 : - it is an GIMPLE_CALL,
1127 : - it has a FNDECL,
1128 : - it has SIMD clones,
1129 : - it has at least one inbranch clone. */
1130 : static bool
1131 1594 : if_convertible_simdclone_stmt_p (gimple *stmt)
1132 : {
1133 1594 : if (!is_gimple_call (stmt))
1134 : return false;
1135 :
1136 1594 : tree fndecl = gimple_call_fndecl (stmt);
1137 1594 : if (fndecl)
1138 : {
1139 : /* We can vectorize some builtins and functions with SIMD "inbranch"
1140 : clones. */
1141 1326 : struct cgraph_node *node = cgraph_node::get (fndecl);
1142 1326 : if (node && node->simd_clones != NULL)
1143 : /* Ensure that at least one clone can be "inbranch". */
1144 1962 : for (struct cgraph_node *n = node->simd_clones; n != NULL;
1145 961 : n = n->simdclone->next_clone)
1146 1960 : if (n->simdclone->inbranch)
1147 : return true;
1148 : }
1149 :
1150 : return false;
1151 : }
1152 :
1153 : /* Return true when STMT is if-convertible.
1154 :
1155 : A statement is if-convertible if:
1156 : - it is an if-convertible GIMPLE_ASSIGN,
1157 : - it is a GIMPLE_LABEL or a GIMPLE_COND,
1158 : - it is a switch equivalent to COND
1159 : - it is builtins call,
1160 : - it is a call to a function with a SIMD clone. */
1161 :
1162 : static bool
1163 171823 : if_convertible_stmt_p (gimple *stmt, vec<data_reference_p> refs)
1164 : {
1165 171823 : switch (gimple_code (stmt))
1166 : {
1167 : case GIMPLE_LABEL:
1168 : case GIMPLE_DEBUG:
1169 : case GIMPLE_COND:
1170 : return true;
1171 :
1172 : case GIMPLE_SWITCH:
1173 : /* Checked elsewhere. */
1174 : return true;
1175 :
1176 76824 : case GIMPLE_ASSIGN:
1177 76824 : return if_convertible_gimple_assign_stmt_p (stmt, refs);
1178 :
1179 1486 : case GIMPLE_CALL:
1180 1486 : {
1181 : /* Check if stmt is a simd clone first. */
1182 1486 : if (if_convertible_simdclone_stmt_p (stmt))
1183 : {
1184 999 : gimple_set_plf (stmt, GF_PLF_2, true);
1185 999 : need_to_predicate = true;
1186 999 : return true;
1187 : }
1188 :
1189 : /* Check if the call can trap and if so require predication. */
1190 487 : if (gimple_could_trap_p (stmt))
1191 : {
1192 155 : if (ifcvt_can_predicate (stmt))
1193 : {
1194 108 : gimple_set_plf (stmt, GF_PLF_2, true);
1195 108 : need_to_predicate = true;
1196 108 : return true;
1197 : }
1198 : else
1199 : {
1200 47 : if (dump_file && (dump_flags & TDF_DETAILS))
1201 0 : fprintf (dump_file, "stmt could trap...\n");
1202 : return false;
1203 : }
1204 : }
1205 :
1206 : /* Check if it's a prefetch. Many ISAs contain vectorized and/or
1207 : conditional prefetches so if-convert should convert them or remove
1208 : them. Mark them as supported. */
1209 332 : if (gimple_call_builtin_p (stmt, BUILT_IN_PREFETCH))
1210 : return true;
1211 :
1212 : /* There are some IFN_s that are used to replace builtins but have the
1213 : same semantics. Even if MASK_CALL cannot handle them vectorable_call
1214 : will insert the proper selection, so do not block conversion. */
1215 330 : int flags = gimple_call_flags (stmt);
1216 330 : if ((flags & ECF_CONST)
1217 330 : && !(flags & ECF_LOOPING_CONST_OR_PURE)
1218 660 : && gimple_call_combined_fn (stmt) != CFN_LAST)
1219 316 : return true;
1220 :
1221 : return false;
1222 : }
1223 :
1224 0 : default:
1225 : /* Don't know what to do with 'em so don't do anything. */
1226 0 : if (dump_file && (dump_flags & TDF_DETAILS))
1227 : {
1228 0 : fprintf (dump_file, "don't know what to do\n");
1229 0 : print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1230 : }
1231 : return false;
1232 : }
1233 : }
1234 :
1235 : /* Assumes that BB has more than 1 predecessors.
1236 : Returns false if at least one successor is not on critical edge
1237 : and true otherwise. */
1238 :
1239 : static inline bool
1240 80824 : all_preds_critical_p (basic_block bb)
1241 : {
1242 80824 : edge e;
1243 80824 : edge_iterator ei;
1244 :
1245 157434 : FOR_EACH_EDGE (e, ei, bb->preds)
1246 138869 : if (EDGE_COUNT (e->src->succs) == 1)
1247 : return false;
1248 : return true;
1249 : }
1250 :
1251 : /* Return true when BB is if-convertible. This routine does not check
1252 : basic block's statements and phis.
1253 :
1254 : A basic block is not if-convertible if:
1255 : - it is non-empty and it is after the exit block (in BFS order),
1256 : - it is after the exit block but before the latch,
1257 : - its edges are not normal.
1258 :
1259 : EXIT_BB is the basic block containing the exit of the LOOP. BB is
1260 : inside LOOP. */
1261 :
1262 : static bool
1263 213719 : if_convertible_bb_p (class loop *loop, basic_block bb, basic_block exit_bb)
1264 : {
1265 213719 : edge e;
1266 213719 : edge_iterator ei;
1267 :
1268 213719 : if (dump_file && (dump_flags & TDF_DETAILS))
1269 86 : fprintf (dump_file, "----------[%d]-------------\n", bb->index);
1270 :
1271 213719 : if (EDGE_COUNT (bb->succs) > 2)
1272 : return false;
1273 :
1274 427310 : if (gcall *call = safe_dyn_cast <gcall *> (*gsi_last_bb (bb)))
1275 194 : if (gimple_call_ctrl_altering_p (call))
1276 : return false;
1277 :
1278 213655 : if (exit_bb)
1279 : {
1280 38641 : if (bb != loop->latch)
1281 : {
1282 545 : if (dump_file && (dump_flags & TDF_DETAILS))
1283 0 : fprintf (dump_file, "basic block after exit bb but before latch\n");
1284 : return false;
1285 : }
1286 38096 : else if (!empty_block_p (bb))
1287 : {
1288 1418 : if (dump_file && (dump_flags & TDF_DETAILS))
1289 0 : fprintf (dump_file, "non empty basic block after exit bb\n");
1290 : return false;
1291 : }
1292 36678 : else if (bb == loop->latch
1293 36678 : && bb != exit_bb
1294 73356 : && !dominated_by_p (CDI_DOMINATORS, bb, exit_bb))
1295 : {
1296 11 : if (dump_file && (dump_flags & TDF_DETAILS))
1297 0 : fprintf (dump_file, "latch is not dominated by exit_block\n");
1298 : return false;
1299 : }
1300 : }
1301 :
1302 : /* Be less adventurous and handle only normal edges. */
1303 517669 : FOR_EACH_EDGE (e, ei, bb->succs)
1304 306000 : if (e->flags & (EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP))
1305 : {
1306 12 : if (dump_file && (dump_flags & TDF_DETAILS))
1307 0 : fprintf (dump_file, "Difficult to handle edges\n");
1308 : return false;
1309 : }
1310 :
1311 : return true;
1312 : }
1313 :
1314 : /* Return true when all predecessor blocks of BB are visited. The
1315 : VISITED bitmap keeps track of the visited blocks. */
1316 :
1317 : static bool
1318 2363329 : pred_blocks_visited_p (basic_block bb, bitmap *visited)
1319 : {
1320 2363329 : edge e;
1321 2363329 : edge_iterator ei;
1322 4063350 : FOR_EACH_EDGE (e, ei, bb->preds)
1323 2676193 : if (!bitmap_bit_p (*visited, e->src->index))
1324 : return false;
1325 :
1326 : return true;
1327 : }
1328 :
1329 : /* Get body of a LOOP in suitable order for if-conversion. It is
1330 : caller's responsibility to deallocate basic block list.
1331 : If-conversion suitable order is, breadth first sort (BFS) order
1332 : with an additional constraint: select a block only if all its
1333 : predecessors are already selected. */
1334 :
1335 : static basic_block *
1336 410447 : get_loop_body_in_if_conv_order (const class loop *loop)
1337 : {
1338 410447 : basic_block *blocks, *blocks_in_bfs_order;
1339 410447 : basic_block bb;
1340 410447 : bitmap visited;
1341 410447 : unsigned int index = 0;
1342 410447 : unsigned int visited_count = 0;
1343 :
1344 410447 : gcc_assert (loop->num_nodes);
1345 410447 : gcc_assert (loop->latch != EXIT_BLOCK_PTR_FOR_FN (cfun));
1346 :
1347 410447 : blocks = XCNEWVEC (basic_block, loop->num_nodes);
1348 410447 : visited = BITMAP_ALLOC (NULL);
1349 :
1350 410447 : blocks_in_bfs_order = get_loop_body_in_bfs_order (loop);
1351 :
1352 410447 : index = 0;
1353 4107101 : while (index < loop->num_nodes)
1354 : {
1355 3286259 : bb = blocks_in_bfs_order [index];
1356 :
1357 3286259 : if (bb->flags & BB_IRREDUCIBLE_LOOP)
1358 : {
1359 52 : free (blocks_in_bfs_order);
1360 52 : BITMAP_FREE (visited);
1361 52 : free (blocks);
1362 52 : return NULL;
1363 : }
1364 :
1365 3286207 : if (!bitmap_bit_p (visited, bb->index))
1366 : {
1367 2363329 : if (pred_blocks_visited_p (bb, &visited)
1368 2363329 : || bb == loop->header)
1369 : {
1370 : /* This block is now visited. */
1371 1797604 : bitmap_set_bit (visited, bb->index);
1372 1797604 : blocks[visited_count++] = bb;
1373 : }
1374 : }
1375 :
1376 3286207 : index++;
1377 :
1378 3286207 : if (index == loop->num_nodes
1379 472935 : && visited_count != loop->num_nodes)
1380 : /* Not done yet. */
1381 3286207 : index = 0;
1382 : }
1383 410395 : free (blocks_in_bfs_order);
1384 410395 : BITMAP_FREE (visited);
1385 :
1386 : /* Go through loop and reject if-conversion or lowering of bitfields if we
1387 : encounter statements we do not believe the vectorizer will be able to
1388 : handle. If adding a new type of statement here, make sure
1389 : 'ifcvt_local_dce' is also able to handle it properly. */
1390 2606496 : for (index = 0; index < loop->num_nodes; index++)
1391 : {
1392 1788268 : basic_block bb = blocks[index];
1393 1788268 : gimple_stmt_iterator gsi;
1394 :
1395 1788268 : bool may_have_nonlocal_labels
1396 1788268 : = bb_with_exit_edge_p (loop, bb) || bb == loop->latch;
1397 16876636 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1398 13302662 : switch (gimple_code (gsi_stmt (gsi)))
1399 : {
1400 40540 : case GIMPLE_LABEL:
1401 40540 : if (!may_have_nonlocal_labels)
1402 : {
1403 6802 : tree label
1404 6802 : = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi)));
1405 13604 : if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
1406 : {
1407 47 : free (blocks);
1408 47 : return NULL;
1409 : }
1410 : }
1411 : /* Fallthru. */
1412 13300100 : case GIMPLE_ASSIGN:
1413 13300100 : case GIMPLE_CALL:
1414 13300100 : case GIMPLE_DEBUG:
1415 13300100 : case GIMPLE_COND:
1416 13300100 : case GIMPLE_SWITCH:
1417 13300100 : gimple_set_uid (gsi_stmt (gsi), 0);
1418 13300100 : break;
1419 2515 : default:
1420 2515 : free (blocks);
1421 2515 : return NULL;
1422 : }
1423 : }
1424 : return blocks;
1425 : }
1426 :
1427 : /* Returns true when the analysis of the predicates for all the basic
1428 : blocks in LOOP succeeded.
1429 :
1430 : predicate_bbs first allocates the predicates of the basic blocks.
1431 : These fields are then initialized with the tree expressions
1432 : representing the predicates under which a basic block is executed
1433 : in the LOOP. As the loop->header is executed at each iteration, it
1434 : has the "true" predicate. Other statements executed under a
1435 : condition are predicated with that condition, for example
1436 :
1437 : | if (x)
1438 : | S1;
1439 : | else
1440 : | S2;
1441 :
1442 : S1 will be predicated with "x", and
1443 : S2 will be predicated with "!x". */
1444 :
1445 : static void
1446 36667 : predicate_bbs (loop_p loop)
1447 : {
1448 36667 : unsigned int i;
1449 :
1450 240885 : for (i = 0; i < loop->num_nodes; i++)
1451 204218 : init_bb_predicate (ifc_bbs[i]);
1452 :
1453 240885 : for (i = 0; i < loop->num_nodes; i++)
1454 : {
1455 204218 : basic_block bb = ifc_bbs[i];
1456 204218 : tree cond;
1457 :
1458 : /* The loop latch and loop exit block are always executed and
1459 : have no extra conditions to be processed: skip them. */
1460 277552 : if (bb == loop->latch
1461 204218 : || bb_with_exit_edge_p (loop, bb))
1462 : {
1463 73334 : reset_bb_predicate (bb);
1464 73334 : continue;
1465 : }
1466 :
1467 130884 : cond = bb_predicate (bb);
1468 261768 : if (gcond *stmt = safe_dyn_cast <gcond *> (*gsi_last_bb (bb)))
1469 : {
1470 53193 : tree c2;
1471 53193 : edge true_edge, false_edge;
1472 53193 : location_t loc = gimple_location (stmt);
1473 53193 : tree c;
1474 : /* gcc.dg/fold-bopcond-1.c shows that despite all forwprop passes
1475 : conditions can remain unfolded because of multiple uses so
1476 : try to re-fold here, especially to get precision changing
1477 : conversions sorted out. Do not simply fold the stmt since
1478 : this is analysis only. When conditions were embedded in
1479 : COND_EXPRs those were folded separately before folding the
1480 : COND_EXPR but as they are now outside we have to make sure
1481 : to fold them. Do it here - another opportunity would be to
1482 : fold predicates as they are inserted. */
1483 53193 : gimple_match_op cexpr (gimple_match_cond::UNCOND,
1484 53193 : gimple_cond_code (stmt),
1485 : boolean_type_node,
1486 : gimple_cond_lhs (stmt),
1487 53193 : gimple_cond_rhs (stmt));
1488 53193 : if (cexpr.resimplify (NULL, follow_all_ssa_edges)
1489 4036 : && cexpr.code.is_tree_code ()
1490 57229 : && TREE_CODE_CLASS ((tree_code)cexpr.code) == tcc_comparison)
1491 566 : c = build2_loc (loc, (tree_code)cexpr.code, boolean_type_node,
1492 : cexpr.ops[0], cexpr.ops[1]);
1493 : else
1494 52627 : c = build2_loc (loc, gimple_cond_code (stmt),
1495 : boolean_type_node,
1496 : gimple_cond_lhs (stmt),
1497 : gimple_cond_rhs (stmt));
1498 :
1499 : /* Add new condition into destination's predicate list. */
1500 53193 : extract_true_false_edges_from_block (gimple_bb (stmt),
1501 : &true_edge, &false_edge);
1502 :
1503 : /* If C is true, then TRUE_EDGE is taken. */
1504 53193 : add_to_dst_predicate_list (loop, true_edge, unshare_expr (cond),
1505 : unshare_expr (c));
1506 :
1507 : /* If C is false, then FALSE_EDGE is taken. */
1508 53193 : c2 = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node,
1509 : unshare_expr (c));
1510 53193 : add_to_dst_predicate_list (loop, false_edge,
1511 : unshare_expr (cond), c2);
1512 :
1513 53193 : cond = NULL_TREE;
1514 : }
1515 :
1516 : /* Assumes the limited COND like switches checked for earlier. */
1517 77691 : else if (gswitch *sw = safe_dyn_cast <gswitch *> (*gsi_last_bb (bb)))
1518 : {
1519 79 : location_t loc = gimple_location (*gsi_last_bb (bb));
1520 :
1521 79 : tree default_label = CASE_LABEL (gimple_switch_default_label (sw));
1522 79 : tree cond_label = CASE_LABEL (gimple_switch_label (sw, 1));
1523 :
1524 79 : edge false_edge = find_edge (bb, label_to_block (cfun, default_label));
1525 79 : edge true_edge = find_edge (bb, label_to_block (cfun, cond_label));
1526 :
1527 : /* Create chain of switch tests for each case. */
1528 79 : tree switch_cond = NULL_TREE;
1529 79 : tree index = gimple_switch_index (sw);
1530 802 : for (unsigned i = 1; i < gimple_switch_num_labels (sw); i++)
1531 : {
1532 723 : tree label = gimple_switch_label (sw, i);
1533 723 : tree case_cond;
1534 723 : if (CASE_HIGH (label))
1535 : {
1536 7 : tree low = build2_loc (loc, GE_EXPR,
1537 : boolean_type_node,
1538 7 : index, fold_convert_loc (loc, TREE_TYPE (index),
1539 7 : CASE_LOW (label)));
1540 14 : tree high = build2_loc (loc, LE_EXPR,
1541 : boolean_type_node,
1542 7 : index, fold_convert_loc (loc, TREE_TYPE (index),
1543 7 : CASE_HIGH (label)));
1544 7 : case_cond = build2_loc (loc, TRUTH_AND_EXPR,
1545 : boolean_type_node,
1546 : low, high);
1547 : }
1548 : else
1549 716 : case_cond = build2_loc (loc, EQ_EXPR,
1550 : boolean_type_node,
1551 : index,
1552 716 : fold_convert_loc (loc, TREE_TYPE (index),
1553 716 : CASE_LOW (label)));
1554 723 : if (i > 1)
1555 644 : switch_cond = build2_loc (loc, TRUTH_OR_EXPR,
1556 : boolean_type_node,
1557 : case_cond, switch_cond);
1558 : else
1559 : switch_cond = case_cond;
1560 : }
1561 :
1562 79 : add_to_dst_predicate_list (loop, true_edge, unshare_expr (cond),
1563 : unshare_expr (switch_cond));
1564 79 : switch_cond = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node,
1565 : unshare_expr (switch_cond));
1566 79 : add_to_dst_predicate_list (loop, false_edge,
1567 : unshare_expr (cond), switch_cond);
1568 79 : cond = NULL_TREE;
1569 : }
1570 :
1571 : /* If current bb has only one successor, then consider it as an
1572 : unconditional goto. */
1573 281830 : if (single_succ_p (bb))
1574 : {
1575 77612 : basic_block bb_n = single_succ (bb);
1576 :
1577 : /* The successor bb inherits the predicate of its
1578 : predecessor. If there is no predicate in the predecessor
1579 : bb, then consider the successor bb as always executed. */
1580 77612 : if (cond == NULL_TREE)
1581 0 : cond = boolean_true_node;
1582 :
1583 77612 : add_to_predicate_list (loop, bb_n, cond);
1584 : }
1585 : }
1586 :
1587 : /* The loop header is always executed. */
1588 36667 : reset_bb_predicate (loop->header);
1589 36667 : gcc_assert (bb_predicate_gimplified_stmts (loop->header) == NULL
1590 : && bb_predicate_gimplified_stmts (loop->latch) == NULL);
1591 36667 : }
1592 :
1593 : /* Build region by adding loop pre-header and post-header blocks. */
1594 :
1595 : static vec<basic_block>
1596 36667 : build_region (class loop *loop)
1597 : {
1598 36667 : vec<basic_block> region = vNULL;
1599 36667 : basic_block exit_bb = NULL;
1600 :
1601 36667 : gcc_assert (ifc_bbs);
1602 : /* The first element is loop pre-header. */
1603 36667 : region.safe_push (loop_preheader_edge (loop)->src);
1604 :
1605 277552 : for (unsigned int i = 0; i < loop->num_nodes; i++)
1606 : {
1607 204218 : basic_block bb = ifc_bbs[i];
1608 204218 : region.safe_push (bb);
1609 : /* Find loop postheader. */
1610 204218 : edge e;
1611 204218 : edge_iterator ei;
1612 453098 : FOR_EACH_EDGE (e, ei, bb->succs)
1613 285547 : if (loop_exit_edge_p (loop, e))
1614 : {
1615 36667 : exit_bb = e->dest;
1616 36667 : break;
1617 : }
1618 : }
1619 : /* The last element is loop post-header. */
1620 36667 : gcc_assert (exit_bb);
1621 36667 : region.safe_push (exit_bb);
1622 36667 : return region;
1623 : }
1624 :
1625 : /* Return true when LOOP is if-convertible. This is a helper function
1626 : for if_convertible_loop_p. REFS and DDRS are initialized and freed
1627 : in if_convertible_loop_p. */
1628 :
1629 : static bool
1630 38717 : if_convertible_loop_p_1 (class loop *loop, vec<data_reference_p> *refs)
1631 : {
1632 38717 : unsigned int i;
1633 38717 : basic_block exit_bb = NULL;
1634 38717 : vec<basic_block> region;
1635 :
1636 38717 : calculate_dominance_info (CDI_DOMINATORS);
1637 :
1638 289103 : for (i = 0; i < loop->num_nodes; i++)
1639 : {
1640 213719 : basic_block bb = ifc_bbs[i];
1641 :
1642 213719 : if (!if_convertible_bb_p (loop, bb, exit_bb))
1643 : return false;
1644 :
1645 211669 : if (bb_with_exit_edge_p (loop, bb))
1646 38641 : exit_bb = bb;
1647 : }
1648 :
1649 36667 : data_reference_p dr;
1650 :
1651 36667 : innermost_DR_map
1652 36667 : = new hash_map<innermost_loop_behavior_hash, data_reference_p>;
1653 36667 : baseref_DR_map = new hash_map<tree_operand_hash, data_reference_p>;
1654 :
1655 : /* Compute post-dominator tree locally. */
1656 36667 : region = build_region (loop);
1657 36667 : calculate_dominance_info_for_region (CDI_POST_DOMINATORS, region);
1658 :
1659 36667 : predicate_bbs (loop);
1660 :
1661 : /* Free post-dominator tree since it is not used after predication. */
1662 36667 : free_dominance_info_for_region (cfun, CDI_POST_DOMINATORS, region);
1663 36667 : region.release ();
1664 :
1665 192756 : for (i = 0; refs->iterate (i, &dr); i++)
1666 : {
1667 119422 : tree ref = DR_REF (dr);
1668 :
1669 119422 : dr->aux = XNEW (struct ifc_dr);
1670 119422 : DR_BASE_W_UNCONDITIONALLY (dr) = false;
1671 119422 : DR_RW_UNCONDITIONALLY (dr) = false;
1672 119422 : DR_W_UNCONDITIONALLY (dr) = false;
1673 119422 : IFC_DR (dr)->rw_predicate = boolean_false_node;
1674 119422 : IFC_DR (dr)->w_predicate = boolean_false_node;
1675 119422 : IFC_DR (dr)->base_w_predicate = boolean_false_node;
1676 119422 : if (gimple_uid (DR_STMT (dr)) == 0)
1677 118733 : gimple_set_uid (DR_STMT (dr), i + 1);
1678 :
1679 : /* If DR doesn't have innermost loop behavior or it's a compound
1680 : memory reference, we synthesize its innermost loop behavior
1681 : for hashing. */
1682 119422 : if (TREE_CODE (ref) == COMPONENT_REF
1683 : || TREE_CODE (ref) == IMAGPART_EXPR
1684 : || TREE_CODE (ref) == REALPART_EXPR
1685 82574 : || !(DR_BASE_ADDRESS (dr) || DR_OFFSET (dr)
1686 26602 : || DR_INIT (dr) || DR_STEP (dr)))
1687 : {
1688 108715 : while (TREE_CODE (ref) == COMPONENT_REF
1689 64609 : || TREE_CODE (ref) == IMAGPART_EXPR
1690 172746 : || TREE_CODE (ref) == REALPART_EXPR)
1691 45265 : ref = TREE_OPERAND (ref, 0);
1692 :
1693 63450 : memset (&DR_INNERMOST (dr), 0, sizeof (DR_INNERMOST (dr)));
1694 63450 : DR_BASE_ADDRESS (dr) = ref;
1695 : }
1696 119422 : hash_memrefs_baserefs_and_store_DRs_read_written_info (dr);
1697 : }
1698 :
1699 183885 : for (i = 0; i < loop->num_nodes; i++)
1700 : {
1701 158653 : basic_block bb = ifc_bbs[i];
1702 158653 : gimple_stmt_iterator itr;
1703 :
1704 : /* Check the if-convertibility of statements in predicated BBs. */
1705 158653 : if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
1706 295038 : for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr))
1707 171823 : if (!if_convertible_stmt_p (gsi_stmt (itr), *refs))
1708 38717 : return false;
1709 : }
1710 :
1711 : /* Checking PHIs needs to be done after stmts, as the fact whether there
1712 : are any masked loads or stores affects the tests. Also check switch
1713 : stmts for supported shape as that cannot be skipped for always
1714 : executed blocks. */
1715 158225 : for (i = 0; i < loop->num_nodes; i++)
1716 : {
1717 132999 : basic_block bb = ifc_bbs[i];
1718 132999 : gphi_iterator itr;
1719 :
1720 261112 : for (itr = gsi_start_phis (bb); !gsi_end_p (itr); gsi_next (&itr))
1721 128113 : if (!if_convertible_phi_p (loop, bb, itr.phi ()))
1722 6 : return false;
1723 346935 : if (gswitch *s = safe_dyn_cast <gswitch *> (*gsi_last_bb (bb)))
1724 70 : if (!if_convertible_switch_p (s))
1725 6 : return false;
1726 : }
1727 :
1728 25226 : if (dump_file)
1729 30 : fprintf (dump_file, "Applying if-conversion\n");
1730 :
1731 : return true;
1732 : }
1733 :
1734 : /* Return true when LOOP is if-convertible.
1735 : LOOP is if-convertible if:
1736 : - it is innermost,
1737 : - it has two or more basic blocks,
1738 : - it has only one exit,
1739 : - loop header is not the exit edge,
1740 : - if its basic blocks and phi nodes are if convertible. */
1741 :
1742 : static bool
1743 38857 : if_convertible_loop_p (class loop *loop, vec<data_reference_p> *refs)
1744 : {
1745 38857 : edge e;
1746 38857 : edge_iterator ei;
1747 38857 : bool res = false;
1748 :
1749 : /* Handle only innermost loop. */
1750 38857 : if (!loop || loop->inner)
1751 : {
1752 0 : if (dump_file && (dump_flags & TDF_DETAILS))
1753 0 : fprintf (dump_file, "not innermost loop\n");
1754 : return false;
1755 : }
1756 :
1757 : /* If only one block, no need for if-conversion. */
1758 38857 : if (loop->num_nodes <= 2)
1759 : {
1760 0 : if (dump_file && (dump_flags & TDF_DETAILS))
1761 0 : fprintf (dump_file, "less than 2 basic blocks\n");
1762 : return false;
1763 : }
1764 :
1765 : /* If one of the loop header's edge is an exit edge then do not
1766 : apply if-conversion. */
1767 116452 : FOR_EACH_EDGE (e, ei, loop->header->succs)
1768 77735 : if (loop_exit_edge_p (loop, e))
1769 : return false;
1770 :
1771 38717 : res = if_convertible_loop_p_1 (loop, refs);
1772 :
1773 75384 : delete innermost_DR_map;
1774 38717 : innermost_DR_map = NULL;
1775 :
1776 75384 : delete baseref_DR_map;
1777 38717 : baseref_DR_map = NULL;
1778 :
1779 38717 : return res;
1780 : }
1781 :
1782 : /* Return reduc_1 if has_nop.
1783 :
1784 : if (...)
1785 : tmp1 = (unsigned type) reduc_1;
1786 : tmp2 = tmp1 + rhs2;
1787 : reduc_3 = (signed type) tmp2. */
1788 : static tree
1789 11314 : strip_nop_cond_scalar_reduction (bool has_nop, tree op)
1790 : {
1791 11314 : if (!has_nop)
1792 : return op;
1793 :
1794 414 : if (TREE_CODE (op) != SSA_NAME)
1795 : return NULL_TREE;
1796 :
1797 368 : gassign *stmt = safe_dyn_cast <gassign *> (SSA_NAME_DEF_STMT (op));
1798 368 : if (!stmt
1799 368 : || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
1800 230 : || !tree_nop_conversion_p (TREE_TYPE (op), TREE_TYPE
1801 : (gimple_assign_rhs1 (stmt))))
1802 : return NULL_TREE;
1803 :
1804 219 : return gimple_assign_rhs1 (stmt);
1805 : }
1806 :
1807 : /* Returns true if def-stmt for phi argument ARG is simple increment/decrement
1808 : which is in predicated basic block.
1809 : In fact, the following PHI pattern is searching:
1810 : loop-header:
1811 : reduc_1 = PHI <..., reduc_2>
1812 : ...
1813 : if (...)
1814 : reduc_3 = ...
1815 : reduc_2 = PHI <reduc_1, reduc_3>
1816 :
1817 : ARG_0 and ARG_1 are correspondent PHI arguments.
1818 : REDUC, OP0 and OP1 contain reduction stmt and its operands.
1819 : EXTENDED is true if PHI has > 2 arguments. */
1820 :
1821 : static bool
1822 46813 : is_cond_scalar_reduction (gimple *phi, gimple **reduc, tree arg_0, tree arg_1,
1823 : tree *op0, tree *op1, bool extended, bool* has_nop,
1824 : gimple **nop_reduc)
1825 : {
1826 46813 : tree lhs, r_op1, r_op2, r_nop1, r_nop2;
1827 46813 : gimple *stmt;
1828 46813 : gimple *header_phi = NULL;
1829 46813 : enum tree_code reduction_op;
1830 46813 : basic_block bb = gimple_bb (phi);
1831 46813 : class loop *loop = bb->loop_father;
1832 46813 : edge latch_e = loop_latch_edge (loop);
1833 46813 : imm_use_iterator imm_iter;
1834 46813 : use_operand_p use_p;
1835 46813 : edge e;
1836 46813 : edge_iterator ei;
1837 46813 : bool result = *has_nop = false;
1838 46813 : if (TREE_CODE (arg_0) != SSA_NAME || TREE_CODE (arg_1) != SSA_NAME)
1839 : return false;
1840 :
1841 34188 : if (!extended && gimple_code (SSA_NAME_DEF_STMT (arg_0)) == GIMPLE_PHI)
1842 : {
1843 8553 : lhs = arg_1;
1844 8553 : header_phi = SSA_NAME_DEF_STMT (arg_0);
1845 8553 : stmt = SSA_NAME_DEF_STMT (arg_1);
1846 : }
1847 25635 : else if (gimple_code (SSA_NAME_DEF_STMT (arg_1)) == GIMPLE_PHI)
1848 : {
1849 11317 : lhs = arg_0;
1850 11317 : header_phi = SSA_NAME_DEF_STMT (arg_1);
1851 11317 : stmt = SSA_NAME_DEF_STMT (arg_0);
1852 : }
1853 : else
1854 : return false;
1855 19870 : if (gimple_bb (header_phi) != loop->header)
1856 : return false;
1857 :
1858 18983 : if (PHI_ARG_DEF_FROM_EDGE (header_phi, latch_e) != PHI_RESULT (phi))
1859 : return false;
1860 :
1861 12889 : if (gimple_code (stmt) != GIMPLE_ASSIGN
1862 12889 : || gimple_has_volatile_ops (stmt))
1863 : return false;
1864 :
1865 12755 : if (!flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
1866 : return false;
1867 :
1868 12663 : if (!is_predicated (gimple_bb (stmt)))
1869 : return false;
1870 :
1871 : /* Check that stmt-block is predecessor of phi-block. */
1872 10510 : FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
1873 10446 : if (e->dest == bb)
1874 : {
1875 : result = true;
1876 : break;
1877 : }
1878 10382 : if (!result)
1879 : return false;
1880 :
1881 10318 : if (!has_single_use (lhs))
1882 : return false;
1883 :
1884 10267 : reduction_op = gimple_assign_rhs_code (stmt);
1885 :
1886 : /* Catch something like below
1887 :
1888 : loop-header:
1889 : reduc_1 = PHI <..., reduc_2>
1890 : ...
1891 : if (...)
1892 : tmp1 = (unsigned type) reduc_1;
1893 : tmp2 = tmp1 + rhs2;
1894 : reduc_3 = (signed type) tmp2;
1895 :
1896 : reduc_2 = PHI <reduc_1, reduc_3>
1897 :
1898 : and convert to
1899 :
1900 : reduc_2 = PHI <0, reduc_1>
1901 : tmp1 = (unsigned type)reduc_1;
1902 : ifcvt = cond_expr ? rhs2 : 0
1903 : tmp2 = tmp1 +/- ifcvt;
1904 : reduc_1 = (signed type)tmp2; */
1905 :
1906 10267 : if (CONVERT_EXPR_CODE_P (reduction_op))
1907 : {
1908 418 : lhs = gimple_assign_rhs1 (stmt);
1909 418 : if (TREE_CODE (lhs) != SSA_NAME
1910 418 : || !has_single_use (lhs))
1911 : return false;
1912 :
1913 230 : *nop_reduc = stmt;
1914 230 : stmt = SSA_NAME_DEF_STMT (lhs);
1915 230 : if (gimple_bb (stmt) != gimple_bb (*nop_reduc)
1916 230 : || !is_gimple_assign (stmt))
1917 : return false;
1918 :
1919 221 : *has_nop = true;
1920 221 : reduction_op = gimple_assign_rhs_code (stmt);
1921 : }
1922 :
1923 10070 : if (reduction_op != PLUS_EXPR
1924 : && reduction_op != MINUS_EXPR
1925 10070 : && reduction_op != MULT_EXPR
1926 10070 : && reduction_op != BIT_IOR_EXPR
1927 : && reduction_op != BIT_XOR_EXPR
1928 4528 : && reduction_op != BIT_AND_EXPR)
1929 : return false;
1930 5657 : r_op1 = gimple_assign_rhs1 (stmt);
1931 5657 : r_op2 = gimple_assign_rhs2 (stmt);
1932 :
1933 5657 : r_nop1 = strip_nop_cond_scalar_reduction (*has_nop, r_op1);
1934 5657 : r_nop2 = strip_nop_cond_scalar_reduction (*has_nop, r_op2);
1935 :
1936 : /* Make R_OP1 to hold reduction variable. */
1937 5657 : if (r_nop2 == PHI_RESULT (header_phi)
1938 5657 : && commutative_tree_code (reduction_op))
1939 : {
1940 : std::swap (r_op1, r_op2);
1941 : std::swap (r_nop1, r_nop2);
1942 : }
1943 4517 : else if (r_nop1 != PHI_RESULT (header_phi))
1944 : return false;
1945 :
1946 5351 : if (*has_nop)
1947 : {
1948 : /* Check that R_NOP1 is used in nop_stmt or in PHI only. */
1949 430 : FOR_EACH_IMM_USE_FAST (use_p, imm_iter, r_nop1)
1950 : {
1951 304 : gimple *use_stmt = USE_STMT (use_p);
1952 304 : if (is_gimple_debug (use_stmt))
1953 0 : continue;
1954 304 : if (use_stmt == SSA_NAME_DEF_STMT (r_op1))
1955 126 : continue;
1956 178 : if (use_stmt != phi)
1957 42 : return false;
1958 168 : }
1959 : }
1960 :
1961 : /* Check that R_OP1 is used in reduction stmt or in PHI only. */
1962 16410 : FOR_EACH_IMM_USE_FAST (use_p, imm_iter, r_op1)
1963 : {
1964 11362 : gimple *use_stmt = USE_STMT (use_p);
1965 11362 : if (is_gimple_debug (use_stmt))
1966 29 : continue;
1967 11333 : if (use_stmt == stmt)
1968 5073 : continue;
1969 6260 : if (gimple_code (use_stmt) != GIMPLE_PHI)
1970 261 : return false;
1971 261 : }
1972 :
1973 5048 : *op0 = r_op1; *op1 = r_op2;
1974 5048 : *reduc = stmt;
1975 5048 : return true;
1976 : }
1977 :
1978 : /* Converts conditional scalar reduction into unconditional form, e.g.
1979 : bb_4
1980 : if (_5 != 0) goto bb_5 else goto bb_6
1981 : end_bb_4
1982 : bb_5
1983 : res_6 = res_13 + 1;
1984 : end_bb_5
1985 : bb_6
1986 : # res_2 = PHI <res_13(4), res_6(5)>
1987 : end_bb_6
1988 :
1989 : will be converted into sequence
1990 : _ifc__1 = _5 != 0 ? 1 : 0;
1991 : res_2 = res_13 + _ifc__1;
1992 : Argument SWAP tells that arguments of conditional expression should be
1993 : swapped.
1994 : We can assume that we versioned the loop for vectorization, so can
1995 : create a COND_OP.
1996 : Returns rhs of resulting PHI assignment. */
1997 :
1998 : static tree
1999 5048 : convert_scalar_cond_reduction (gimple *reduc, gimple_stmt_iterator *gsi,
2000 : tree cond, tree op0, tree op1, bool swap,
2001 : bool has_nop, gimple* nop_reduc)
2002 : {
2003 5048 : gimple_stmt_iterator stmt_it;
2004 5048 : gimple *new_assign;
2005 5048 : tree rhs;
2006 5048 : tree rhs1 = gimple_assign_rhs1 (reduc);
2007 5048 : tree lhs = gimple_assign_lhs (reduc);
2008 5048 : tree tmp = make_temp_ssa_name (TREE_TYPE (rhs1), NULL, "_ifc_");
2009 5048 : tree c;
2010 5048 : enum tree_code reduction_op = gimple_assign_rhs_code (reduc);
2011 5048 : tree op_nochange = neutral_op_for_reduction (TREE_TYPE (rhs1), reduction_op,
2012 : NULL, false);
2013 5048 : gimple_seq stmts = NULL;
2014 :
2015 5048 : if (dump_file && (dump_flags & TDF_DETAILS))
2016 : {
2017 2 : fprintf (dump_file, "Found cond scalar reduction.\n");
2018 2 : print_gimple_stmt (dump_file, reduc, 0, TDF_SLIM);
2019 : }
2020 :
2021 : /* If possible create a COND_OP instead of a COND_EXPR and an OP_EXPR.
2022 : The COND_OP will have a neutral_op else value. */
2023 5048 : internal_fn ifn;
2024 5048 : ifn = get_conditional_internal_fn (reduction_op);
2025 5048 : if (ifn != IFN_LAST
2026 5048 : && vectorized_internal_fn_supported_p (ifn, TREE_TYPE (lhs))
2027 1363 : && !VECTOR_TYPE_P (TREE_TYPE (lhs))
2028 6411 : && !swap)
2029 : {
2030 1343 : gcall *cond_call = gimple_build_call_internal (ifn, 4,
2031 : unshare_expr (cond),
2032 : op0, op1, op0);
2033 1343 : gsi_insert_before (gsi, cond_call, GSI_SAME_STMT);
2034 1343 : gimple_call_set_lhs (cond_call, tmp);
2035 : rhs = tmp;
2036 : }
2037 : else
2038 : {
2039 : /* Build cond expression using COND and constant operand
2040 : of reduction rhs. */
2041 7155 : c = fold_build_cond_expr (TREE_TYPE (rhs1),
2042 : unshare_expr (cond),
2043 : swap ? op_nochange : op1,
2044 : swap ? op1 : op_nochange);
2045 : /* Create assignment stmt and insert it at GSI. */
2046 3705 : new_assign = gimple_build_assign (tmp, c);
2047 3705 : gsi_insert_before (gsi, new_assign, GSI_SAME_STMT);
2048 : /* Build rhs for unconditional increment/decrement/logic_operation. */
2049 3705 : rhs = gimple_build (&stmts, reduction_op,
2050 3705 : TREE_TYPE (rhs1), op0, tmp);
2051 : }
2052 :
2053 5048 : if (has_nop)
2054 : {
2055 126 : rhs = gimple_convert (&stmts,
2056 126 : TREE_TYPE (gimple_assign_lhs (nop_reduc)), rhs);
2057 126 : stmt_it = gsi_for_stmt (nop_reduc);
2058 126 : gsi_remove (&stmt_it, true);
2059 126 : release_defs (nop_reduc);
2060 : }
2061 5048 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
2062 :
2063 : /* Delete original reduction stmt. */
2064 5048 : stmt_it = gsi_for_stmt (reduc);
2065 5048 : gsi_remove (&stmt_it, true);
2066 5048 : release_defs (reduc);
2067 5048 : return rhs;
2068 : }
2069 :
2070 : /* Generate a simplified conditional. */
2071 :
2072 : static tree
2073 53068 : gen_simplified_condition (tree cond, scalar_cond_masked_set_type &cond_set)
2074 : {
2075 : /* Check if the value is already live in a previous branch. This resolves
2076 : nested conditionals from diamond PHI reductions. */
2077 53068 : if (TREE_CODE (cond) == SSA_NAME)
2078 : {
2079 53060 : gimple *stmt = SSA_NAME_DEF_STMT (cond);
2080 53060 : gassign *assign = NULL;
2081 53060 : if ((assign = as_a <gassign *> (stmt))
2082 53060 : && gimple_assign_rhs_code (assign) == BIT_AND_EXPR)
2083 : {
2084 3566 : tree arg1 = gimple_assign_rhs1 (assign);
2085 3566 : tree arg2 = gimple_assign_rhs2 (assign);
2086 3566 : if (cond_set.contains ({ arg1, 1 }))
2087 165 : arg1 = boolean_true_node;
2088 : else
2089 3401 : arg1 = gen_simplified_condition (arg1, cond_set);
2090 :
2091 3566 : if (cond_set.contains ({ arg2, 1 }))
2092 1792 : arg2 = boolean_true_node;
2093 : else
2094 1774 : arg2 = gen_simplified_condition (arg2, cond_set);
2095 :
2096 3566 : cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, arg1, arg2);
2097 : }
2098 : }
2099 53068 : return cond;
2100 : }
2101 :
2102 : /* Structure used to track meta-data on PHI arguments used to generate
2103 : most efficient comparison sequence to slatten a PHI node. */
2104 :
2105 : typedef struct ifcvt_arg_entry
2106 : {
2107 : /* The PHI node argument value. */
2108 : tree arg;
2109 :
2110 : /* The number of compares required to reach this PHI node from start of the
2111 : BB being if-converted. */
2112 : unsigned num_compares;
2113 :
2114 : /* The number of times this PHI node argument appears in the current PHI
2115 : node. */
2116 : unsigned occurs;
2117 :
2118 : /* The indices at which this PHI arg occurs inside the PHI node. */
2119 : vec <int> *indexes;
2120 : } ifcvt_arg_entry_t;
2121 :
2122 : /* Produce condition for all occurrences of ARG in PHI node. Set *INVERT
2123 : as to whether the condition is inverted. */
2124 :
2125 : static tree
2126 4247 : gen_phi_arg_condition (gphi *phi, ifcvt_arg_entry_t &arg,
2127 : gimple_stmt_iterator *gsi,
2128 : scalar_cond_masked_set_type &cond_set, bool *invert)
2129 : {
2130 4247 : int len;
2131 4247 : int i;
2132 4247 : tree cond = NULL_TREE;
2133 4247 : tree c;
2134 4247 : edge e;
2135 :
2136 4247 : *invert = false;
2137 4247 : len = arg.indexes->length ();
2138 4247 : gcc_assert (len > 0);
2139 8552 : for (i = 0; i < len; i++)
2140 : {
2141 4305 : e = gimple_phi_arg_edge (phi, (*arg.indexes)[i]);
2142 4305 : c = bb_predicate (e->src);
2143 4305 : if (is_true_predicate (c))
2144 : {
2145 0 : cond = c;
2146 0 : break;
2147 : }
2148 : /* If we have just a single inverted predicate, signal that and
2149 : instead invert the COND_EXPR arms. */
2150 4305 : if (len == 1 && TREE_CODE (c) == TRUTH_NOT_EXPR)
2151 : {
2152 92 : c = TREE_OPERAND (c, 0);
2153 92 : *invert = true;
2154 : }
2155 :
2156 4305 : c = gen_simplified_condition (c, cond_set);
2157 4305 : c = force_gimple_operand_gsi (gsi, unshare_expr (c),
2158 : true, NULL_TREE, true, GSI_SAME_STMT);
2159 4305 : if (cond != NULL_TREE)
2160 : {
2161 : /* Must build OR expression. */
2162 58 : cond = fold_or_predicates (EXPR_LOCATION (c), c, cond);
2163 58 : cond = force_gimple_operand_gsi (gsi, unshare_expr (cond), true,
2164 : NULL_TREE, true, GSI_SAME_STMT);
2165 : }
2166 : else
2167 : cond = c;
2168 :
2169 : /* Register the new possibly simplified conditional. When more than 2
2170 : entries in a phi node we chain entries in the false branch, so the
2171 : inverted condition is active. */
2172 4305 : scalar_cond_masked_key pred_cond ({ cond, 1 });
2173 4305 : if (!*invert)
2174 4213 : pred_cond.inverted_p = !pred_cond.inverted_p;
2175 4305 : cond_set.add (pred_cond);
2176 : }
2177 4247 : gcc_assert (cond != NULL_TREE);
2178 4247 : return cond;
2179 : }
2180 :
2181 : /* Factors out an operation from *ARG0 and *ARG1 and
2182 : create the new statement at GSI. *RES is the
2183 : result of that new statement. Update *ARG0 and *ARG1
2184 : and *RES to the new values if the factoring happened.
2185 : Loops until all of the factoring is completed. */
2186 :
2187 : static void
2188 43588 : factor_out_operators (tree *res, gimple_stmt_iterator *gsi,
2189 : tree *arg0, tree *arg1, gphi *phi)
2190 : {
2191 43588 : gimple_match_op arg0_op, arg1_op;
2192 43588 : bool repeated = false;
2193 :
2194 44302 : again:
2195 44302 : if (TREE_CODE (*arg0) != SSA_NAME || TREE_CODE (*arg1) != SSA_NAME)
2196 : return;
2197 :
2198 32690 : if (operand_equal_p (*arg0, *arg1))
2199 : return;
2200 :
2201 : /* If either args have > 1 use, then this transformation actually
2202 : increases the number of expressions evaluated at runtime. */
2203 32690 : if (repeated
2204 32690 : ? (!has_zero_uses (*arg0) || !has_zero_uses (*arg1))
2205 32026 : : (!has_single_use (*arg0) || !has_single_use (*arg1)))
2206 : return;
2207 :
2208 5556 : gimple *arg0_def_stmt = SSA_NAME_DEF_STMT (*arg0);
2209 5556 : if (!gimple_extract_op (arg0_def_stmt, &arg0_op))
2210 : return;
2211 :
2212 : /* Might pick up abnormals from previous bbs so stop the loop. */
2213 2284 : if (arg0_op.operands_occurs_in_abnormal_phi ())
2214 : return;
2215 :
2216 2282 : gimple *arg1_def_stmt = SSA_NAME_DEF_STMT (*arg1);
2217 2282 : if (!gimple_extract_op (arg1_def_stmt, &arg1_op))
2218 : return;
2219 :
2220 : /* Might pick up abnormals from previous bbs so stop the loop. */
2221 1957 : if (arg1_op.operands_occurs_in_abnormal_phi ())
2222 : return;
2223 :
2224 : /* No factoring can happen if the codes are different
2225 : or the number operands. */
2226 1957 : if (arg1_op.code != arg0_op.code
2227 1957 : || arg1_op.num_ops != arg0_op.num_ops)
2228 : return;
2229 :
2230 1001 : tree new_arg0, new_arg1;
2231 1001 : int opnum = find_different_opnum (arg0_op, arg1_op, &new_arg0, &new_arg1);
2232 1001 : if (opnum == -1)
2233 : return;
2234 :
2235 733 : tree args[2] = { new_arg0, new_arg1 };
2236 733 : location_t locs[2];
2237 733 : locs[0] = gimple_location (arg0_def_stmt);
2238 733 : locs[1] = gimple_location (arg1_def_stmt);
2239 733 : if (!factor_operation_ok (arg1_op.code, opnum, args, locs, 2, true, true))
2240 : return;
2241 :
2242 714 : tree new_res = make_ssa_name (TREE_TYPE (new_arg0), NULL);
2243 :
2244 : /* Create the operation stmt if possible and insert it. */
2245 :
2246 714 : gimple_match_op new_op = arg0_op;
2247 714 : new_op.ops[opnum] = new_res;
2248 714 : gimple_seq seq = NULL;
2249 714 : tree result = *res;
2250 714 : result = maybe_push_res_to_seq (&new_op, &seq, result);
2251 :
2252 : /* If we can't create the new statement, release the temp name
2253 : and return back. */
2254 714 : if (!result)
2255 : {
2256 0 : release_ssa_name (new_res);
2257 0 : return;
2258 : }
2259 714 : gsi_insert_seq_before (gsi, seq, GSI_CONTINUE_LINKING);
2260 :
2261 714 : if (dump_file && (dump_flags & TDF_DETAILS))
2262 : {
2263 1 : fprintf (dump_file, "PHI ");
2264 1 : print_generic_expr (dump_file, gimple_phi_result (phi));
2265 1 : fprintf (dump_file,
2266 : " changed to factor operation out from COND_EXPR.\n");
2267 1 : fprintf (dump_file, "New stmt with OPERATION that defines ");
2268 1 : print_generic_expr (dump_file, result);
2269 1 : fprintf (dump_file, ".\n");
2270 : }
2271 :
2272 : /* Remove the old operation(s) that has single use. */
2273 714 : gimple_stmt_iterator gsi_for_def;
2274 :
2275 714 : gsi_for_def = gsi_for_stmt (arg0_def_stmt);
2276 714 : gsi_remove (&gsi_for_def, true);
2277 714 : release_defs (arg0_def_stmt);
2278 714 : gsi_for_def = gsi_for_stmt (arg1_def_stmt);
2279 714 : gsi_remove (&gsi_for_def, true);
2280 714 : release_defs (arg1_def_stmt);
2281 :
2282 : /* Update the arguments and try again. */
2283 714 : *arg0 = new_arg0;
2284 714 : *arg1 = new_arg1;
2285 714 : *res = new_res;
2286 :
2287 : /* Update the phi node too. */
2288 714 : gimple_phi_set_result (phi, new_res);
2289 714 : gimple_phi_arg (phi, 0)->def = new_arg0;
2290 714 : gimple_phi_arg (phi, 1)->def = new_arg1;
2291 714 : update_stmt (phi);
2292 :
2293 714 : repeated = true;
2294 714 : goto again;
2295 : }
2296 :
2297 : /* Create the smallest nested conditional possible. On pre-order we record
2298 : which conditionals are live, and on post-order rewrite the chain by removing
2299 : already active conditions.
2300 :
2301 : As an example we simplify:
2302 :
2303 : _7 = a_10 < 0;
2304 : _21 = a_10 >= 0;
2305 : _22 = a_10 < e_11(D);
2306 : _23 = _21 & _22;
2307 : _ifc__42 = _23 ? t_13 : 0;
2308 : t_6 = _7 ? 1 : _ifc__42
2309 :
2310 : into
2311 :
2312 : _7 = a_10 < 0;
2313 : _22 = a_10 < e_11(D);
2314 : _ifc__42 = _22 ? t_13 : 0;
2315 : t_6 = _7 ? 1 : _ifc__42;
2316 :
2317 : which produces better code. */
2318 :
2319 : static tree
2320 6368 : gen_phi_nest_statement (gphi *phi, gimple_stmt_iterator *gsi,
2321 : scalar_cond_masked_set_type &cond_set, tree type,
2322 : gimple **res_stmt, tree lhs0,
2323 : vec<struct ifcvt_arg_entry> &args, unsigned idx)
2324 : {
2325 12736 : if (idx == args.length ())
2326 2121 : return args[idx - 1].arg;
2327 :
2328 4247 : bool invert;
2329 4247 : tree cond = gen_phi_arg_condition (phi, args[idx - 1], gsi, cond_set,
2330 : &invert);
2331 4247 : tree arg1 = gen_phi_nest_statement (phi, gsi, cond_set, type, res_stmt, lhs0,
2332 : args, idx + 1);
2333 :
2334 4247 : unsigned prev = idx;
2335 4247 : unsigned curr = prev - 1;
2336 4247 : tree arg0 = args[curr].arg;
2337 4247 : tree rhs, lhs;
2338 4247 : if (idx > 1)
2339 2126 : lhs = make_temp_ssa_name (type, NULL, "_ifc_");
2340 : else
2341 : lhs = lhs0;
2342 :
2343 4247 : if (invert)
2344 92 : rhs = fold_build_cond_expr (type, unshare_expr (cond),
2345 : arg1, arg0);
2346 : else
2347 4155 : rhs = fold_build_cond_expr (type, unshare_expr (cond),
2348 : arg0, arg1);
2349 4247 : gassign *new_stmt = gimple_build_assign (lhs, rhs);
2350 4247 : gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
2351 4247 : update_stmt (new_stmt);
2352 4247 : *res_stmt = new_stmt;
2353 4247 : return lhs;
2354 : }
2355 :
2356 : /* When flattening a PHI node we have a choice of which conditions to test to
2357 : for all the paths from the start of the dominator block of the BB with the
2358 : PHI node. If the PHI node has X arguments we have to only test X - 1
2359 : conditions as the last one is implicit. It does matter which conditions we
2360 : test first. We should test the shortest condition first (distance here is
2361 : measures in the number of logical operators in the condition) and the
2362 : longest one last. This allows us to skip testing the most expensive
2363 : condition. To accomplish this we need to sort the conditions. P1 and P2
2364 : are sorted first based on the number of logical operations (num_compares)
2365 : and then by how often they occur in the PHI node. */
2366 :
2367 : static int
2368 36417 : cmp_arg_entry (const void *p1, const void *p2, void * /* data. */)
2369 : {
2370 36417 : const ifcvt_arg_entry sval1 = *(const ifcvt_arg_entry *)p1;
2371 36417 : const ifcvt_arg_entry sval2 = *(const ifcvt_arg_entry *)p2;
2372 :
2373 36417 : if (sval1.num_compares < sval2.num_compares)
2374 : return -1;
2375 12386 : else if (sval1.num_compares > sval2.num_compares)
2376 : return 1;
2377 :
2378 642 : if (sval1.occurs < sval2.occurs)
2379 : return -1;
2380 642 : else if (sval1.occurs > sval2.occurs)
2381 0 : return 1;
2382 :
2383 : return 0;
2384 : }
2385 :
2386 : /* Replace a scalar PHI node with a COND_EXPR using COND as condition.
2387 : This routine can handle PHI nodes with more than two arguments.
2388 :
2389 : For example,
2390 : S1: A = PHI <x1(1), x2(5)>
2391 : is converted into,
2392 : S2: A = cond ? x1 : x2;
2393 :
2394 : The generated code is inserted at GSI that points to the top of
2395 : basic block's statement list.
2396 : If PHI node has more than two arguments a chain of conditional
2397 : expression is produced. */
2398 :
2399 :
2400 : static void
2401 48993 : predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi)
2402 : {
2403 48993 : gimple *new_stmt = NULL, *reduc, *nop_reduc;
2404 48993 : tree rhs, res, arg0, arg1, op0, op1, scev;
2405 48993 : tree cond;
2406 48993 : unsigned int index0;
2407 48993 : edge e;
2408 48993 : basic_block bb;
2409 48993 : unsigned int i;
2410 48993 : bool has_nop;
2411 :
2412 48993 : res = gimple_phi_result (phi);
2413 97986 : if (virtual_operand_p (res))
2414 43647 : return;
2415 :
2416 48993 : if ((rhs = degenerate_phi_result (phi))
2417 48993 : || ((scev = analyze_scalar_evolution (gimple_bb (phi)->loop_father,
2418 : res))
2419 48951 : && !chrec_contains_undetermined (scev)
2420 48951 : && scev != res
2421 17 : && (rhs = gimple_phi_arg_def (phi, 0))))
2422 : {
2423 59 : if (dump_file && (dump_flags & TDF_DETAILS))
2424 : {
2425 0 : fprintf (dump_file, "Degenerate phi!\n");
2426 0 : print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
2427 : }
2428 59 : new_stmt = gimple_build_assign (res, rhs);
2429 59 : gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
2430 59 : update_stmt (new_stmt);
2431 59 : return;
2432 : }
2433 :
2434 48934 : bb = gimple_bb (phi);
2435 : /* Keep track of conditionals already seen. */
2436 48934 : scalar_cond_masked_set_type cond_set;
2437 48934 : if (EDGE_COUNT (bb->preds) == 2)
2438 : {
2439 : /* Predicate ordinary PHI node with 2 arguments. */
2440 43588 : edge first_edge, second_edge;
2441 43588 : basic_block true_bb;
2442 43588 : first_edge = EDGE_PRED (bb, 0);
2443 43588 : second_edge = EDGE_PRED (bb, 1);
2444 43588 : cond = bb_predicate (first_edge->src);
2445 43588 : cond_set.add ({ cond, 1 });
2446 43588 : if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
2447 22698 : std::swap (first_edge, second_edge);
2448 43588 : if (EDGE_COUNT (first_edge->src->succs) > 1)
2449 : {
2450 19415 : cond = bb_predicate (second_edge->src);
2451 19415 : if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
2452 10422 : cond = TREE_OPERAND (cond, 0);
2453 : else
2454 : first_edge = second_edge;
2455 : }
2456 : else
2457 24173 : cond = bb_predicate (first_edge->src);
2458 :
2459 : /* Gimplify the condition to a valid cond-expr conditional operand. */
2460 43588 : cond = gen_simplified_condition (cond, cond_set);
2461 43588 : cond = force_gimple_operand_gsi (gsi, unshare_expr (cond), true,
2462 : NULL_TREE, true, GSI_SAME_STMT);
2463 43588 : true_bb = first_edge->src;
2464 43588 : if (EDGE_PRED (bb, 1)->src == true_bb)
2465 : {
2466 31691 : arg0 = gimple_phi_arg_def (phi, 1);
2467 31691 : arg1 = gimple_phi_arg_def (phi, 0);
2468 : }
2469 : else
2470 : {
2471 11897 : arg0 = gimple_phi_arg_def (phi, 0);
2472 11897 : arg1 = gimple_phi_arg_def (phi, 1);
2473 : }
2474 :
2475 : /* Factor out operand if possible. This can only be done easily
2476 : for PHI with 2 elements. */
2477 43588 : factor_out_operators (&res, gsi, &arg0, &arg1, phi);
2478 :
2479 43588 : if (is_cond_scalar_reduction (phi, &reduc, arg0, arg1,
2480 : &op0, &op1, false, &has_nop,
2481 : &nop_reduc))
2482 : {
2483 : /* Convert reduction stmt into vectorizable form. */
2484 8180 : rhs = convert_scalar_cond_reduction (reduc, gsi, cond, op0, op1,
2485 4090 : true_bb != gimple_bb (reduc),
2486 : has_nop, nop_reduc);
2487 4090 : redundant_ssa_names.safe_push (std::make_pair (res, rhs));
2488 : }
2489 : else
2490 : /* Build new RHS using selected condition and arguments. */
2491 39498 : rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond),
2492 : arg0, arg1);
2493 43588 : new_stmt = gimple_build_assign (res, rhs);
2494 43588 : gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
2495 43588 : gimple_stmt_iterator new_gsi = gsi_for_stmt (new_stmt);
2496 43588 : if (fold_stmt (&new_gsi, follow_all_ssa_edges))
2497 : {
2498 1540 : new_stmt = gsi_stmt (new_gsi);
2499 1540 : update_stmt (new_stmt);
2500 : }
2501 :
2502 43588 : if (dump_file && (dump_flags & TDF_DETAILS))
2503 : {
2504 16 : fprintf (dump_file, "new phi replacement stmt\n");
2505 16 : print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
2506 : }
2507 43588 : return;
2508 : }
2509 :
2510 : /* Create hashmap for PHI node which contain vector of argument indexes
2511 : having the same value. */
2512 5346 : bool swap = false;
2513 5346 : hash_map<tree_operand_hash, auto_vec<int> > phi_arg_map;
2514 5346 : unsigned int num_args = gimple_phi_num_args (phi);
2515 : /* Vector of different PHI argument values. */
2516 5346 : auto_vec<ifcvt_arg_entry_t> args;
2517 :
2518 : /* Compute phi_arg_map, determine the list of unique PHI args and the indices
2519 : where they are in the PHI node. The indices will be used to determine
2520 : the conditions to apply and their complexity. */
2521 21653 : for (i = 0; i < num_args; i++)
2522 : {
2523 16307 : tree arg;
2524 :
2525 16307 : arg = gimple_phi_arg_def (phi, i);
2526 16307 : if (!phi_arg_map.get (arg))
2527 12818 : args.safe_push ({ arg, 0, 0, NULL });
2528 16307 : phi_arg_map.get_or_insert (arg).safe_push (i);
2529 : }
2530 :
2531 : /* Determine element with max number of occurrences and complexity. Looking
2532 : at only number of occurrences as a measure for complexity isn't enough as
2533 : all usages can be unique but the comparisons to reach the PHI node differ
2534 : per branch. */
2535 18164 : for (unsigned i = 0; i < args.length (); i++)
2536 : {
2537 12818 : unsigned int len = 0;
2538 12818 : vec<int> *indices = phi_arg_map.get (args[i].arg);
2539 54761 : for (int index : *indices)
2540 : {
2541 16307 : edge e = gimple_phi_arg_edge (phi, index);
2542 16307 : len += get_bb_num_predicate_stmts (e->src);
2543 : }
2544 :
2545 12818 : unsigned occur = indices->length ();
2546 12818 : if (dump_file && (dump_flags & TDF_DETAILS))
2547 7 : fprintf (dump_file, "Ranking %d as len=%d, idx=%d\n", i, len, occur);
2548 12818 : args[i].num_compares = len;
2549 12818 : args[i].occurs = occur;
2550 12818 : args[i].indexes = indices;
2551 : }
2552 :
2553 : /* Sort elements based on rankings ARGS. */
2554 5346 : args.stablesort (cmp_arg_entry, NULL);
2555 :
2556 : /* Handle one special case when number of arguments with different values
2557 : is equal 2 and one argument has the only occurrence. Such PHI can be
2558 : handled as if would have only 2 arguments. */
2559 5346 : if (args.length () == 2
2560 8629 : && args[0].indexes->length () == 1)
2561 : {
2562 3225 : index0 = (*args[0].indexes)[0];
2563 3225 : arg0 = args[0].arg;
2564 3225 : arg1 = args[1].arg;
2565 3225 : e = gimple_phi_arg_edge (phi, index0);
2566 3225 : cond = bb_predicate (e->src);
2567 3225 : if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
2568 : {
2569 36 : swap = true;
2570 36 : cond = TREE_OPERAND (cond, 0);
2571 : }
2572 : /* Gimplify the condition to a valid cond-expr conditional operand. */
2573 3225 : cond = force_gimple_operand_gsi (gsi, unshare_expr (cond), true,
2574 : NULL_TREE, true, GSI_SAME_STMT);
2575 3225 : if (!(is_cond_scalar_reduction (phi, &reduc, arg0 , arg1,
2576 : &op0, &op1, true, &has_nop, &nop_reduc)))
2577 4500 : rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond),
2578 : swap ? arg1 : arg0,
2579 : swap ? arg0 : arg1);
2580 : else
2581 : {
2582 : /* Convert reduction stmt into vectorizable form. */
2583 958 : rhs = convert_scalar_cond_reduction (reduc, gsi, cond, op0, op1,
2584 : swap, has_nop, nop_reduc);
2585 958 : redundant_ssa_names.safe_push (std::make_pair (res, rhs));
2586 : }
2587 3225 : new_stmt = gimple_build_assign (res, rhs);
2588 3225 : gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
2589 3225 : update_stmt (new_stmt);
2590 : }
2591 : else
2592 : {
2593 : /* Common case. */
2594 2121 : tree type = TREE_TYPE (gimple_phi_result (phi));
2595 2121 : gen_phi_nest_statement (phi, gsi, cond_set, type, &new_stmt, res,
2596 : args, 1);
2597 : }
2598 :
2599 5346 : if (dump_file && (dump_flags & TDF_DETAILS))
2600 : {
2601 3 : fprintf (dump_file, "new extended phi replacement stmt\n");
2602 3 : print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
2603 : }
2604 48934 : }
2605 :
2606 : /* Replaces in LOOP all the scalar phi nodes other than those in the
2607 : LOOP->header block with conditional modify expressions. */
2608 :
2609 : static void
2610 25226 : predicate_all_scalar_phis (class loop *loop)
2611 : {
2612 25226 : basic_block bb;
2613 25226 : unsigned int orig_loop_num_nodes = loop->num_nodes;
2614 25226 : unsigned int i;
2615 :
2616 132993 : for (i = 1; i < orig_loop_num_nodes; i++)
2617 : {
2618 107767 : gphi *phi;
2619 107767 : gimple_stmt_iterator gsi;
2620 107767 : gphi_iterator phi_gsi;
2621 107767 : bb = ifc_bbs[i];
2622 :
2623 107767 : if (bb == loop->header)
2624 77405 : continue;
2625 :
2626 107767 : phi_gsi = gsi_start_phis (bb);
2627 107767 : if (gsi_end_p (phi_gsi))
2628 77405 : continue;
2629 :
2630 30362 : gsi = gsi_after_labels (bb);
2631 81703 : while (!gsi_end_p (phi_gsi))
2632 : {
2633 51341 : phi = phi_gsi.phi ();
2634 102682 : if (virtual_operand_p (gimple_phi_result (phi)))
2635 2348 : gsi_next (&phi_gsi);
2636 : else
2637 : {
2638 48993 : predicate_scalar_phi (phi, &gsi);
2639 48993 : remove_phi_node (&phi_gsi, false);
2640 : }
2641 : }
2642 : }
2643 25226 : }
2644 :
2645 : /* Insert in each basic block of LOOP the statements produced by the
2646 : gimplification of the predicates. */
2647 :
2648 : static void
2649 25226 : insert_gimplified_predicates (loop_p loop)
2650 : {
2651 25226 : unsigned int i;
2652 :
2653 158219 : for (i = 0; i < loop->num_nodes; i++)
2654 : {
2655 132993 : basic_block bb = ifc_bbs[i];
2656 132993 : gimple_seq stmts;
2657 132993 : if (!is_predicated (bb))
2658 79801 : gcc_assert (bb_predicate_gimplified_stmts (bb) == NULL);
2659 132993 : if (!is_predicated (bb))
2660 : {
2661 : /* Do not insert statements for a basic block that is not
2662 : predicated. Also make sure that the predicate of the
2663 : basic block is set to true. */
2664 79801 : reset_bb_predicate (bb);
2665 79801 : continue;
2666 : }
2667 :
2668 53192 : stmts = bb_predicate_gimplified_stmts (bb);
2669 53192 : if (stmts)
2670 : {
2671 52780 : if (need_to_predicate)
2672 : {
2673 : /* Insert the predicate of the BB just after the label,
2674 : as the if-conversion of memory writes will use this
2675 : predicate. */
2676 5724 : gimple_stmt_iterator gsi = gsi_after_labels (bb);
2677 5724 : gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
2678 : }
2679 : else
2680 : {
2681 : /* Insert the predicate of the BB at the end of the BB
2682 : as this would reduce the register pressure: the only
2683 : use of this predicate will be in successor BBs. */
2684 47056 : gimple_stmt_iterator gsi = gsi_last_bb (bb);
2685 :
2686 47056 : if (gsi_end_p (gsi)
2687 47056 : || stmt_ends_bb_p (gsi_stmt (gsi)))
2688 25106 : gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
2689 : else
2690 21950 : gsi_insert_seq_after (&gsi, stmts, GSI_SAME_STMT);
2691 : }
2692 :
2693 : /* Once the sequence is code generated, set it to NULL. */
2694 132993 : set_bb_predicate_gimplified_stmts (bb, NULL, true);
2695 : }
2696 : }
2697 25226 : }
2698 :
2699 : /* Helper function for predicate_statements. Returns index of existent
2700 : mask if it was created for given SIZE and -1 otherwise. */
2701 :
2702 : static int
2703 934 : mask_exists (int size, const vec<int> &vec)
2704 : {
2705 934 : unsigned int ix;
2706 934 : int v;
2707 1023 : FOR_EACH_VEC_ELT (vec, ix, v)
2708 962 : if (v == size)
2709 873 : return (int) ix;
2710 : return -1;
2711 : }
2712 :
2713 : /* Helper function for predicate_statements. STMT is a memory read or
2714 : write and it needs to be predicated by MASK. Return a statement
2715 : that does so. */
2716 :
2717 : static gimple *
2718 1992 : predicate_load_or_store (gimple_stmt_iterator *gsi, gassign *stmt, tree mask)
2719 : {
2720 1992 : gcall *new_stmt;
2721 :
2722 1992 : tree lhs = gimple_assign_lhs (stmt);
2723 1992 : tree rhs = gimple_assign_rhs1 (stmt);
2724 1992 : tree ref = TREE_CODE (lhs) == SSA_NAME ? rhs : lhs;
2725 1992 : mark_addressable (ref);
2726 1992 : tree addr = force_gimple_operand_gsi (gsi, build_fold_addr_expr (ref),
2727 : true, NULL_TREE, true, GSI_SAME_STMT);
2728 1992 : tree ptr = build_int_cst (reference_alias_ptr_type (ref),
2729 1992 : get_object_alignment (ref));
2730 : /* Copy points-to info if possible. */
2731 1992 : if (TREE_CODE (addr) == SSA_NAME && !SSA_NAME_PTR_INFO (addr))
2732 599 : copy_ref_info (build2 (MEM_REF, TREE_TYPE (ref), addr, ptr),
2733 : ref);
2734 1992 : if (TREE_CODE (lhs) == SSA_NAME)
2735 : {
2736 : /* Get a zero else value. This might not be what a target actually uses
2737 : but we cannot be sure about which vector mode the vectorizer will
2738 : choose. Therefore, leave the decision whether we need to force the
2739 : inactive elements to zero to the vectorizer. */
2740 1159 : tree els = vect_get_mask_load_else (MASK_LOAD_ELSE_ZERO,
2741 1159 : TREE_TYPE (lhs));
2742 :
2743 1159 : new_stmt
2744 1159 : = gimple_build_call_internal (IFN_MASK_LOAD, 4, addr,
2745 : ptr, mask, els);
2746 :
2747 1159 : gimple_call_set_lhs (new_stmt, lhs);
2748 2318 : gimple_set_vuse (new_stmt, gimple_vuse (stmt));
2749 : }
2750 : else
2751 : {
2752 833 : new_stmt
2753 833 : = gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr,
2754 : mask, rhs);
2755 833 : gimple_move_vops (new_stmt, stmt);
2756 : }
2757 1992 : gimple_call_set_nothrow (new_stmt, true);
2758 1992 : return new_stmt;
2759 : }
2760 :
2761 : /* STMT uses OP_LHS. Check whether it is equivalent to:
2762 :
2763 : ... = OP_MASK ? OP_LHS : X;
2764 :
2765 : Return X if so, otherwise return null. OP_MASK is an SSA_NAME that is
2766 : known to have value OP_COND. */
2767 :
2768 : static tree
2769 820 : check_redundant_cond_expr (gimple *stmt, tree op_mask, tree op_cond,
2770 : tree op_lhs)
2771 : {
2772 820 : gassign *assign = dyn_cast <gassign *> (stmt);
2773 1028 : if (!assign || gimple_assign_rhs_code (assign) != COND_EXPR)
2774 : return NULL_TREE;
2775 :
2776 203 : tree use_cond = gimple_assign_rhs1 (assign);
2777 203 : tree if_true = gimple_assign_rhs2 (assign);
2778 203 : tree if_false = gimple_assign_rhs3 (assign);
2779 :
2780 72 : if ((use_cond == op_mask || operand_equal_p (use_cond, op_cond, 0))
2781 203 : && if_true == op_lhs)
2782 : return if_false;
2783 :
2784 72 : if (inverse_conditions_p (use_cond, op_cond) && if_false == op_lhs)
2785 0 : return if_true;
2786 :
2787 : return NULL_TREE;
2788 : }
2789 :
2790 : /* Return true if VALUE is available for use at STMT. SSA_NAMES is
2791 : the set of SSA names defined earlier in STMT's block. */
2792 :
2793 : static bool
2794 131 : value_available_p (gimple *stmt, hash_set<tree_ssa_name_hash> *ssa_names,
2795 : tree value)
2796 : {
2797 131 : if (is_gimple_min_invariant (value))
2798 : return true;
2799 :
2800 95 : if (TREE_CODE (value) == SSA_NAME)
2801 : {
2802 95 : if (SSA_NAME_IS_DEFAULT_DEF (value))
2803 : return true;
2804 :
2805 95 : basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (value));
2806 95 : basic_block use_bb = gimple_bb (stmt);
2807 95 : return (def_bb == use_bb
2808 95 : ? ssa_names->contains (value)
2809 95 : : dominated_by_p (CDI_DOMINATORS, use_bb, def_bb));
2810 : }
2811 :
2812 : return false;
2813 : }
2814 :
2815 : /* Helper function for predicate_statements. STMT is a potentially-trapping
2816 : arithmetic operation that needs to be predicated by MASK, an SSA_NAME that
2817 : has value COND. Return a statement that does so. SSA_NAMES is the set of
2818 : SSA names defined earlier in STMT's block. */
2819 :
2820 : static gimple *
2821 615 : predicate_rhs_code (gimple *stmt, tree mask, tree cond,
2822 : hash_set<tree_ssa_name_hash> *ssa_names)
2823 : {
2824 615 : internal_fn cond_fn;
2825 615 : if (is_gimple_assign (stmt))
2826 : {
2827 507 : tree_code code = gimple_assign_rhs_code (stmt);
2828 507 : cond_fn = get_conditional_internal_fn (code);
2829 : }
2830 108 : else if (tree callee = gimple_call_fndecl (stmt))
2831 : {
2832 108 : auto ifn = associated_internal_fn (callee);
2833 108 : cond_fn = get_conditional_internal_fn (ifn);
2834 : }
2835 : else
2836 : return NULL;
2837 :
2838 615 : if (cond_fn == IFN_LAST)
2839 : {
2840 0 : gcc_assert (!gimple_could_trap_p (stmt));
2841 : return NULL;
2842 : }
2843 :
2844 615 : tree lhs = gimple_get_lhs (stmt);
2845 615 : unsigned int nops = gimple_num_args (stmt) + 1;
2846 :
2847 : /* Construct the arguments to the conditional internal function. */
2848 615 : auto_vec<tree, 8> args;
2849 615 : args.safe_grow (nops + 1, true);
2850 615 : args[0] = mask;
2851 1953 : for (unsigned int i = 0; i < nops - 1; ++i)
2852 1338 : args[i+1] = gimple_arg (stmt, i);
2853 615 : args[nops] = NULL_TREE;
2854 :
2855 : /* Look for uses of the result to see whether they are COND_EXPRs that can
2856 : be folded into the conditional call. */
2857 615 : imm_use_iterator imm_iter;
2858 615 : gimple *use_stmt;
2859 1435 : FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, lhs)
2860 : {
2861 820 : tree new_else = check_redundant_cond_expr (use_stmt, mask, cond, lhs);
2862 820 : if (new_else && value_available_p (stmt, ssa_names, new_else))
2863 : {
2864 110 : if (!args[nops])
2865 110 : args[nops] = new_else;
2866 110 : if (operand_equal_p (new_else, args[nops], 0))
2867 : {
2868 : /* We have:
2869 :
2870 : LHS = IFN_COND (MASK, ..., ELSE);
2871 : X = MASK ? LHS : ELSE;
2872 :
2873 : which makes X equivalent to LHS. */
2874 110 : tree use_lhs = gimple_assign_lhs (use_stmt);
2875 110 : redundant_ssa_names.safe_push (std::make_pair (use_lhs, lhs));
2876 : }
2877 : }
2878 615 : }
2879 615 : if (!args[nops])
2880 1010 : args[nops] = targetm.preferred_else_value (cond_fn, TREE_TYPE (lhs),
2881 505 : nops - 1, &args[1]);
2882 :
2883 : /* Create and insert the call. */
2884 615 : gcall *new_stmt = gimple_build_call_internal_vec (cond_fn, args);
2885 615 : gimple_call_set_lhs (new_stmt, lhs);
2886 615 : gimple_call_set_nothrow (new_stmt, true);
2887 :
2888 615 : return new_stmt;
2889 615 : }
2890 :
2891 : /* Predicate each write to memory in LOOP.
2892 :
2893 : This function transforms control flow constructs containing memory
2894 : writes of the form:
2895 :
2896 : | for (i = 0; i < N; i++)
2897 : | if (cond)
2898 : | A[i] = expr;
2899 :
2900 : into the following form that does not contain control flow:
2901 :
2902 : | for (i = 0; i < N; i++)
2903 : | A[i] = cond ? expr : A[i];
2904 :
2905 : The original CFG looks like this:
2906 :
2907 : | bb_0
2908 : | i = 0
2909 : | end_bb_0
2910 : |
2911 : | bb_1
2912 : | if (i < N) goto bb_5 else goto bb_2
2913 : | end_bb_1
2914 : |
2915 : | bb_2
2916 : | cond = some_computation;
2917 : | if (cond) goto bb_3 else goto bb_4
2918 : | end_bb_2
2919 : |
2920 : | bb_3
2921 : | A[i] = expr;
2922 : | goto bb_4
2923 : | end_bb_3
2924 : |
2925 : | bb_4
2926 : | goto bb_1
2927 : | end_bb_4
2928 :
2929 : insert_gimplified_predicates inserts the computation of the COND
2930 : expression at the beginning of the destination basic block:
2931 :
2932 : | bb_0
2933 : | i = 0
2934 : | end_bb_0
2935 : |
2936 : | bb_1
2937 : | if (i < N) goto bb_5 else goto bb_2
2938 : | end_bb_1
2939 : |
2940 : | bb_2
2941 : | cond = some_computation;
2942 : | if (cond) goto bb_3 else goto bb_4
2943 : | end_bb_2
2944 : |
2945 : | bb_3
2946 : | cond = some_computation;
2947 : | A[i] = expr;
2948 : | goto bb_4
2949 : | end_bb_3
2950 : |
2951 : | bb_4
2952 : | goto bb_1
2953 : | end_bb_4
2954 :
2955 : predicate_statements is then predicating the memory write as follows:
2956 :
2957 : | bb_0
2958 : | i = 0
2959 : | end_bb_0
2960 : |
2961 : | bb_1
2962 : | if (i < N) goto bb_5 else goto bb_2
2963 : | end_bb_1
2964 : |
2965 : | bb_2
2966 : | if (cond) goto bb_3 else goto bb_4
2967 : | end_bb_2
2968 : |
2969 : | bb_3
2970 : | cond = some_computation;
2971 : | A[i] = cond ? expr : A[i];
2972 : | goto bb_4
2973 : | end_bb_3
2974 : |
2975 : | bb_4
2976 : | goto bb_1
2977 : | end_bb_4
2978 :
2979 : and finally combine_blocks removes the basic block boundaries making
2980 : the loop vectorizable:
2981 :
2982 : | bb_0
2983 : | i = 0
2984 : | if (i < N) goto bb_5 else goto bb_1
2985 : | end_bb_0
2986 : |
2987 : | bb_1
2988 : | cond = some_computation;
2989 : | A[i] = cond ? expr : A[i];
2990 : | if (i < N) goto bb_5 else goto bb_4
2991 : | end_bb_1
2992 : |
2993 : | bb_4
2994 : | goto bb_1
2995 : | end_bb_4
2996 : */
2997 :
2998 : static void
2999 11910 : predicate_statements (loop_p loop)
3000 : {
3001 11910 : unsigned int i, orig_loop_num_nodes = loop->num_nodes;
3002 11910 : auto_vec<int, 1> vect_sizes;
3003 11910 : auto_vec<tree, 1> vect_masks;
3004 11910 : hash_set<tree_ssa_name_hash> ssa_names;
3005 :
3006 74511 : for (i = 1; i < orig_loop_num_nodes; i++)
3007 : {
3008 50691 : gimple_stmt_iterator gsi;
3009 50691 : basic_block bb = ifc_bbs[i];
3010 50691 : tree cond = bb_predicate (bb);
3011 50691 : bool swap;
3012 50691 : int index;
3013 :
3014 50691 : if (is_true_predicate (cond))
3015 25143 : continue;
3016 :
3017 25548 : swap = false;
3018 25548 : if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
3019 : {
3020 9700 : swap = true;
3021 9700 : cond = TREE_OPERAND (cond, 0);
3022 : }
3023 :
3024 25548 : vect_sizes.truncate (0);
3025 25548 : vect_masks.truncate (0);
3026 :
3027 198672 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
3028 : {
3029 147576 : gimple *stmt = gsi_stmt (gsi);
3030 147576 : if (!is_gimple_assign (stmt)
3031 147576 : && !gimple_call_builtin_p (stmt))
3032 : ;
3033 90012 : else if (is_false_predicate (cond)
3034 90012 : && gimple_vdef (stmt))
3035 : {
3036 0 : unlink_stmt_vdef (stmt);
3037 0 : gsi_remove (&gsi, true);
3038 0 : release_defs (stmt);
3039 2 : continue;
3040 : }
3041 : /* For now, just drop prefetches. Do it now to remove any possible
3042 : aliasing check failures from the address calculations of the
3043 : prefetch. Vect would be too late in that regard. */
3044 90012 : else if (gimple_call_builtin_p (stmt, BUILT_IN_PREFETCH))
3045 : {
3046 2 : unlink_stmt_vdef (stmt);
3047 2 : gsi_remove (&gsi, true);
3048 2 : release_defs (stmt);
3049 2 : continue;
3050 : }
3051 90010 : else if (gimple_plf (stmt, GF_PLF_2)
3052 90010 : && (is_gimple_assign (stmt)
3053 108 : || (gimple_call_builtin_p (stmt)
3054 108 : && !if_convertible_simdclone_stmt_p (stmt))))
3055 : {
3056 2607 : tree lhs = gimple_get_lhs (stmt);
3057 : /* ?? Assume that calls without an LHS are not data processing
3058 : and so no issues with traps. */
3059 2607 : if (!lhs)
3060 0 : continue;
3061 2607 : tree mask;
3062 2607 : gimple *new_stmt;
3063 2607 : gimple_seq stmts = NULL;
3064 2607 : machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
3065 : /* We checked before setting GF_PLF_2 that an equivalent
3066 : integer mode exists. */
3067 2607 : int bitsize = GET_MODE_BITSIZE (mode).to_constant ();
3068 2607 : if (!vect_sizes.is_empty ()
3069 934 : && (index = mask_exists (bitsize, vect_sizes)) != -1)
3070 : /* Use created mask. */
3071 873 : mask = vect_masks[index];
3072 : else
3073 : {
3074 1734 : if (COMPARISON_CLASS_P (cond))
3075 0 : mask = gimple_build (&stmts, TREE_CODE (cond),
3076 : boolean_type_node,
3077 0 : TREE_OPERAND (cond, 0),
3078 0 : TREE_OPERAND (cond, 1));
3079 : else
3080 : mask = cond;
3081 :
3082 1734 : if (swap)
3083 : {
3084 389 : tree true_val
3085 389 : = constant_boolean_node (true, TREE_TYPE (mask));
3086 389 : mask = gimple_build (&stmts, BIT_XOR_EXPR,
3087 389 : TREE_TYPE (mask), mask, true_val);
3088 : }
3089 1734 : gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
3090 :
3091 : /* Save mask and its size for further use. */
3092 1734 : vect_sizes.safe_push (bitsize);
3093 1734 : vect_masks.safe_push (mask);
3094 : }
3095 2607 : if (gimple_assign_single_p (stmt))
3096 1992 : new_stmt = predicate_load_or_store (&gsi,
3097 : as_a <gassign *> (stmt),
3098 : mask);
3099 : else
3100 615 : new_stmt = predicate_rhs_code (stmt, mask, cond, &ssa_names);
3101 :
3102 2607 : if (new_stmt)
3103 2607 : gsi_replace (&gsi, new_stmt, true);
3104 : }
3105 87403 : else if (gimple_needing_rewrite_undefined (stmt))
3106 18050 : rewrite_to_defined_unconditional (&gsi);
3107 138706 : else if (gimple_vdef (stmt))
3108 : {
3109 1387 : tree lhs = gimple_assign_lhs (stmt);
3110 1387 : tree rhs = gimple_assign_rhs1 (stmt);
3111 1387 : tree type = TREE_TYPE (lhs);
3112 :
3113 1387 : lhs = ifc_temp_var (type, unshare_expr (lhs), &gsi);
3114 1387 : rhs = ifc_temp_var (type, unshare_expr (rhs), &gsi);
3115 1387 : if (swap)
3116 479 : std::swap (lhs, rhs);
3117 1387 : cond = force_gimple_operand_gsi (&gsi, unshare_expr (cond), true,
3118 : NULL_TREE, true, GSI_SAME_STMT);
3119 1387 : rhs = fold_build_cond_expr (type, unshare_expr (cond), rhs, lhs);
3120 1387 : gimple_assign_set_rhs1 (stmt, ifc_temp_var (type, rhs, &gsi));
3121 1387 : update_stmt (stmt);
3122 : }
3123 :
3124 147574 : if (gimple_plf (gsi_stmt (gsi), GF_PLF_2)
3125 147574 : && is_gimple_call (gsi_stmt (gsi)))
3126 : {
3127 : /* Convert functions that have a SIMD clone to IFN_MASK_CALL.
3128 : This will cause the vectorizer to match the "in branch"
3129 : clone variants, and serves to build the mask vector
3130 : in a natural way. */
3131 999 : tree mask = cond;
3132 999 : gcall *call = dyn_cast <gcall *> (gsi_stmt (gsi));
3133 999 : tree orig_fn = gimple_call_fn (call);
3134 999 : int orig_nargs = gimple_call_num_args (call);
3135 999 : auto_vec<tree> args;
3136 999 : args.safe_push (orig_fn);
3137 3012 : for (int i = 0; i < orig_nargs; i++)
3138 1014 : args.safe_push (gimple_call_arg (call, i));
3139 : /* If `swap', we invert the mask used for the if branch for use
3140 : when masking the function call. */
3141 999 : if (swap)
3142 : {
3143 948 : gimple_seq stmts = NULL;
3144 948 : tree true_val
3145 948 : = constant_boolean_node (true, TREE_TYPE (mask));
3146 948 : mask = gimple_build (&stmts, BIT_XOR_EXPR,
3147 948 : TREE_TYPE (mask), mask, true_val);
3148 948 : gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
3149 : }
3150 999 : args.safe_push (mask);
3151 :
3152 : /* Replace the call with a IFN_MASK_CALL that has the extra
3153 : condition parameter. */
3154 999 : gcall *new_call = gimple_build_call_internal_vec (IFN_MASK_CALL,
3155 : args);
3156 999 : gimple_call_set_lhs (new_call, gimple_call_lhs (call));
3157 999 : gsi_replace (&gsi, new_call, true);
3158 999 : }
3159 :
3160 147574 : tree lhs = gimple_get_lhs (gsi_stmt (gsi));
3161 147574 : if (lhs && TREE_CODE (lhs) == SSA_NAME)
3162 87891 : ssa_names.add (lhs);
3163 147574 : gsi_next (&gsi);
3164 : }
3165 51074 : ssa_names.empty ();
3166 : }
3167 11910 : }
3168 :
3169 : /* Remove all GIMPLE_CONDs and GIMPLE_LABELs and GIMPLE_SWITCH of all
3170 : the basic blocks other than the exit and latch of the LOOP. Also
3171 : resets the GIMPLE_DEBUG information. */
3172 :
3173 : static void
3174 25226 : remove_conditions_and_labels (loop_p loop)
3175 : {
3176 25226 : gimple_stmt_iterator gsi;
3177 25226 : unsigned int i;
3178 :
3179 158219 : for (i = 0; i < loop->num_nodes; i++)
3180 : {
3181 132993 : basic_block bb = ifc_bbs[i];
3182 :
3183 132993 : if (bb_with_exit_edge_p (loop, bb)
3184 132993 : || bb == loop->latch)
3185 50452 : continue;
3186 :
3187 702140 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
3188 537058 : switch (gimple_code (gsi_stmt (gsi)))
3189 : {
3190 33331 : case GIMPLE_COND:
3191 33331 : case GIMPLE_LABEL:
3192 33331 : case GIMPLE_SWITCH:
3193 33331 : gsi_remove (&gsi, true);
3194 33331 : break;
3195 :
3196 340301 : case GIMPLE_DEBUG:
3197 : /* ??? Should there be conditional GIMPLE_DEBUG_BINDs? */
3198 340301 : if (gimple_debug_bind_p (gsi_stmt (gsi)))
3199 : {
3200 271736 : gimple_debug_bind_reset_value (gsi_stmt (gsi));
3201 271736 : update_stmt (gsi_stmt (gsi));
3202 : }
3203 340301 : gsi_next (&gsi);
3204 340301 : break;
3205 :
3206 163426 : default:
3207 163426 : gsi_next (&gsi);
3208 : }
3209 : }
3210 25226 : }
3211 :
3212 : /* Combine all the basic blocks from LOOP into one or two super basic
3213 : blocks. Replace PHI nodes with conditional modify expressions. */
3214 :
3215 : static void
3216 25226 : combine_blocks (class loop *loop)
3217 : {
3218 25226 : basic_block bb, exit_bb, merge_target_bb;
3219 25226 : unsigned int orig_loop_num_nodes = loop->num_nodes;
3220 25226 : unsigned int i;
3221 25226 : edge e;
3222 25226 : edge_iterator ei;
3223 :
3224 : /* Reset flow-sensitive info before predicating stmts or PHIs we
3225 : might fold. */
3226 158219 : for (i = 0; i < orig_loop_num_nodes; i++)
3227 : {
3228 132993 : bb = ifc_bbs[i];
3229 132993 : if (is_predicated (bb))
3230 : {
3231 53192 : for (auto gsi = gsi_start_phis (bb);
3232 54746 : !gsi_end_p (gsi); gsi_next (&gsi))
3233 1554 : reset_flow_sensitive_info (gimple_phi_result (*gsi));
3234 225191 : for (auto gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3235 : {
3236 118807 : gimple *stmt = gsi_stmt (gsi);
3237 118807 : ssa_op_iter i;
3238 118807 : tree op;
3239 169323 : FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF)
3240 50516 : reset_flow_sensitive_info (op);
3241 : }
3242 : }
3243 : }
3244 :
3245 25226 : remove_conditions_and_labels (loop);
3246 25226 : insert_gimplified_predicates (loop);
3247 25226 : predicate_all_scalar_phis (loop);
3248 :
3249 25226 : if (need_to_predicate || need_to_rewrite_undefined)
3250 11910 : predicate_statements (loop);
3251 :
3252 : /* Merge basic blocks. */
3253 25226 : exit_bb = single_exit (loop)->src;
3254 25226 : gcc_assert (exit_bb != loop->latch);
3255 158219 : for (i = 0; i < orig_loop_num_nodes; i++)
3256 : {
3257 132993 : bb = ifc_bbs[i];
3258 132993 : free_bb_predicate (bb);
3259 : }
3260 :
3261 25226 : merge_target_bb = loop->header;
3262 :
3263 : /* Get at the virtual def valid for uses starting at the first block
3264 : we merge into the header. Without a virtual PHI the loop has the
3265 : same virtual use on all stmts. */
3266 25226 : gphi *vphi = get_virtual_phi (loop->header);
3267 25226 : tree last_vdef = NULL_TREE;
3268 25226 : if (vphi)
3269 : {
3270 13524 : last_vdef = gimple_phi_result (vphi);
3271 27048 : for (gimple_stmt_iterator gsi = gsi_start_bb (loop->header);
3272 233153 : ! gsi_end_p (gsi); gsi_next (&gsi))
3273 281949 : if (gimple_vdef (gsi_stmt (gsi)))
3274 219629 : last_vdef = gimple_vdef (gsi_stmt (gsi));
3275 : }
3276 132993 : for (i = 1; i < orig_loop_num_nodes; i++)
3277 : {
3278 107767 : gimple_stmt_iterator gsi;
3279 107767 : gimple_stmt_iterator last;
3280 :
3281 107767 : bb = ifc_bbs[i];
3282 :
3283 107767 : if (bb == exit_bb || bb == loop->latch)
3284 50452 : continue;
3285 :
3286 : /* We release virtual PHIs late because we have to propagate them
3287 : out using the current VUSE. The def might be the one used
3288 : after the loop. */
3289 57315 : vphi = get_virtual_phi (bb);
3290 57315 : if (vphi)
3291 : {
3292 : /* When there's just loads inside the loop a stray virtual
3293 : PHI merging the uses can appear, update last_vdef from
3294 : it. */
3295 675 : if (!last_vdef)
3296 0 : last_vdef = gimple_phi_arg_def (vphi, 0);
3297 675 : imm_use_iterator iter;
3298 675 : use_operand_p use_p;
3299 675 : gimple *use_stmt;
3300 2360 : FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_phi_result (vphi))
3301 : {
3302 3376 : FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
3303 1688 : SET_USE (use_p, last_vdef);
3304 675 : }
3305 675 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (vphi)))
3306 0 : SSA_NAME_OCCURS_IN_ABNORMAL_PHI (last_vdef) = 1;
3307 675 : gsi = gsi_for_stmt (vphi);
3308 675 : remove_phi_node (&gsi, true);
3309 : }
3310 :
3311 : /* Make stmts member of loop->header and clear range info from all stmts
3312 : in BB which is now no longer executed conditional on a predicate we
3313 : could have derived it from. */
3314 376633 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3315 : {
3316 262003 : gimple *stmt = gsi_stmt (gsi);
3317 262003 : gimple_set_bb (stmt, merge_target_bb);
3318 : /* Update virtual operands. */
3319 262003 : if (last_vdef)
3320 : {
3321 202145 : use_operand_p use_p = ssa_vuse_operand (stmt);
3322 14324 : if (use_p
3323 14324 : && USE_FROM_PTR (use_p) != last_vdef)
3324 522 : SET_USE (use_p, last_vdef);
3325 608251 : if (gimple_vdef (stmt))
3326 : last_vdef = gimple_vdef (stmt);
3327 : }
3328 : else
3329 : /* If this is the first load we arrive at update last_vdef
3330 : so we handle stray PHIs correctly. */
3331 302497 : last_vdef = gimple_vuse (stmt);
3332 : }
3333 :
3334 : /* Update stmt list. */
3335 57315 : last = gsi_last_bb (merge_target_bb);
3336 114630 : gsi_insert_seq_after_without_update (&last, bb_seq (bb), GSI_NEW_STMT);
3337 57315 : set_bb_seq (bb, NULL);
3338 : }
3339 :
3340 : /* Fixup virtual operands in the exit block. */
3341 25226 : if (exit_bb
3342 25226 : && exit_bb != loop->header)
3343 : {
3344 : /* We release virtual PHIs late because we have to propagate them
3345 : out using the current VUSE. The def might be the one used
3346 : after the loop. */
3347 25226 : vphi = get_virtual_phi (exit_bb);
3348 25226 : if (vphi)
3349 : {
3350 : /* When there's just loads inside the loop a stray virtual
3351 : PHI merging the uses can appear, update last_vdef from
3352 : it. */
3353 1673 : if (!last_vdef)
3354 0 : last_vdef = gimple_phi_arg_def (vphi, 0);
3355 1673 : imm_use_iterator iter;
3356 1673 : use_operand_p use_p;
3357 1673 : gimple *use_stmt;
3358 5013 : FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_phi_result (vphi))
3359 : {
3360 6680 : FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
3361 3340 : SET_USE (use_p, last_vdef);
3362 1673 : }
3363 1673 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (vphi)))
3364 0 : SSA_NAME_OCCURS_IN_ABNORMAL_PHI (last_vdef) = 1;
3365 1673 : gimple_stmt_iterator gsi = gsi_for_stmt (vphi);
3366 1673 : remove_phi_node (&gsi, true);
3367 : }
3368 : }
3369 :
3370 : /* Now remove all the edges in the loop, except for those from the exit
3371 : block and delete the blocks we elided. */
3372 132993 : for (i = 1; i < orig_loop_num_nodes; i++)
3373 : {
3374 107767 : bb = ifc_bbs[i];
3375 :
3376 248483 : for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei));)
3377 : {
3378 140716 : if (e->src == exit_bb)
3379 25226 : ei_next (&ei);
3380 : else
3381 115490 : remove_edge (e);
3382 : }
3383 : }
3384 132993 : for (i = 1; i < orig_loop_num_nodes; i++)
3385 : {
3386 107767 : bb = ifc_bbs[i];
3387 :
3388 107767 : if (bb == exit_bb || bb == loop->latch)
3389 50452 : continue;
3390 :
3391 57315 : delete_basic_block (bb);
3392 : }
3393 :
3394 : /* Re-connect the exit block. */
3395 25226 : if (exit_bb != NULL)
3396 : {
3397 25226 : if (exit_bb != loop->header)
3398 : {
3399 : /* Connect this node to loop header. */
3400 25226 : make_single_succ_edge (loop->header, exit_bb, EDGE_FALLTHRU);
3401 25226 : set_immediate_dominator (CDI_DOMINATORS, exit_bb, loop->header);
3402 : }
3403 :
3404 : /* Redirect non-exit edges to loop->latch. */
3405 75678 : FOR_EACH_EDGE (e, ei, exit_bb->succs)
3406 : {
3407 50452 : if (!loop_exit_edge_p (loop, e))
3408 25226 : redirect_edge_and_branch (e, loop->latch);
3409 : }
3410 25226 : set_immediate_dominator (CDI_DOMINATORS, loop->latch, exit_bb);
3411 : }
3412 : else
3413 : {
3414 : /* If the loop does not have an exit, reconnect header and latch. */
3415 0 : make_edge (loop->header, loop->latch, EDGE_FALLTHRU);
3416 0 : set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header);
3417 : }
3418 :
3419 : /* If possible, merge loop header to the block with the exit edge.
3420 : This reduces the number of basic blocks to two, to please the
3421 : vectorizer that handles only loops with two nodes. */
3422 25226 : if (exit_bb
3423 25226 : && exit_bb != loop->header)
3424 : {
3425 25226 : if (can_merge_blocks_p (loop->header, exit_bb))
3426 25224 : merge_blocks (loop->header, exit_bb);
3427 : }
3428 :
3429 25226 : free (ifc_bbs);
3430 25226 : ifc_bbs = NULL;
3431 25226 : }
3432 :
3433 : /* Version LOOP before if-converting it; the original loop
3434 : will be if-converted, the new copy of the loop will not,
3435 : and the LOOP_VECTORIZED internal call will be guarding which
3436 : loop to execute. The vectorizer pass will fold this
3437 : internal call into either true or false.
3438 :
3439 : Note that this function intentionally invalidates profile. Both edges
3440 : out of LOOP_VECTORIZED must have 100% probability so the profile remains
3441 : consistent after the condition is folded in the vectorizer. */
3442 :
3443 : static class loop *
3444 25491 : version_loop_for_if_conversion (class loop *loop, vec<gimple *> *preds)
3445 : {
3446 25491 : basic_block cond_bb;
3447 25491 : tree cond = make_ssa_name (boolean_type_node);
3448 25491 : class loop *new_loop;
3449 25491 : gimple *g;
3450 25491 : gimple_stmt_iterator gsi;
3451 25491 : unsigned int save_length = 0;
3452 :
3453 25491 : g = gimple_build_call_internal (IFN_LOOP_VECTORIZED, 2,
3454 25491 : build_int_cst (integer_type_node, loop->num),
3455 : integer_zero_node);
3456 25491 : gimple_call_set_lhs (g, cond);
3457 :
3458 25491 : void **saved_preds = NULL;
3459 25491 : if (any_complicated_phi || need_to_predicate)
3460 : {
3461 : /* Save BB->aux around loop_version as that uses the same field. */
3462 3386 : save_length = loop->inner ? loop->inner->num_nodes : loop->num_nodes;
3463 3386 : saved_preds = XALLOCAVEC (void *, save_length);
3464 25807 : for (unsigned i = 0; i < save_length; i++)
3465 22421 : saved_preds[i] = ifc_bbs[i]->aux;
3466 : }
3467 :
3468 25491 : initialize_original_copy_tables ();
3469 : /* At this point we invalidate profile consistency until IFN_LOOP_VECTORIZED
3470 : is re-merged in the vectorizer. */
3471 25491 : new_loop = loop_version (loop, cond, &cond_bb,
3472 : profile_probability::always (),
3473 : profile_probability::always (),
3474 : profile_probability::always (),
3475 : profile_probability::always (), true);
3476 25491 : free_original_copy_tables ();
3477 :
3478 25491 : if (any_complicated_phi || need_to_predicate)
3479 25807 : for (unsigned i = 0; i < save_length; i++)
3480 22421 : ifc_bbs[i]->aux = saved_preds[i];
3481 :
3482 25491 : if (new_loop == NULL)
3483 : return NULL;
3484 :
3485 25491 : new_loop->dont_vectorize = true;
3486 25491 : new_loop->force_vectorize = false;
3487 25491 : gsi = gsi_last_bb (cond_bb);
3488 25491 : gimple_call_set_arg (g, 1, build_int_cst (integer_type_node, new_loop->num));
3489 25491 : if (preds)
3490 25491 : preds->safe_push (g);
3491 25491 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
3492 25491 : update_ssa (TODO_update_ssa_no_phi);
3493 25491 : return new_loop;
3494 : }
3495 :
3496 : /* Return true when LOOP satisfies the follow conditions that will
3497 : allow it to be recognized by the vectorizer for outer-loop
3498 : vectorization:
3499 : - The loop is not the root node of the loop tree.
3500 : - The loop has exactly one inner loop.
3501 : - The loop has a single exit.
3502 : - The loop header has a single successor, which is the inner
3503 : loop header.
3504 : - Each of the inner and outer loop latches have a single
3505 : predecessor.
3506 : - The loop exit block has a single predecessor, which is the
3507 : inner loop's exit block. */
3508 :
3509 : static bool
3510 25491 : versionable_outer_loop_p (class loop *loop)
3511 : {
3512 25491 : if (!loop_outer (loop)
3513 8010 : || loop->dont_vectorize
3514 7024 : || !loop->inner
3515 7024 : || loop->inner->next
3516 2911 : || !single_exit (loop)
3517 2248 : || !single_succ_p (loop->header)
3518 936 : || single_succ (loop->header) != loop->inner->header
3519 936 : || !single_pred_p (loop->latch)
3520 26427 : || !single_pred_p (loop->inner->latch))
3521 : return false;
3522 :
3523 936 : basic_block outer_exit = single_pred (loop->latch);
3524 936 : basic_block inner_exit = single_pred (loop->inner->latch);
3525 :
3526 1863 : if (!single_pred_p (outer_exit) || single_pred (outer_exit) != inner_exit)
3527 : return false;
3528 :
3529 926 : if (dump_file)
3530 0 : fprintf (dump_file, "Found vectorizable outer loop for versioning\n");
3531 :
3532 : return true;
3533 : }
3534 :
3535 : /* Performs splitting of critical edges. Skip splitting and return false
3536 : if LOOP will not be converted because:
3537 :
3538 : - LOOP is not well formed.
3539 : - LOOP has PHI with more than MAX_PHI_ARG_NUM arguments.
3540 :
3541 : Last restriction is valid only if AGGRESSIVE_IF_CONV is false. */
3542 :
3543 : static bool
3544 316550 : ifcvt_split_critical_edges (class loop *loop, bool aggressive_if_conv)
3545 : {
3546 316550 : basic_block *body;
3547 316550 : basic_block bb;
3548 316550 : unsigned int num = loop->num_nodes;
3549 316550 : unsigned int i;
3550 316550 : edge e;
3551 316550 : edge_iterator ei;
3552 316550 : auto_vec<edge> critical_edges;
3553 :
3554 : /* Loop is not well formed. */
3555 316550 : if (loop->inner)
3556 : return false;
3557 :
3558 228808 : body = get_loop_body (loop);
3559 1840723 : for (i = 0; i < num; i++)
3560 : {
3561 1389529 : bb = body[i];
3562 1389529 : if (!aggressive_if_conv
3563 1381377 : && phi_nodes (bb)
3564 1821146 : && EDGE_COUNT (bb->preds) > MAX_PHI_ARG_NUM)
3565 : {
3566 6422 : if (dump_file && (dump_flags & TDF_DETAILS))
3567 0 : fprintf (dump_file,
3568 : "BB %d has complicated PHI with more than %u args.\n",
3569 : bb->index, MAX_PHI_ARG_NUM);
3570 :
3571 6422 : free (body);
3572 6422 : return false;
3573 : }
3574 1383107 : if (bb == loop->latch || bb_with_exit_edge_p (loop, bb))
3575 787715 : continue;
3576 :
3577 : /* Skip basic blocks not ending with conditional branch. */
3578 1427570 : if (!safe_is_a <gcond *> (*gsi_last_bb (bb))
3579 595392 : && !safe_is_a <gswitch *> (*gsi_last_bb (bb)))
3580 330358 : continue;
3581 :
3582 806950 : FOR_EACH_EDGE (e, ei, bb->succs)
3583 664069 : if (EDGE_CRITICAL_P (e) && e->dest->loop_father == loop)
3584 122153 : critical_edges.safe_push (e);
3585 : }
3586 222386 : free (body);
3587 :
3588 434879 : while (critical_edges.length () > 0)
3589 : {
3590 118329 : e = critical_edges.pop ();
3591 : /* Don't split if bb can be predicated along non-critical edge. */
3592 118329 : if (EDGE_COUNT (e->dest->preds) > 2 || all_preds_critical_p (e->dest))
3593 56070 : split_edge (e);
3594 : }
3595 :
3596 : return true;
3597 316550 : }
3598 :
3599 : /* Delete redundant statements produced by predication which prevents
3600 : loop vectorization. */
3601 :
3602 : static void
3603 25491 : ifcvt_local_dce (class loop *loop)
3604 : {
3605 25491 : gimple *stmt;
3606 25491 : gimple *stmt1;
3607 25491 : gimple *phi;
3608 25491 : gimple_stmt_iterator gsi;
3609 25491 : auto_vec<gimple *> worklist;
3610 25491 : enum gimple_code code;
3611 25491 : use_operand_p use_p;
3612 25491 : imm_use_iterator imm_iter;
3613 :
3614 : /* The loop has a single BB only. */
3615 25491 : basic_block bb = loop->header;
3616 25491 : tree latch_vdef = NULL_TREE;
3617 :
3618 25491 : worklist.create (64);
3619 : /* Consider all phi as live statements. */
3620 103039 : for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3621 : {
3622 77548 : phi = gsi_stmt (gsi);
3623 77548 : gimple_set_plf (phi, GF_PLF_2, true);
3624 77548 : worklist.safe_push (phi);
3625 168818 : if (virtual_operand_p (gimple_phi_result (phi)))
3626 13722 : latch_vdef = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
3627 : }
3628 : /* Consider load/store statements, CALL and COND as live. */
3629 861887 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3630 : {
3631 810905 : stmt = gsi_stmt (gsi);
3632 810905 : if (is_gimple_debug (stmt))
3633 : {
3634 436636 : gimple_set_plf (stmt, GF_PLF_2, true);
3635 436636 : continue;
3636 : }
3637 374269 : if (gimple_store_p (stmt) || gimple_assign_load_p (stmt))
3638 : {
3639 58084 : gimple_set_plf (stmt, GF_PLF_2, true);
3640 58084 : worklist.safe_push (stmt);
3641 58084 : continue;
3642 : }
3643 316185 : code = gimple_code (stmt);
3644 316185 : if (code == GIMPLE_COND || code == GIMPLE_CALL || code == GIMPLE_SWITCH)
3645 : {
3646 30941 : gimple_set_plf (stmt, GF_PLF_2, true);
3647 30941 : worklist.safe_push (stmt);
3648 30941 : continue;
3649 : }
3650 285244 : gimple_set_plf (stmt, GF_PLF_2, false);
3651 :
3652 285244 : if (code == GIMPLE_ASSIGN)
3653 : {
3654 285235 : tree lhs = gimple_assign_lhs (stmt);
3655 661237 : FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
3656 : {
3657 395674 : stmt1 = USE_STMT (use_p);
3658 395674 : if (!is_gimple_debug (stmt1) && gimple_bb (stmt1) != bb)
3659 : {
3660 19672 : gimple_set_plf (stmt, GF_PLF_2, true);
3661 19672 : worklist.safe_push (stmt);
3662 19672 : break;
3663 : }
3664 285235 : }
3665 : }
3666 : }
3667 : /* Propagate liveness through arguments of live stmt. */
3668 465333 : while (worklist.length () > 0)
3669 : {
3670 439842 : ssa_op_iter iter;
3671 439842 : use_operand_p use_p;
3672 439842 : tree use;
3673 :
3674 439842 : stmt = worklist.pop ();
3675 1548084 : FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
3676 : {
3677 668400 : use = USE_FROM_PTR (use_p);
3678 668400 : if (TREE_CODE (use) != SSA_NAME)
3679 42674 : continue;
3680 625726 : stmt1 = SSA_NAME_DEF_STMT (use);
3681 625726 : if (gimple_bb (stmt1) != bb || gimple_plf (stmt1, GF_PLF_2))
3682 372129 : continue;
3683 253597 : gimple_set_plf (stmt1, GF_PLF_2, true);
3684 253597 : worklist.safe_push (stmt1);
3685 : }
3686 : }
3687 : /* Delete dead statements. */
3688 25491 : gsi = gsi_last_bb (bb);
3689 836396 : while (!gsi_end_p (gsi))
3690 : {
3691 810905 : gimple_stmt_iterator gsiprev = gsi;
3692 810905 : gsi_prev (&gsiprev);
3693 810905 : stmt = gsi_stmt (gsi);
3694 810905 : if (!gimple_has_volatile_ops (stmt)
3695 810758 : && gimple_store_p (stmt)
3696 374403 : && gimple_vdef (stmt))
3697 : {
3698 12815 : tree lhs = gimple_get_lhs (stmt);
3699 12815 : ao_ref write;
3700 12815 : ao_ref_init (&write, lhs);
3701 :
3702 12815 : if (dse_classify_store (&write, stmt, false, NULL, NULL, latch_vdef)
3703 : == DSE_STORE_DEAD)
3704 270 : delete_dead_or_redundant_assignment (&gsi, "dead");
3705 12815 : gsi = gsiprev;
3706 12815 : continue;
3707 12815 : }
3708 :
3709 798090 : if (gimple_plf (stmt, GF_PLF_2))
3710 : {
3711 786115 : gsi = gsiprev;
3712 786115 : continue;
3713 : }
3714 11975 : if (dump_file && (dump_flags & TDF_DETAILS))
3715 : {
3716 16 : fprintf (dump_file, "Delete dead stmt in bb#%d\n", bb->index);
3717 16 : print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
3718 : }
3719 11975 : gsi_remove (&gsi, true);
3720 11975 : release_defs (stmt);
3721 11975 : gsi = gsiprev;
3722 : }
3723 25491 : }
3724 :
3725 : /* Return true if VALUE is already available on edge PE. */
3726 :
3727 : static bool
3728 246047 : ifcvt_available_on_edge_p (edge pe, tree value)
3729 : {
3730 246047 : if (is_gimple_min_invariant (value))
3731 : return true;
3732 :
3733 239440 : if (TREE_CODE (value) == SSA_NAME)
3734 : {
3735 238228 : basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (value));
3736 238228 : if (!def_bb || dominated_by_p (CDI_DOMINATORS, pe->dest, def_bb))
3737 26619 : return true;
3738 : }
3739 :
3740 : return false;
3741 : }
3742 :
3743 : /* Return true if STMT can be hoisted from if-converted loop LOOP to
3744 : edge PE. */
3745 :
3746 : static bool
3747 798660 : ifcvt_can_hoist (class loop *loop, edge pe, gimple *stmt)
3748 : {
3749 798660 : if (auto *call = dyn_cast<gcall *> (stmt))
3750 : {
3751 5456 : if (gimple_call_internal_p (call)
3752 5456 : && internal_fn_mask_index (gimple_call_internal_fn (call)) >= 0)
3753 : return false;
3754 : }
3755 793204 : else if (auto *assign = dyn_cast<gassign *> (stmt))
3756 : {
3757 390217 : if (gimple_assign_rhs_code (assign) == COND_EXPR)
3758 : return false;
3759 : }
3760 : else
3761 : return false;
3762 :
3763 287582 : if (gimple_has_side_effects (stmt)
3764 286404 : || gimple_could_trap_p (stmt)
3765 225654 : || stmt_could_throw_p (cfun, stmt)
3766 225652 : || gimple_vdef (stmt)
3767 512734 : || gimple_vuse (stmt))
3768 : return false;
3769 :
3770 224223 : int num_args = gimple_num_args (stmt);
3771 224223 : if (pe != loop_preheader_edge (loop))
3772 : {
3773 250936 : for (int i = 0; i < num_args; ++i)
3774 246047 : if (!ifcvt_available_on_edge_p (pe, gimple_arg (stmt, i)))
3775 : return false;
3776 : }
3777 : else
3778 : {
3779 8162 : for (int i = 0; i < num_args; ++i)
3780 7934 : if (!expr_invariant_in_loop_p (loop, gimple_arg (stmt, i)))
3781 : return false;
3782 : }
3783 :
3784 : return true;
3785 : }
3786 :
3787 : /* Hoist invariant statements from LOOP to edge PE. */
3788 :
3789 : static void
3790 25491 : ifcvt_hoist_invariants (class loop *loop, edge pe)
3791 : {
3792 : /* Only hoist from the now unconditionally executed part of the loop. */
3793 25491 : basic_block bb = loop->header;
3794 25491 : gimple_stmt_iterator hoist_gsi = {};
3795 849642 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
3796 : {
3797 798660 : gimple *stmt = gsi_stmt (gsi);
3798 798660 : if (ifcvt_can_hoist (loop, pe, stmt))
3799 : {
3800 : /* Once we've hoisted one statement, insert other statements
3801 : after it. */
3802 5117 : gsi_remove (&gsi, false);
3803 5117 : if (hoist_gsi.ptr)
3804 2742 : gsi_insert_after (&hoist_gsi, stmt, GSI_NEW_STMT);
3805 : else
3806 : {
3807 2375 : gsi_insert_on_edge_immediate (pe, stmt);
3808 2375 : hoist_gsi = gsi_for_stmt (stmt);
3809 : }
3810 5117 : continue;
3811 : }
3812 793543 : gsi_next (&gsi);
3813 : }
3814 25491 : }
3815 :
3816 : /* Returns the DECL_FIELD_BIT_OFFSET of the bitfield accesse in stmt iff its
3817 : type mode is not BLKmode. If BITPOS is not NULL it will hold the poly_int64
3818 : value of the DECL_FIELD_BIT_OFFSET of the bitfield access and STRUCT_EXPR,
3819 : if not NULL, will hold the tree representing the base struct of this
3820 : bitfield. */
3821 :
3822 : static tree
3823 1251 : get_bitfield_rep (gassign *stmt, bool write, tree *bitpos,
3824 : tree *struct_expr)
3825 : {
3826 1251 : tree comp_ref = write ? gimple_assign_lhs (stmt)
3827 384 : : gimple_assign_rhs1 (stmt);
3828 :
3829 1251 : tree field_decl = TREE_OPERAND (comp_ref, 1);
3830 1251 : tree ref_offset = component_ref_field_offset (comp_ref);
3831 1251 : tree rep_decl = DECL_BIT_FIELD_REPRESENTATIVE (field_decl);
3832 :
3833 : /* Bail out if the representative is not a suitable type for a scalar
3834 : register variable. */
3835 1251 : if (!is_gimple_reg_type (TREE_TYPE (rep_decl)))
3836 : return NULL_TREE;
3837 :
3838 : /* Bail out if the DECL_SIZE of the field_decl isn't the same as the BF's
3839 : precision. */
3840 1236 : unsigned HOST_WIDE_INT bf_prec
3841 1236 : = TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (stmt)));
3842 1236 : if (compare_tree_int (DECL_SIZE (field_decl), bf_prec) != 0)
3843 : return NULL_TREE;
3844 :
3845 1236 : if (TREE_CODE (DECL_FIELD_OFFSET (rep_decl)) != INTEGER_CST
3846 1236 : || TREE_CODE (ref_offset) != INTEGER_CST)
3847 : {
3848 2 : if (dump_file && (dump_flags & TDF_DETAILS))
3849 2 : fprintf (dump_file, "\t Bitfield NOT OK to lower,"
3850 : " offset is non-constant.\n");
3851 : return NULL_TREE;
3852 : }
3853 :
3854 1234 : if (struct_expr)
3855 617 : *struct_expr = TREE_OPERAND (comp_ref, 0);
3856 :
3857 1234 : if (bitpos)
3858 : {
3859 : /* To calculate the bitposition of the BITFIELD_REF we have to determine
3860 : where our bitfield starts in relation to the container REP_DECL. The
3861 : DECL_FIELD_OFFSET of the original bitfield's member FIELD_DECL tells
3862 : us how many bytes from the start of the structure there are until the
3863 : start of the group of bitfield members the FIELD_DECL belongs to,
3864 : whereas DECL_FIELD_BIT_OFFSET will tell us how many bits from that
3865 : position our actual bitfield member starts. For the container
3866 : REP_DECL adding DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET will tell
3867 : us the distance between the start of the structure and the start of
3868 : the container, though the first is in bytes and the later other in
3869 : bits. With this in mind we calculate the bit position of our new
3870 : BITFIELD_REF by subtracting the number of bits between the start of
3871 : the structure and the container from the number of bits from the start
3872 : of the structure and the actual bitfield member. */
3873 617 : tree bf_pos = fold_build2 (MULT_EXPR, bitsizetype,
3874 : ref_offset,
3875 : build_int_cst (bitsizetype, BITS_PER_UNIT));
3876 617 : bf_pos = fold_build2 (PLUS_EXPR, bitsizetype, bf_pos,
3877 : DECL_FIELD_BIT_OFFSET (field_decl));
3878 617 : tree rep_pos = fold_build2 (MULT_EXPR, bitsizetype,
3879 : DECL_FIELD_OFFSET (rep_decl),
3880 : build_int_cst (bitsizetype, BITS_PER_UNIT));
3881 617 : rep_pos = fold_build2 (PLUS_EXPR, bitsizetype, rep_pos,
3882 : DECL_FIELD_BIT_OFFSET (rep_decl));
3883 :
3884 617 : *bitpos = fold_build2 (MINUS_EXPR, bitsizetype, bf_pos, rep_pos);
3885 : }
3886 :
3887 : return rep_decl;
3888 :
3889 : }
3890 :
3891 : /* Lowers the bitfield described by DATA.
3892 : For a write like:
3893 :
3894 : struct.bf = _1;
3895 :
3896 : lower to:
3897 :
3898 : __ifc_1 = struct.<representative>;
3899 : __ifc_2 = BIT_INSERT_EXPR (__ifc_1, _1, bitpos);
3900 : struct.<representative> = __ifc_2;
3901 :
3902 : For a read:
3903 :
3904 : _1 = struct.bf;
3905 :
3906 : lower to:
3907 :
3908 : __ifc_1 = struct.<representative>;
3909 : _1 = BIT_FIELD_REF (__ifc_1, bitsize, bitpos);
3910 :
3911 : where representative is a legal load that contains the bitfield value,
3912 : bitsize is the size of the bitfield and bitpos the offset to the start of
3913 : the bitfield within the representative. */
3914 :
3915 : static void
3916 617 : lower_bitfield (gassign *stmt, bool write)
3917 : {
3918 617 : tree struct_expr;
3919 617 : tree bitpos;
3920 617 : tree rep_decl = get_bitfield_rep (stmt, write, &bitpos, &struct_expr);
3921 617 : tree rep_type = TREE_TYPE (rep_decl);
3922 617 : tree bf_type = TREE_TYPE (gimple_assign_lhs (stmt));
3923 :
3924 617 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
3925 617 : if (dump_file && (dump_flags & TDF_DETAILS))
3926 : {
3927 9 : fprintf (dump_file, "Lowering:\n");
3928 9 : print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
3929 9 : fprintf (dump_file, "to:\n");
3930 : }
3931 :
3932 : /* REP_COMP_REF is a COMPONENT_REF for the representative. NEW_VAL is it's
3933 : defining SSA_NAME. */
3934 617 : tree rep_comp_ref = build3 (COMPONENT_REF, rep_type, struct_expr, rep_decl,
3935 : NULL_TREE);
3936 617 : tree new_val = ifc_temp_var (rep_type, rep_comp_ref, &gsi);
3937 :
3938 617 : if (dump_file && (dump_flags & TDF_DETAILS))
3939 9 : print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (new_val), 0, TDF_SLIM);
3940 :
3941 617 : if (write)
3942 : {
3943 429 : new_val = ifc_temp_var (rep_type,
3944 : build3 (BIT_INSERT_EXPR, rep_type, new_val,
3945 : unshare_expr (gimple_assign_rhs1 (stmt)),
3946 : bitpos), &gsi);
3947 :
3948 429 : if (dump_file && (dump_flags & TDF_DETAILS))
3949 0 : print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (new_val), 0, TDF_SLIM);
3950 :
3951 429 : gimple *new_stmt = gimple_build_assign (unshare_expr (rep_comp_ref),
3952 : new_val);
3953 429 : gimple_move_vops (new_stmt, stmt);
3954 429 : gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
3955 :
3956 429 : if (dump_file && (dump_flags & TDF_DETAILS))
3957 0 : print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
3958 : }
3959 : else
3960 : {
3961 188 : tree bfr = build3 (BIT_FIELD_REF, bf_type, new_val,
3962 188 : build_int_cst (bitsizetype, TYPE_PRECISION (bf_type)),
3963 : bitpos);
3964 188 : new_val = ifc_temp_var (bf_type, bfr, &gsi);
3965 :
3966 188 : gimple *new_stmt = gimple_build_assign (gimple_assign_lhs (stmt),
3967 : new_val);
3968 188 : gimple_move_vops (new_stmt, stmt);
3969 188 : gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
3970 :
3971 188 : if (dump_file && (dump_flags & TDF_DETAILS))
3972 9 : print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
3973 : }
3974 :
3975 617 : gsi_remove (&gsi, true);
3976 617 : }
3977 :
3978 : /* Return TRUE if there are bitfields to lower in this LOOP. Fill TO_LOWER
3979 : with data structures representing these bitfields. */
3980 :
3981 : static bool
3982 241654 : bitfields_to_lower_p (class loop *loop,
3983 : vec <gassign *> &reads_to_lower,
3984 : vec <gassign *> &writes_to_lower)
3985 : {
3986 241654 : gimple_stmt_iterator gsi;
3987 :
3988 241654 : if (dump_file && (dump_flags & TDF_DETAILS))
3989 : {
3990 28 : fprintf (dump_file, "Analyzing loop %d for bitfields:\n", loop->num);
3991 : }
3992 :
3993 1015544 : for (unsigned i = 0; i < loop->num_nodes; ++i)
3994 : {
3995 773911 : basic_block bb = ifc_bbs[i];
3996 6735047 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3997 : {
3998 5187246 : gassign *stmt = dyn_cast<gassign*> (gsi_stmt (gsi));
3999 5187246 : if (!stmt)
4000 5060591 : continue;
4001 :
4002 2056714 : tree op = gimple_assign_lhs (stmt);
4003 2056714 : bool write = TREE_CODE (op) == COMPONENT_REF;
4004 :
4005 2056714 : if (!write)
4006 2025051 : op = gimple_assign_rhs1 (stmt);
4007 :
4008 2056714 : if (TREE_CODE (op) != COMPONENT_REF)
4009 1930059 : continue;
4010 :
4011 126655 : if (DECL_BIT_FIELD_TYPE (TREE_OPERAND (op, 1)))
4012 : {
4013 638 : if (dump_file && (dump_flags & TDF_DETAILS))
4014 11 : print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
4015 :
4016 638 : if (TREE_THIS_VOLATILE (op))
4017 : {
4018 4 : if (dump_file && (dump_flags & TDF_DETAILS))
4019 0 : fprintf (dump_file, "\t Bitfield NO OK to lower,"
4020 : " the access is volatile.\n");
4021 21 : return false;
4022 : }
4023 :
4024 634 : if (!INTEGRAL_TYPE_P (TREE_TYPE (op)))
4025 : {
4026 0 : if (dump_file && (dump_flags & TDF_DETAILS))
4027 0 : fprintf (dump_file, "\t Bitfield NO OK to lower,"
4028 : " field type is not Integral.\n");
4029 : return false;
4030 : }
4031 :
4032 634 : if (!get_bitfield_rep (stmt, write, NULL, NULL))
4033 : {
4034 17 : if (dump_file && (dump_flags & TDF_DETAILS))
4035 2 : fprintf (dump_file, "\t Bitfield NOT OK to lower,"
4036 : " representative is BLKmode.\n");
4037 : return false;
4038 : }
4039 :
4040 617 : if (dump_file && (dump_flags & TDF_DETAILS))
4041 9 : fprintf (dump_file, "\tBitfield OK to lower.\n");
4042 617 : if (write)
4043 429 : writes_to_lower.safe_push (stmt);
4044 : else
4045 188 : reads_to_lower.safe_push (stmt);
4046 : }
4047 : }
4048 : }
4049 483131 : return !reads_to_lower.is_empty () || !writes_to_lower.is_empty ();
4050 : }
4051 :
4052 :
4053 : /* If-convert LOOP when it is legal. For the moment this pass has no
4054 : profitability analysis. Returns non-zero todo flags when something
4055 : changed. */
4056 :
4057 : unsigned int
4058 503685 : tree_if_conversion (class loop *loop, vec<gimple *> *preds)
4059 : {
4060 503685 : unsigned int todo = 0;
4061 503685 : bool aggressive_if_conv;
4062 503685 : class loop *rloop;
4063 503685 : auto_vec <gassign *, 4> reads_to_lower;
4064 503685 : auto_vec <gassign *, 4> writes_to_lower;
4065 503685 : bitmap exit_bbs;
4066 503685 : edge pe;
4067 503685 : auto_vec<data_reference_p, 10> refs;
4068 504611 : class loop *vloop, *nloop;
4069 :
4070 504611 : again:
4071 504611 : rloop = NULL;
4072 504611 : ifc_bbs = NULL;
4073 504611 : need_to_lower_bitfields = false;
4074 504611 : need_to_ifcvt = false;
4075 504611 : need_to_predicate = false;
4076 504611 : need_to_rewrite_undefined = false;
4077 504611 : any_complicated_phi = false;
4078 :
4079 : /* Apply more aggressive if-conversion when loop or its outer loop were
4080 : marked with simd pragma. When that's the case, we try to if-convert
4081 : loop containing PHIs with more than MAX_PHI_ARG_NUM arguments. */
4082 504611 : aggressive_if_conv = loop->force_vectorize;
4083 504611 : if (!aggressive_if_conv)
4084 : {
4085 496243 : class loop *outer_loop = loop_outer (loop);
4086 496243 : if (outer_loop && outer_loop->force_vectorize)
4087 8624 : aggressive_if_conv = true;
4088 : }
4089 :
4090 : /* If there are more than two BBs in the loop then there is at least one if
4091 : to convert. */
4092 504611 : if (loop->num_nodes > 2
4093 504611 : && !ifcvt_split_critical_edges (loop, aggressive_if_conv))
4094 94164 : goto cleanup;
4095 :
4096 410447 : ifc_bbs = get_loop_body_in_if_conv_order (loop);
4097 410447 : if (!ifc_bbs)
4098 : {
4099 2614 : if (dump_file && (dump_flags & TDF_DETAILS))
4100 3 : fprintf (dump_file, "Irreducible loop\n");
4101 2614 : goto cleanup;
4102 : }
4103 :
4104 407833 : if (find_data_references_in_loop (loop, &refs) == chrec_dont_know)
4105 152548 : goto cleanup;
4106 :
4107 255285 : if (loop->num_nodes > 2)
4108 : {
4109 : /* More than one loop exit is too much to handle. */
4110 136081 : if (!single_exit (loop))
4111 : {
4112 97224 : if (dump_file && (dump_flags & TDF_DETAILS))
4113 10 : fprintf (dump_file, "Can not ifcvt due to multiple exits\n");
4114 : }
4115 : else
4116 : {
4117 38857 : need_to_ifcvt = true;
4118 :
4119 38857 : if (!if_convertible_loop_p (loop, &refs)
4120 38857 : || !dbg_cnt (if_conversion_tree))
4121 13631 : goto cleanup;
4122 : }
4123 : }
4124 :
4125 241654 : need_to_lower_bitfields = bitfields_to_lower_p (loop, reads_to_lower,
4126 : writes_to_lower);
4127 :
4128 241654 : if (!need_to_ifcvt && !need_to_lower_bitfields)
4129 216163 : goto cleanup;
4130 :
4131 : /* The edge to insert invariant stmts on. */
4132 25491 : pe = loop_preheader_edge (loop);
4133 :
4134 : /* Since we have no cost model, always version loops.
4135 : Either version this loop, or if the pattern is right for outer-loop
4136 : vectorization, version the outer loop. In the latter case we will
4137 : still if-convert the original inner loop. */
4138 25491 : vloop = (versionable_outer_loop_p (loop_outer (loop))
4139 25491 : ? loop_outer (loop) : loop);
4140 25491 : nloop = version_loop_for_if_conversion (vloop, preds);
4141 25491 : if (nloop == NULL)
4142 0 : goto cleanup;
4143 25491 : if (vloop != loop)
4144 : {
4145 : /* If versionable_outer_loop_p decided to version the
4146 : outer loop, version also the inner loop of the non-vectorized
4147 : loop copy. So we transform:
4148 : loop1
4149 : loop2
4150 : into:
4151 : if (LOOP_VECTORIZED (1, 3))
4152 : {
4153 : loop1
4154 : loop2
4155 : }
4156 : else
4157 : loop3 (copy of loop1)
4158 : if (LOOP_VECTORIZED (4, 5))
4159 : loop4 (copy of loop2)
4160 : else
4161 : loop5 (copy of loop4) */
4162 926 : gcc_assert (nloop->inner && nloop->inner->next == NULL);
4163 : rloop = nloop->inner;
4164 : }
4165 : else
4166 : /* If we versioned loop then make sure to insert invariant
4167 : stmts before the .LOOP_VECTORIZED check since the vectorizer
4168 : will re-use that for things like runtime alias versioning
4169 : whose condition can end up using those invariants. */
4170 24565 : pe = single_pred_edge (gimple_bb (preds->last ()));
4171 :
4172 25491 : if (need_to_lower_bitfields)
4173 : {
4174 266 : if (dump_file && (dump_flags & TDF_DETAILS))
4175 : {
4176 9 : fprintf (dump_file, "-------------------------\n");
4177 9 : fprintf (dump_file, "Start lowering bitfields\n");
4178 : }
4179 454 : while (!reads_to_lower.is_empty ())
4180 188 : lower_bitfield (reads_to_lower.pop (), false);
4181 695 : while (!writes_to_lower.is_empty ())
4182 429 : lower_bitfield (writes_to_lower.pop (), true);
4183 :
4184 266 : if (dump_file && (dump_flags & TDF_DETAILS))
4185 : {
4186 9 : fprintf (dump_file, "Done lowering bitfields\n");
4187 9 : fprintf (dump_file, "-------------------------\n");
4188 : }
4189 : }
4190 25491 : if (need_to_ifcvt)
4191 : {
4192 : /* Before we rewrite edges we'll record their original position in the
4193 : edge map such that we can map the edges between the ifcvt and the
4194 : non-ifcvt loop during peeling. */
4195 25226 : uintptr_t idx = 0;
4196 100904 : for (edge exit : get_loop_exit_edges (loop))
4197 25226 : exit->aux = (void*)idx++;
4198 :
4199 : /* Now all statements are if-convertible. Combine all the basic
4200 : blocks into one huge basic block doing the if-conversion
4201 : on-the-fly. */
4202 25226 : combine_blocks (loop);
4203 : }
4204 :
4205 25491 : std::pair <tree, tree> *name_pair;
4206 25491 : unsigned ssa_names_idx;
4207 30649 : FOR_EACH_VEC_ELT (redundant_ssa_names, ssa_names_idx, name_pair)
4208 5158 : replace_uses_by (name_pair->first, name_pair->second);
4209 25491 : redundant_ssa_names.release ();
4210 :
4211 : /* Perform local CSE, this esp. helps the vectorizer analysis if loads
4212 : and stores are involved. CSE only the loop body, not the entry
4213 : PHIs, those are to be kept in sync with the non-if-converted copy.
4214 : ??? We'll still keep dead stores though. */
4215 25491 : exit_bbs = BITMAP_ALLOC (NULL);
4216 102146 : for (edge exit : get_loop_exit_edges (loop))
4217 25691 : bitmap_set_bit (exit_bbs, exit->dest->index);
4218 25491 : todo |= do_rpo_vn (cfun, loop_preheader_edge (loop), exit_bbs,
4219 : false, true, true);
4220 :
4221 : /* Delete dead predicate computations. */
4222 25491 : ifcvt_local_dce (loop);
4223 25491 : BITMAP_FREE (exit_bbs);
4224 :
4225 25491 : ifcvt_hoist_invariants (loop, pe);
4226 :
4227 25491 : todo |= TODO_cleanup_cfg;
4228 :
4229 504611 : cleanup:
4230 504611 : data_reference_p dr;
4231 504611 : unsigned int i;
4232 1671404 : for (i = 0; refs.iterate (i, &dr); i++)
4233 : {
4234 1166793 : free (dr->aux);
4235 1166793 : free_data_ref (dr);
4236 : }
4237 504611 : refs.truncate (0);
4238 :
4239 504611 : if (ifc_bbs)
4240 : {
4241 : unsigned int i;
4242 :
4243 2034003 : for (i = 0; i < loop->num_nodes; i++)
4244 1651396 : free_bb_predicate (ifc_bbs[i]);
4245 :
4246 382607 : free (ifc_bbs);
4247 382607 : ifc_bbs = NULL;
4248 : }
4249 504611 : if (rloop != NULL)
4250 : {
4251 926 : loop = rloop;
4252 926 : reads_to_lower.truncate (0);
4253 926 : writes_to_lower.truncate (0);
4254 926 : goto again;
4255 : }
4256 :
4257 503685 : return todo;
4258 503685 : }
4259 :
4260 : /* Tree if-conversion pass management. */
4261 :
4262 : namespace {
4263 :
4264 : const pass_data pass_data_if_conversion =
4265 : {
4266 : GIMPLE_PASS, /* type */
4267 : "ifcvt", /* name */
4268 : OPTGROUP_NONE, /* optinfo_flags */
4269 : TV_TREE_LOOP_IFCVT, /* tv_id */
4270 : ( PROP_cfg | PROP_ssa ), /* properties_required */
4271 : 0, /* properties_provided */
4272 : 0, /* properties_destroyed */
4273 : 0, /* todo_flags_start */
4274 : 0, /* todo_flags_finish */
4275 : };
4276 :
4277 : class pass_if_conversion : public gimple_opt_pass
4278 : {
4279 : public:
4280 294587 : pass_if_conversion (gcc::context *ctxt)
4281 589174 : : gimple_opt_pass (pass_data_if_conversion, ctxt)
4282 : {}
4283 :
4284 : /* opt_pass methods: */
4285 : bool gate (function *) final override;
4286 : unsigned int execute (function *) final override;
4287 :
4288 : }; // class pass_if_conversion
4289 :
4290 : bool
4291 245657 : pass_if_conversion::gate (function *fun)
4292 : {
4293 245657 : return flag_tree_loop_vectorize || fun->has_force_vectorize_loops;
4294 : }
4295 :
4296 : unsigned int
4297 211782 : pass_if_conversion::execute (function *fun)
4298 : {
4299 211782 : unsigned todo = 0;
4300 :
4301 423564 : if (number_of_loops (fun) <= 1)
4302 : return 0;
4303 :
4304 211782 : auto_vec<gimple *> preds;
4305 1146523 : for (auto loop : loops_list (cfun, 0))
4306 511177 : if ((flag_tree_loop_vectorize || loop->force_vectorize)
4307 508369 : && !loop->dont_vectorize)
4308 503685 : todo |= tree_if_conversion (loop, &preds);
4309 :
4310 211782 : if (todo)
4311 : {
4312 17354 : free_numbers_of_iterations_estimates (fun);
4313 17354 : scev_reset ();
4314 : }
4315 :
4316 211782 : if (flag_checking)
4317 : {
4318 211778 : basic_block bb;
4319 7167796 : FOR_EACH_BB_FN (bb, fun)
4320 6956018 : gcc_assert (!bb->aux);
4321 : }
4322 :
4323 : /* Perform IL update now, it might elide some loops. */
4324 211782 : if (todo & TODO_cleanup_cfg)
4325 : {
4326 17354 : cleanup_tree_cfg ();
4327 17354 : if (need_ssa_update_p (fun))
4328 0 : todo |= TODO_update_ssa;
4329 : }
4330 211782 : if (todo & TODO_update_ssa_any)
4331 0 : update_ssa (todo & TODO_update_ssa_any);
4332 :
4333 : /* If if-conversion elided the loop fall back to the original one. Likewise
4334 : if the loops are not nested in the same outer loop. */
4335 237273 : for (unsigned i = 0; i < preds.length (); ++i)
4336 : {
4337 25491 : gimple *g = preds[i];
4338 25491 : if (!gimple_bb (g))
4339 0 : continue;
4340 25491 : auto ifcvt_loop = get_loop (fun, tree_to_uhwi (gimple_call_arg (g, 0)));
4341 25491 : auto orig_loop = get_loop (fun, tree_to_uhwi (gimple_call_arg (g, 1)));
4342 25491 : if (!ifcvt_loop || !orig_loop)
4343 : {
4344 2 : if (dump_file)
4345 0 : fprintf (dump_file, "If-converted loop vanished\n");
4346 2 : fold_loop_internal_call (g, boolean_false_node);
4347 : }
4348 25489 : else if (loop_outer (ifcvt_loop) != loop_outer (orig_loop))
4349 : {
4350 0 : if (dump_file)
4351 0 : fprintf (dump_file, "If-converted loop in different outer loop\n");
4352 0 : fold_loop_internal_call (g, boolean_false_node);
4353 : }
4354 : }
4355 :
4356 211782 : return 0;
4357 211782 : }
4358 :
4359 : } // anon namespace
4360 :
4361 : gimple_opt_pass *
4362 294587 : make_pass_if_conversion (gcc::context *ctxt)
4363 : {
4364 294587 : return new pass_if_conversion (ctxt);
4365 : }
|