tree-if-conv.cc revision 1.1 1 1.1 mrg /* If-conversion for vectorizer.
2 1.1 mrg Copyright (C) 2004-2022 Free Software Foundation, Inc.
3 1.1 mrg Contributed by Devang Patel <dpatel (at) apple.com>
4 1.1 mrg
5 1.1 mrg This file is part of GCC.
6 1.1 mrg
7 1.1 mrg GCC is free software; you can redistribute it and/or modify it under
8 1.1 mrg the terms of the GNU General Public License as published by the Free
9 1.1 mrg Software Foundation; either version 3, or (at your option) any later
10 1.1 mrg version.
11 1.1 mrg
12 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 1.1 mrg for more details.
16 1.1 mrg
17 1.1 mrg You should have received a copy of the GNU General Public License
18 1.1 mrg along with GCC; see the file COPYING3. If not see
19 1.1 mrg <http://www.gnu.org/licenses/>. */
20 1.1 mrg
21 1.1 mrg /* This pass implements a tree level if-conversion of loops. Its
22 1.1 mrg initial goal is to help the vectorizer to vectorize loops with
23 1.1 mrg conditions.
24 1.1 mrg
25 1.1 mrg A short description of if-conversion:
26 1.1 mrg
27 1.1 mrg o Decide if a loop is if-convertible or not.
28 1.1 mrg o Walk all loop basic blocks in breadth first order (BFS order).
29 1.1 mrg o Remove conditional statements (at the end of basic block)
30 1.1 mrg and propagate condition into destination basic blocks'
31 1.1 mrg predicate list.
32 1.1 mrg o Replace modify expression with conditional modify expression
33 1.1 mrg using current basic block's condition.
34 1.1 mrg o Merge all basic blocks
35 1.1 mrg o Replace phi nodes with conditional modify expr
36 1.1 mrg o Merge all basic blocks into header
37 1.1 mrg
38 1.1 mrg Sample transformation:
39 1.1 mrg
40 1.1 mrg INPUT
41 1.1 mrg -----
42 1.1 mrg
43 1.1 mrg # i_23 = PHI <0(0), i_18(10)>;
44 1.1 mrg <L0>:;
45 1.1 mrg j_15 = A[i_23];
46 1.1 mrg if (j_15 > 41) goto <L1>; else goto <L17>;
47 1.1 mrg
48 1.1 mrg <L17>:;
49 1.1 mrg goto <bb 3> (<L3>);
50 1.1 mrg
51 1.1 mrg <L1>:;
52 1.1 mrg
53 1.1 mrg # iftmp.2_4 = PHI <0(8), 42(2)>;
54 1.1 mrg <L3>:;
55 1.1 mrg A[i_23] = iftmp.2_4;
56 1.1 mrg i_18 = i_23 + 1;
57 1.1 mrg if (i_18 <= 15) goto <L19>; else goto <L18>;
58 1.1 mrg
59 1.1 mrg <L19>:;
60 1.1 mrg goto <bb 1> (<L0>);
61 1.1 mrg
62 1.1 mrg <L18>:;
63 1.1 mrg
64 1.1 mrg OUTPUT
65 1.1 mrg ------
66 1.1 mrg
67 1.1 mrg # i_23 = PHI <0(0), i_18(10)>;
68 1.1 mrg <L0>:;
69 1.1 mrg j_15 = A[i_23];
70 1.1 mrg
71 1.1 mrg <L3>:;
72 1.1 mrg iftmp.2_4 = j_15 > 41 ? 42 : 0;
73 1.1 mrg A[i_23] = iftmp.2_4;
74 1.1 mrg i_18 = i_23 + 1;
75 1.1 mrg if (i_18 <= 15) goto <L19>; else goto <L18>;
76 1.1 mrg
77 1.1 mrg <L19>:;
78 1.1 mrg goto <bb 1> (<L0>);
79 1.1 mrg
80 1.1 mrg <L18>:;
81 1.1 mrg */
82 1.1 mrg
83 1.1 mrg #include "config.h"
84 1.1 mrg #include "system.h"
85 1.1 mrg #include "coretypes.h"
86 1.1 mrg #include "backend.h"
87 1.1 mrg #include "rtl.h"
88 1.1 mrg #include "tree.h"
89 1.1 mrg #include "gimple.h"
90 1.1 mrg #include "cfghooks.h"
91 1.1 mrg #include "tree-pass.h"
92 1.1 mrg #include "ssa.h"
93 1.1 mrg #include "expmed.h"
94 1.1 mrg #include "optabs-query.h"
95 1.1 mrg #include "gimple-pretty-print.h"
96 1.1 mrg #include "alias.h"
97 1.1 mrg #include "fold-const.h"
98 1.1 mrg #include "stor-layout.h"
99 1.1 mrg #include "gimple-fold.h"
100 1.1 mrg #include "gimplify.h"
101 1.1 mrg #include "gimple-iterator.h"
102 1.1 mrg #include "gimplify-me.h"
103 1.1 mrg #include "tree-cfg.h"
104 1.1 mrg #include "tree-into-ssa.h"
105 1.1 mrg #include "tree-ssa.h"
106 1.1 mrg #include "cfgloop.h"
107 1.1 mrg #include "tree-data-ref.h"
108 1.1 mrg #include "tree-scalar-evolution.h"
109 1.1 mrg #include "tree-ssa-loop.h"
110 1.1 mrg #include "tree-ssa-loop-niter.h"
111 1.1 mrg #include "tree-ssa-loop-ivopts.h"
112 1.1 mrg #include "tree-ssa-address.h"
113 1.1 mrg #include "dbgcnt.h"
114 1.1 mrg #include "tree-hash-traits.h"
115 1.1 mrg #include "varasm.h"
116 1.1 mrg #include "builtins.h"
117 1.1 mrg #include "cfganal.h"
118 1.1 mrg #include "internal-fn.h"
119 1.1 mrg #include "fold-const.h"
120 1.1 mrg #include "tree-ssa-sccvn.h"
121 1.1 mrg #include "tree-cfgcleanup.h"
122 1.1 mrg #include "tree-ssa-dse.h"
123 1.1 mrg #include "tree-vectorizer.h"
124 1.1 mrg #include "tree-eh.h"
125 1.1 mrg
126 1.1 mrg /* Only handle PHIs with no more arguments unless we are asked to by
127 1.1 mrg simd pragma. */
128 1.1 mrg #define MAX_PHI_ARG_NUM \
129 1.1 mrg ((unsigned) param_max_tree_if_conversion_phi_args)
130 1.1 mrg
131 1.1 mrg /* True if we've converted a statement that was only executed when some
132 1.1 mrg condition C was true, and if for correctness we need to predicate the
133 1.1 mrg statement to ensure that it is a no-op when C is false. See
134 1.1 mrg predicate_statements for the kinds of predication we support. */
135 1.1 mrg static bool need_to_predicate;
136 1.1 mrg
137 1.1 mrg /* True if we have to rewrite stmts that may invoke undefined behavior
138 1.1 mrg when a condition C was false so it doesn't if it is always executed.
139 1.1 mrg See predicate_statements for the kinds of predication we support. */
140 1.1 mrg static bool need_to_rewrite_undefined;
141 1.1 mrg
142 1.1 mrg /* Indicate if there are any complicated PHIs that need to be handled in
143 1.1 mrg if-conversion. Complicated PHI has more than two arguments and can't
144 1.1 mrg be degenerated to two arguments PHI. See more information in comment
145 1.1 mrg before phi_convertible_by_degenerating_args. */
146 1.1 mrg static bool any_complicated_phi;
147 1.1 mrg
148 1.1 mrg /* Hash for struct innermost_loop_behavior. It depends on the user to
149 1.1 mrg free the memory. */
150 1.1 mrg
151 1.1 mrg struct innermost_loop_behavior_hash : nofree_ptr_hash <innermost_loop_behavior>
152 1.1 mrg {
153 1.1 mrg static inline hashval_t hash (const value_type &);
154 1.1 mrg static inline bool equal (const value_type &,
155 1.1 mrg const compare_type &);
156 1.1 mrg };
157 1.1 mrg
158 1.1 mrg inline hashval_t
159 1.1 mrg innermost_loop_behavior_hash::hash (const value_type &e)
160 1.1 mrg {
161 1.1 mrg hashval_t hash;
162 1.1 mrg
163 1.1 mrg hash = iterative_hash_expr (e->base_address, 0);
164 1.1 mrg hash = iterative_hash_expr (e->offset, hash);
165 1.1 mrg hash = iterative_hash_expr (e->init, hash);
166 1.1 mrg return iterative_hash_expr (e->step, hash);
167 1.1 mrg }
168 1.1 mrg
169 1.1 mrg inline bool
170 1.1 mrg innermost_loop_behavior_hash::equal (const value_type &e1,
171 1.1 mrg const compare_type &e2)
172 1.1 mrg {
173 1.1 mrg if ((e1->base_address && !e2->base_address)
174 1.1 mrg || (!e1->base_address && e2->base_address)
175 1.1 mrg || (!e1->offset && e2->offset)
176 1.1 mrg || (e1->offset && !e2->offset)
177 1.1 mrg || (!e1->init && e2->init)
178 1.1 mrg || (e1->init && !e2->init)
179 1.1 mrg || (!e1->step && e2->step)
180 1.1 mrg || (e1->step && !e2->step))
181 1.1 mrg return false;
182 1.1 mrg
183 1.1 mrg if (e1->base_address && e2->base_address
184 1.1 mrg && !operand_equal_p (e1->base_address, e2->base_address, 0))
185 1.1 mrg return false;
186 1.1 mrg if (e1->offset && e2->offset
187 1.1 mrg && !operand_equal_p (e1->offset, e2->offset, 0))
188 1.1 mrg return false;
189 1.1 mrg if (e1->init && e2->init
190 1.1 mrg && !operand_equal_p (e1->init, e2->init, 0))
191 1.1 mrg return false;
192 1.1 mrg if (e1->step && e2->step
193 1.1 mrg && !operand_equal_p (e1->step, e2->step, 0))
194 1.1 mrg return false;
195 1.1 mrg
196 1.1 mrg return true;
197 1.1 mrg }
198 1.1 mrg
199 1.1 mrg /* List of basic blocks in if-conversion-suitable order. */
200 1.1 mrg static basic_block *ifc_bbs;
201 1.1 mrg
202 1.1 mrg /* Hash table to store <DR's innermost loop behavior, DR> pairs. */
203 1.1 mrg static hash_map<innermost_loop_behavior_hash,
204 1.1 mrg data_reference_p> *innermost_DR_map;
205 1.1 mrg
206 1.1 mrg /* Hash table to store <base reference, DR> pairs. */
207 1.1 mrg static hash_map<tree_operand_hash, data_reference_p> *baseref_DR_map;
208 1.1 mrg
209 1.1 mrg /* List of redundant SSA names: the first should be replaced by the second. */
210 1.1 mrg static vec< std::pair<tree, tree> > redundant_ssa_names;
211 1.1 mrg
212 1.1 mrg /* Structure used to predicate basic blocks. This is attached to the
213 1.1 mrg ->aux field of the BBs in the loop to be if-converted. */
214 1.1 mrg struct bb_predicate {
215 1.1 mrg
216 1.1 mrg /* The condition under which this basic block is executed. */
217 1.1 mrg tree predicate;
218 1.1 mrg
219 1.1 mrg /* PREDICATE is gimplified, and the sequence of statements is
220 1.1 mrg recorded here, in order to avoid the duplication of computations
221 1.1 mrg that occur in previous conditions. See PR44483. */
222 1.1 mrg gimple_seq predicate_gimplified_stmts;
223 1.1 mrg };
224 1.1 mrg
225 1.1 mrg /* Returns true when the basic block BB has a predicate. */
226 1.1 mrg
227 1.1 mrg static inline bool
228 1.1 mrg bb_has_predicate (basic_block bb)
229 1.1 mrg {
230 1.1 mrg return bb->aux != NULL;
231 1.1 mrg }
232 1.1 mrg
233 1.1 mrg /* Returns the gimplified predicate for basic block BB. */
234 1.1 mrg
235 1.1 mrg static inline tree
236 1.1 mrg bb_predicate (basic_block bb)
237 1.1 mrg {
238 1.1 mrg return ((struct bb_predicate *) bb->aux)->predicate;
239 1.1 mrg }
240 1.1 mrg
241 1.1 mrg /* Sets the gimplified predicate COND for basic block BB. */
242 1.1 mrg
243 1.1 mrg static inline void
244 1.1 mrg set_bb_predicate (basic_block bb, tree cond)
245 1.1 mrg {
246 1.1 mrg gcc_assert ((TREE_CODE (cond) == TRUTH_NOT_EXPR
247 1.1 mrg && is_gimple_condexpr (TREE_OPERAND (cond, 0)))
248 1.1 mrg || is_gimple_condexpr (cond));
249 1.1 mrg ((struct bb_predicate *) bb->aux)->predicate = cond;
250 1.1 mrg }
251 1.1 mrg
252 1.1 mrg /* Returns the sequence of statements of the gimplification of the
253 1.1 mrg predicate for basic block BB. */
254 1.1 mrg
255 1.1 mrg static inline gimple_seq
256 1.1 mrg bb_predicate_gimplified_stmts (basic_block bb)
257 1.1 mrg {
258 1.1 mrg return ((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts;
259 1.1 mrg }
260 1.1 mrg
261 1.1 mrg /* Sets the sequence of statements STMTS of the gimplification of the
262 1.1 mrg predicate for basic block BB. */
263 1.1 mrg
264 1.1 mrg static inline void
265 1.1 mrg set_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts)
266 1.1 mrg {
267 1.1 mrg ((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts = stmts;
268 1.1 mrg }
269 1.1 mrg
270 1.1 mrg /* Adds the sequence of statements STMTS to the sequence of statements
271 1.1 mrg of the predicate for basic block BB. */
272 1.1 mrg
273 1.1 mrg static inline void
274 1.1 mrg add_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts)
275 1.1 mrg {
276 1.1 mrg /* We might have updated some stmts in STMTS via force_gimple_operand
277 1.1 mrg calling fold_stmt and that producing multiple stmts. Delink immediate
278 1.1 mrg uses so update_ssa after loop versioning doesn't get confused for
279 1.1 mrg the not yet inserted predicates.
280 1.1 mrg ??? This should go away once we reliably avoid updating stmts
281 1.1 mrg not in any BB. */
282 1.1 mrg for (gimple_stmt_iterator gsi = gsi_start (stmts);
283 1.1 mrg !gsi_end_p (gsi); gsi_next (&gsi))
284 1.1 mrg {
285 1.1 mrg gimple *stmt = gsi_stmt (gsi);
286 1.1 mrg delink_stmt_imm_use (stmt);
287 1.1 mrg gimple_set_modified (stmt, true);
288 1.1 mrg }
289 1.1 mrg gimple_seq_add_seq_without_update
290 1.1 mrg (&(((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts), stmts);
291 1.1 mrg }
292 1.1 mrg
293 1.1 mrg /* Initializes to TRUE the predicate of basic block BB. */
294 1.1 mrg
295 1.1 mrg static inline void
296 1.1 mrg init_bb_predicate (basic_block bb)
297 1.1 mrg {
298 1.1 mrg bb->aux = XNEW (struct bb_predicate);
299 1.1 mrg set_bb_predicate_gimplified_stmts (bb, NULL);
300 1.1 mrg set_bb_predicate (bb, boolean_true_node);
301 1.1 mrg }
302 1.1 mrg
303 1.1 mrg /* Release the SSA_NAMEs associated with the predicate of basic block BB. */
304 1.1 mrg
305 1.1 mrg static inline void
306 1.1 mrg release_bb_predicate (basic_block bb)
307 1.1 mrg {
308 1.1 mrg gimple_seq stmts = bb_predicate_gimplified_stmts (bb);
309 1.1 mrg if (stmts)
310 1.1 mrg {
311 1.1 mrg /* Ensure that these stmts haven't yet been added to a bb. */
312 1.1 mrg if (flag_checking)
313 1.1 mrg for (gimple_stmt_iterator i = gsi_start (stmts);
314 1.1 mrg !gsi_end_p (i); gsi_next (&i))
315 1.1 mrg gcc_assert (! gimple_bb (gsi_stmt (i)));
316 1.1 mrg
317 1.1 mrg /* Discard them. */
318 1.1 mrg gimple_seq_discard (stmts);
319 1.1 mrg set_bb_predicate_gimplified_stmts (bb, NULL);
320 1.1 mrg }
321 1.1 mrg }
322 1.1 mrg
323 1.1 mrg /* Free the predicate of basic block BB. */
324 1.1 mrg
325 1.1 mrg static inline void
326 1.1 mrg free_bb_predicate (basic_block bb)
327 1.1 mrg {
328 1.1 mrg if (!bb_has_predicate (bb))
329 1.1 mrg return;
330 1.1 mrg
331 1.1 mrg release_bb_predicate (bb);
332 1.1 mrg free (bb->aux);
333 1.1 mrg bb->aux = NULL;
334 1.1 mrg }
335 1.1 mrg
336 1.1 mrg /* Reinitialize predicate of BB with the true predicate. */
337 1.1 mrg
338 1.1 mrg static inline void
339 1.1 mrg reset_bb_predicate (basic_block bb)
340 1.1 mrg {
341 1.1 mrg if (!bb_has_predicate (bb))
342 1.1 mrg init_bb_predicate (bb);
343 1.1 mrg else
344 1.1 mrg {
345 1.1 mrg release_bb_predicate (bb);
346 1.1 mrg set_bb_predicate (bb, boolean_true_node);
347 1.1 mrg }
348 1.1 mrg }
349 1.1 mrg
350 1.1 mrg /* Returns a new SSA_NAME of type TYPE that is assigned the value of
351 1.1 mrg the expression EXPR. Inserts the statement created for this
352 1.1 mrg computation before GSI and leaves the iterator GSI at the same
353 1.1 mrg statement. */
354 1.1 mrg
355 1.1 mrg static tree
356 1.1 mrg ifc_temp_var (tree type, tree expr, gimple_stmt_iterator *gsi)
357 1.1 mrg {
358 1.1 mrg tree new_name = make_temp_ssa_name (type, NULL, "_ifc_");
359 1.1 mrg gimple *stmt = gimple_build_assign (new_name, expr);
360 1.1 mrg gimple_set_vuse (stmt, gimple_vuse (gsi_stmt (*gsi)));
361 1.1 mrg gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
362 1.1 mrg return new_name;
363 1.1 mrg }
364 1.1 mrg
365 1.1 mrg /* Return true when COND is a false predicate. */
366 1.1 mrg
367 1.1 mrg static inline bool
368 1.1 mrg is_false_predicate (tree cond)
369 1.1 mrg {
370 1.1 mrg return (cond != NULL_TREE
371 1.1 mrg && (cond == boolean_false_node
372 1.1 mrg || integer_zerop (cond)));
373 1.1 mrg }
374 1.1 mrg
375 1.1 mrg /* Return true when COND is a true predicate. */
376 1.1 mrg
377 1.1 mrg static inline bool
378 1.1 mrg is_true_predicate (tree cond)
379 1.1 mrg {
380 1.1 mrg return (cond == NULL_TREE
381 1.1 mrg || cond == boolean_true_node
382 1.1 mrg || integer_onep (cond));
383 1.1 mrg }
384 1.1 mrg
385 1.1 mrg /* Returns true when BB has a predicate that is not trivial: true or
386 1.1 mrg NULL_TREE. */
387 1.1 mrg
388 1.1 mrg static inline bool
389 1.1 mrg is_predicated (basic_block bb)
390 1.1 mrg {
391 1.1 mrg return !is_true_predicate (bb_predicate (bb));
392 1.1 mrg }
393 1.1 mrg
394 1.1 mrg /* Parses the predicate COND and returns its comparison code and
395 1.1 mrg operands OP0 and OP1. */
396 1.1 mrg
397 1.1 mrg static enum tree_code
398 1.1 mrg parse_predicate (tree cond, tree *op0, tree *op1)
399 1.1 mrg {
400 1.1 mrg gimple *s;
401 1.1 mrg
402 1.1 mrg if (TREE_CODE (cond) == SSA_NAME
403 1.1 mrg && is_gimple_assign (s = SSA_NAME_DEF_STMT (cond)))
404 1.1 mrg {
405 1.1 mrg if (TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison)
406 1.1 mrg {
407 1.1 mrg *op0 = gimple_assign_rhs1 (s);
408 1.1 mrg *op1 = gimple_assign_rhs2 (s);
409 1.1 mrg return gimple_assign_rhs_code (s);
410 1.1 mrg }
411 1.1 mrg
412 1.1 mrg else if (gimple_assign_rhs_code (s) == TRUTH_NOT_EXPR)
413 1.1 mrg {
414 1.1 mrg tree op = gimple_assign_rhs1 (s);
415 1.1 mrg tree type = TREE_TYPE (op);
416 1.1 mrg enum tree_code code = parse_predicate (op, op0, op1);
417 1.1 mrg
418 1.1 mrg return code == ERROR_MARK ? ERROR_MARK
419 1.1 mrg : invert_tree_comparison (code, HONOR_NANS (type));
420 1.1 mrg }
421 1.1 mrg
422 1.1 mrg return ERROR_MARK;
423 1.1 mrg }
424 1.1 mrg
425 1.1 mrg if (COMPARISON_CLASS_P (cond))
426 1.1 mrg {
427 1.1 mrg *op0 = TREE_OPERAND (cond, 0);
428 1.1 mrg *op1 = TREE_OPERAND (cond, 1);
429 1.1 mrg return TREE_CODE (cond);
430 1.1 mrg }
431 1.1 mrg
432 1.1 mrg return ERROR_MARK;
433 1.1 mrg }
434 1.1 mrg
435 1.1 mrg /* Returns the fold of predicate C1 OR C2 at location LOC. */
436 1.1 mrg
437 1.1 mrg static tree
438 1.1 mrg fold_or_predicates (location_t loc, tree c1, tree c2)
439 1.1 mrg {
440 1.1 mrg tree op1a, op1b, op2a, op2b;
441 1.1 mrg enum tree_code code1 = parse_predicate (c1, &op1a, &op1b);
442 1.1 mrg enum tree_code code2 = parse_predicate (c2, &op2a, &op2b);
443 1.1 mrg
444 1.1 mrg if (code1 != ERROR_MARK && code2 != ERROR_MARK)
445 1.1 mrg {
446 1.1 mrg tree t = maybe_fold_or_comparisons (boolean_type_node, code1, op1a, op1b,
447 1.1 mrg code2, op2a, op2b);
448 1.1 mrg if (t)
449 1.1 mrg return t;
450 1.1 mrg }
451 1.1 mrg
452 1.1 mrg return fold_build2_loc (loc, TRUTH_OR_EXPR, boolean_type_node, c1, c2);
453 1.1 mrg }
454 1.1 mrg
455 1.1 mrg /* Returns either a COND_EXPR or the folded expression if the folded
456 1.1 mrg expression is a MIN_EXPR, a MAX_EXPR, an ABS_EXPR,
457 1.1 mrg a constant or a SSA_NAME. */
458 1.1 mrg
459 1.1 mrg static tree
460 1.1 mrg fold_build_cond_expr (tree type, tree cond, tree rhs, tree lhs)
461 1.1 mrg {
462 1.1 mrg tree rhs1, lhs1, cond_expr;
463 1.1 mrg
464 1.1 mrg /* If COND is comparison r != 0 and r has boolean type, convert COND
465 1.1 mrg to SSA_NAME to accept by vect bool pattern. */
466 1.1 mrg if (TREE_CODE (cond) == NE_EXPR)
467 1.1 mrg {
468 1.1 mrg tree op0 = TREE_OPERAND (cond, 0);
469 1.1 mrg tree op1 = TREE_OPERAND (cond, 1);
470 1.1 mrg if (TREE_CODE (op0) == SSA_NAME
471 1.1 mrg && TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
472 1.1 mrg && (integer_zerop (op1)))
473 1.1 mrg cond = op0;
474 1.1 mrg }
475 1.1 mrg cond_expr = fold_ternary (COND_EXPR, type, cond, rhs, lhs);
476 1.1 mrg
477 1.1 mrg if (cond_expr == NULL_TREE)
478 1.1 mrg return build3 (COND_EXPR, type, cond, rhs, lhs);
479 1.1 mrg
480 1.1 mrg STRIP_USELESS_TYPE_CONVERSION (cond_expr);
481 1.1 mrg
482 1.1 mrg if (is_gimple_val (cond_expr))
483 1.1 mrg return cond_expr;
484 1.1 mrg
485 1.1 mrg if (TREE_CODE (cond_expr) == ABS_EXPR)
486 1.1 mrg {
487 1.1 mrg rhs1 = TREE_OPERAND (cond_expr, 1);
488 1.1 mrg STRIP_USELESS_TYPE_CONVERSION (rhs1);
489 1.1 mrg if (is_gimple_val (rhs1))
490 1.1 mrg return build1 (ABS_EXPR, type, rhs1);
491 1.1 mrg }
492 1.1 mrg
493 1.1 mrg if (TREE_CODE (cond_expr) == MIN_EXPR
494 1.1 mrg || TREE_CODE (cond_expr) == MAX_EXPR)
495 1.1 mrg {
496 1.1 mrg lhs1 = TREE_OPERAND (cond_expr, 0);
497 1.1 mrg STRIP_USELESS_TYPE_CONVERSION (lhs1);
498 1.1 mrg rhs1 = TREE_OPERAND (cond_expr, 1);
499 1.1 mrg STRIP_USELESS_TYPE_CONVERSION (rhs1);
500 1.1 mrg if (is_gimple_val (rhs1) && is_gimple_val (lhs1))
501 1.1 mrg return build2 (TREE_CODE (cond_expr), type, lhs1, rhs1);
502 1.1 mrg }
503 1.1 mrg return build3 (COND_EXPR, type, cond, rhs, lhs);
504 1.1 mrg }
505 1.1 mrg
506 1.1 mrg /* Add condition NC to the predicate list of basic block BB. LOOP is
507 1.1 mrg the loop to be if-converted. Use predicate of cd-equivalent block
508 1.1 mrg for join bb if it exists: we call basic blocks bb1 and bb2
509 1.1 mrg cd-equivalent if they are executed under the same condition. */
510 1.1 mrg
511 1.1 mrg static inline void
512 1.1 mrg add_to_predicate_list (class loop *loop, basic_block bb, tree nc)
513 1.1 mrg {
514 1.1 mrg tree bc, *tp;
515 1.1 mrg basic_block dom_bb;
516 1.1 mrg
517 1.1 mrg if (is_true_predicate (nc))
518 1.1 mrg return;
519 1.1 mrg
520 1.1 mrg /* If dominance tells us this basic block is always executed,
521 1.1 mrg don't record any predicates for it. */
522 1.1 mrg if (dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
523 1.1 mrg return;
524 1.1 mrg
525 1.1 mrg dom_bb = get_immediate_dominator (CDI_DOMINATORS, bb);
526 1.1 mrg /* We use notion of cd equivalence to get simpler predicate for
527 1.1 mrg join block, e.g. if join block has 2 predecessors with predicates
528 1.1 mrg p1 & p2 and p1 & !p2, we'd like to get p1 for it instead of
529 1.1 mrg p1 & p2 | p1 & !p2. */
530 1.1 mrg if (dom_bb != loop->header
531 1.1 mrg && get_immediate_dominator (CDI_POST_DOMINATORS, dom_bb) == bb)
532 1.1 mrg {
533 1.1 mrg gcc_assert (flow_bb_inside_loop_p (loop, dom_bb));
534 1.1 mrg bc = bb_predicate (dom_bb);
535 1.1 mrg if (!is_true_predicate (bc))
536 1.1 mrg set_bb_predicate (bb, bc);
537 1.1 mrg else
538 1.1 mrg gcc_assert (is_true_predicate (bb_predicate (bb)));
539 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
540 1.1 mrg fprintf (dump_file, "Use predicate of bb#%d for bb#%d\n",
541 1.1 mrg dom_bb->index, bb->index);
542 1.1 mrg return;
543 1.1 mrg }
544 1.1 mrg
545 1.1 mrg if (!is_predicated (bb))
546 1.1 mrg bc = nc;
547 1.1 mrg else
548 1.1 mrg {
549 1.1 mrg bc = bb_predicate (bb);
550 1.1 mrg bc = fold_or_predicates (EXPR_LOCATION (bc), nc, bc);
551 1.1 mrg if (is_true_predicate (bc))
552 1.1 mrg {
553 1.1 mrg reset_bb_predicate (bb);
554 1.1 mrg return;
555 1.1 mrg }
556 1.1 mrg }
557 1.1 mrg
558 1.1 mrg /* Allow a TRUTH_NOT_EXPR around the main predicate. */
559 1.1 mrg if (TREE_CODE (bc) == TRUTH_NOT_EXPR)
560 1.1 mrg tp = &TREE_OPERAND (bc, 0);
561 1.1 mrg else
562 1.1 mrg tp = &bc;
563 1.1 mrg if (!is_gimple_condexpr (*tp))
564 1.1 mrg {
565 1.1 mrg gimple_seq stmts;
566 1.1 mrg *tp = force_gimple_operand_1 (*tp, &stmts, is_gimple_condexpr, NULL_TREE);
567 1.1 mrg add_bb_predicate_gimplified_stmts (bb, stmts);
568 1.1 mrg }
569 1.1 mrg set_bb_predicate (bb, bc);
570 1.1 mrg }
571 1.1 mrg
572 1.1 mrg /* Add the condition COND to the previous condition PREV_COND, and add
573 1.1 mrg this to the predicate list of the destination of edge E. LOOP is
574 1.1 mrg the loop to be if-converted. */
575 1.1 mrg
576 1.1 mrg static void
577 1.1 mrg add_to_dst_predicate_list (class loop *loop, edge e,
578 1.1 mrg tree prev_cond, tree cond)
579 1.1 mrg {
580 1.1 mrg if (!flow_bb_inside_loop_p (loop, e->dest))
581 1.1 mrg return;
582 1.1 mrg
583 1.1 mrg if (!is_true_predicate (prev_cond))
584 1.1 mrg cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
585 1.1 mrg prev_cond, cond);
586 1.1 mrg
587 1.1 mrg if (!dominated_by_p (CDI_DOMINATORS, loop->latch, e->dest))
588 1.1 mrg add_to_predicate_list (loop, e->dest, cond);
589 1.1 mrg }
590 1.1 mrg
591 1.1 mrg /* Return true if one of the successor edges of BB exits LOOP. */
592 1.1 mrg
593 1.1 mrg static bool
594 1.1 mrg bb_with_exit_edge_p (class loop *loop, basic_block bb)
595 1.1 mrg {
596 1.1 mrg edge e;
597 1.1 mrg edge_iterator ei;
598 1.1 mrg
599 1.1 mrg FOR_EACH_EDGE (e, ei, bb->succs)
600 1.1 mrg if (loop_exit_edge_p (loop, e))
601 1.1 mrg return true;
602 1.1 mrg
603 1.1 mrg return false;
604 1.1 mrg }
605 1.1 mrg
606 1.1 mrg /* Given PHI which has more than two arguments, this function checks if
607 1.1 mrg it's if-convertible by degenerating its arguments. Specifically, if
608 1.1 mrg below two conditions are satisfied:
609 1.1 mrg
610 1.1 mrg 1) Number of PHI arguments with different values equals to 2 and one
611 1.1 mrg argument has the only occurrence.
612 1.1 mrg 2) The edge corresponding to the unique argument isn't critical edge.
613 1.1 mrg
614 1.1 mrg Such PHI can be handled as PHIs have only two arguments. For example,
615 1.1 mrg below PHI:
616 1.1 mrg
617 1.1 mrg res = PHI <A_1(e1), A_1(e2), A_2(e3)>;
618 1.1 mrg
619 1.1 mrg can be transformed into:
620 1.1 mrg
621 1.1 mrg res = (predicate of e3) ? A_2 : A_1;
622 1.1 mrg
623 1.1 mrg Return TRUE if it is the case, FALSE otherwise. */
624 1.1 mrg
625 1.1 mrg static bool
626 1.1 mrg phi_convertible_by_degenerating_args (gphi *phi)
627 1.1 mrg {
628 1.1 mrg edge e;
629 1.1 mrg tree arg, t1 = NULL, t2 = NULL;
630 1.1 mrg unsigned int i, i1 = 0, i2 = 0, n1 = 0, n2 = 0;
631 1.1 mrg unsigned int num_args = gimple_phi_num_args (phi);
632 1.1 mrg
633 1.1 mrg gcc_assert (num_args > 2);
634 1.1 mrg
635 1.1 mrg for (i = 0; i < num_args; i++)
636 1.1 mrg {
637 1.1 mrg arg = gimple_phi_arg_def (phi, i);
638 1.1 mrg if (t1 == NULL || operand_equal_p (t1, arg, 0))
639 1.1 mrg {
640 1.1 mrg n1++;
641 1.1 mrg i1 = i;
642 1.1 mrg t1 = arg;
643 1.1 mrg }
644 1.1 mrg else if (t2 == NULL || operand_equal_p (t2, arg, 0))
645 1.1 mrg {
646 1.1 mrg n2++;
647 1.1 mrg i2 = i;
648 1.1 mrg t2 = arg;
649 1.1 mrg }
650 1.1 mrg else
651 1.1 mrg return false;
652 1.1 mrg }
653 1.1 mrg
654 1.1 mrg if (n1 != 1 && n2 != 1)
655 1.1 mrg return false;
656 1.1 mrg
657 1.1 mrg /* Check if the edge corresponding to the unique arg is critical. */
658 1.1 mrg e = gimple_phi_arg_edge (phi, (n1 == 1) ? i1 : i2);
659 1.1 mrg if (EDGE_COUNT (e->src->succs) > 1)
660 1.1 mrg return false;
661 1.1 mrg
662 1.1 mrg return true;
663 1.1 mrg }
664 1.1 mrg
665 1.1 mrg /* Return true when PHI is if-convertible. PHI is part of loop LOOP
666 1.1 mrg and it belongs to basic block BB. Note at this point, it is sure
667 1.1 mrg that PHI is if-convertible. This function updates global variable
668 1.1 mrg ANY_COMPLICATED_PHI if PHI is complicated. */
669 1.1 mrg
670 1.1 mrg static bool
671 1.1 mrg if_convertible_phi_p (class loop *loop, basic_block bb, gphi *phi)
672 1.1 mrg {
673 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
674 1.1 mrg {
675 1.1 mrg fprintf (dump_file, "-------------------------\n");
676 1.1 mrg print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
677 1.1 mrg }
678 1.1 mrg
679 1.1 mrg if (bb != loop->header
680 1.1 mrg && gimple_phi_num_args (phi) > 2
681 1.1 mrg && !phi_convertible_by_degenerating_args (phi))
682 1.1 mrg any_complicated_phi = true;
683 1.1 mrg
684 1.1 mrg return true;
685 1.1 mrg }
686 1.1 mrg
687 1.1 mrg /* Records the status of a data reference. This struct is attached to
688 1.1 mrg each DR->aux field. */
689 1.1 mrg
690 1.1 mrg struct ifc_dr {
691 1.1 mrg bool rw_unconditionally;
692 1.1 mrg bool w_unconditionally;
693 1.1 mrg bool written_at_least_once;
694 1.1 mrg
695 1.1 mrg tree rw_predicate;
696 1.1 mrg tree w_predicate;
697 1.1 mrg tree base_w_predicate;
698 1.1 mrg };
699 1.1 mrg
700 1.1 mrg #define IFC_DR(DR) ((struct ifc_dr *) (DR)->aux)
701 1.1 mrg #define DR_BASE_W_UNCONDITIONALLY(DR) (IFC_DR (DR)->written_at_least_once)
702 1.1 mrg #define DR_RW_UNCONDITIONALLY(DR) (IFC_DR (DR)->rw_unconditionally)
703 1.1 mrg #define DR_W_UNCONDITIONALLY(DR) (IFC_DR (DR)->w_unconditionally)
704 1.1 mrg
705 1.1 mrg /* Iterates over DR's and stores refs, DR and base refs, DR pairs in
706 1.1 mrg HASH tables. While storing them in HASH table, it checks if the
707 1.1 mrg reference is unconditionally read or written and stores that as a flag
708 1.1 mrg information. For base reference it checks if it is written atlest once
709 1.1 mrg unconditionally and stores it as flag information along with DR.
710 1.1 mrg In other words for every data reference A in STMT there exist other
711 1.1 mrg accesses to a data reference with the same base with predicates that
712 1.1 mrg add up (OR-up) to the true predicate: this ensures that the data
713 1.1 mrg reference A is touched (read or written) on every iteration of the
714 1.1 mrg if-converted loop. */
715 1.1 mrg static void
716 1.1 mrg hash_memrefs_baserefs_and_store_DRs_read_written_info (data_reference_p a)
717 1.1 mrg {
718 1.1 mrg
719 1.1 mrg data_reference_p *master_dr, *base_master_dr;
720 1.1 mrg tree base_ref = DR_BASE_OBJECT (a);
721 1.1 mrg innermost_loop_behavior *innermost = &DR_INNERMOST (a);
722 1.1 mrg tree ca = bb_predicate (gimple_bb (DR_STMT (a)));
723 1.1 mrg bool exist1, exist2;
724 1.1 mrg
725 1.1 mrg master_dr = &innermost_DR_map->get_or_insert (innermost, &exist1);
726 1.1 mrg if (!exist1)
727 1.1 mrg *master_dr = a;
728 1.1 mrg
729 1.1 mrg if (DR_IS_WRITE (a))
730 1.1 mrg {
731 1.1 mrg IFC_DR (*master_dr)->w_predicate
732 1.1 mrg = fold_or_predicates (UNKNOWN_LOCATION, ca,
733 1.1 mrg IFC_DR (*master_dr)->w_predicate);
734 1.1 mrg if (is_true_predicate (IFC_DR (*master_dr)->w_predicate))
735 1.1 mrg DR_W_UNCONDITIONALLY (*master_dr) = true;
736 1.1 mrg }
737 1.1 mrg IFC_DR (*master_dr)->rw_predicate
738 1.1 mrg = fold_or_predicates (UNKNOWN_LOCATION, ca,
739 1.1 mrg IFC_DR (*master_dr)->rw_predicate);
740 1.1 mrg if (is_true_predicate (IFC_DR (*master_dr)->rw_predicate))
741 1.1 mrg DR_RW_UNCONDITIONALLY (*master_dr) = true;
742 1.1 mrg
743 1.1 mrg if (DR_IS_WRITE (a))
744 1.1 mrg {
745 1.1 mrg base_master_dr = &baseref_DR_map->get_or_insert (base_ref, &exist2);
746 1.1 mrg if (!exist2)
747 1.1 mrg *base_master_dr = a;
748 1.1 mrg IFC_DR (*base_master_dr)->base_w_predicate
749 1.1 mrg = fold_or_predicates (UNKNOWN_LOCATION, ca,
750 1.1 mrg IFC_DR (*base_master_dr)->base_w_predicate);
751 1.1 mrg if (is_true_predicate (IFC_DR (*base_master_dr)->base_w_predicate))
752 1.1 mrg DR_BASE_W_UNCONDITIONALLY (*base_master_dr) = true;
753 1.1 mrg }
754 1.1 mrg }
755 1.1 mrg
756 1.1 mrg /* Return TRUE if can prove the index IDX of an array reference REF is
757 1.1 mrg within array bound. Return false otherwise. */
758 1.1 mrg
759 1.1 mrg static bool
760 1.1 mrg idx_within_array_bound (tree ref, tree *idx, void *dta)
761 1.1 mrg {
762 1.1 mrg wi::overflow_type overflow;
763 1.1 mrg widest_int niter, valid_niter, delta, wi_step;
764 1.1 mrg tree ev, init, step;
765 1.1 mrg tree low, high;
766 1.1 mrg class loop *loop = (class loop*) dta;
767 1.1 mrg
768 1.1 mrg /* Only support within-bound access for array references. */
769 1.1 mrg if (TREE_CODE (ref) != ARRAY_REF)
770 1.1 mrg return false;
771 1.1 mrg
772 1.1 mrg /* For arrays at the end of the structure, we are not guaranteed that they
773 1.1 mrg do not really extend over their declared size. However, for arrays of
774 1.1 mrg size greater than one, this is unlikely to be intended. */
775 1.1 mrg if (array_at_struct_end_p (ref))
776 1.1 mrg return false;
777 1.1 mrg
778 1.1 mrg ev = analyze_scalar_evolution (loop, *idx);
779 1.1 mrg ev = instantiate_parameters (loop, ev);
780 1.1 mrg init = initial_condition (ev);
781 1.1 mrg step = evolution_part_in_loop_num (ev, loop->num);
782 1.1 mrg
783 1.1 mrg if (!init || TREE_CODE (init) != INTEGER_CST
784 1.1 mrg || (step && TREE_CODE (step) != INTEGER_CST))
785 1.1 mrg return false;
786 1.1 mrg
787 1.1 mrg low = array_ref_low_bound (ref);
788 1.1 mrg high = array_ref_up_bound (ref);
789 1.1 mrg
790 1.1 mrg /* The case of nonconstant bounds could be handled, but it would be
791 1.1 mrg complicated. */
792 1.1 mrg if (TREE_CODE (low) != INTEGER_CST
793 1.1 mrg || !high || TREE_CODE (high) != INTEGER_CST)
794 1.1 mrg return false;
795 1.1 mrg
796 1.1 mrg /* Check if the intial idx is within bound. */
797 1.1 mrg if (wi::to_widest (init) < wi::to_widest (low)
798 1.1 mrg || wi::to_widest (init) > wi::to_widest (high))
799 1.1 mrg return false;
800 1.1 mrg
801 1.1 mrg /* The idx is always within bound. */
802 1.1 mrg if (!step || integer_zerop (step))
803 1.1 mrg return true;
804 1.1 mrg
805 1.1 mrg if (!max_loop_iterations (loop, &niter))
806 1.1 mrg return false;
807 1.1 mrg
808 1.1 mrg if (wi::to_widest (step) < 0)
809 1.1 mrg {
810 1.1 mrg delta = wi::to_widest (init) - wi::to_widest (low);
811 1.1 mrg wi_step = -wi::to_widest (step);
812 1.1 mrg }
813 1.1 mrg else
814 1.1 mrg {
815 1.1 mrg delta = wi::to_widest (high) - wi::to_widest (init);
816 1.1 mrg wi_step = wi::to_widest (step);
817 1.1 mrg }
818 1.1 mrg
819 1.1 mrg valid_niter = wi::div_floor (delta, wi_step, SIGNED, &overflow);
820 1.1 mrg /* The iteration space of idx is within array bound. */
821 1.1 mrg if (!overflow && niter <= valid_niter)
822 1.1 mrg return true;
823 1.1 mrg
824 1.1 mrg return false;
825 1.1 mrg }
826 1.1 mrg
827 1.1 mrg /* Return TRUE if ref is a within bound array reference. */
828 1.1 mrg
829 1.1 mrg static bool
830 1.1 mrg ref_within_array_bound (gimple *stmt, tree ref)
831 1.1 mrg {
832 1.1 mrg class loop *loop = loop_containing_stmt (stmt);
833 1.1 mrg
834 1.1 mrg gcc_assert (loop != NULL);
835 1.1 mrg return for_each_index (&ref, idx_within_array_bound, loop);
836 1.1 mrg }
837 1.1 mrg
838 1.1 mrg
839 1.1 mrg /* Given a memory reference expression T, return TRUE if base object
840 1.1 mrg it refers to is writable. The base object of a memory reference
841 1.1 mrg is the main object being referenced, which is returned by function
842 1.1 mrg get_base_address. */
843 1.1 mrg
844 1.1 mrg static bool
845 1.1 mrg base_object_writable (tree ref)
846 1.1 mrg {
847 1.1 mrg tree base_tree = get_base_address (ref);
848 1.1 mrg
849 1.1 mrg return (base_tree
850 1.1 mrg && DECL_P (base_tree)
851 1.1 mrg && decl_binds_to_current_def_p (base_tree)
852 1.1 mrg && !TREE_READONLY (base_tree));
853 1.1 mrg }
854 1.1 mrg
855 1.1 mrg /* Return true when the memory references of STMT won't trap in the
856 1.1 mrg if-converted code. There are two things that we have to check for:
857 1.1 mrg
858 1.1 mrg - writes to memory occur to writable memory: if-conversion of
859 1.1 mrg memory writes transforms the conditional memory writes into
860 1.1 mrg unconditional writes, i.e. "if (cond) A[i] = foo" is transformed
861 1.1 mrg into "A[i] = cond ? foo : A[i]", and as the write to memory may not
862 1.1 mrg be executed at all in the original code, it may be a readonly
863 1.1 mrg memory. To check that A is not const-qualified, we check that
864 1.1 mrg there exists at least an unconditional write to A in the current
865 1.1 mrg function.
866 1.1 mrg
867 1.1 mrg - reads or writes to memory are valid memory accesses for every
868 1.1 mrg iteration. To check that the memory accesses are correctly formed
869 1.1 mrg and that we are allowed to read and write in these locations, we
870 1.1 mrg check that the memory accesses to be if-converted occur at every
871 1.1 mrg iteration unconditionally.
872 1.1 mrg
873 1.1 mrg Returns true for the memory reference in STMT, same memory reference
874 1.1 mrg is read or written unconditionally atleast once and the base memory
875 1.1 mrg reference is written unconditionally once. This is to check reference
876 1.1 mrg will not write fault. Also retuns true if the memory reference is
877 1.1 mrg unconditionally read once then we are conditionally writing to memory
878 1.1 mrg which is defined as read and write and is bound to the definition
879 1.1 mrg we are seeing. */
880 1.1 mrg static bool
881 1.1 mrg ifcvt_memrefs_wont_trap (gimple *stmt, vec<data_reference_p> drs)
882 1.1 mrg {
883 1.1 mrg /* If DR didn't see a reference here we can't use it to tell
884 1.1 mrg whether the ref traps or not. */
885 1.1 mrg if (gimple_uid (stmt) == 0)
886 1.1 mrg return false;
887 1.1 mrg
888 1.1 mrg data_reference_p *master_dr, *base_master_dr;
889 1.1 mrg data_reference_p a = drs[gimple_uid (stmt) - 1];
890 1.1 mrg
891 1.1 mrg tree base = DR_BASE_OBJECT (a);
892 1.1 mrg innermost_loop_behavior *innermost = &DR_INNERMOST (a);
893 1.1 mrg
894 1.1 mrg gcc_assert (DR_STMT (a) == stmt);
895 1.1 mrg gcc_assert (DR_BASE_ADDRESS (a) || DR_OFFSET (a)
896 1.1 mrg || DR_INIT (a) || DR_STEP (a));
897 1.1 mrg
898 1.1 mrg master_dr = innermost_DR_map->get (innermost);
899 1.1 mrg gcc_assert (master_dr != NULL);
900 1.1 mrg
901 1.1 mrg base_master_dr = baseref_DR_map->get (base);
902 1.1 mrg
903 1.1 mrg /* If a is unconditionally written to it doesn't trap. */
904 1.1 mrg if (DR_W_UNCONDITIONALLY (*master_dr))
905 1.1 mrg return true;
906 1.1 mrg
907 1.1 mrg /* If a is unconditionally accessed then ...
908 1.1 mrg
909 1.1 mrg Even a is conditional access, we can treat it as an unconditional
910 1.1 mrg one if it's an array reference and all its index are within array
911 1.1 mrg bound. */
912 1.1 mrg if (DR_RW_UNCONDITIONALLY (*master_dr)
913 1.1 mrg || ref_within_array_bound (stmt, DR_REF (a)))
914 1.1 mrg {
915 1.1 mrg /* an unconditional read won't trap. */
916 1.1 mrg if (DR_IS_READ (a))
917 1.1 mrg return true;
918 1.1 mrg
919 1.1 mrg /* an unconditionaly write won't trap if the base is written
920 1.1 mrg to unconditionally. */
921 1.1 mrg if (base_master_dr
922 1.1 mrg && DR_BASE_W_UNCONDITIONALLY (*base_master_dr))
923 1.1 mrg return flag_store_data_races;
924 1.1 mrg /* or the base is known to be not readonly. */
925 1.1 mrg else if (base_object_writable (DR_REF (a)))
926 1.1 mrg return flag_store_data_races;
927 1.1 mrg }
928 1.1 mrg
929 1.1 mrg return false;
930 1.1 mrg }
931 1.1 mrg
932 1.1 mrg /* Return true if STMT could be converted into a masked load or store
933 1.1 mrg (conditional load or store based on a mask computed from bb predicate). */
934 1.1 mrg
935 1.1 mrg static bool
936 1.1 mrg ifcvt_can_use_mask_load_store (gimple *stmt)
937 1.1 mrg {
938 1.1 mrg /* Check whether this is a load or store. */
939 1.1 mrg tree lhs = gimple_assign_lhs (stmt);
940 1.1 mrg bool is_load;
941 1.1 mrg tree ref;
942 1.1 mrg if (gimple_store_p (stmt))
943 1.1 mrg {
944 1.1 mrg if (!is_gimple_val (gimple_assign_rhs1 (stmt)))
945 1.1 mrg return false;
946 1.1 mrg is_load = false;
947 1.1 mrg ref = lhs;
948 1.1 mrg }
949 1.1 mrg else if (gimple_assign_load_p (stmt))
950 1.1 mrg {
951 1.1 mrg is_load = true;
952 1.1 mrg ref = gimple_assign_rhs1 (stmt);
953 1.1 mrg }
954 1.1 mrg else
955 1.1 mrg return false;
956 1.1 mrg
957 1.1 mrg if (may_be_nonaddressable_p (ref))
958 1.1 mrg return false;
959 1.1 mrg
960 1.1 mrg /* Mask should be integer mode of the same size as the load/store
961 1.1 mrg mode. */
962 1.1 mrg machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
963 1.1 mrg if (!int_mode_for_mode (mode).exists () || VECTOR_MODE_P (mode))
964 1.1 mrg return false;
965 1.1 mrg
966 1.1 mrg if (can_vec_mask_load_store_p (mode, VOIDmode, is_load))
967 1.1 mrg return true;
968 1.1 mrg
969 1.1 mrg return false;
970 1.1 mrg }
971 1.1 mrg
972 1.1 mrg /* Return true if STMT could be converted from an operation that is
973 1.1 mrg unconditional to one that is conditional on a bb predicate mask. */
974 1.1 mrg
975 1.1 mrg static bool
976 1.1 mrg ifcvt_can_predicate (gimple *stmt)
977 1.1 mrg {
978 1.1 mrg basic_block bb = gimple_bb (stmt);
979 1.1 mrg
980 1.1 mrg if (!(flag_tree_loop_vectorize || bb->loop_father->force_vectorize)
981 1.1 mrg || bb->loop_father->dont_vectorize
982 1.1 mrg || gimple_has_volatile_ops (stmt))
983 1.1 mrg return false;
984 1.1 mrg
985 1.1 mrg if (gimple_assign_single_p (stmt))
986 1.1 mrg return ifcvt_can_use_mask_load_store (stmt);
987 1.1 mrg
988 1.1 mrg tree_code code = gimple_assign_rhs_code (stmt);
989 1.1 mrg tree lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
990 1.1 mrg tree rhs_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
991 1.1 mrg if (!types_compatible_p (lhs_type, rhs_type))
992 1.1 mrg return false;
993 1.1 mrg internal_fn cond_fn = get_conditional_internal_fn (code);
994 1.1 mrg return (cond_fn != IFN_LAST
995 1.1 mrg && vectorized_internal_fn_supported_p (cond_fn, lhs_type));
996 1.1 mrg }
997 1.1 mrg
998 1.1 mrg /* Return true when STMT is if-convertible.
999 1.1 mrg
1000 1.1 mrg GIMPLE_ASSIGN statement is not if-convertible if,
1001 1.1 mrg - it is not movable,
1002 1.1 mrg - it could trap,
1003 1.1 mrg - LHS is not var decl. */
1004 1.1 mrg
1005 1.1 mrg static bool
1006 1.1 mrg if_convertible_gimple_assign_stmt_p (gimple *stmt,
1007 1.1 mrg vec<data_reference_p> refs)
1008 1.1 mrg {
1009 1.1 mrg tree lhs = gimple_assign_lhs (stmt);
1010 1.1 mrg
1011 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
1012 1.1 mrg {
1013 1.1 mrg fprintf (dump_file, "-------------------------\n");
1014 1.1 mrg print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1015 1.1 mrg }
1016 1.1 mrg
1017 1.1 mrg if (!is_gimple_reg_type (TREE_TYPE (lhs)))
1018 1.1 mrg return false;
1019 1.1 mrg
1020 1.1 mrg /* Some of these constrains might be too conservative. */
1021 1.1 mrg if (stmt_ends_bb_p (stmt)
1022 1.1 mrg || gimple_has_volatile_ops (stmt)
1023 1.1 mrg || (TREE_CODE (lhs) == SSA_NAME
1024 1.1 mrg && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
1025 1.1 mrg || gimple_has_side_effects (stmt))
1026 1.1 mrg {
1027 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
1028 1.1 mrg fprintf (dump_file, "stmt not suitable for ifcvt\n");
1029 1.1 mrg return false;
1030 1.1 mrg }
1031 1.1 mrg
1032 1.1 mrg /* tree-into-ssa.cc uses GF_PLF_1, so avoid it, because
1033 1.1 mrg in between if_convertible_loop_p and combine_blocks
1034 1.1 mrg we can perform loop versioning. */
1035 1.1 mrg gimple_set_plf (stmt, GF_PLF_2, false);
1036 1.1 mrg
1037 1.1 mrg if ((! gimple_vuse (stmt)
1038 1.1 mrg || gimple_could_trap_p_1 (stmt, false, false)
1039 1.1 mrg || ! ifcvt_memrefs_wont_trap (stmt, refs))
1040 1.1 mrg && gimple_could_trap_p (stmt))
1041 1.1 mrg {
1042 1.1 mrg if (ifcvt_can_predicate (stmt))
1043 1.1 mrg {
1044 1.1 mrg gimple_set_plf (stmt, GF_PLF_2, true);
1045 1.1 mrg need_to_predicate = true;
1046 1.1 mrg return true;
1047 1.1 mrg }
1048 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
1049 1.1 mrg fprintf (dump_file, "tree could trap...\n");
1050 1.1 mrg return false;
1051 1.1 mrg }
1052 1.1 mrg else if ((INTEGRAL_TYPE_P (TREE_TYPE (lhs))
1053 1.1 mrg || POINTER_TYPE_P (TREE_TYPE (lhs)))
1054 1.1 mrg && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (lhs))
1055 1.1 mrg && arith_code_with_undefined_signed_overflow
1056 1.1 mrg (gimple_assign_rhs_code (stmt)))
1057 1.1 mrg /* We have to rewrite stmts with undefined overflow. */
1058 1.1 mrg need_to_rewrite_undefined = true;
1059 1.1 mrg
1060 1.1 mrg /* When if-converting stores force versioning, likewise if we
1061 1.1 mrg ended up generating store data races. */
1062 1.1 mrg if (gimple_vdef (stmt))
1063 1.1 mrg need_to_predicate = true;
1064 1.1 mrg
1065 1.1 mrg return true;
1066 1.1 mrg }
1067 1.1 mrg
1068 1.1 mrg /* Return true when STMT is if-convertible.
1069 1.1 mrg
1070 1.1 mrg A statement is if-convertible if:
1071 1.1 mrg - it is an if-convertible GIMPLE_ASSIGN,
1072 1.1 mrg - it is a GIMPLE_LABEL or a GIMPLE_COND,
1073 1.1 mrg - it is builtins call. */
1074 1.1 mrg
1075 1.1 mrg static bool
1076 1.1 mrg if_convertible_stmt_p (gimple *stmt, vec<data_reference_p> refs)
1077 1.1 mrg {
1078 1.1 mrg switch (gimple_code (stmt))
1079 1.1 mrg {
1080 1.1 mrg case GIMPLE_LABEL:
1081 1.1 mrg case GIMPLE_DEBUG:
1082 1.1 mrg case GIMPLE_COND:
1083 1.1 mrg return true;
1084 1.1 mrg
1085 1.1 mrg case GIMPLE_ASSIGN:
1086 1.1 mrg return if_convertible_gimple_assign_stmt_p (stmt, refs);
1087 1.1 mrg
1088 1.1 mrg case GIMPLE_CALL:
1089 1.1 mrg {
1090 1.1 mrg tree fndecl = gimple_call_fndecl (stmt);
1091 1.1 mrg if (fndecl)
1092 1.1 mrg {
1093 1.1 mrg int flags = gimple_call_flags (stmt);
1094 1.1 mrg if ((flags & ECF_CONST)
1095 1.1 mrg && !(flags & ECF_LOOPING_CONST_OR_PURE)
1096 1.1 mrg /* We can only vectorize some builtins at the moment,
1097 1.1 mrg so restrict if-conversion to those. */
1098 1.1 mrg && fndecl_built_in_p (fndecl))
1099 1.1 mrg return true;
1100 1.1 mrg }
1101 1.1 mrg return false;
1102 1.1 mrg }
1103 1.1 mrg
1104 1.1 mrg default:
1105 1.1 mrg /* Don't know what to do with 'em so don't do anything. */
1106 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
1107 1.1 mrg {
1108 1.1 mrg fprintf (dump_file, "don't know what to do\n");
1109 1.1 mrg print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
1110 1.1 mrg }
1111 1.1 mrg return false;
1112 1.1 mrg }
1113 1.1 mrg }
1114 1.1 mrg
1115 1.1 mrg /* Assumes that BB has more than 1 predecessors.
1116 1.1 mrg Returns false if at least one successor is not on critical edge
1117 1.1 mrg and true otherwise. */
1118 1.1 mrg
1119 1.1 mrg static inline bool
1120 1.1 mrg all_preds_critical_p (basic_block bb)
1121 1.1 mrg {
1122 1.1 mrg edge e;
1123 1.1 mrg edge_iterator ei;
1124 1.1 mrg
1125 1.1 mrg FOR_EACH_EDGE (e, ei, bb->preds)
1126 1.1 mrg if (EDGE_COUNT (e->src->succs) == 1)
1127 1.1 mrg return false;
1128 1.1 mrg return true;
1129 1.1 mrg }
1130 1.1 mrg
1131 1.1 mrg /* Return true when BB is if-convertible. This routine does not check
1132 1.1 mrg basic block's statements and phis.
1133 1.1 mrg
1134 1.1 mrg A basic block is not if-convertible if:
1135 1.1 mrg - it is non-empty and it is after the exit block (in BFS order),
1136 1.1 mrg - it is after the exit block but before the latch,
1137 1.1 mrg - its edges are not normal.
1138 1.1 mrg
1139 1.1 mrg EXIT_BB is the basic block containing the exit of the LOOP. BB is
1140 1.1 mrg inside LOOP. */
1141 1.1 mrg
1142 1.1 mrg static bool
1143 1.1 mrg if_convertible_bb_p (class loop *loop, basic_block bb, basic_block exit_bb)
1144 1.1 mrg {
1145 1.1 mrg edge e;
1146 1.1 mrg edge_iterator ei;
1147 1.1 mrg
1148 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
1149 1.1 mrg fprintf (dump_file, "----------[%d]-------------\n", bb->index);
1150 1.1 mrg
1151 1.1 mrg if (EDGE_COUNT (bb->succs) > 2)
1152 1.1 mrg return false;
1153 1.1 mrg
1154 1.1 mrg gimple *last = last_stmt (bb);
1155 1.1 mrg if (gcall *call = safe_dyn_cast <gcall *> (last))
1156 1.1 mrg if (gimple_call_ctrl_altering_p (call))
1157 1.1 mrg return false;
1158 1.1 mrg
1159 1.1 mrg if (exit_bb)
1160 1.1 mrg {
1161 1.1 mrg if (bb != loop->latch)
1162 1.1 mrg {
1163 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
1164 1.1 mrg fprintf (dump_file, "basic block after exit bb but before latch\n");
1165 1.1 mrg return false;
1166 1.1 mrg }
1167 1.1 mrg else if (!empty_block_p (bb))
1168 1.1 mrg {
1169 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
1170 1.1 mrg fprintf (dump_file, "non empty basic block after exit bb\n");
1171 1.1 mrg return false;
1172 1.1 mrg }
1173 1.1 mrg else if (bb == loop->latch
1174 1.1 mrg && bb != exit_bb
1175 1.1 mrg && !dominated_by_p (CDI_DOMINATORS, bb, exit_bb))
1176 1.1 mrg {
1177 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
1178 1.1 mrg fprintf (dump_file, "latch is not dominated by exit_block\n");
1179 1.1 mrg return false;
1180 1.1 mrg }
1181 1.1 mrg }
1182 1.1 mrg
1183 1.1 mrg /* Be less adventurous and handle only normal edges. */
1184 1.1 mrg FOR_EACH_EDGE (e, ei, bb->succs)
1185 1.1 mrg if (e->flags & (EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP))
1186 1.1 mrg {
1187 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
1188 1.1 mrg fprintf (dump_file, "Difficult to handle edges\n");
1189 1.1 mrg return false;
1190 1.1 mrg }
1191 1.1 mrg
1192 1.1 mrg return true;
1193 1.1 mrg }
1194 1.1 mrg
1195 1.1 mrg /* Return true when all predecessor blocks of BB are visited. The
1196 1.1 mrg VISITED bitmap keeps track of the visited blocks. */
1197 1.1 mrg
1198 1.1 mrg static bool
1199 1.1 mrg pred_blocks_visited_p (basic_block bb, bitmap *visited)
1200 1.1 mrg {
1201 1.1 mrg edge e;
1202 1.1 mrg edge_iterator ei;
1203 1.1 mrg FOR_EACH_EDGE (e, ei, bb->preds)
1204 1.1 mrg if (!bitmap_bit_p (*visited, e->src->index))
1205 1.1 mrg return false;
1206 1.1 mrg
1207 1.1 mrg return true;
1208 1.1 mrg }
1209 1.1 mrg
1210 1.1 mrg /* Get body of a LOOP in suitable order for if-conversion. It is
1211 1.1 mrg caller's responsibility to deallocate basic block list.
1212 1.1 mrg If-conversion suitable order is, breadth first sort (BFS) order
1213 1.1 mrg with an additional constraint: select a block only if all its
1214 1.1 mrg predecessors are already selected. */
1215 1.1 mrg
1216 1.1 mrg static basic_block *
1217 1.1 mrg get_loop_body_in_if_conv_order (const class loop *loop)
1218 1.1 mrg {
1219 1.1 mrg basic_block *blocks, *blocks_in_bfs_order;
1220 1.1 mrg basic_block bb;
1221 1.1 mrg bitmap visited;
1222 1.1 mrg unsigned int index = 0;
1223 1.1 mrg unsigned int visited_count = 0;
1224 1.1 mrg
1225 1.1 mrg gcc_assert (loop->num_nodes);
1226 1.1 mrg gcc_assert (loop->latch != EXIT_BLOCK_PTR_FOR_FN (cfun));
1227 1.1 mrg
1228 1.1 mrg blocks = XCNEWVEC (basic_block, loop->num_nodes);
1229 1.1 mrg visited = BITMAP_ALLOC (NULL);
1230 1.1 mrg
1231 1.1 mrg blocks_in_bfs_order = get_loop_body_in_bfs_order (loop);
1232 1.1 mrg
1233 1.1 mrg index = 0;
1234 1.1 mrg while (index < loop->num_nodes)
1235 1.1 mrg {
1236 1.1 mrg bb = blocks_in_bfs_order [index];
1237 1.1 mrg
1238 1.1 mrg if (bb->flags & BB_IRREDUCIBLE_LOOP)
1239 1.1 mrg {
1240 1.1 mrg free (blocks_in_bfs_order);
1241 1.1 mrg BITMAP_FREE (visited);
1242 1.1 mrg free (blocks);
1243 1.1 mrg return NULL;
1244 1.1 mrg }
1245 1.1 mrg
1246 1.1 mrg if (!bitmap_bit_p (visited, bb->index))
1247 1.1 mrg {
1248 1.1 mrg if (pred_blocks_visited_p (bb, &visited)
1249 1.1 mrg || bb == loop->header)
1250 1.1 mrg {
1251 1.1 mrg /* This block is now visited. */
1252 1.1 mrg bitmap_set_bit (visited, bb->index);
1253 1.1 mrg blocks[visited_count++] = bb;
1254 1.1 mrg }
1255 1.1 mrg }
1256 1.1 mrg
1257 1.1 mrg index++;
1258 1.1 mrg
1259 1.1 mrg if (index == loop->num_nodes
1260 1.1 mrg && visited_count != loop->num_nodes)
1261 1.1 mrg /* Not done yet. */
1262 1.1 mrg index = 0;
1263 1.1 mrg }
1264 1.1 mrg free (blocks_in_bfs_order);
1265 1.1 mrg BITMAP_FREE (visited);
1266 1.1 mrg return blocks;
1267 1.1 mrg }
1268 1.1 mrg
1269 1.1 mrg /* Returns true when the analysis of the predicates for all the basic
1270 1.1 mrg blocks in LOOP succeeded.
1271 1.1 mrg
1272 1.1 mrg predicate_bbs first allocates the predicates of the basic blocks.
1273 1.1 mrg These fields are then initialized with the tree expressions
1274 1.1 mrg representing the predicates under which a basic block is executed
1275 1.1 mrg in the LOOP. As the loop->header is executed at each iteration, it
1276 1.1 mrg has the "true" predicate. Other statements executed under a
1277 1.1 mrg condition are predicated with that condition, for example
1278 1.1 mrg
1279 1.1 mrg | if (x)
1280 1.1 mrg | S1;
1281 1.1 mrg | else
1282 1.1 mrg | S2;
1283 1.1 mrg
1284 1.1 mrg S1 will be predicated with "x", and
1285 1.1 mrg S2 will be predicated with "!x". */
1286 1.1 mrg
1287 1.1 mrg static void
1288 1.1 mrg predicate_bbs (loop_p loop)
1289 1.1 mrg {
1290 1.1 mrg unsigned int i;
1291 1.1 mrg
1292 1.1 mrg for (i = 0; i < loop->num_nodes; i++)
1293 1.1 mrg init_bb_predicate (ifc_bbs[i]);
1294 1.1 mrg
1295 1.1 mrg for (i = 0; i < loop->num_nodes; i++)
1296 1.1 mrg {
1297 1.1 mrg basic_block bb = ifc_bbs[i];
1298 1.1 mrg tree cond;
1299 1.1 mrg gimple *stmt;
1300 1.1 mrg
1301 1.1 mrg /* The loop latch and loop exit block are always executed and
1302 1.1 mrg have no extra conditions to be processed: skip them. */
1303 1.1 mrg if (bb == loop->latch
1304 1.1 mrg || bb_with_exit_edge_p (loop, bb))
1305 1.1 mrg {
1306 1.1 mrg reset_bb_predicate (bb);
1307 1.1 mrg continue;
1308 1.1 mrg }
1309 1.1 mrg
1310 1.1 mrg cond = bb_predicate (bb);
1311 1.1 mrg stmt = last_stmt (bb);
1312 1.1 mrg if (stmt && gimple_code (stmt) == GIMPLE_COND)
1313 1.1 mrg {
1314 1.1 mrg tree c2;
1315 1.1 mrg edge true_edge, false_edge;
1316 1.1 mrg location_t loc = gimple_location (stmt);
1317 1.1 mrg tree c = build2_loc (loc, gimple_cond_code (stmt),
1318 1.1 mrg boolean_type_node,
1319 1.1 mrg gimple_cond_lhs (stmt),
1320 1.1 mrg gimple_cond_rhs (stmt));
1321 1.1 mrg
1322 1.1 mrg /* Add new condition into destination's predicate list. */
1323 1.1 mrg extract_true_false_edges_from_block (gimple_bb (stmt),
1324 1.1 mrg &true_edge, &false_edge);
1325 1.1 mrg
1326 1.1 mrg /* If C is true, then TRUE_EDGE is taken. */
1327 1.1 mrg add_to_dst_predicate_list (loop, true_edge, unshare_expr (cond),
1328 1.1 mrg unshare_expr (c));
1329 1.1 mrg
1330 1.1 mrg /* If C is false, then FALSE_EDGE is taken. */
1331 1.1 mrg c2 = build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node,
1332 1.1 mrg unshare_expr (c));
1333 1.1 mrg add_to_dst_predicate_list (loop, false_edge,
1334 1.1 mrg unshare_expr (cond), c2);
1335 1.1 mrg
1336 1.1 mrg cond = NULL_TREE;
1337 1.1 mrg }
1338 1.1 mrg
1339 1.1 mrg /* If current bb has only one successor, then consider it as an
1340 1.1 mrg unconditional goto. */
1341 1.1 mrg if (single_succ_p (bb))
1342 1.1 mrg {
1343 1.1 mrg basic_block bb_n = single_succ (bb);
1344 1.1 mrg
1345 1.1 mrg /* The successor bb inherits the predicate of its
1346 1.1 mrg predecessor. If there is no predicate in the predecessor
1347 1.1 mrg bb, then consider the successor bb as always executed. */
1348 1.1 mrg if (cond == NULL_TREE)
1349 1.1 mrg cond = boolean_true_node;
1350 1.1 mrg
1351 1.1 mrg add_to_predicate_list (loop, bb_n, cond);
1352 1.1 mrg }
1353 1.1 mrg }
1354 1.1 mrg
1355 1.1 mrg /* The loop header is always executed. */
1356 1.1 mrg reset_bb_predicate (loop->header);
1357 1.1 mrg gcc_assert (bb_predicate_gimplified_stmts (loop->header) == NULL
1358 1.1 mrg && bb_predicate_gimplified_stmts (loop->latch) == NULL);
1359 1.1 mrg }
1360 1.1 mrg
1361 1.1 mrg /* Build region by adding loop pre-header and post-header blocks. */
1362 1.1 mrg
1363 1.1 mrg static vec<basic_block>
1364 1.1 mrg build_region (class loop *loop)
1365 1.1 mrg {
1366 1.1 mrg vec<basic_block> region = vNULL;
1367 1.1 mrg basic_block exit_bb = NULL;
1368 1.1 mrg
1369 1.1 mrg gcc_assert (ifc_bbs);
1370 1.1 mrg /* The first element is loop pre-header. */
1371 1.1 mrg region.safe_push (loop_preheader_edge (loop)->src);
1372 1.1 mrg
1373 1.1 mrg for (unsigned int i = 0; i < loop->num_nodes; i++)
1374 1.1 mrg {
1375 1.1 mrg basic_block bb = ifc_bbs[i];
1376 1.1 mrg region.safe_push (bb);
1377 1.1 mrg /* Find loop postheader. */
1378 1.1 mrg edge e;
1379 1.1 mrg edge_iterator ei;
1380 1.1 mrg FOR_EACH_EDGE (e, ei, bb->succs)
1381 1.1 mrg if (loop_exit_edge_p (loop, e))
1382 1.1 mrg {
1383 1.1 mrg exit_bb = e->dest;
1384 1.1 mrg break;
1385 1.1 mrg }
1386 1.1 mrg }
1387 1.1 mrg /* The last element is loop post-header. */
1388 1.1 mrg gcc_assert (exit_bb);
1389 1.1 mrg region.safe_push (exit_bb);
1390 1.1 mrg return region;
1391 1.1 mrg }
1392 1.1 mrg
1393 1.1 mrg /* Return true when LOOP is if-convertible. This is a helper function
1394 1.1 mrg for if_convertible_loop_p. REFS and DDRS are initialized and freed
1395 1.1 mrg in if_convertible_loop_p. */
1396 1.1 mrg
1397 1.1 mrg static bool
1398 1.1 mrg if_convertible_loop_p_1 (class loop *loop, vec<data_reference_p> *refs)
1399 1.1 mrg {
1400 1.1 mrg unsigned int i;
1401 1.1 mrg basic_block exit_bb = NULL;
1402 1.1 mrg vec<basic_block> region;
1403 1.1 mrg
1404 1.1 mrg if (find_data_references_in_loop (loop, refs) == chrec_dont_know)
1405 1.1 mrg return false;
1406 1.1 mrg
1407 1.1 mrg calculate_dominance_info (CDI_DOMINATORS);
1408 1.1 mrg
1409 1.1 mrg /* Allow statements that can be handled during if-conversion. */
1410 1.1 mrg ifc_bbs = get_loop_body_in_if_conv_order (loop);
1411 1.1 mrg if (!ifc_bbs)
1412 1.1 mrg {
1413 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
1414 1.1 mrg fprintf (dump_file, "Irreducible loop\n");
1415 1.1 mrg return false;
1416 1.1 mrg }
1417 1.1 mrg
1418 1.1 mrg for (i = 0; i < loop->num_nodes; i++)
1419 1.1 mrg {
1420 1.1 mrg basic_block bb = ifc_bbs[i];
1421 1.1 mrg
1422 1.1 mrg if (!if_convertible_bb_p (loop, bb, exit_bb))
1423 1.1 mrg return false;
1424 1.1 mrg
1425 1.1 mrg if (bb_with_exit_edge_p (loop, bb))
1426 1.1 mrg exit_bb = bb;
1427 1.1 mrg }
1428 1.1 mrg
1429 1.1 mrg for (i = 0; i < loop->num_nodes; i++)
1430 1.1 mrg {
1431 1.1 mrg basic_block bb = ifc_bbs[i];
1432 1.1 mrg gimple_stmt_iterator gsi;
1433 1.1 mrg
1434 1.1 mrg bool may_have_nonlocal_labels
1435 1.1 mrg = bb_with_exit_edge_p (loop, bb) || bb == loop->latch;
1436 1.1 mrg for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1437 1.1 mrg switch (gimple_code (gsi_stmt (gsi)))
1438 1.1 mrg {
1439 1.1 mrg case GIMPLE_LABEL:
1440 1.1 mrg if (!may_have_nonlocal_labels)
1441 1.1 mrg {
1442 1.1 mrg tree label
1443 1.1 mrg = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi)));
1444 1.1 mrg if (DECL_NONLOCAL (label) || FORCED_LABEL (label))
1445 1.1 mrg return false;
1446 1.1 mrg }
1447 1.1 mrg /* Fallthru. */
1448 1.1 mrg case GIMPLE_ASSIGN:
1449 1.1 mrg case GIMPLE_CALL:
1450 1.1 mrg case GIMPLE_DEBUG:
1451 1.1 mrg case GIMPLE_COND:
1452 1.1 mrg gimple_set_uid (gsi_stmt (gsi), 0);
1453 1.1 mrg break;
1454 1.1 mrg default:
1455 1.1 mrg return false;
1456 1.1 mrg }
1457 1.1 mrg }
1458 1.1 mrg
1459 1.1 mrg data_reference_p dr;
1460 1.1 mrg
1461 1.1 mrg innermost_DR_map
1462 1.1 mrg = new hash_map<innermost_loop_behavior_hash, data_reference_p>;
1463 1.1 mrg baseref_DR_map = new hash_map<tree_operand_hash, data_reference_p>;
1464 1.1 mrg
1465 1.1 mrg /* Compute post-dominator tree locally. */
1466 1.1 mrg region = build_region (loop);
1467 1.1 mrg calculate_dominance_info_for_region (CDI_POST_DOMINATORS, region);
1468 1.1 mrg
1469 1.1 mrg predicate_bbs (loop);
1470 1.1 mrg
1471 1.1 mrg /* Free post-dominator tree since it is not used after predication. */
1472 1.1 mrg free_dominance_info_for_region (cfun, CDI_POST_DOMINATORS, region);
1473 1.1 mrg region.release ();
1474 1.1 mrg
1475 1.1 mrg for (i = 0; refs->iterate (i, &dr); i++)
1476 1.1 mrg {
1477 1.1 mrg tree ref = DR_REF (dr);
1478 1.1 mrg
1479 1.1 mrg dr->aux = XNEW (struct ifc_dr);
1480 1.1 mrg DR_BASE_W_UNCONDITIONALLY (dr) = false;
1481 1.1 mrg DR_RW_UNCONDITIONALLY (dr) = false;
1482 1.1 mrg DR_W_UNCONDITIONALLY (dr) = false;
1483 1.1 mrg IFC_DR (dr)->rw_predicate = boolean_false_node;
1484 1.1 mrg IFC_DR (dr)->w_predicate = boolean_false_node;
1485 1.1 mrg IFC_DR (dr)->base_w_predicate = boolean_false_node;
1486 1.1 mrg if (gimple_uid (DR_STMT (dr)) == 0)
1487 1.1 mrg gimple_set_uid (DR_STMT (dr), i + 1);
1488 1.1 mrg
1489 1.1 mrg /* If DR doesn't have innermost loop behavior or it's a compound
1490 1.1 mrg memory reference, we synthesize its innermost loop behavior
1491 1.1 mrg for hashing. */
1492 1.1 mrg if (TREE_CODE (ref) == COMPONENT_REF
1493 1.1 mrg || TREE_CODE (ref) == IMAGPART_EXPR
1494 1.1 mrg || TREE_CODE (ref) == REALPART_EXPR
1495 1.1 mrg || !(DR_BASE_ADDRESS (dr) || DR_OFFSET (dr)
1496 1.1 mrg || DR_INIT (dr) || DR_STEP (dr)))
1497 1.1 mrg {
1498 1.1 mrg while (TREE_CODE (ref) == COMPONENT_REF
1499 1.1 mrg || TREE_CODE (ref) == IMAGPART_EXPR
1500 1.1 mrg || TREE_CODE (ref) == REALPART_EXPR)
1501 1.1 mrg ref = TREE_OPERAND (ref, 0);
1502 1.1 mrg
1503 1.1 mrg memset (&DR_INNERMOST (dr), 0, sizeof (DR_INNERMOST (dr)));
1504 1.1 mrg DR_BASE_ADDRESS (dr) = ref;
1505 1.1 mrg }
1506 1.1 mrg hash_memrefs_baserefs_and_store_DRs_read_written_info (dr);
1507 1.1 mrg }
1508 1.1 mrg
1509 1.1 mrg for (i = 0; i < loop->num_nodes; i++)
1510 1.1 mrg {
1511 1.1 mrg basic_block bb = ifc_bbs[i];
1512 1.1 mrg gimple_stmt_iterator itr;
1513 1.1 mrg
1514 1.1 mrg /* Check the if-convertibility of statements in predicated BBs. */
1515 1.1 mrg if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
1516 1.1 mrg for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr))
1517 1.1 mrg if (!if_convertible_stmt_p (gsi_stmt (itr), *refs))
1518 1.1 mrg return false;
1519 1.1 mrg }
1520 1.1 mrg
1521 1.1 mrg /* Checking PHIs needs to be done after stmts, as the fact whether there
1522 1.1 mrg are any masked loads or stores affects the tests. */
1523 1.1 mrg for (i = 0; i < loop->num_nodes; i++)
1524 1.1 mrg {
1525 1.1 mrg basic_block bb = ifc_bbs[i];
1526 1.1 mrg gphi_iterator itr;
1527 1.1 mrg
1528 1.1 mrg for (itr = gsi_start_phis (bb); !gsi_end_p (itr); gsi_next (&itr))
1529 1.1 mrg if (!if_convertible_phi_p (loop, bb, itr.phi ()))
1530 1.1 mrg return false;
1531 1.1 mrg }
1532 1.1 mrg
1533 1.1 mrg if (dump_file)
1534 1.1 mrg fprintf (dump_file, "Applying if-conversion\n");
1535 1.1 mrg
1536 1.1 mrg return true;
1537 1.1 mrg }
1538 1.1 mrg
1539 1.1 mrg /* Return true when LOOP is if-convertible.
1540 1.1 mrg LOOP is if-convertible if:
1541 1.1 mrg - it is innermost,
1542 1.1 mrg - it has two or more basic blocks,
1543 1.1 mrg - it has only one exit,
1544 1.1 mrg - loop header is not the exit edge,
1545 1.1 mrg - if its basic blocks and phi nodes are if convertible. */
1546 1.1 mrg
1547 1.1 mrg static bool
1548 1.1 mrg if_convertible_loop_p (class loop *loop)
1549 1.1 mrg {
1550 1.1 mrg edge e;
1551 1.1 mrg edge_iterator ei;
1552 1.1 mrg bool res = false;
1553 1.1 mrg vec<data_reference_p> refs;
1554 1.1 mrg
1555 1.1 mrg /* Handle only innermost loop. */
1556 1.1 mrg if (!loop || loop->inner)
1557 1.1 mrg {
1558 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
1559 1.1 mrg fprintf (dump_file, "not innermost loop\n");
1560 1.1 mrg return false;
1561 1.1 mrg }
1562 1.1 mrg
1563 1.1 mrg /* If only one block, no need for if-conversion. */
1564 1.1 mrg if (loop->num_nodes <= 2)
1565 1.1 mrg {
1566 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
1567 1.1 mrg fprintf (dump_file, "less than 2 basic blocks\n");
1568 1.1 mrg return false;
1569 1.1 mrg }
1570 1.1 mrg
1571 1.1 mrg /* More than one loop exit is too much to handle. */
1572 1.1 mrg if (!single_exit (loop))
1573 1.1 mrg {
1574 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
1575 1.1 mrg fprintf (dump_file, "multiple exits\n");
1576 1.1 mrg return false;
1577 1.1 mrg }
1578 1.1 mrg
1579 1.1 mrg /* If one of the loop header's edge is an exit edge then do not
1580 1.1 mrg apply if-conversion. */
1581 1.1 mrg FOR_EACH_EDGE (e, ei, loop->header->succs)
1582 1.1 mrg if (loop_exit_edge_p (loop, e))
1583 1.1 mrg return false;
1584 1.1 mrg
1585 1.1 mrg refs.create (5);
1586 1.1 mrg res = if_convertible_loop_p_1 (loop, &refs);
1587 1.1 mrg
1588 1.1 mrg data_reference_p dr;
1589 1.1 mrg unsigned int i;
1590 1.1 mrg for (i = 0; refs.iterate (i, &dr); i++)
1591 1.1 mrg free (dr->aux);
1592 1.1 mrg
1593 1.1 mrg free_data_refs (refs);
1594 1.1 mrg
1595 1.1 mrg delete innermost_DR_map;
1596 1.1 mrg innermost_DR_map = NULL;
1597 1.1 mrg
1598 1.1 mrg delete baseref_DR_map;
1599 1.1 mrg baseref_DR_map = NULL;
1600 1.1 mrg
1601 1.1 mrg return res;
1602 1.1 mrg }
1603 1.1 mrg
1604 1.1 mrg /* Return reduc_1 if has_nop.
1605 1.1 mrg
1606 1.1 mrg if (...)
1607 1.1 mrg tmp1 = (unsigned type) reduc_1;
1608 1.1 mrg tmp2 = tmp1 + rhs2;
1609 1.1 mrg reduc_3 = (signed type) tmp2. */
1610 1.1 mrg static tree
1611 1.1 mrg strip_nop_cond_scalar_reduction (bool has_nop, tree op)
1612 1.1 mrg {
1613 1.1 mrg if (!has_nop)
1614 1.1 mrg return op;
1615 1.1 mrg
1616 1.1 mrg if (TREE_CODE (op) != SSA_NAME)
1617 1.1 mrg return NULL_TREE;
1618 1.1 mrg
1619 1.1 mrg gassign *stmt = safe_dyn_cast <gassign *> (SSA_NAME_DEF_STMT (op));
1620 1.1 mrg if (!stmt
1621 1.1 mrg || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
1622 1.1 mrg || !tree_nop_conversion_p (TREE_TYPE (op), TREE_TYPE
1623 1.1 mrg (gimple_assign_rhs1 (stmt))))
1624 1.1 mrg return NULL_TREE;
1625 1.1 mrg
1626 1.1 mrg return gimple_assign_rhs1 (stmt);
1627 1.1 mrg }
1628 1.1 mrg
1629 1.1 mrg /* Returns true if def-stmt for phi argument ARG is simple increment/decrement
1630 1.1 mrg which is in predicated basic block.
1631 1.1 mrg In fact, the following PHI pattern is searching:
1632 1.1 mrg loop-header:
1633 1.1 mrg reduc_1 = PHI <..., reduc_2>
1634 1.1 mrg ...
1635 1.1 mrg if (...)
1636 1.1 mrg reduc_3 = ...
1637 1.1 mrg reduc_2 = PHI <reduc_1, reduc_3>
1638 1.1 mrg
1639 1.1 mrg ARG_0 and ARG_1 are correspondent PHI arguments.
1640 1.1 mrg REDUC, OP0 and OP1 contain reduction stmt and its operands.
1641 1.1 mrg EXTENDED is true if PHI has > 2 arguments. */
1642 1.1 mrg
1643 1.1 mrg static bool
1644 1.1 mrg is_cond_scalar_reduction (gimple *phi, gimple **reduc, tree arg_0, tree arg_1,
1645 1.1 mrg tree *op0, tree *op1, bool extended, bool* has_nop,
1646 1.1 mrg gimple **nop_reduc)
1647 1.1 mrg {
1648 1.1 mrg tree lhs, r_op1, r_op2, r_nop1, r_nop2;
1649 1.1 mrg gimple *stmt;
1650 1.1 mrg gimple *header_phi = NULL;
1651 1.1 mrg enum tree_code reduction_op;
1652 1.1 mrg basic_block bb = gimple_bb (phi);
1653 1.1 mrg class loop *loop = bb->loop_father;
1654 1.1 mrg edge latch_e = loop_latch_edge (loop);
1655 1.1 mrg imm_use_iterator imm_iter;
1656 1.1 mrg use_operand_p use_p;
1657 1.1 mrg edge e;
1658 1.1 mrg edge_iterator ei;
1659 1.1 mrg bool result = *has_nop = false;
1660 1.1 mrg if (TREE_CODE (arg_0) != SSA_NAME || TREE_CODE (arg_1) != SSA_NAME)
1661 1.1 mrg return false;
1662 1.1 mrg
1663 1.1 mrg if (!extended && gimple_code (SSA_NAME_DEF_STMT (arg_0)) == GIMPLE_PHI)
1664 1.1 mrg {
1665 1.1 mrg lhs = arg_1;
1666 1.1 mrg header_phi = SSA_NAME_DEF_STMT (arg_0);
1667 1.1 mrg stmt = SSA_NAME_DEF_STMT (arg_1);
1668 1.1 mrg }
1669 1.1 mrg else if (gimple_code (SSA_NAME_DEF_STMT (arg_1)) == GIMPLE_PHI)
1670 1.1 mrg {
1671 1.1 mrg lhs = arg_0;
1672 1.1 mrg header_phi = SSA_NAME_DEF_STMT (arg_1);
1673 1.1 mrg stmt = SSA_NAME_DEF_STMT (arg_0);
1674 1.1 mrg }
1675 1.1 mrg else
1676 1.1 mrg return false;
1677 1.1 mrg if (gimple_bb (header_phi) != loop->header)
1678 1.1 mrg return false;
1679 1.1 mrg
1680 1.1 mrg if (PHI_ARG_DEF_FROM_EDGE (header_phi, latch_e) != PHI_RESULT (phi))
1681 1.1 mrg return false;
1682 1.1 mrg
1683 1.1 mrg if (gimple_code (stmt) != GIMPLE_ASSIGN
1684 1.1 mrg || gimple_has_volatile_ops (stmt))
1685 1.1 mrg return false;
1686 1.1 mrg
1687 1.1 mrg if (!flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
1688 1.1 mrg return false;
1689 1.1 mrg
1690 1.1 mrg if (!is_predicated (gimple_bb (stmt)))
1691 1.1 mrg return false;
1692 1.1 mrg
1693 1.1 mrg /* Check that stmt-block is predecessor of phi-block. */
1694 1.1 mrg FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
1695 1.1 mrg if (e->dest == bb)
1696 1.1 mrg {
1697 1.1 mrg result = true;
1698 1.1 mrg break;
1699 1.1 mrg }
1700 1.1 mrg if (!result)
1701 1.1 mrg return false;
1702 1.1 mrg
1703 1.1 mrg if (!has_single_use (lhs))
1704 1.1 mrg return false;
1705 1.1 mrg
1706 1.1 mrg reduction_op = gimple_assign_rhs_code (stmt);
1707 1.1 mrg
1708 1.1 mrg /* Catch something like below
1709 1.1 mrg
1710 1.1 mrg loop-header:
1711 1.1 mrg reduc_1 = PHI <..., reduc_2>
1712 1.1 mrg ...
1713 1.1 mrg if (...)
1714 1.1 mrg tmp1 = (unsigned type) reduc_1;
1715 1.1 mrg tmp2 = tmp1 + rhs2;
1716 1.1 mrg reduc_3 = (signed type) tmp2;
1717 1.1 mrg
1718 1.1 mrg reduc_2 = PHI <reduc_1, reduc_3>
1719 1.1 mrg
1720 1.1 mrg and convert to
1721 1.1 mrg
1722 1.1 mrg reduc_2 = PHI <0, reduc_3>
1723 1.1 mrg tmp1 = (unsigned type)reduce_1;
1724 1.1 mrg ifcvt = cond_expr ? rhs2 : 0
1725 1.1 mrg tmp2 = tmp1 +/- ifcvt;
1726 1.1 mrg reduce_1 = (signed type)tmp2; */
1727 1.1 mrg
1728 1.1 mrg if (CONVERT_EXPR_CODE_P (reduction_op))
1729 1.1 mrg {
1730 1.1 mrg lhs = gimple_assign_rhs1 (stmt);
1731 1.1 mrg if (TREE_CODE (lhs) != SSA_NAME
1732 1.1 mrg || !has_single_use (lhs))
1733 1.1 mrg return false;
1734 1.1 mrg
1735 1.1 mrg *nop_reduc = stmt;
1736 1.1 mrg stmt = SSA_NAME_DEF_STMT (lhs);
1737 1.1 mrg if (gimple_bb (stmt) != gimple_bb (*nop_reduc)
1738 1.1 mrg || !is_gimple_assign (stmt))
1739 1.1 mrg return false;
1740 1.1 mrg
1741 1.1 mrg *has_nop = true;
1742 1.1 mrg reduction_op = gimple_assign_rhs_code (stmt);
1743 1.1 mrg }
1744 1.1 mrg
1745 1.1 mrg if (reduction_op != PLUS_EXPR
1746 1.1 mrg && reduction_op != MINUS_EXPR
1747 1.1 mrg && reduction_op != BIT_IOR_EXPR
1748 1.1 mrg && reduction_op != BIT_XOR_EXPR
1749 1.1 mrg && reduction_op != BIT_AND_EXPR)
1750 1.1 mrg return false;
1751 1.1 mrg r_op1 = gimple_assign_rhs1 (stmt);
1752 1.1 mrg r_op2 = gimple_assign_rhs2 (stmt);
1753 1.1 mrg
1754 1.1 mrg r_nop1 = strip_nop_cond_scalar_reduction (*has_nop, r_op1);
1755 1.1 mrg r_nop2 = strip_nop_cond_scalar_reduction (*has_nop, r_op2);
1756 1.1 mrg
1757 1.1 mrg /* Make R_OP1 to hold reduction variable. */
1758 1.1 mrg if (r_nop2 == PHI_RESULT (header_phi)
1759 1.1 mrg && commutative_tree_code (reduction_op))
1760 1.1 mrg {
1761 1.1 mrg std::swap (r_op1, r_op2);
1762 1.1 mrg std::swap (r_nop1, r_nop2);
1763 1.1 mrg }
1764 1.1 mrg else if (r_nop1 != PHI_RESULT (header_phi))
1765 1.1 mrg return false;
1766 1.1 mrg
1767 1.1 mrg if (*has_nop)
1768 1.1 mrg {
1769 1.1 mrg /* Check that R_NOP1 is used in nop_stmt or in PHI only. */
1770 1.1 mrg FOR_EACH_IMM_USE_FAST (use_p, imm_iter, r_nop1)
1771 1.1 mrg {
1772 1.1 mrg gimple *use_stmt = USE_STMT (use_p);
1773 1.1 mrg if (is_gimple_debug (use_stmt))
1774 1.1 mrg continue;
1775 1.1 mrg if (use_stmt == SSA_NAME_DEF_STMT (r_op1))
1776 1.1 mrg continue;
1777 1.1 mrg if (use_stmt != phi)
1778 1.1 mrg return false;
1779 1.1 mrg }
1780 1.1 mrg }
1781 1.1 mrg
1782 1.1 mrg /* Check that R_OP1 is used in reduction stmt or in PHI only. */
1783 1.1 mrg FOR_EACH_IMM_USE_FAST (use_p, imm_iter, r_op1)
1784 1.1 mrg {
1785 1.1 mrg gimple *use_stmt = USE_STMT (use_p);
1786 1.1 mrg if (is_gimple_debug (use_stmt))
1787 1.1 mrg continue;
1788 1.1 mrg if (use_stmt == stmt)
1789 1.1 mrg continue;
1790 1.1 mrg if (gimple_code (use_stmt) != GIMPLE_PHI)
1791 1.1 mrg return false;
1792 1.1 mrg }
1793 1.1 mrg
1794 1.1 mrg *op0 = r_op1; *op1 = r_op2;
1795 1.1 mrg *reduc = stmt;
1796 1.1 mrg return true;
1797 1.1 mrg }
1798 1.1 mrg
1799 1.1 mrg /* Converts conditional scalar reduction into unconditional form, e.g.
1800 1.1 mrg bb_4
1801 1.1 mrg if (_5 != 0) goto bb_5 else goto bb_6
1802 1.1 mrg end_bb_4
1803 1.1 mrg bb_5
1804 1.1 mrg res_6 = res_13 + 1;
1805 1.1 mrg end_bb_5
1806 1.1 mrg bb_6
1807 1.1 mrg # res_2 = PHI <res_13(4), res_6(5)>
1808 1.1 mrg end_bb_6
1809 1.1 mrg
1810 1.1 mrg will be converted into sequence
1811 1.1 mrg _ifc__1 = _5 != 0 ? 1 : 0;
1812 1.1 mrg res_2 = res_13 + _ifc__1;
1813 1.1 mrg Argument SWAP tells that arguments of conditional expression should be
1814 1.1 mrg swapped.
1815 1.1 mrg Returns rhs of resulting PHI assignment. */
1816 1.1 mrg
1817 1.1 mrg static tree
1818 1.1 mrg convert_scalar_cond_reduction (gimple *reduc, gimple_stmt_iterator *gsi,
1819 1.1 mrg tree cond, tree op0, tree op1, bool swap,
1820 1.1 mrg bool has_nop, gimple* nop_reduc)
1821 1.1 mrg {
1822 1.1 mrg gimple_stmt_iterator stmt_it;
1823 1.1 mrg gimple *new_assign;
1824 1.1 mrg tree rhs;
1825 1.1 mrg tree rhs1 = gimple_assign_rhs1 (reduc);
1826 1.1 mrg tree tmp = make_temp_ssa_name (TREE_TYPE (rhs1), NULL, "_ifc_");
1827 1.1 mrg tree c;
1828 1.1 mrg enum tree_code reduction_op = gimple_assign_rhs_code (reduc);
1829 1.1 mrg tree op_nochange = neutral_op_for_reduction (TREE_TYPE (rhs1), reduction_op, NULL);
1830 1.1 mrg gimple_seq stmts = NULL;
1831 1.1 mrg
1832 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
1833 1.1 mrg {
1834 1.1 mrg fprintf (dump_file, "Found cond scalar reduction.\n");
1835 1.1 mrg print_gimple_stmt (dump_file, reduc, 0, TDF_SLIM);
1836 1.1 mrg }
1837 1.1 mrg
1838 1.1 mrg /* Build cond expression using COND and constant operand
1839 1.1 mrg of reduction rhs. */
1840 1.1 mrg c = fold_build_cond_expr (TREE_TYPE (rhs1),
1841 1.1 mrg unshare_expr (cond),
1842 1.1 mrg swap ? op_nochange : op1,
1843 1.1 mrg swap ? op1 : op_nochange);
1844 1.1 mrg
1845 1.1 mrg /* Create assignment stmt and insert it at GSI. */
1846 1.1 mrg new_assign = gimple_build_assign (tmp, c);
1847 1.1 mrg gsi_insert_before (gsi, new_assign, GSI_SAME_STMT);
1848 1.1 mrg /* Build rhs for unconditional increment/decrement/logic_operation. */
1849 1.1 mrg rhs = gimple_build (&stmts, reduction_op,
1850 1.1 mrg TREE_TYPE (rhs1), op0, tmp);
1851 1.1 mrg
1852 1.1 mrg if (has_nop)
1853 1.1 mrg {
1854 1.1 mrg rhs = gimple_convert (&stmts,
1855 1.1 mrg TREE_TYPE (gimple_assign_lhs (nop_reduc)), rhs);
1856 1.1 mrg stmt_it = gsi_for_stmt (nop_reduc);
1857 1.1 mrg gsi_remove (&stmt_it, true);
1858 1.1 mrg release_defs (nop_reduc);
1859 1.1 mrg }
1860 1.1 mrg gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1861 1.1 mrg
1862 1.1 mrg /* Delete original reduction stmt. */
1863 1.1 mrg stmt_it = gsi_for_stmt (reduc);
1864 1.1 mrg gsi_remove (&stmt_it, true);
1865 1.1 mrg release_defs (reduc);
1866 1.1 mrg return rhs;
1867 1.1 mrg }
1868 1.1 mrg
1869 1.1 mrg /* Produce condition for all occurrences of ARG in PHI node. */
1870 1.1 mrg
1871 1.1 mrg static tree
1872 1.1 mrg gen_phi_arg_condition (gphi *phi, vec<int> *occur,
1873 1.1 mrg gimple_stmt_iterator *gsi)
1874 1.1 mrg {
1875 1.1 mrg int len;
1876 1.1 mrg int i;
1877 1.1 mrg tree cond = NULL_TREE;
1878 1.1 mrg tree c;
1879 1.1 mrg edge e;
1880 1.1 mrg
1881 1.1 mrg len = occur->length ();
1882 1.1 mrg gcc_assert (len > 0);
1883 1.1 mrg for (i = 0; i < len; i++)
1884 1.1 mrg {
1885 1.1 mrg e = gimple_phi_arg_edge (phi, (*occur)[i]);
1886 1.1 mrg c = bb_predicate (e->src);
1887 1.1 mrg if (is_true_predicate (c))
1888 1.1 mrg {
1889 1.1 mrg cond = c;
1890 1.1 mrg break;
1891 1.1 mrg }
1892 1.1 mrg c = force_gimple_operand_gsi_1 (gsi, unshare_expr (c),
1893 1.1 mrg is_gimple_condexpr, NULL_TREE,
1894 1.1 mrg true, GSI_SAME_STMT);
1895 1.1 mrg if (cond != NULL_TREE)
1896 1.1 mrg {
1897 1.1 mrg /* Must build OR expression. */
1898 1.1 mrg cond = fold_or_predicates (EXPR_LOCATION (c), c, cond);
1899 1.1 mrg cond = force_gimple_operand_gsi_1 (gsi, unshare_expr (cond),
1900 1.1 mrg is_gimple_condexpr, NULL_TREE,
1901 1.1 mrg true, GSI_SAME_STMT);
1902 1.1 mrg }
1903 1.1 mrg else
1904 1.1 mrg cond = c;
1905 1.1 mrg }
1906 1.1 mrg gcc_assert (cond != NULL_TREE);
1907 1.1 mrg return cond;
1908 1.1 mrg }
1909 1.1 mrg
1910 1.1 mrg /* Local valueization callback that follows all-use SSA edges. */
1911 1.1 mrg
1912 1.1 mrg static tree
1913 1.1 mrg ifcvt_follow_ssa_use_edges (tree val)
1914 1.1 mrg {
1915 1.1 mrg return val;
1916 1.1 mrg }
1917 1.1 mrg
1918 1.1 mrg /* Replace a scalar PHI node with a COND_EXPR using COND as condition.
1919 1.1 mrg This routine can handle PHI nodes with more than two arguments.
1920 1.1 mrg
1921 1.1 mrg For example,
1922 1.1 mrg S1: A = PHI <x1(1), x2(5)>
1923 1.1 mrg is converted into,
1924 1.1 mrg S2: A = cond ? x1 : x2;
1925 1.1 mrg
1926 1.1 mrg The generated code is inserted at GSI that points to the top of
1927 1.1 mrg basic block's statement list.
1928 1.1 mrg If PHI node has more than two arguments a chain of conditional
1929 1.1 mrg expression is produced. */
1930 1.1 mrg
1931 1.1 mrg
1932 1.1 mrg static void
1933 1.1 mrg predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi)
1934 1.1 mrg {
1935 1.1 mrg gimple *new_stmt = NULL, *reduc, *nop_reduc;
1936 1.1 mrg tree rhs, res, arg0, arg1, op0, op1, scev;
1937 1.1 mrg tree cond;
1938 1.1 mrg unsigned int index0;
1939 1.1 mrg unsigned int max, args_len;
1940 1.1 mrg edge e;
1941 1.1 mrg basic_block bb;
1942 1.1 mrg unsigned int i;
1943 1.1 mrg bool has_nop;
1944 1.1 mrg
1945 1.1 mrg res = gimple_phi_result (phi);
1946 1.1 mrg if (virtual_operand_p (res))
1947 1.1 mrg return;
1948 1.1 mrg
1949 1.1 mrg if ((rhs = degenerate_phi_result (phi))
1950 1.1 mrg || ((scev = analyze_scalar_evolution (gimple_bb (phi)->loop_father,
1951 1.1 mrg res))
1952 1.1 mrg && !chrec_contains_undetermined (scev)
1953 1.1 mrg && scev != res
1954 1.1 mrg && (rhs = gimple_phi_arg_def (phi, 0))))
1955 1.1 mrg {
1956 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
1957 1.1 mrg {
1958 1.1 mrg fprintf (dump_file, "Degenerate phi!\n");
1959 1.1 mrg print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
1960 1.1 mrg }
1961 1.1 mrg new_stmt = gimple_build_assign (res, rhs);
1962 1.1 mrg gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1963 1.1 mrg update_stmt (new_stmt);
1964 1.1 mrg return;
1965 1.1 mrg }
1966 1.1 mrg
1967 1.1 mrg bb = gimple_bb (phi);
1968 1.1 mrg if (EDGE_COUNT (bb->preds) == 2)
1969 1.1 mrg {
1970 1.1 mrg /* Predicate ordinary PHI node with 2 arguments. */
1971 1.1 mrg edge first_edge, second_edge;
1972 1.1 mrg basic_block true_bb;
1973 1.1 mrg first_edge = EDGE_PRED (bb, 0);
1974 1.1 mrg second_edge = EDGE_PRED (bb, 1);
1975 1.1 mrg cond = bb_predicate (first_edge->src);
1976 1.1 mrg if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
1977 1.1 mrg std::swap (first_edge, second_edge);
1978 1.1 mrg if (EDGE_COUNT (first_edge->src->succs) > 1)
1979 1.1 mrg {
1980 1.1 mrg cond = bb_predicate (second_edge->src);
1981 1.1 mrg if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
1982 1.1 mrg cond = TREE_OPERAND (cond, 0);
1983 1.1 mrg else
1984 1.1 mrg first_edge = second_edge;
1985 1.1 mrg }
1986 1.1 mrg else
1987 1.1 mrg cond = bb_predicate (first_edge->src);
1988 1.1 mrg /* Gimplify the condition to a valid cond-expr conditonal operand. */
1989 1.1 mrg cond = force_gimple_operand_gsi_1 (gsi, unshare_expr (cond),
1990 1.1 mrg is_gimple_condexpr, NULL_TREE,
1991 1.1 mrg true, GSI_SAME_STMT);
1992 1.1 mrg true_bb = first_edge->src;
1993 1.1 mrg if (EDGE_PRED (bb, 1)->src == true_bb)
1994 1.1 mrg {
1995 1.1 mrg arg0 = gimple_phi_arg_def (phi, 1);
1996 1.1 mrg arg1 = gimple_phi_arg_def (phi, 0);
1997 1.1 mrg }
1998 1.1 mrg else
1999 1.1 mrg {
2000 1.1 mrg arg0 = gimple_phi_arg_def (phi, 0);
2001 1.1 mrg arg1 = gimple_phi_arg_def (phi, 1);
2002 1.1 mrg }
2003 1.1 mrg if (is_cond_scalar_reduction (phi, &reduc, arg0, arg1,
2004 1.1 mrg &op0, &op1, false, &has_nop,
2005 1.1 mrg &nop_reduc))
2006 1.1 mrg {
2007 1.1 mrg /* Convert reduction stmt into vectorizable form. */
2008 1.1 mrg rhs = convert_scalar_cond_reduction (reduc, gsi, cond, op0, op1,
2009 1.1 mrg true_bb != gimple_bb (reduc),
2010 1.1 mrg has_nop, nop_reduc);
2011 1.1 mrg redundant_ssa_names.safe_push (std::make_pair (res, rhs));
2012 1.1 mrg }
2013 1.1 mrg else
2014 1.1 mrg /* Build new RHS using selected condition and arguments. */
2015 1.1 mrg rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond),
2016 1.1 mrg arg0, arg1);
2017 1.1 mrg new_stmt = gimple_build_assign (res, rhs);
2018 1.1 mrg gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
2019 1.1 mrg gimple_stmt_iterator new_gsi = gsi_for_stmt (new_stmt);
2020 1.1 mrg if (fold_stmt (&new_gsi, ifcvt_follow_ssa_use_edges))
2021 1.1 mrg {
2022 1.1 mrg new_stmt = gsi_stmt (new_gsi);
2023 1.1 mrg update_stmt (new_stmt);
2024 1.1 mrg }
2025 1.1 mrg
2026 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
2027 1.1 mrg {
2028 1.1 mrg fprintf (dump_file, "new phi replacement stmt\n");
2029 1.1 mrg print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
2030 1.1 mrg }
2031 1.1 mrg return;
2032 1.1 mrg }
2033 1.1 mrg
2034 1.1 mrg /* Create hashmap for PHI node which contain vector of argument indexes
2035 1.1 mrg having the same value. */
2036 1.1 mrg bool swap = false;
2037 1.1 mrg hash_map<tree_operand_hash, auto_vec<int> > phi_arg_map;
2038 1.1 mrg unsigned int num_args = gimple_phi_num_args (phi);
2039 1.1 mrg int max_ind = -1;
2040 1.1 mrg /* Vector of different PHI argument values. */
2041 1.1 mrg auto_vec<tree> args (num_args);
2042 1.1 mrg
2043 1.1 mrg /* Compute phi_arg_map. */
2044 1.1 mrg for (i = 0; i < num_args; i++)
2045 1.1 mrg {
2046 1.1 mrg tree arg;
2047 1.1 mrg
2048 1.1 mrg arg = gimple_phi_arg_def (phi, i);
2049 1.1 mrg if (!phi_arg_map.get (arg))
2050 1.1 mrg args.quick_push (arg);
2051 1.1 mrg phi_arg_map.get_or_insert (arg).safe_push (i);
2052 1.1 mrg }
2053 1.1 mrg
2054 1.1 mrg /* Determine element with max number of occurrences. */
2055 1.1 mrg max_ind = -1;
2056 1.1 mrg max = 1;
2057 1.1 mrg args_len = args.length ();
2058 1.1 mrg for (i = 0; i < args_len; i++)
2059 1.1 mrg {
2060 1.1 mrg unsigned int len;
2061 1.1 mrg if ((len = phi_arg_map.get (args[i])->length ()) > max)
2062 1.1 mrg {
2063 1.1 mrg max_ind = (int) i;
2064 1.1 mrg max = len;
2065 1.1 mrg }
2066 1.1 mrg }
2067 1.1 mrg
2068 1.1 mrg /* Put element with max number of occurences to the end of ARGS. */
2069 1.1 mrg if (max_ind != -1 && max_ind +1 != (int) args_len)
2070 1.1 mrg std::swap (args[args_len - 1], args[max_ind]);
2071 1.1 mrg
2072 1.1 mrg /* Handle one special case when number of arguments with different values
2073 1.1 mrg is equal 2 and one argument has the only occurrence. Such PHI can be
2074 1.1 mrg handled as if would have only 2 arguments. */
2075 1.1 mrg if (args_len == 2 && phi_arg_map.get (args[0])->length () == 1)
2076 1.1 mrg {
2077 1.1 mrg vec<int> *indexes;
2078 1.1 mrg indexes = phi_arg_map.get (args[0]);
2079 1.1 mrg index0 = (*indexes)[0];
2080 1.1 mrg arg0 = args[0];
2081 1.1 mrg arg1 = args[1];
2082 1.1 mrg e = gimple_phi_arg_edge (phi, index0);
2083 1.1 mrg cond = bb_predicate (e->src);
2084 1.1 mrg if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
2085 1.1 mrg {
2086 1.1 mrg swap = true;
2087 1.1 mrg cond = TREE_OPERAND (cond, 0);
2088 1.1 mrg }
2089 1.1 mrg /* Gimplify the condition to a valid cond-expr conditonal operand. */
2090 1.1 mrg cond = force_gimple_operand_gsi_1 (gsi, unshare_expr (cond),
2091 1.1 mrg is_gimple_condexpr, NULL_TREE,
2092 1.1 mrg true, GSI_SAME_STMT);
2093 1.1 mrg if (!(is_cond_scalar_reduction (phi, &reduc, arg0 , arg1,
2094 1.1 mrg &op0, &op1, true, &has_nop, &nop_reduc)))
2095 1.1 mrg rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond),
2096 1.1 mrg swap? arg1 : arg0,
2097 1.1 mrg swap? arg0 : arg1);
2098 1.1 mrg else
2099 1.1 mrg {
2100 1.1 mrg /* Convert reduction stmt into vectorizable form. */
2101 1.1 mrg rhs = convert_scalar_cond_reduction (reduc, gsi, cond, op0, op1,
2102 1.1 mrg swap,has_nop, nop_reduc);
2103 1.1 mrg redundant_ssa_names.safe_push (std::make_pair (res, rhs));
2104 1.1 mrg }
2105 1.1 mrg new_stmt = gimple_build_assign (res, rhs);
2106 1.1 mrg gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
2107 1.1 mrg update_stmt (new_stmt);
2108 1.1 mrg }
2109 1.1 mrg else
2110 1.1 mrg {
2111 1.1 mrg /* Common case. */
2112 1.1 mrg vec<int> *indexes;
2113 1.1 mrg tree type = TREE_TYPE (gimple_phi_result (phi));
2114 1.1 mrg tree lhs;
2115 1.1 mrg arg1 = args[1];
2116 1.1 mrg for (i = 0; i < args_len; i++)
2117 1.1 mrg {
2118 1.1 mrg arg0 = args[i];
2119 1.1 mrg indexes = phi_arg_map.get (args[i]);
2120 1.1 mrg if (i != args_len - 1)
2121 1.1 mrg lhs = make_temp_ssa_name (type, NULL, "_ifc_");
2122 1.1 mrg else
2123 1.1 mrg lhs = res;
2124 1.1 mrg cond = gen_phi_arg_condition (phi, indexes, gsi);
2125 1.1 mrg rhs = fold_build_cond_expr (type, unshare_expr (cond),
2126 1.1 mrg arg0, arg1);
2127 1.1 mrg new_stmt = gimple_build_assign (lhs, rhs);
2128 1.1 mrg gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
2129 1.1 mrg update_stmt (new_stmt);
2130 1.1 mrg arg1 = lhs;
2131 1.1 mrg }
2132 1.1 mrg }
2133 1.1 mrg
2134 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
2135 1.1 mrg {
2136 1.1 mrg fprintf (dump_file, "new extended phi replacement stmt\n");
2137 1.1 mrg print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
2138 1.1 mrg }
2139 1.1 mrg }
2140 1.1 mrg
2141 1.1 mrg /* Replaces in LOOP all the scalar phi nodes other than those in the
2142 1.1 mrg LOOP->header block with conditional modify expressions. */
2143 1.1 mrg
2144 1.1 mrg static void
2145 1.1 mrg predicate_all_scalar_phis (class loop *loop)
2146 1.1 mrg {
2147 1.1 mrg basic_block bb;
2148 1.1 mrg unsigned int orig_loop_num_nodes = loop->num_nodes;
2149 1.1 mrg unsigned int i;
2150 1.1 mrg
2151 1.1 mrg for (i = 1; i < orig_loop_num_nodes; i++)
2152 1.1 mrg {
2153 1.1 mrg gphi *phi;
2154 1.1 mrg gimple_stmt_iterator gsi;
2155 1.1 mrg gphi_iterator phi_gsi;
2156 1.1 mrg bb = ifc_bbs[i];
2157 1.1 mrg
2158 1.1 mrg if (bb == loop->header)
2159 1.1 mrg continue;
2160 1.1 mrg
2161 1.1 mrg phi_gsi = gsi_start_phis (bb);
2162 1.1 mrg if (gsi_end_p (phi_gsi))
2163 1.1 mrg continue;
2164 1.1 mrg
2165 1.1 mrg gsi = gsi_after_labels (bb);
2166 1.1 mrg while (!gsi_end_p (phi_gsi))
2167 1.1 mrg {
2168 1.1 mrg phi = phi_gsi.phi ();
2169 1.1 mrg if (virtual_operand_p (gimple_phi_result (phi)))
2170 1.1 mrg gsi_next (&phi_gsi);
2171 1.1 mrg else
2172 1.1 mrg {
2173 1.1 mrg predicate_scalar_phi (phi, &gsi);
2174 1.1 mrg remove_phi_node (&phi_gsi, false);
2175 1.1 mrg }
2176 1.1 mrg }
2177 1.1 mrg }
2178 1.1 mrg }
2179 1.1 mrg
2180 1.1 mrg /* Insert in each basic block of LOOP the statements produced by the
2181 1.1 mrg gimplification of the predicates. */
2182 1.1 mrg
2183 1.1 mrg static void
2184 1.1 mrg insert_gimplified_predicates (loop_p loop)
2185 1.1 mrg {
2186 1.1 mrg unsigned int i;
2187 1.1 mrg
2188 1.1 mrg for (i = 0; i < loop->num_nodes; i++)
2189 1.1 mrg {
2190 1.1 mrg basic_block bb = ifc_bbs[i];
2191 1.1 mrg gimple_seq stmts;
2192 1.1 mrg if (!is_predicated (bb))
2193 1.1 mrg gcc_assert (bb_predicate_gimplified_stmts (bb) == NULL);
2194 1.1 mrg if (!is_predicated (bb))
2195 1.1 mrg {
2196 1.1 mrg /* Do not insert statements for a basic block that is not
2197 1.1 mrg predicated. Also make sure that the predicate of the
2198 1.1 mrg basic block is set to true. */
2199 1.1 mrg reset_bb_predicate (bb);
2200 1.1 mrg continue;
2201 1.1 mrg }
2202 1.1 mrg
2203 1.1 mrg stmts = bb_predicate_gimplified_stmts (bb);
2204 1.1 mrg if (stmts)
2205 1.1 mrg {
2206 1.1 mrg if (need_to_predicate)
2207 1.1 mrg {
2208 1.1 mrg /* Insert the predicate of the BB just after the label,
2209 1.1 mrg as the if-conversion of memory writes will use this
2210 1.1 mrg predicate. */
2211 1.1 mrg gimple_stmt_iterator gsi = gsi_after_labels (bb);
2212 1.1 mrg gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
2213 1.1 mrg }
2214 1.1 mrg else
2215 1.1 mrg {
2216 1.1 mrg /* Insert the predicate of the BB at the end of the BB
2217 1.1 mrg as this would reduce the register pressure: the only
2218 1.1 mrg use of this predicate will be in successor BBs. */
2219 1.1 mrg gimple_stmt_iterator gsi = gsi_last_bb (bb);
2220 1.1 mrg
2221 1.1 mrg if (gsi_end_p (gsi)
2222 1.1 mrg || stmt_ends_bb_p (gsi_stmt (gsi)))
2223 1.1 mrg gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
2224 1.1 mrg else
2225 1.1 mrg gsi_insert_seq_after (&gsi, stmts, GSI_SAME_STMT);
2226 1.1 mrg }
2227 1.1 mrg
2228 1.1 mrg /* Once the sequence is code generated, set it to NULL. */
2229 1.1 mrg set_bb_predicate_gimplified_stmts (bb, NULL);
2230 1.1 mrg }
2231 1.1 mrg }
2232 1.1 mrg }
2233 1.1 mrg
2234 1.1 mrg /* Helper function for predicate_statements. Returns index of existent
2235 1.1 mrg mask if it was created for given SIZE and -1 otherwise. */
2236 1.1 mrg
2237 1.1 mrg static int
2238 1.1 mrg mask_exists (int size, const vec<int> &vec)
2239 1.1 mrg {
2240 1.1 mrg unsigned int ix;
2241 1.1 mrg int v;
2242 1.1 mrg FOR_EACH_VEC_ELT (vec, ix, v)
2243 1.1 mrg if (v == size)
2244 1.1 mrg return (int) ix;
2245 1.1 mrg return -1;
2246 1.1 mrg }
2247 1.1 mrg
2248 1.1 mrg /* Helper function for predicate_statements. STMT is a memory read or
2249 1.1 mrg write and it needs to be predicated by MASK. Return a statement
2250 1.1 mrg that does so. */
2251 1.1 mrg
2252 1.1 mrg static gimple *
2253 1.1 mrg predicate_load_or_store (gimple_stmt_iterator *gsi, gassign *stmt, tree mask)
2254 1.1 mrg {
2255 1.1 mrg gcall *new_stmt;
2256 1.1 mrg
2257 1.1 mrg tree lhs = gimple_assign_lhs (stmt);
2258 1.1 mrg tree rhs = gimple_assign_rhs1 (stmt);
2259 1.1 mrg tree ref = TREE_CODE (lhs) == SSA_NAME ? rhs : lhs;
2260 1.1 mrg mark_addressable (ref);
2261 1.1 mrg tree addr = force_gimple_operand_gsi (gsi, build_fold_addr_expr (ref),
2262 1.1 mrg true, NULL_TREE, true, GSI_SAME_STMT);
2263 1.1 mrg tree ptr = build_int_cst (reference_alias_ptr_type (ref),
2264 1.1 mrg get_object_alignment (ref));
2265 1.1 mrg /* Copy points-to info if possible. */
2266 1.1 mrg if (TREE_CODE (addr) == SSA_NAME && !SSA_NAME_PTR_INFO (addr))
2267 1.1 mrg copy_ref_info (build2 (MEM_REF, TREE_TYPE (ref), addr, ptr),
2268 1.1 mrg ref);
2269 1.1 mrg if (TREE_CODE (lhs) == SSA_NAME)
2270 1.1 mrg {
2271 1.1 mrg new_stmt
2272 1.1 mrg = gimple_build_call_internal (IFN_MASK_LOAD, 3, addr,
2273 1.1 mrg ptr, mask);
2274 1.1 mrg gimple_call_set_lhs (new_stmt, lhs);
2275 1.1 mrg gimple_set_vuse (new_stmt, gimple_vuse (stmt));
2276 1.1 mrg }
2277 1.1 mrg else
2278 1.1 mrg {
2279 1.1 mrg new_stmt
2280 1.1 mrg = gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr,
2281 1.1 mrg mask, rhs);
2282 1.1 mrg gimple_move_vops (new_stmt, stmt);
2283 1.1 mrg }
2284 1.1 mrg gimple_call_set_nothrow (new_stmt, true);
2285 1.1 mrg return new_stmt;
2286 1.1 mrg }
2287 1.1 mrg
2288 1.1 mrg /* STMT uses OP_LHS. Check whether it is equivalent to:
2289 1.1 mrg
2290 1.1 mrg ... = OP_MASK ? OP_LHS : X;
2291 1.1 mrg
2292 1.1 mrg Return X if so, otherwise return null. OP_MASK is an SSA_NAME that is
2293 1.1 mrg known to have value OP_COND. */
2294 1.1 mrg
2295 1.1 mrg static tree
2296 1.1 mrg check_redundant_cond_expr (gimple *stmt, tree op_mask, tree op_cond,
2297 1.1 mrg tree op_lhs)
2298 1.1 mrg {
2299 1.1 mrg gassign *assign = dyn_cast <gassign *> (stmt);
2300 1.1 mrg if (!assign || gimple_assign_rhs_code (assign) != COND_EXPR)
2301 1.1 mrg return NULL_TREE;
2302 1.1 mrg
2303 1.1 mrg tree use_cond = gimple_assign_rhs1 (assign);
2304 1.1 mrg tree if_true = gimple_assign_rhs2 (assign);
2305 1.1 mrg tree if_false = gimple_assign_rhs3 (assign);
2306 1.1 mrg
2307 1.1 mrg if ((use_cond == op_mask || operand_equal_p (use_cond, op_cond, 0))
2308 1.1 mrg && if_true == op_lhs)
2309 1.1 mrg return if_false;
2310 1.1 mrg
2311 1.1 mrg if (inverse_conditions_p (use_cond, op_cond) && if_false == op_lhs)
2312 1.1 mrg return if_true;
2313 1.1 mrg
2314 1.1 mrg return NULL_TREE;
2315 1.1 mrg }
2316 1.1 mrg
2317 1.1 mrg /* Return true if VALUE is available for use at STMT. SSA_NAMES is
2318 1.1 mrg the set of SSA names defined earlier in STMT's block. */
2319 1.1 mrg
2320 1.1 mrg static bool
2321 1.1 mrg value_available_p (gimple *stmt, hash_set<tree_ssa_name_hash> *ssa_names,
2322 1.1 mrg tree value)
2323 1.1 mrg {
2324 1.1 mrg if (is_gimple_min_invariant (value))
2325 1.1 mrg return true;
2326 1.1 mrg
2327 1.1 mrg if (TREE_CODE (value) == SSA_NAME)
2328 1.1 mrg {
2329 1.1 mrg if (SSA_NAME_IS_DEFAULT_DEF (value))
2330 1.1 mrg return true;
2331 1.1 mrg
2332 1.1 mrg basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (value));
2333 1.1 mrg basic_block use_bb = gimple_bb (stmt);
2334 1.1 mrg return (def_bb == use_bb
2335 1.1 mrg ? ssa_names->contains (value)
2336 1.1 mrg : dominated_by_p (CDI_DOMINATORS, use_bb, def_bb));
2337 1.1 mrg }
2338 1.1 mrg
2339 1.1 mrg return false;
2340 1.1 mrg }
2341 1.1 mrg
2342 1.1 mrg /* Helper function for predicate_statements. STMT is a potentially-trapping
2343 1.1 mrg arithmetic operation that needs to be predicated by MASK, an SSA_NAME that
2344 1.1 mrg has value COND. Return a statement that does so. SSA_NAMES is the set of
2345 1.1 mrg SSA names defined earlier in STMT's block. */
2346 1.1 mrg
2347 1.1 mrg static gimple *
2348 1.1 mrg predicate_rhs_code (gassign *stmt, tree mask, tree cond,
2349 1.1 mrg hash_set<tree_ssa_name_hash> *ssa_names)
2350 1.1 mrg {
2351 1.1 mrg tree lhs = gimple_assign_lhs (stmt);
2352 1.1 mrg tree_code code = gimple_assign_rhs_code (stmt);
2353 1.1 mrg unsigned int nops = gimple_num_ops (stmt);
2354 1.1 mrg internal_fn cond_fn = get_conditional_internal_fn (code);
2355 1.1 mrg
2356 1.1 mrg /* Construct the arguments to the conditional internal function. */
2357 1.1 mrg auto_vec<tree, 8> args;
2358 1.1 mrg args.safe_grow (nops + 1, true);
2359 1.1 mrg args[0] = mask;
2360 1.1 mrg for (unsigned int i = 1; i < nops; ++i)
2361 1.1 mrg args[i] = gimple_op (stmt, i);
2362 1.1 mrg args[nops] = NULL_TREE;
2363 1.1 mrg
2364 1.1 mrg /* Look for uses of the result to see whether they are COND_EXPRs that can
2365 1.1 mrg be folded into the conditional call. */
2366 1.1 mrg imm_use_iterator imm_iter;
2367 1.1 mrg gimple *use_stmt;
2368 1.1 mrg FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, lhs)
2369 1.1 mrg {
2370 1.1 mrg tree new_else = check_redundant_cond_expr (use_stmt, mask, cond, lhs);
2371 1.1 mrg if (new_else && value_available_p (stmt, ssa_names, new_else))
2372 1.1 mrg {
2373 1.1 mrg if (!args[nops])
2374 1.1 mrg args[nops] = new_else;
2375 1.1 mrg if (operand_equal_p (new_else, args[nops], 0))
2376 1.1 mrg {
2377 1.1 mrg /* We have:
2378 1.1 mrg
2379 1.1 mrg LHS = IFN_COND (MASK, ..., ELSE);
2380 1.1 mrg X = MASK ? LHS : ELSE;
2381 1.1 mrg
2382 1.1 mrg which makes X equivalent to LHS. */
2383 1.1 mrg tree use_lhs = gimple_assign_lhs (use_stmt);
2384 1.1 mrg redundant_ssa_names.safe_push (std::make_pair (use_lhs, lhs));
2385 1.1 mrg }
2386 1.1 mrg }
2387 1.1 mrg }
2388 1.1 mrg if (!args[nops])
2389 1.1 mrg args[nops] = targetm.preferred_else_value (cond_fn, TREE_TYPE (lhs),
2390 1.1 mrg nops - 1, &args[1]);
2391 1.1 mrg
2392 1.1 mrg /* Create and insert the call. */
2393 1.1 mrg gcall *new_stmt = gimple_build_call_internal_vec (cond_fn, args);
2394 1.1 mrg gimple_call_set_lhs (new_stmt, lhs);
2395 1.1 mrg gimple_call_set_nothrow (new_stmt, true);
2396 1.1 mrg
2397 1.1 mrg return new_stmt;
2398 1.1 mrg }
2399 1.1 mrg
2400 1.1 mrg /* Predicate each write to memory in LOOP.
2401 1.1 mrg
2402 1.1 mrg This function transforms control flow constructs containing memory
2403 1.1 mrg writes of the form:
2404 1.1 mrg
2405 1.1 mrg | for (i = 0; i < N; i++)
2406 1.1 mrg | if (cond)
2407 1.1 mrg | A[i] = expr;
2408 1.1 mrg
2409 1.1 mrg into the following form that does not contain control flow:
2410 1.1 mrg
2411 1.1 mrg | for (i = 0; i < N; i++)
2412 1.1 mrg | A[i] = cond ? expr : A[i];
2413 1.1 mrg
2414 1.1 mrg The original CFG looks like this:
2415 1.1 mrg
2416 1.1 mrg | bb_0
2417 1.1 mrg | i = 0
2418 1.1 mrg | end_bb_0
2419 1.1 mrg |
2420 1.1 mrg | bb_1
2421 1.1 mrg | if (i < N) goto bb_5 else goto bb_2
2422 1.1 mrg | end_bb_1
2423 1.1 mrg |
2424 1.1 mrg | bb_2
2425 1.1 mrg | cond = some_computation;
2426 1.1 mrg | if (cond) goto bb_3 else goto bb_4
2427 1.1 mrg | end_bb_2
2428 1.1 mrg |
2429 1.1 mrg | bb_3
2430 1.1 mrg | A[i] = expr;
2431 1.1 mrg | goto bb_4
2432 1.1 mrg | end_bb_3
2433 1.1 mrg |
2434 1.1 mrg | bb_4
2435 1.1 mrg | goto bb_1
2436 1.1 mrg | end_bb_4
2437 1.1 mrg
2438 1.1 mrg insert_gimplified_predicates inserts the computation of the COND
2439 1.1 mrg expression at the beginning of the destination basic block:
2440 1.1 mrg
2441 1.1 mrg | bb_0
2442 1.1 mrg | i = 0
2443 1.1 mrg | end_bb_0
2444 1.1 mrg |
2445 1.1 mrg | bb_1
2446 1.1 mrg | if (i < N) goto bb_5 else goto bb_2
2447 1.1 mrg | end_bb_1
2448 1.1 mrg |
2449 1.1 mrg | bb_2
2450 1.1 mrg | cond = some_computation;
2451 1.1 mrg | if (cond) goto bb_3 else goto bb_4
2452 1.1 mrg | end_bb_2
2453 1.1 mrg |
2454 1.1 mrg | bb_3
2455 1.1 mrg | cond = some_computation;
2456 1.1 mrg | A[i] = expr;
2457 1.1 mrg | goto bb_4
2458 1.1 mrg | end_bb_3
2459 1.1 mrg |
2460 1.1 mrg | bb_4
2461 1.1 mrg | goto bb_1
2462 1.1 mrg | end_bb_4
2463 1.1 mrg
2464 1.1 mrg predicate_statements is then predicating the memory write as follows:
2465 1.1 mrg
2466 1.1 mrg | bb_0
2467 1.1 mrg | i = 0
2468 1.1 mrg | end_bb_0
2469 1.1 mrg |
2470 1.1 mrg | bb_1
2471 1.1 mrg | if (i < N) goto bb_5 else goto bb_2
2472 1.1 mrg | end_bb_1
2473 1.1 mrg |
2474 1.1 mrg | bb_2
2475 1.1 mrg | if (cond) goto bb_3 else goto bb_4
2476 1.1 mrg | end_bb_2
2477 1.1 mrg |
2478 1.1 mrg | bb_3
2479 1.1 mrg | cond = some_computation;
2480 1.1 mrg | A[i] = cond ? expr : A[i];
2481 1.1 mrg | goto bb_4
2482 1.1 mrg | end_bb_3
2483 1.1 mrg |
2484 1.1 mrg | bb_4
2485 1.1 mrg | goto bb_1
2486 1.1 mrg | end_bb_4
2487 1.1 mrg
2488 1.1 mrg and finally combine_blocks removes the basic block boundaries making
2489 1.1 mrg the loop vectorizable:
2490 1.1 mrg
2491 1.1 mrg | bb_0
2492 1.1 mrg | i = 0
2493 1.1 mrg | if (i < N) goto bb_5 else goto bb_1
2494 1.1 mrg | end_bb_0
2495 1.1 mrg |
2496 1.1 mrg | bb_1
2497 1.1 mrg | cond = some_computation;
2498 1.1 mrg | A[i] = cond ? expr : A[i];
2499 1.1 mrg | if (i < N) goto bb_5 else goto bb_4
2500 1.1 mrg | end_bb_1
2501 1.1 mrg |
2502 1.1 mrg | bb_4
2503 1.1 mrg | goto bb_1
2504 1.1 mrg | end_bb_4
2505 1.1 mrg */
2506 1.1 mrg
2507 1.1 mrg static void
2508 1.1 mrg predicate_statements (loop_p loop)
2509 1.1 mrg {
2510 1.1 mrg unsigned int i, orig_loop_num_nodes = loop->num_nodes;
2511 1.1 mrg auto_vec<int, 1> vect_sizes;
2512 1.1 mrg auto_vec<tree, 1> vect_masks;
2513 1.1 mrg hash_set<tree_ssa_name_hash> ssa_names;
2514 1.1 mrg
2515 1.1 mrg for (i = 1; i < orig_loop_num_nodes; i++)
2516 1.1 mrg {
2517 1.1 mrg gimple_stmt_iterator gsi;
2518 1.1 mrg basic_block bb = ifc_bbs[i];
2519 1.1 mrg tree cond = bb_predicate (bb);
2520 1.1 mrg bool swap;
2521 1.1 mrg int index;
2522 1.1 mrg
2523 1.1 mrg if (is_true_predicate (cond))
2524 1.1 mrg continue;
2525 1.1 mrg
2526 1.1 mrg swap = false;
2527 1.1 mrg if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
2528 1.1 mrg {
2529 1.1 mrg swap = true;
2530 1.1 mrg cond = TREE_OPERAND (cond, 0);
2531 1.1 mrg }
2532 1.1 mrg
2533 1.1 mrg vect_sizes.truncate (0);
2534 1.1 mrg vect_masks.truncate (0);
2535 1.1 mrg
2536 1.1 mrg for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
2537 1.1 mrg {
2538 1.1 mrg gassign *stmt = dyn_cast <gassign *> (gsi_stmt (gsi));
2539 1.1 mrg tree lhs;
2540 1.1 mrg if (!stmt)
2541 1.1 mrg ;
2542 1.1 mrg else if (is_false_predicate (cond)
2543 1.1 mrg && gimple_vdef (stmt))
2544 1.1 mrg {
2545 1.1 mrg unlink_stmt_vdef (stmt);
2546 1.1 mrg gsi_remove (&gsi, true);
2547 1.1 mrg release_defs (stmt);
2548 1.1 mrg continue;
2549 1.1 mrg }
2550 1.1 mrg else if (gimple_plf (stmt, GF_PLF_2))
2551 1.1 mrg {
2552 1.1 mrg tree lhs = gimple_assign_lhs (stmt);
2553 1.1 mrg tree mask;
2554 1.1 mrg gimple *new_stmt;
2555 1.1 mrg gimple_seq stmts = NULL;
2556 1.1 mrg machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
2557 1.1 mrg /* We checked before setting GF_PLF_2 that an equivalent
2558 1.1 mrg integer mode exists. */
2559 1.1 mrg int bitsize = GET_MODE_BITSIZE (mode).to_constant ();
2560 1.1 mrg if (!vect_sizes.is_empty ()
2561 1.1 mrg && (index = mask_exists (bitsize, vect_sizes)) != -1)
2562 1.1 mrg /* Use created mask. */
2563 1.1 mrg mask = vect_masks[index];
2564 1.1 mrg else
2565 1.1 mrg {
2566 1.1 mrg if (COMPARISON_CLASS_P (cond))
2567 1.1 mrg mask = gimple_build (&stmts, TREE_CODE (cond),
2568 1.1 mrg boolean_type_node,
2569 1.1 mrg TREE_OPERAND (cond, 0),
2570 1.1 mrg TREE_OPERAND (cond, 1));
2571 1.1 mrg else
2572 1.1 mrg mask = cond;
2573 1.1 mrg
2574 1.1 mrg if (swap)
2575 1.1 mrg {
2576 1.1 mrg tree true_val
2577 1.1 mrg = constant_boolean_node (true, TREE_TYPE (mask));
2578 1.1 mrg mask = gimple_build (&stmts, BIT_XOR_EXPR,
2579 1.1 mrg TREE_TYPE (mask), mask, true_val);
2580 1.1 mrg }
2581 1.1 mrg gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
2582 1.1 mrg
2583 1.1 mrg /* Save mask and its size for further use. */
2584 1.1 mrg vect_sizes.safe_push (bitsize);
2585 1.1 mrg vect_masks.safe_push (mask);
2586 1.1 mrg }
2587 1.1 mrg if (gimple_assign_single_p (stmt))
2588 1.1 mrg new_stmt = predicate_load_or_store (&gsi, stmt, mask);
2589 1.1 mrg else
2590 1.1 mrg new_stmt = predicate_rhs_code (stmt, mask, cond, &ssa_names);
2591 1.1 mrg
2592 1.1 mrg gsi_replace (&gsi, new_stmt, true);
2593 1.1 mrg }
2594 1.1 mrg else if (((lhs = gimple_assign_lhs (stmt)), true)
2595 1.1 mrg && (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
2596 1.1 mrg || POINTER_TYPE_P (TREE_TYPE (lhs)))
2597 1.1 mrg && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (lhs))
2598 1.1 mrg && arith_code_with_undefined_signed_overflow
2599 1.1 mrg (gimple_assign_rhs_code (stmt)))
2600 1.1 mrg {
2601 1.1 mrg gsi_remove (&gsi, true);
2602 1.1 mrg gimple_seq stmts = rewrite_to_defined_overflow (stmt);
2603 1.1 mrg bool first = true;
2604 1.1 mrg for (gimple_stmt_iterator gsi2 = gsi_start (stmts);
2605 1.1 mrg !gsi_end_p (gsi2);)
2606 1.1 mrg {
2607 1.1 mrg gassign *stmt2 = as_a <gassign *> (gsi_stmt (gsi2));
2608 1.1 mrg gsi_remove (&gsi2, false);
2609 1.1 mrg if (first)
2610 1.1 mrg {
2611 1.1 mrg gsi_insert_before (&gsi, stmt2, GSI_NEW_STMT);
2612 1.1 mrg first = false;
2613 1.1 mrg }
2614 1.1 mrg else
2615 1.1 mrg gsi_insert_after (&gsi, stmt2, GSI_NEW_STMT);
2616 1.1 mrg }
2617 1.1 mrg }
2618 1.1 mrg else if (gimple_vdef (stmt))
2619 1.1 mrg {
2620 1.1 mrg tree lhs = gimple_assign_lhs (stmt);
2621 1.1 mrg tree rhs = gimple_assign_rhs1 (stmt);
2622 1.1 mrg tree type = TREE_TYPE (lhs);
2623 1.1 mrg
2624 1.1 mrg lhs = ifc_temp_var (type, unshare_expr (lhs), &gsi);
2625 1.1 mrg rhs = ifc_temp_var (type, unshare_expr (rhs), &gsi);
2626 1.1 mrg if (swap)
2627 1.1 mrg std::swap (lhs, rhs);
2628 1.1 mrg cond = force_gimple_operand_gsi_1 (&gsi, unshare_expr (cond),
2629 1.1 mrg is_gimple_condexpr, NULL_TREE,
2630 1.1 mrg true, GSI_SAME_STMT);
2631 1.1 mrg rhs = fold_build_cond_expr (type, unshare_expr (cond), rhs, lhs);
2632 1.1 mrg gimple_assign_set_rhs1 (stmt, ifc_temp_var (type, rhs, &gsi));
2633 1.1 mrg update_stmt (stmt);
2634 1.1 mrg }
2635 1.1 mrg lhs = gimple_get_lhs (gsi_stmt (gsi));
2636 1.1 mrg if (lhs && TREE_CODE (lhs) == SSA_NAME)
2637 1.1 mrg ssa_names.add (lhs);
2638 1.1 mrg gsi_next (&gsi);
2639 1.1 mrg }
2640 1.1 mrg ssa_names.empty ();
2641 1.1 mrg }
2642 1.1 mrg }
2643 1.1 mrg
2644 1.1 mrg /* Remove all GIMPLE_CONDs and GIMPLE_LABELs of all the basic blocks
2645 1.1 mrg other than the exit and latch of the LOOP. Also resets the
2646 1.1 mrg GIMPLE_DEBUG information. */
2647 1.1 mrg
2648 1.1 mrg static void
2649 1.1 mrg remove_conditions_and_labels (loop_p loop)
2650 1.1 mrg {
2651 1.1 mrg gimple_stmt_iterator gsi;
2652 1.1 mrg unsigned int i;
2653 1.1 mrg
2654 1.1 mrg for (i = 0; i < loop->num_nodes; i++)
2655 1.1 mrg {
2656 1.1 mrg basic_block bb = ifc_bbs[i];
2657 1.1 mrg
2658 1.1 mrg if (bb_with_exit_edge_p (loop, bb)
2659 1.1 mrg || bb == loop->latch)
2660 1.1 mrg continue;
2661 1.1 mrg
2662 1.1 mrg for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
2663 1.1 mrg switch (gimple_code (gsi_stmt (gsi)))
2664 1.1 mrg {
2665 1.1 mrg case GIMPLE_COND:
2666 1.1 mrg case GIMPLE_LABEL:
2667 1.1 mrg gsi_remove (&gsi, true);
2668 1.1 mrg break;
2669 1.1 mrg
2670 1.1 mrg case GIMPLE_DEBUG:
2671 1.1 mrg /* ??? Should there be conditional GIMPLE_DEBUG_BINDs? */
2672 1.1 mrg if (gimple_debug_bind_p (gsi_stmt (gsi)))
2673 1.1 mrg {
2674 1.1 mrg gimple_debug_bind_reset_value (gsi_stmt (gsi));
2675 1.1 mrg update_stmt (gsi_stmt (gsi));
2676 1.1 mrg }
2677 1.1 mrg gsi_next (&gsi);
2678 1.1 mrg break;
2679 1.1 mrg
2680 1.1 mrg default:
2681 1.1 mrg gsi_next (&gsi);
2682 1.1 mrg }
2683 1.1 mrg }
2684 1.1 mrg }
2685 1.1 mrg
2686 1.1 mrg /* Combine all the basic blocks from LOOP into one or two super basic
2687 1.1 mrg blocks. Replace PHI nodes with conditional modify expressions. */
2688 1.1 mrg
2689 1.1 mrg static void
2690 1.1 mrg combine_blocks (class loop *loop)
2691 1.1 mrg {
2692 1.1 mrg basic_block bb, exit_bb, merge_target_bb;
2693 1.1 mrg unsigned int orig_loop_num_nodes = loop->num_nodes;
2694 1.1 mrg unsigned int i;
2695 1.1 mrg edge e;
2696 1.1 mrg edge_iterator ei;
2697 1.1 mrg
2698 1.1 mrg remove_conditions_and_labels (loop);
2699 1.1 mrg insert_gimplified_predicates (loop);
2700 1.1 mrg predicate_all_scalar_phis (loop);
2701 1.1 mrg
2702 1.1 mrg if (need_to_predicate || need_to_rewrite_undefined)
2703 1.1 mrg predicate_statements (loop);
2704 1.1 mrg
2705 1.1 mrg /* Merge basic blocks. */
2706 1.1 mrg exit_bb = NULL;
2707 1.1 mrg bool *predicated = XNEWVEC (bool, orig_loop_num_nodes);
2708 1.1 mrg for (i = 0; i < orig_loop_num_nodes; i++)
2709 1.1 mrg {
2710 1.1 mrg bb = ifc_bbs[i];
2711 1.1 mrg predicated[i] = !is_true_predicate (bb_predicate (bb));
2712 1.1 mrg free_bb_predicate (bb);
2713 1.1 mrg if (bb_with_exit_edge_p (loop, bb))
2714 1.1 mrg {
2715 1.1 mrg gcc_assert (exit_bb == NULL);
2716 1.1 mrg exit_bb = bb;
2717 1.1 mrg }
2718 1.1 mrg }
2719 1.1 mrg gcc_assert (exit_bb != loop->latch);
2720 1.1 mrg
2721 1.1 mrg merge_target_bb = loop->header;
2722 1.1 mrg
2723 1.1 mrg /* Get at the virtual def valid for uses starting at the first block
2724 1.1 mrg we merge into the header. Without a virtual PHI the loop has the
2725 1.1 mrg same virtual use on all stmts. */
2726 1.1 mrg gphi *vphi = get_virtual_phi (loop->header);
2727 1.1 mrg tree last_vdef = NULL_TREE;
2728 1.1 mrg if (vphi)
2729 1.1 mrg {
2730 1.1 mrg last_vdef = gimple_phi_result (vphi);
2731 1.1 mrg for (gimple_stmt_iterator gsi = gsi_start_bb (loop->header);
2732 1.1 mrg ! gsi_end_p (gsi); gsi_next (&gsi))
2733 1.1 mrg if (gimple_vdef (gsi_stmt (gsi)))
2734 1.1 mrg last_vdef = gimple_vdef (gsi_stmt (gsi));
2735 1.1 mrg }
2736 1.1 mrg for (i = 1; i < orig_loop_num_nodes; i++)
2737 1.1 mrg {
2738 1.1 mrg gimple_stmt_iterator gsi;
2739 1.1 mrg gimple_stmt_iterator last;
2740 1.1 mrg
2741 1.1 mrg bb = ifc_bbs[i];
2742 1.1 mrg
2743 1.1 mrg if (bb == exit_bb || bb == loop->latch)
2744 1.1 mrg continue;
2745 1.1 mrg
2746 1.1 mrg /* We release virtual PHIs late because we have to propagate them
2747 1.1 mrg out using the current VUSE. The def might be the one used
2748 1.1 mrg after the loop. */
2749 1.1 mrg vphi = get_virtual_phi (bb);
2750 1.1 mrg if (vphi)
2751 1.1 mrg {
2752 1.1 mrg /* When there's just loads inside the loop a stray virtual
2753 1.1 mrg PHI merging the uses can appear, update last_vdef from
2754 1.1 mrg it. */
2755 1.1 mrg if (!last_vdef)
2756 1.1 mrg last_vdef = gimple_phi_arg_def (vphi, 0);
2757 1.1 mrg imm_use_iterator iter;
2758 1.1 mrg use_operand_p use_p;
2759 1.1 mrg gimple *use_stmt;
2760 1.1 mrg FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_phi_result (vphi))
2761 1.1 mrg {
2762 1.1 mrg FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
2763 1.1 mrg SET_USE (use_p, last_vdef);
2764 1.1 mrg }
2765 1.1 mrg if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (vphi)))
2766 1.1 mrg SSA_NAME_OCCURS_IN_ABNORMAL_PHI (last_vdef) = 1;
2767 1.1 mrg gsi = gsi_for_stmt (vphi);
2768 1.1 mrg remove_phi_node (&gsi, true);
2769 1.1 mrg }
2770 1.1 mrg
2771 1.1 mrg /* Make stmts member of loop->header and clear range info from all stmts
2772 1.1 mrg in BB which is now no longer executed conditional on a predicate we
2773 1.1 mrg could have derived it from. */
2774 1.1 mrg for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2775 1.1 mrg {
2776 1.1 mrg gimple *stmt = gsi_stmt (gsi);
2777 1.1 mrg gimple_set_bb (stmt, merge_target_bb);
2778 1.1 mrg /* Update virtual operands. */
2779 1.1 mrg if (last_vdef)
2780 1.1 mrg {
2781 1.1 mrg use_operand_p use_p = ssa_vuse_operand (stmt);
2782 1.1 mrg if (use_p
2783 1.1 mrg && USE_FROM_PTR (use_p) != last_vdef)
2784 1.1 mrg SET_USE (use_p, last_vdef);
2785 1.1 mrg if (gimple_vdef (stmt))
2786 1.1 mrg last_vdef = gimple_vdef (stmt);
2787 1.1 mrg }
2788 1.1 mrg else
2789 1.1 mrg /* If this is the first load we arrive at update last_vdef
2790 1.1 mrg so we handle stray PHIs correctly. */
2791 1.1 mrg last_vdef = gimple_vuse (stmt);
2792 1.1 mrg if (predicated[i])
2793 1.1 mrg {
2794 1.1 mrg ssa_op_iter i;
2795 1.1 mrg tree op;
2796 1.1 mrg FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF)
2797 1.1 mrg reset_flow_sensitive_info (op);
2798 1.1 mrg }
2799 1.1 mrg }
2800 1.1 mrg
2801 1.1 mrg /* Update stmt list. */
2802 1.1 mrg last = gsi_last_bb (merge_target_bb);
2803 1.1 mrg gsi_insert_seq_after_without_update (&last, bb_seq (bb), GSI_NEW_STMT);
2804 1.1 mrg set_bb_seq (bb, NULL);
2805 1.1 mrg }
2806 1.1 mrg
2807 1.1 mrg /* Fixup virtual operands in the exit block. */
2808 1.1 mrg if (exit_bb
2809 1.1 mrg && exit_bb != loop->header)
2810 1.1 mrg {
2811 1.1 mrg /* We release virtual PHIs late because we have to propagate them
2812 1.1 mrg out using the current VUSE. The def might be the one used
2813 1.1 mrg after the loop. */
2814 1.1 mrg vphi = get_virtual_phi (exit_bb);
2815 1.1 mrg if (vphi)
2816 1.1 mrg {
2817 1.1 mrg /* When there's just loads inside the loop a stray virtual
2818 1.1 mrg PHI merging the uses can appear, update last_vdef from
2819 1.1 mrg it. */
2820 1.1 mrg if (!last_vdef)
2821 1.1 mrg last_vdef = gimple_phi_arg_def (vphi, 0);
2822 1.1 mrg imm_use_iterator iter;
2823 1.1 mrg use_operand_p use_p;
2824 1.1 mrg gimple *use_stmt;
2825 1.1 mrg FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_phi_result (vphi))
2826 1.1 mrg {
2827 1.1 mrg FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
2828 1.1 mrg SET_USE (use_p, last_vdef);
2829 1.1 mrg }
2830 1.1 mrg if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (vphi)))
2831 1.1 mrg SSA_NAME_OCCURS_IN_ABNORMAL_PHI (last_vdef) = 1;
2832 1.1 mrg gimple_stmt_iterator gsi = gsi_for_stmt (vphi);
2833 1.1 mrg remove_phi_node (&gsi, true);
2834 1.1 mrg }
2835 1.1 mrg }
2836 1.1 mrg
2837 1.1 mrg /* Now remove all the edges in the loop, except for those from the exit
2838 1.1 mrg block and delete the blocks we elided. */
2839 1.1 mrg for (i = 1; i < orig_loop_num_nodes; i++)
2840 1.1 mrg {
2841 1.1 mrg bb = ifc_bbs[i];
2842 1.1 mrg
2843 1.1 mrg for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei));)
2844 1.1 mrg {
2845 1.1 mrg if (e->src == exit_bb)
2846 1.1 mrg ei_next (&ei);
2847 1.1 mrg else
2848 1.1 mrg remove_edge (e);
2849 1.1 mrg }
2850 1.1 mrg }
2851 1.1 mrg for (i = 1; i < orig_loop_num_nodes; i++)
2852 1.1 mrg {
2853 1.1 mrg bb = ifc_bbs[i];
2854 1.1 mrg
2855 1.1 mrg if (bb == exit_bb || bb == loop->latch)
2856 1.1 mrg continue;
2857 1.1 mrg
2858 1.1 mrg delete_basic_block (bb);
2859 1.1 mrg }
2860 1.1 mrg
2861 1.1 mrg /* Re-connect the exit block. */
2862 1.1 mrg if (exit_bb != NULL)
2863 1.1 mrg {
2864 1.1 mrg if (exit_bb != loop->header)
2865 1.1 mrg {
2866 1.1 mrg /* Connect this node to loop header. */
2867 1.1 mrg make_single_succ_edge (loop->header, exit_bb, EDGE_FALLTHRU);
2868 1.1 mrg set_immediate_dominator (CDI_DOMINATORS, exit_bb, loop->header);
2869 1.1 mrg }
2870 1.1 mrg
2871 1.1 mrg /* Redirect non-exit edges to loop->latch. */
2872 1.1 mrg FOR_EACH_EDGE (e, ei, exit_bb->succs)
2873 1.1 mrg {
2874 1.1 mrg if (!loop_exit_edge_p (loop, e))
2875 1.1 mrg redirect_edge_and_branch (e, loop->latch);
2876 1.1 mrg }
2877 1.1 mrg set_immediate_dominator (CDI_DOMINATORS, loop->latch, exit_bb);
2878 1.1 mrg }
2879 1.1 mrg else
2880 1.1 mrg {
2881 1.1 mrg /* If the loop does not have an exit, reconnect header and latch. */
2882 1.1 mrg make_edge (loop->header, loop->latch, EDGE_FALLTHRU);
2883 1.1 mrg set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header);
2884 1.1 mrg }
2885 1.1 mrg
2886 1.1 mrg /* If possible, merge loop header to the block with the exit edge.
2887 1.1 mrg This reduces the number of basic blocks to two, to please the
2888 1.1 mrg vectorizer that handles only loops with two nodes. */
2889 1.1 mrg if (exit_bb
2890 1.1 mrg && exit_bb != loop->header)
2891 1.1 mrg {
2892 1.1 mrg if (can_merge_blocks_p (loop->header, exit_bb))
2893 1.1 mrg merge_blocks (loop->header, exit_bb);
2894 1.1 mrg }
2895 1.1 mrg
2896 1.1 mrg free (ifc_bbs);
2897 1.1 mrg ifc_bbs = NULL;
2898 1.1 mrg free (predicated);
2899 1.1 mrg }
2900 1.1 mrg
2901 1.1 mrg /* Version LOOP before if-converting it; the original loop
2902 1.1 mrg will be if-converted, the new copy of the loop will not,
2903 1.1 mrg and the LOOP_VECTORIZED internal call will be guarding which
2904 1.1 mrg loop to execute. The vectorizer pass will fold this
2905 1.1 mrg internal call into either true or false.
2906 1.1 mrg
2907 1.1 mrg Note that this function intentionally invalidates profile. Both edges
2908 1.1 mrg out of LOOP_VECTORIZED must have 100% probability so the profile remains
2909 1.1 mrg consistent after the condition is folded in the vectorizer. */
2910 1.1 mrg
2911 1.1 mrg static class loop *
2912 1.1 mrg version_loop_for_if_conversion (class loop *loop, vec<gimple *> *preds)
2913 1.1 mrg {
2914 1.1 mrg basic_block cond_bb;
2915 1.1 mrg tree cond = make_ssa_name (boolean_type_node);
2916 1.1 mrg class loop *new_loop;
2917 1.1 mrg gimple *g;
2918 1.1 mrg gimple_stmt_iterator gsi;
2919 1.1 mrg unsigned int save_length;
2920 1.1 mrg
2921 1.1 mrg g = gimple_build_call_internal (IFN_LOOP_VECTORIZED, 2,
2922 1.1 mrg build_int_cst (integer_type_node, loop->num),
2923 1.1 mrg integer_zero_node);
2924 1.1 mrg gimple_call_set_lhs (g, cond);
2925 1.1 mrg
2926 1.1 mrg /* Save BB->aux around loop_version as that uses the same field. */
2927 1.1 mrg save_length = loop->inner ? loop->inner->num_nodes : loop->num_nodes;
2928 1.1 mrg void **saved_preds = XALLOCAVEC (void *, save_length);
2929 1.1 mrg for (unsigned i = 0; i < save_length; i++)
2930 1.1 mrg saved_preds[i] = ifc_bbs[i]->aux;
2931 1.1 mrg
2932 1.1 mrg initialize_original_copy_tables ();
2933 1.1 mrg /* At this point we invalidate porfile confistency until IFN_LOOP_VECTORIZED
2934 1.1 mrg is re-merged in the vectorizer. */
2935 1.1 mrg new_loop = loop_version (loop, cond, &cond_bb,
2936 1.1 mrg profile_probability::always (),
2937 1.1 mrg profile_probability::always (),
2938 1.1 mrg profile_probability::always (),
2939 1.1 mrg profile_probability::always (), true);
2940 1.1 mrg free_original_copy_tables ();
2941 1.1 mrg
2942 1.1 mrg for (unsigned i = 0; i < save_length; i++)
2943 1.1 mrg ifc_bbs[i]->aux = saved_preds[i];
2944 1.1 mrg
2945 1.1 mrg if (new_loop == NULL)
2946 1.1 mrg return NULL;
2947 1.1 mrg
2948 1.1 mrg new_loop->dont_vectorize = true;
2949 1.1 mrg new_loop->force_vectorize = false;
2950 1.1 mrg gsi = gsi_last_bb (cond_bb);
2951 1.1 mrg gimple_call_set_arg (g, 1, build_int_cst (integer_type_node, new_loop->num));
2952 1.1 mrg if (preds)
2953 1.1 mrg preds->safe_push (g);
2954 1.1 mrg gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2955 1.1 mrg update_ssa (TODO_update_ssa);
2956 1.1 mrg return new_loop;
2957 1.1 mrg }
2958 1.1 mrg
2959 1.1 mrg /* Return true when LOOP satisfies the follow conditions that will
2960 1.1 mrg allow it to be recognized by the vectorizer for outer-loop
2961 1.1 mrg vectorization:
2962 1.1 mrg - The loop is not the root node of the loop tree.
2963 1.1 mrg - The loop has exactly one inner loop.
2964 1.1 mrg - The loop has a single exit.
2965 1.1 mrg - The loop header has a single successor, which is the inner
2966 1.1 mrg loop header.
2967 1.1 mrg - Each of the inner and outer loop latches have a single
2968 1.1 mrg predecessor.
2969 1.1 mrg - The loop exit block has a single predecessor, which is the
2970 1.1 mrg inner loop's exit block. */
2971 1.1 mrg
2972 1.1 mrg static bool
2973 1.1 mrg versionable_outer_loop_p (class loop *loop)
2974 1.1 mrg {
2975 1.1 mrg if (!loop_outer (loop)
2976 1.1 mrg || loop->dont_vectorize
2977 1.1 mrg || !loop->inner
2978 1.1 mrg || loop->inner->next
2979 1.1 mrg || !single_exit (loop)
2980 1.1 mrg || !single_succ_p (loop->header)
2981 1.1 mrg || single_succ (loop->header) != loop->inner->header
2982 1.1 mrg || !single_pred_p (loop->latch)
2983 1.1 mrg || !single_pred_p (loop->inner->latch))
2984 1.1 mrg return false;
2985 1.1 mrg
2986 1.1 mrg basic_block outer_exit = single_pred (loop->latch);
2987 1.1 mrg basic_block inner_exit = single_pred (loop->inner->latch);
2988 1.1 mrg
2989 1.1 mrg if (!single_pred_p (outer_exit) || single_pred (outer_exit) != inner_exit)
2990 1.1 mrg return false;
2991 1.1 mrg
2992 1.1 mrg if (dump_file)
2993 1.1 mrg fprintf (dump_file, "Found vectorizable outer loop for versioning\n");
2994 1.1 mrg
2995 1.1 mrg return true;
2996 1.1 mrg }
2997 1.1 mrg
2998 1.1 mrg /* Performs splitting of critical edges. Skip splitting and return false
2999 1.1 mrg if LOOP will not be converted because:
3000 1.1 mrg
3001 1.1 mrg - LOOP is not well formed.
3002 1.1 mrg - LOOP has PHI with more than MAX_PHI_ARG_NUM arguments.
3003 1.1 mrg
3004 1.1 mrg Last restriction is valid only if AGGRESSIVE_IF_CONV is false. */
3005 1.1 mrg
3006 1.1 mrg static bool
3007 1.1 mrg ifcvt_split_critical_edges (class loop *loop, bool aggressive_if_conv)
3008 1.1 mrg {
3009 1.1 mrg basic_block *body;
3010 1.1 mrg basic_block bb;
3011 1.1 mrg unsigned int num = loop->num_nodes;
3012 1.1 mrg unsigned int i;
3013 1.1 mrg gimple *stmt;
3014 1.1 mrg edge e;
3015 1.1 mrg edge_iterator ei;
3016 1.1 mrg auto_vec<edge> critical_edges;
3017 1.1 mrg
3018 1.1 mrg /* Loop is not well formed. */
3019 1.1 mrg if (num <= 2 || loop->inner || !single_exit (loop))
3020 1.1 mrg return false;
3021 1.1 mrg
3022 1.1 mrg body = get_loop_body (loop);
3023 1.1 mrg for (i = 0; i < num; i++)
3024 1.1 mrg {
3025 1.1 mrg bb = body[i];
3026 1.1 mrg if (!aggressive_if_conv
3027 1.1 mrg && phi_nodes (bb)
3028 1.1 mrg && EDGE_COUNT (bb->preds) > MAX_PHI_ARG_NUM)
3029 1.1 mrg {
3030 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
3031 1.1 mrg fprintf (dump_file,
3032 1.1 mrg "BB %d has complicated PHI with more than %u args.\n",
3033 1.1 mrg bb->index, MAX_PHI_ARG_NUM);
3034 1.1 mrg
3035 1.1 mrg free (body);
3036 1.1 mrg return false;
3037 1.1 mrg }
3038 1.1 mrg if (bb == loop->latch || bb_with_exit_edge_p (loop, bb))
3039 1.1 mrg continue;
3040 1.1 mrg
3041 1.1 mrg stmt = last_stmt (bb);
3042 1.1 mrg /* Skip basic blocks not ending with conditional branch. */
3043 1.1 mrg if (!stmt || gimple_code (stmt) != GIMPLE_COND)
3044 1.1 mrg continue;
3045 1.1 mrg
3046 1.1 mrg FOR_EACH_EDGE (e, ei, bb->succs)
3047 1.1 mrg if (EDGE_CRITICAL_P (e) && e->dest->loop_father == loop)
3048 1.1 mrg critical_edges.safe_push (e);
3049 1.1 mrg }
3050 1.1 mrg free (body);
3051 1.1 mrg
3052 1.1 mrg while (critical_edges.length () > 0)
3053 1.1 mrg {
3054 1.1 mrg e = critical_edges.pop ();
3055 1.1 mrg /* Don't split if bb can be predicated along non-critical edge. */
3056 1.1 mrg if (EDGE_COUNT (e->dest->preds) > 2 || all_preds_critical_p (e->dest))
3057 1.1 mrg split_edge (e);
3058 1.1 mrg }
3059 1.1 mrg
3060 1.1 mrg return true;
3061 1.1 mrg }
3062 1.1 mrg
3063 1.1 mrg /* Delete redundant statements produced by predication which prevents
3064 1.1 mrg loop vectorization. */
3065 1.1 mrg
3066 1.1 mrg static void
3067 1.1 mrg ifcvt_local_dce (class loop *loop)
3068 1.1 mrg {
3069 1.1 mrg gimple *stmt;
3070 1.1 mrg gimple *stmt1;
3071 1.1 mrg gimple *phi;
3072 1.1 mrg gimple_stmt_iterator gsi;
3073 1.1 mrg auto_vec<gimple *> worklist;
3074 1.1 mrg enum gimple_code code;
3075 1.1 mrg use_operand_p use_p;
3076 1.1 mrg imm_use_iterator imm_iter;
3077 1.1 mrg
3078 1.1 mrg /* The loop has a single BB only. */
3079 1.1 mrg basic_block bb = loop->header;
3080 1.1 mrg tree latch_vdef = NULL_TREE;
3081 1.1 mrg
3082 1.1 mrg worklist.create (64);
3083 1.1 mrg /* Consider all phi as live statements. */
3084 1.1 mrg for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3085 1.1 mrg {
3086 1.1 mrg phi = gsi_stmt (gsi);
3087 1.1 mrg gimple_set_plf (phi, GF_PLF_2, true);
3088 1.1 mrg worklist.safe_push (phi);
3089 1.1 mrg if (virtual_operand_p (gimple_phi_result (phi)))
3090 1.1 mrg latch_vdef = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
3091 1.1 mrg }
3092 1.1 mrg /* Consider load/store statements, CALL and COND as live. */
3093 1.1 mrg for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3094 1.1 mrg {
3095 1.1 mrg stmt = gsi_stmt (gsi);
3096 1.1 mrg if (is_gimple_debug (stmt))
3097 1.1 mrg {
3098 1.1 mrg gimple_set_plf (stmt, GF_PLF_2, true);
3099 1.1 mrg continue;
3100 1.1 mrg }
3101 1.1 mrg if (gimple_store_p (stmt) || gimple_assign_load_p (stmt))
3102 1.1 mrg {
3103 1.1 mrg gimple_set_plf (stmt, GF_PLF_2, true);
3104 1.1 mrg worklist.safe_push (stmt);
3105 1.1 mrg continue;
3106 1.1 mrg }
3107 1.1 mrg code = gimple_code (stmt);
3108 1.1 mrg if (code == GIMPLE_COND || code == GIMPLE_CALL)
3109 1.1 mrg {
3110 1.1 mrg gimple_set_plf (stmt, GF_PLF_2, true);
3111 1.1 mrg worklist.safe_push (stmt);
3112 1.1 mrg continue;
3113 1.1 mrg }
3114 1.1 mrg gimple_set_plf (stmt, GF_PLF_2, false);
3115 1.1 mrg
3116 1.1 mrg if (code == GIMPLE_ASSIGN)
3117 1.1 mrg {
3118 1.1 mrg tree lhs = gimple_assign_lhs (stmt);
3119 1.1 mrg FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
3120 1.1 mrg {
3121 1.1 mrg stmt1 = USE_STMT (use_p);
3122 1.1 mrg if (!is_gimple_debug (stmt1) && gimple_bb (stmt1) != bb)
3123 1.1 mrg {
3124 1.1 mrg gimple_set_plf (stmt, GF_PLF_2, true);
3125 1.1 mrg worklist.safe_push (stmt);
3126 1.1 mrg break;
3127 1.1 mrg }
3128 1.1 mrg }
3129 1.1 mrg }
3130 1.1 mrg }
3131 1.1 mrg /* Propagate liveness through arguments of live stmt. */
3132 1.1 mrg while (worklist.length () > 0)
3133 1.1 mrg {
3134 1.1 mrg ssa_op_iter iter;
3135 1.1 mrg use_operand_p use_p;
3136 1.1 mrg tree use;
3137 1.1 mrg
3138 1.1 mrg stmt = worklist.pop ();
3139 1.1 mrg FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
3140 1.1 mrg {
3141 1.1 mrg use = USE_FROM_PTR (use_p);
3142 1.1 mrg if (TREE_CODE (use) != SSA_NAME)
3143 1.1 mrg continue;
3144 1.1 mrg stmt1 = SSA_NAME_DEF_STMT (use);
3145 1.1 mrg if (gimple_bb (stmt1) != bb || gimple_plf (stmt1, GF_PLF_2))
3146 1.1 mrg continue;
3147 1.1 mrg gimple_set_plf (stmt1, GF_PLF_2, true);
3148 1.1 mrg worklist.safe_push (stmt1);
3149 1.1 mrg }
3150 1.1 mrg }
3151 1.1 mrg /* Delete dead statements. */
3152 1.1 mrg gsi = gsi_last_bb (bb);
3153 1.1 mrg while (!gsi_end_p (gsi))
3154 1.1 mrg {
3155 1.1 mrg gimple_stmt_iterator gsiprev = gsi;
3156 1.1 mrg gsi_prev (&gsiprev);
3157 1.1 mrg stmt = gsi_stmt (gsi);
3158 1.1 mrg if (gimple_store_p (stmt) && gimple_vdef (stmt))
3159 1.1 mrg {
3160 1.1 mrg tree lhs = gimple_get_lhs (stmt);
3161 1.1 mrg ao_ref write;
3162 1.1 mrg ao_ref_init (&write, lhs);
3163 1.1 mrg
3164 1.1 mrg if (dse_classify_store (&write, stmt, false, NULL, NULL, latch_vdef)
3165 1.1 mrg == DSE_STORE_DEAD)
3166 1.1 mrg delete_dead_or_redundant_assignment (&gsi, "dead");
3167 1.1 mrg gsi = gsiprev;
3168 1.1 mrg continue;
3169 1.1 mrg }
3170 1.1 mrg
3171 1.1 mrg if (gimple_plf (stmt, GF_PLF_2))
3172 1.1 mrg {
3173 1.1 mrg gsi = gsiprev;
3174 1.1 mrg continue;
3175 1.1 mrg }
3176 1.1 mrg if (dump_file && (dump_flags & TDF_DETAILS))
3177 1.1 mrg {
3178 1.1 mrg fprintf (dump_file, "Delete dead stmt in bb#%d\n", bb->index);
3179 1.1 mrg print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
3180 1.1 mrg }
3181 1.1 mrg gsi_remove (&gsi, true);
3182 1.1 mrg release_defs (stmt);
3183 1.1 mrg gsi = gsiprev;
3184 1.1 mrg }
3185 1.1 mrg }
3186 1.1 mrg
3187 1.1 mrg /* Return true if VALUE is already available on edge PE. */
3188 1.1 mrg
3189 1.1 mrg static bool
3190 1.1 mrg ifcvt_available_on_edge_p (edge pe, tree value)
3191 1.1 mrg {
3192 1.1 mrg if (is_gimple_min_invariant (value))
3193 1.1 mrg return true;
3194 1.1 mrg
3195 1.1 mrg if (TREE_CODE (value) == SSA_NAME)
3196 1.1 mrg {
3197 1.1 mrg basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (value));
3198 1.1 mrg if (!def_bb || dominated_by_p (CDI_DOMINATORS, pe->dest, def_bb))
3199 1.1 mrg return true;
3200 1.1 mrg }
3201 1.1 mrg
3202 1.1 mrg return false;
3203 1.1 mrg }
3204 1.1 mrg
3205 1.1 mrg /* Return true if STMT can be hoisted from if-converted loop LOOP to
3206 1.1 mrg edge PE. */
3207 1.1 mrg
3208 1.1 mrg static bool
3209 1.1 mrg ifcvt_can_hoist (class loop *loop, edge pe, gimple *stmt)
3210 1.1 mrg {
3211 1.1 mrg if (auto *call = dyn_cast<gcall *> (stmt))
3212 1.1 mrg {
3213 1.1 mrg if (gimple_call_internal_p (call)
3214 1.1 mrg && internal_fn_mask_index (gimple_call_internal_fn (call)) >= 0)
3215 1.1 mrg return false;
3216 1.1 mrg }
3217 1.1 mrg else if (auto *assign = dyn_cast<gassign *> (stmt))
3218 1.1 mrg {
3219 1.1 mrg if (gimple_assign_rhs_code (assign) == COND_EXPR)
3220 1.1 mrg return false;
3221 1.1 mrg }
3222 1.1 mrg else
3223 1.1 mrg return false;
3224 1.1 mrg
3225 1.1 mrg if (gimple_has_side_effects (stmt)
3226 1.1 mrg || gimple_could_trap_p (stmt)
3227 1.1 mrg || stmt_could_throw_p (cfun, stmt)
3228 1.1 mrg || gimple_vdef (stmt)
3229 1.1 mrg || gimple_vuse (stmt))
3230 1.1 mrg return false;
3231 1.1 mrg
3232 1.1 mrg int num_args = gimple_num_args (stmt);
3233 1.1 mrg if (pe != loop_preheader_edge (loop))
3234 1.1 mrg {
3235 1.1 mrg for (int i = 0; i < num_args; ++i)
3236 1.1 mrg if (!ifcvt_available_on_edge_p (pe, gimple_arg (stmt, i)))
3237 1.1 mrg return false;
3238 1.1 mrg }
3239 1.1 mrg else
3240 1.1 mrg {
3241 1.1 mrg for (int i = 0; i < num_args; ++i)
3242 1.1 mrg if (!expr_invariant_in_loop_p (loop, gimple_arg (stmt, i)))
3243 1.1 mrg return false;
3244 1.1 mrg }
3245 1.1 mrg
3246 1.1 mrg return true;
3247 1.1 mrg }
3248 1.1 mrg
3249 1.1 mrg /* Hoist invariant statements from LOOP to edge PE. */
3250 1.1 mrg
3251 1.1 mrg static void
3252 1.1 mrg ifcvt_hoist_invariants (class loop *loop, edge pe)
3253 1.1 mrg {
3254 1.1 mrg gimple_stmt_iterator hoist_gsi = {};
3255 1.1 mrg unsigned int num_blocks = loop->num_nodes;
3256 1.1 mrg basic_block *body = get_loop_body (loop);
3257 1.1 mrg for (unsigned int i = 0; i < num_blocks; ++i)
3258 1.1 mrg for (gimple_stmt_iterator gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi);)
3259 1.1 mrg {
3260 1.1 mrg gimple *stmt = gsi_stmt (gsi);
3261 1.1 mrg if (ifcvt_can_hoist (loop, pe, stmt))
3262 1.1 mrg {
3263 1.1 mrg /* Once we've hoisted one statement, insert other statements
3264 1.1 mrg after it. */
3265 1.1 mrg gsi_remove (&gsi, false);
3266 1.1 mrg if (hoist_gsi.ptr)
3267 1.1 mrg gsi_insert_after (&hoist_gsi, stmt, GSI_NEW_STMT);
3268 1.1 mrg else
3269 1.1 mrg {
3270 1.1 mrg gsi_insert_on_edge_immediate (pe, stmt);
3271 1.1 mrg hoist_gsi = gsi_for_stmt (stmt);
3272 1.1 mrg }
3273 1.1 mrg continue;
3274 1.1 mrg }
3275 1.1 mrg gsi_next (&gsi);
3276 1.1 mrg }
3277 1.1 mrg free (body);
3278 1.1 mrg }
3279 1.1 mrg
3280 1.1 mrg /* If-convert LOOP when it is legal. For the moment this pass has no
3281 1.1 mrg profitability analysis. Returns non-zero todo flags when something
3282 1.1 mrg changed. */
3283 1.1 mrg
3284 1.1 mrg unsigned int
3285 1.1 mrg tree_if_conversion (class loop *loop, vec<gimple *> *preds)
3286 1.1 mrg {
3287 1.1 mrg unsigned int todo = 0;
3288 1.1 mrg bool aggressive_if_conv;
3289 1.1 mrg class loop *rloop;
3290 1.1 mrg bitmap exit_bbs;
3291 1.1 mrg edge pe;
3292 1.1 mrg
3293 1.1 mrg again:
3294 1.1 mrg rloop = NULL;
3295 1.1 mrg ifc_bbs = NULL;
3296 1.1 mrg need_to_predicate = false;
3297 1.1 mrg need_to_rewrite_undefined = false;
3298 1.1 mrg any_complicated_phi = false;
3299 1.1 mrg
3300 1.1 mrg /* Apply more aggressive if-conversion when loop or its outer loop were
3301 1.1 mrg marked with simd pragma. When that's the case, we try to if-convert
3302 1.1 mrg loop containing PHIs with more than MAX_PHI_ARG_NUM arguments. */
3303 1.1 mrg aggressive_if_conv = loop->force_vectorize;
3304 1.1 mrg if (!aggressive_if_conv)
3305 1.1 mrg {
3306 1.1 mrg class loop *outer_loop = loop_outer (loop);
3307 1.1 mrg if (outer_loop && outer_loop->force_vectorize)
3308 1.1 mrg aggressive_if_conv = true;
3309 1.1 mrg }
3310 1.1 mrg
3311 1.1 mrg if (!ifcvt_split_critical_edges (loop, aggressive_if_conv))
3312 1.1 mrg goto cleanup;
3313 1.1 mrg
3314 1.1 mrg if (!if_convertible_loop_p (loop)
3315 1.1 mrg || !dbg_cnt (if_conversion_tree))
3316 1.1 mrg goto cleanup;
3317 1.1 mrg
3318 1.1 mrg if ((need_to_predicate || any_complicated_phi)
3319 1.1 mrg && ((!flag_tree_loop_vectorize && !loop->force_vectorize)
3320 1.1 mrg || loop->dont_vectorize))
3321 1.1 mrg goto cleanup;
3322 1.1 mrg
3323 1.1 mrg /* The edge to insert invariant stmts on. */
3324 1.1 mrg pe = loop_preheader_edge (loop);
3325 1.1 mrg
3326 1.1 mrg /* Since we have no cost model, always version loops unless the user
3327 1.1 mrg specified -ftree-loop-if-convert or unless versioning is required.
3328 1.1 mrg Either version this loop, or if the pattern is right for outer-loop
3329 1.1 mrg vectorization, version the outer loop. In the latter case we will
3330 1.1 mrg still if-convert the original inner loop. */
3331 1.1 mrg if (need_to_predicate
3332 1.1 mrg || any_complicated_phi
3333 1.1 mrg || flag_tree_loop_if_convert != 1)
3334 1.1 mrg {
3335 1.1 mrg class loop *vloop
3336 1.1 mrg = (versionable_outer_loop_p (loop_outer (loop))
3337 1.1 mrg ? loop_outer (loop) : loop);
3338 1.1 mrg class loop *nloop = version_loop_for_if_conversion (vloop, preds);
3339 1.1 mrg if (nloop == NULL)
3340 1.1 mrg goto cleanup;
3341 1.1 mrg if (vloop != loop)
3342 1.1 mrg {
3343 1.1 mrg /* If versionable_outer_loop_p decided to version the
3344 1.1 mrg outer loop, version also the inner loop of the non-vectorized
3345 1.1 mrg loop copy. So we transform:
3346 1.1 mrg loop1
3347 1.1 mrg loop2
3348 1.1 mrg into:
3349 1.1 mrg if (LOOP_VECTORIZED (1, 3))
3350 1.1 mrg {
3351 1.1 mrg loop1
3352 1.1 mrg loop2
3353 1.1 mrg }
3354 1.1 mrg else
3355 1.1 mrg loop3 (copy of loop1)
3356 1.1 mrg if (LOOP_VECTORIZED (4, 5))
3357 1.1 mrg loop4 (copy of loop2)
3358 1.1 mrg else
3359 1.1 mrg loop5 (copy of loop4) */
3360 1.1 mrg gcc_assert (nloop->inner && nloop->inner->next == NULL);
3361 1.1 mrg rloop = nloop->inner;
3362 1.1 mrg }
3363 1.1 mrg else
3364 1.1 mrg /* If we versioned loop then make sure to insert invariant
3365 1.1 mrg stmts before the .LOOP_VECTORIZED check since the vectorizer
3366 1.1 mrg will re-use that for things like runtime alias versioning
3367 1.1 mrg whose condition can end up using those invariants. */
3368 1.1 mrg pe = single_pred_edge (gimple_bb (preds->last ()));
3369 1.1 mrg }
3370 1.1 mrg
3371 1.1 mrg /* Now all statements are if-convertible. Combine all the basic
3372 1.1 mrg blocks into one huge basic block doing the if-conversion
3373 1.1 mrg on-the-fly. */
3374 1.1 mrg combine_blocks (loop);
3375 1.1 mrg
3376 1.1 mrg /* Perform local CSE, this esp. helps the vectorizer analysis if loads
3377 1.1 mrg and stores are involved. CSE only the loop body, not the entry
3378 1.1 mrg PHIs, those are to be kept in sync with the non-if-converted copy.
3379 1.1 mrg ??? We'll still keep dead stores though. */
3380 1.1 mrg exit_bbs = BITMAP_ALLOC (NULL);
3381 1.1 mrg bitmap_set_bit (exit_bbs, single_exit (loop)->dest->index);
3382 1.1 mrg bitmap_set_bit (exit_bbs, loop->latch->index);
3383 1.1 mrg
3384 1.1 mrg std::pair <tree, tree> *name_pair;
3385 1.1 mrg unsigned ssa_names_idx;
3386 1.1 mrg FOR_EACH_VEC_ELT (redundant_ssa_names, ssa_names_idx, name_pair)
3387 1.1 mrg replace_uses_by (name_pair->first, name_pair->second);
3388 1.1 mrg redundant_ssa_names.release ();
3389 1.1 mrg
3390 1.1 mrg todo |= do_rpo_vn (cfun, loop_preheader_edge (loop), exit_bbs);
3391 1.1 mrg
3392 1.1 mrg /* Delete dead predicate computations. */
3393 1.1 mrg ifcvt_local_dce (loop);
3394 1.1 mrg BITMAP_FREE (exit_bbs);
3395 1.1 mrg
3396 1.1 mrg ifcvt_hoist_invariants (loop, pe);
3397 1.1 mrg
3398 1.1 mrg todo |= TODO_cleanup_cfg;
3399 1.1 mrg
3400 1.1 mrg cleanup:
3401 1.1 mrg if (ifc_bbs)
3402 1.1 mrg {
3403 1.1 mrg unsigned int i;
3404 1.1 mrg
3405 1.1 mrg for (i = 0; i < loop->num_nodes; i++)
3406 1.1 mrg free_bb_predicate (ifc_bbs[i]);
3407 1.1 mrg
3408 1.1 mrg free (ifc_bbs);
3409 1.1 mrg ifc_bbs = NULL;
3410 1.1 mrg }
3411 1.1 mrg if (rloop != NULL)
3412 1.1 mrg {
3413 1.1 mrg loop = rloop;
3414 1.1 mrg goto again;
3415 1.1 mrg }
3416 1.1 mrg
3417 1.1 mrg return todo;
3418 1.1 mrg }
3419 1.1 mrg
3420 1.1 mrg /* Tree if-conversion pass management. */
3421 1.1 mrg
3422 1.1 mrg namespace {
3423 1.1 mrg
3424 1.1 mrg const pass_data pass_data_if_conversion =
3425 1.1 mrg {
3426 1.1 mrg GIMPLE_PASS, /* type */
3427 1.1 mrg "ifcvt", /* name */
3428 1.1 mrg OPTGROUP_NONE, /* optinfo_flags */
3429 1.1 mrg TV_TREE_LOOP_IFCVT, /* tv_id */
3430 1.1 mrg ( PROP_cfg | PROP_ssa ), /* properties_required */
3431 1.1 mrg 0, /* properties_provided */
3432 1.1 mrg 0, /* properties_destroyed */
3433 1.1 mrg 0, /* todo_flags_start */
3434 1.1 mrg 0, /* todo_flags_finish */
3435 1.1 mrg };
3436 1.1 mrg
3437 1.1 mrg class pass_if_conversion : public gimple_opt_pass
3438 1.1 mrg {
3439 1.1 mrg public:
3440 1.1 mrg pass_if_conversion (gcc::context *ctxt)
3441 1.1 mrg : gimple_opt_pass (pass_data_if_conversion, ctxt)
3442 1.1 mrg {}
3443 1.1 mrg
3444 1.1 mrg /* opt_pass methods: */
3445 1.1 mrg virtual bool gate (function *);
3446 1.1 mrg virtual unsigned int execute (function *);
3447 1.1 mrg
3448 1.1 mrg }; // class pass_if_conversion
3449 1.1 mrg
3450 1.1 mrg bool
3451 1.1 mrg pass_if_conversion::gate (function *fun)
3452 1.1 mrg {
3453 1.1 mrg return (((flag_tree_loop_vectorize || fun->has_force_vectorize_loops)
3454 1.1 mrg && flag_tree_loop_if_convert != 0)
3455 1.1 mrg || flag_tree_loop_if_convert == 1);
3456 1.1 mrg }
3457 1.1 mrg
3458 1.1 mrg unsigned int
3459 1.1 mrg pass_if_conversion::execute (function *fun)
3460 1.1 mrg {
3461 1.1 mrg unsigned todo = 0;
3462 1.1 mrg
3463 1.1 mrg if (number_of_loops (fun) <= 1)
3464 1.1 mrg return 0;
3465 1.1 mrg
3466 1.1 mrg auto_vec<gimple *> preds;
3467 1.1 mrg for (auto loop : loops_list (cfun, 0))
3468 1.1 mrg if (flag_tree_loop_if_convert == 1
3469 1.1 mrg || ((flag_tree_loop_vectorize || loop->force_vectorize)
3470 1.1 mrg && !loop->dont_vectorize))
3471 1.1 mrg todo |= tree_if_conversion (loop, &preds);
3472 1.1 mrg
3473 1.1 mrg if (todo)
3474 1.1 mrg {
3475 1.1 mrg free_numbers_of_iterations_estimates (fun);
3476 1.1 mrg scev_reset ();
3477 1.1 mrg }
3478 1.1 mrg
3479 1.1 mrg if (flag_checking)
3480 1.1 mrg {
3481 1.1 mrg basic_block bb;
3482 1.1 mrg FOR_EACH_BB_FN (bb, fun)
3483 1.1 mrg gcc_assert (!bb->aux);
3484 1.1 mrg }
3485 1.1 mrg
3486 1.1 mrg /* Perform IL update now, it might elide some loops. */
3487 1.1 mrg if (todo & TODO_cleanup_cfg)
3488 1.1 mrg {
3489 1.1 mrg cleanup_tree_cfg ();
3490 1.1 mrg if (need_ssa_update_p (fun))
3491 1.1 mrg todo |= TODO_update_ssa;
3492 1.1 mrg }
3493 1.1 mrg if (todo & TODO_update_ssa_any)
3494 1.1 mrg update_ssa (todo & TODO_update_ssa_any);
3495 1.1 mrg
3496 1.1 mrg /* If if-conversion elided the loop fall back to the original one. */
3497 1.1 mrg for (unsigned i = 0; i < preds.length (); ++i)
3498 1.1 mrg {
3499 1.1 mrg gimple *g = preds[i];
3500 1.1 mrg if (!gimple_bb (g))
3501 1.1 mrg continue;
3502 1.1 mrg unsigned ifcvt_loop = tree_to_uhwi (gimple_call_arg (g, 0));
3503 1.1 mrg if (!get_loop (fun, ifcvt_loop))
3504 1.1 mrg {
3505 1.1 mrg if (dump_file)
3506 1.1 mrg fprintf (dump_file, "If-converted loop vanished\n");
3507 1.1 mrg fold_loop_internal_call (g, boolean_false_node);
3508 1.1 mrg }
3509 1.1 mrg }
3510 1.1 mrg
3511 1.1 mrg return 0;
3512 1.1 mrg }
3513 1.1 mrg
3514 1.1 mrg } // anon namespace
3515 1.1 mrg
3516 1.1 mrg gimple_opt_pass *
3517 1.1 mrg make_pass_if_conversion (gcc::context *ctxt)
3518 1.1 mrg {
3519 1.1 mrg return new pass_if_conversion (ctxt);
3520 1.1 mrg }
3521