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