Line data Source code
1 : /* Optimization of PHI nodes by converting them into straightline code.
2 : Copyright (C) 2004-2026 Free Software Foundation, Inc.
3 :
4 : This file is part of GCC.
5 :
6 : GCC is free software; you can redistribute it and/or modify it
7 : under the terms of the GNU General Public License as published by the
8 : Free Software Foundation; either version 3, or (at your option) any
9 : later version.
10 :
11 : GCC is distributed in the hope that it will be useful, but WITHOUT
12 : ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with GCC; see the file COPYING3. If not see
18 : <http://www.gnu.org/licenses/>. */
19 :
20 : #include "config.h"
21 : #include "system.h"
22 : #include "coretypes.h"
23 : #include "backend.h"
24 : #include "insn-codes.h"
25 : #include "rtl.h"
26 : #include "tree.h"
27 : #include "gimple.h"
28 : #include "cfghooks.h"
29 : #include "tree-pass.h"
30 : #include "ssa.h"
31 : #include "tree-ssa.h"
32 : #include "optabs-tree.h"
33 : #include "insn-config.h"
34 : #include "gimple-pretty-print.h"
35 : #include "fold-const.h"
36 : #include "stor-layout.h"
37 : #include "cfganal.h"
38 : #include "gimple-iterator.h"
39 : #include "tree-cfg.h"
40 : #include "tree-dfa.h"
41 : #include "domwalk.h"
42 : #include "cfgloop.h"
43 : #include "tree-data-ref.h"
44 : #include "tree-scalar-evolution.h"
45 : #include "tree-inline.h"
46 : #include "case-cfn-macros.h"
47 : #include "tree-eh.h"
48 : #include "gimple-fold.h"
49 : #include "internal-fn.h"
50 : #include "gimple-range.h"
51 : #include "gimple-match.h"
52 : #include "dbgcnt.h"
53 : #include "tree-ssa-propagate.h"
54 : #include "tree-ssa-dce.h"
55 : #include "tree-ssa-loop-niter.h"
56 : #include "gimple-predict.h"
57 : #include "alias.h"
58 : #include "tree-ssa-threadedge.h"
59 :
60 : /* Return the singleton PHI in the SEQ of PHIs for edges E0 and E1. */
61 :
62 : static gphi *
63 3561818 : single_non_singleton_phi_for_edges (gimple_seq seq, edge e0, edge e1)
64 : {
65 3561818 : gimple_stmt_iterator i;
66 3561818 : gphi *phi = NULL;
67 5293508 : for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
68 : {
69 4320351 : gphi *p = as_a <gphi *> (gsi_stmt (i));
70 : /* If the PHI arguments are equal then we can skip this PHI. */
71 4320351 : if (operand_equal_for_phi_arg_p (gimple_phi_arg_def (p, e0->dest_idx),
72 4320351 : gimple_phi_arg_def (p, e1->dest_idx)))
73 255525 : continue;
74 :
75 : /* Punt on virtual phis with different arguments from the edges. */
76 8129652 : if (virtual_operand_p (gimple_phi_result (p)))
77 : return NULL;
78 :
79 : /* If we already have a PHI that has the two edge arguments are
80 : different, then return it is not a singleton for these PHIs. */
81 1738110 : if (phi)
82 : return NULL;
83 :
84 : phi = p;
85 : }
86 : return phi;
87 : }
88 :
89 : /* Replace PHI node element whose edge is E in block BB with variable NEW.
90 : Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
91 : is known to have two edges, one of which must reach BB). */
92 :
93 : static void
94 99252 : replace_phi_edge_with_variable (basic_block cond_block,
95 : edge e, gphi *phi, tree new_tree,
96 : bitmap dce_ssa_names = nullptr)
97 : {
98 99252 : basic_block bb = gimple_bb (phi);
99 99252 : gimple_stmt_iterator gsi;
100 99252 : tree phi_result = gimple_phi_result (phi);
101 99252 : bool deleteboth = false;
102 :
103 : /* Duplicate range info if they are the only things setting the target PHI.
104 : This is needed as later on, the new_tree will be replacing
105 : The assignment of the PHI.
106 : For an example:
107 : bb1:
108 : _4 = min<a_1, 255>
109 : goto bb2
110 :
111 : # RANGE [-INF, 255]
112 : a_3 = PHI<_4(1)>
113 : bb3:
114 :
115 : use(a_3)
116 : And _4 gets propagated into the use of a_3 and losing the range info.
117 : This can't be done for more than 2 incoming edges as the propagation
118 : won't happen.
119 : The new_tree needs to be defined in the same basic block as the conditional. */
120 99252 : if (TREE_CODE (new_tree) == SSA_NAME
121 99231 : && EDGE_COUNT (gimple_bb (phi)->preds) == 2
122 64658 : && INTEGRAL_TYPE_P (TREE_TYPE (phi_result))
123 59378 : && !SSA_NAME_RANGE_INFO (new_tree)
124 58970 : && SSA_NAME_RANGE_INFO (phi_result)
125 32269 : && gimple_bb (SSA_NAME_DEF_STMT (new_tree)) == cond_block
126 131521 : && dbg_cnt (phiopt_edge_range))
127 32269 : duplicate_ssa_name_range_info (new_tree, phi_result);
128 :
129 : /* Change the PHI argument to new. */
130 99252 : SET_USE (PHI_ARG_DEF_PTR (phi, e->dest_idx), new_tree);
131 :
132 : /* Remove the empty basic block. */
133 99252 : edge edge_to_remove = NULL, keep_edge = NULL;
134 99252 : if (EDGE_SUCC (cond_block, 0)->dest == bb)
135 : {
136 30150 : edge_to_remove = EDGE_SUCC (cond_block, 1);
137 30150 : keep_edge = EDGE_SUCC (cond_block, 0);
138 : }
139 69102 : else if (EDGE_SUCC (cond_block, 1)->dest == bb)
140 : {
141 : edge_to_remove = EDGE_SUCC (cond_block, 0);
142 : keep_edge = EDGE_SUCC (cond_block, 1);
143 : }
144 1387 : else if ((keep_edge = find_edge (cond_block, e->src)))
145 : {
146 1387 : basic_block bb1 = EDGE_SUCC (cond_block, 0)->dest;
147 1387 : basic_block bb2 = EDGE_SUCC (cond_block, 1)->dest;
148 102026 : if (single_pred_p (bb1) && single_pred_p (bb2)
149 2774 : && single_succ_p (bb1) && single_succ_p (bb2)
150 2774 : && empty_block_p (bb1) && empty_block_p (bb2))
151 : deleteboth = true;
152 : }
153 : else
154 0 : gcc_unreachable ();
155 :
156 : /* If we are removing the cond on a loop exit,
157 : reset number of iteration information of the loop. */
158 99252 : if (loop_exits_from_bb_p (cond_block->loop_father, cond_block))
159 : {
160 0 : auto loop = cond_block->loop_father;
161 0 : free_numbers_of_iterations_estimates (loop);
162 0 : loop->any_upper_bound = false;
163 0 : loop->any_likely_upper_bound = false;
164 : }
165 :
166 99252 : if (edge_to_remove && EDGE_COUNT (edge_to_remove->dest->preds) == 1)
167 : {
168 86415 : e->flags |= EDGE_FALLTHRU;
169 86415 : e->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
170 86415 : e->probability = profile_probability::always ();
171 86415 : delete_basic_block (edge_to_remove->dest);
172 :
173 : /* Eliminate the COND_EXPR at the end of COND_BLOCK. */
174 86415 : gsi = gsi_last_bb (cond_block);
175 86415 : gsi_remove (&gsi, true);
176 : }
177 12837 : else if (deleteboth)
178 : {
179 1385 : basic_block bb1 = EDGE_SUCC (cond_block, 0)->dest;
180 1385 : basic_block bb2 = EDGE_SUCC (cond_block, 1)->dest;
181 :
182 1385 : edge newedge = redirect_edge_and_branch (keep_edge, bb);
183 :
184 : /* The new edge should be the same. */
185 1385 : gcc_assert (newedge == keep_edge);
186 :
187 1385 : keep_edge->flags |= EDGE_FALLTHRU;
188 1385 : keep_edge->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
189 1385 : keep_edge->probability = profile_probability::always ();
190 :
191 : /* Copy the edge's phi entry from the old one. */
192 1385 : copy_phi_arg_into_existing_phi (e, keep_edge);
193 :
194 : /* Delete the old 2 empty basic blocks */
195 1385 : delete_basic_block (bb1);
196 1385 : delete_basic_block (bb2);
197 :
198 : /* Eliminate the COND_EXPR at the end of COND_BLOCK. */
199 1385 : gsi = gsi_last_bb (cond_block);
200 1385 : gsi_remove (&gsi, true);
201 : }
202 : else
203 : {
204 : /* If there are other edges into the middle block make
205 : CFG cleanup deal with the edge removal to avoid
206 : updating dominators here in a non-trivial way. */
207 22904 : gcond *cond = as_a <gcond *> (*gsi_last_bb (cond_block));
208 11452 : if (keep_edge->flags & EDGE_FALSE_VALUE)
209 7522 : gimple_cond_make_false (cond);
210 3930 : else if (keep_edge->flags & EDGE_TRUE_VALUE)
211 3930 : gimple_cond_make_true (cond);
212 : }
213 :
214 99252 : if (dce_ssa_names)
215 97195 : simple_dce_from_worklist (dce_ssa_names);
216 :
217 99252 : statistics_counter_event (cfun, "Replace PHI with variable", 1);
218 :
219 99252 : if (dump_file && (dump_flags & TDF_DETAILS))
220 30 : fprintf (dump_file,
221 : "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
222 : cond_block->index,
223 : bb->index);
224 99252 : }
225 :
226 : /* Returns true if the OPERANDS (OPCOUNTED) defined from DEF_STMT is profitable to move
227 : to the usage into the basic block MERGE where the new statement
228 : will be located. */
229 : static bool
230 73283 : is_factor_profitable (gimple *def_stmt, basic_block merge, tree *operands, unsigned opcount)
231 : {
232 : /* The defining statement should be conditional. */
233 73283 : if (dominated_by_p (CDI_DOMINATORS, merge,
234 73283 : gimple_bb (def_stmt)))
235 : return false;
236 :
237 : /* We should not increase the live range of arg
238 : across too many statements or calls. */
239 69060 : gimple_stmt_iterator gsi = gsi_for_stmt (def_stmt);
240 69060 : gsi_next_nondebug (&gsi);
241 :
242 : /* Skip past nops and predicates. */
243 138773 : while (!gsi_end_p (gsi)
244 69713 : && (gimple_code (gsi_stmt (gsi)) == GIMPLE_NOP
245 10084 : || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
246 653 : gsi_next_nondebug (&gsi);
247 :
248 : /* If the defining statement is at the end of the bb, then it is
249 : always profitable to be to move. */
250 69060 : if (gsi_end_p (gsi))
251 : return true;
252 :
253 : /* If there are a few (non-call/asm) statements between
254 : the old defining statement and end of the bb, then
255 : the live range of operands will increase enough. */
256 9431 : int max_statements = param_phiopt_factor_max_stmts_live;
257 9431 : bool stmts_extending_ok = true;
258 :
259 27327 : while (!gsi_end_p (gsi))
260 : {
261 19018 : gimple *stmt = gsi_stmt (gsi);
262 19018 : auto gcode = gimple_code (stmt);
263 : /* Skip over NOPs and predicts. */
264 19063 : if (gcode == GIMPLE_NOP
265 19018 : || gcode == GIMPLE_PREDICT)
266 : {
267 45 : gsi_next_nondebug (&gsi);
268 45 : continue;
269 : }
270 : /* Non-assigns will extend the live range too much. */
271 18973 : if (gcode != GIMPLE_ASSIGN)
272 : {
273 : stmts_extending_ok = false;
274 : break;
275 : }
276 18691 : max_statements --;
277 18691 : if (max_statements == 0)
278 : {
279 : stmts_extending_ok = false;
280 : break;
281 : }
282 17851 : gsi_next_nondebug (&gsi);
283 : }
284 9431 : if (stmts_extending_ok)
285 : return true;
286 :
287 : /* Loop over all of the operands to see if all are used after anyways. */
288 1625 : for (unsigned i = 0; i < opcount; i++)
289 : {
290 1152 : tree arg = operands[i];
291 : /* If the arg is invariant, then there is
292 : no extending of the live range. */
293 1152 : if (is_gimple_min_invariant (arg))
294 460 : continue;
295 :
296 : /* Otherwise, the arg needs to be a ssa name. */
297 692 : if (TREE_CODE (arg) != SSA_NAME)
298 649 : return false;
299 :
300 : /* Check if the uses of arg is dominated by merge block, this is a quick and
301 : rough estimate if arg is still alive at the merge bb. */
302 : /* FIXME: extend to a more complete live range detection. */
303 692 : use_operand_p use_p;
304 692 : imm_use_iterator iter;
305 692 : bool usedafter = false;
306 2016 : FOR_EACH_IMM_USE_FAST (use_p, iter, arg)
307 : {
308 1367 : gimple *use_stmt = USE_STMT (use_p);
309 1367 : if (is_gimple_debug (use_stmt))
310 216 : continue;
311 1151 : basic_block use_bb = gimple_bb (use_stmt);
312 1151 : if (dominated_by_p (CDI_DOMINATORS, merge, use_bb))
313 : {
314 : usedafter = true;
315 : break;
316 : }
317 692 : }
318 692 : if (!usedafter)
319 : return false;
320 : }
321 : return true;
322 : }
323 :
324 : /* PR66726: Factor operations out of COND_EXPR. If the arguments of the PHI
325 : stmt are Unary operator, factor out the operation and perform the operation
326 : to the result of PHI stmt. COND_STMT is the controlling predicate.
327 : Return true if the operation was factored out; false otherwise. */
328 :
329 : static bool
330 3097453 : factor_out_conditional_operation (edge e0, edge e1, basic_block merge,
331 : gphi *phi, gimple *cond_stmt,
332 : bool early_p)
333 : {
334 3097453 : gimple *arg0_def_stmt = NULL, *arg1_def_stmt = NULL;
335 3097453 : tree temp, result;
336 3097453 : gphi *newphi;
337 3097453 : gimple_stmt_iterator gsi, gsi_for_def;
338 3097453 : location_t locus = gimple_location (phi);
339 3097453 : gimple_match_op arg0_op, arg1_op;
340 :
341 : /* We should only get here if the phi had two arguments. */
342 3097453 : gcc_assert (gimple_phi_num_args (phi) == 2);
343 :
344 : /* Virtual operands are never handled. */
345 6194906 : if (virtual_operand_p (gimple_phi_result (phi)))
346 : return false;
347 :
348 1352897 : tree arg0 = gimple_phi_arg_def (phi, e0->dest_idx);
349 1352897 : tree arg1 = gimple_phi_arg_def (phi, e1->dest_idx);
350 1352897 : location_t narg0_loc = gimple_location (phi);
351 1352897 : location_t narg1_loc = gimple_location (phi);
352 1352897 : if (gimple_phi_arg_location (phi, e0->dest_idx) != UNKNOWN_LOCATION)
353 1134006 : narg0_loc = gimple_phi_arg_location (phi, e0->dest_idx);
354 1352897 : if (gimple_phi_arg_location (phi, e1->dest_idx) != UNKNOWN_LOCATION)
355 952455 : narg1_loc = gimple_phi_arg_location (phi, e1->dest_idx);
356 :
357 1352897 : gcc_assert (arg0 != NULL_TREE && arg1 != NULL_TREE);
358 :
359 : /* Arguments that are the same don't have anything to be
360 : done to them. */
361 1352897 : if (operand_equal_for_phi_arg_p (arg0, arg1))
362 : return false;
363 :
364 : /* First canonicalize to simplify tests. */
365 1352717 : if (TREE_CODE (arg0) != SSA_NAME)
366 : {
367 262683 : std::swap (arg0, arg1);
368 262683 : std::swap (e0, e1);
369 : }
370 :
371 1352717 : if (TREE_CODE (arg0) != SSA_NAME
372 1231674 : || (TREE_CODE (arg1) != SSA_NAME
373 499057 : && TREE_CODE (arg1) != INTEGER_CST))
374 : return false;
375 :
376 : /* Check if arg0 is an SSA_NAME and the stmt which defines arg0 is
377 : an unary operation. */
378 1194231 : arg0_def_stmt = SSA_NAME_DEF_STMT (arg0);
379 1194231 : if (!gimple_extract_op (arg0_def_stmt, &arg0_op))
380 : return false;
381 :
382 : /* Check to make sure none of the operands are in abnormal phis. */
383 619900 : if (arg0_op.operands_occurs_in_abnormal_phi ())
384 : return false;
385 :
386 619900 : tree new_arg0;
387 619900 : tree new_arg1;
388 619900 : int opnum = -1;
389 :
390 : /* If arg0 have > 1 use, then this transformation actually increases
391 : the number of expressions evaluated at runtime. */
392 619900 : if (!has_single_use (arg0))
393 : return false;
394 505747 : if (gimple_has_location (arg0_def_stmt))
395 466504 : narg0_loc = gimple_location (arg0_def_stmt);
396 :
397 505747 : if (TREE_CODE (arg1) == SSA_NAME)
398 : {
399 : /* Check if arg1 is an SSA_NAME. */
400 327496 : arg1_def_stmt = SSA_NAME_DEF_STMT (arg1);
401 327496 : if (!gimple_extract_op (arg1_def_stmt, &arg1_op))
402 318928 : return false;
403 167514 : if (arg1_op.code != arg0_op.code)
404 : return false;
405 48654 : if (arg1_op.num_ops != arg0_op.num_ops)
406 : return false;
407 48638 : if (arg1_op.operands_occurs_in_abnormal_phi ())
408 : return false;
409 :
410 : /* For the complex expression, don't factor
411 : out, that will confuse the uninitializing
412 : warnings. */
413 48638 : if (arg1_op.code == COMPLEX_EXPR)
414 : return false;
415 :
416 : /* If arg1 have > 1 use, then this transformation actually increases
417 : the number of expressions evaluated at runtime. */
418 48523 : if (!has_single_use (arg1))
419 : return false;
420 :
421 36382 : opnum = find_different_opnum (arg0_op, arg1_op, &new_arg0, &new_arg1);
422 36382 : if (opnum == -1)
423 : return false;
424 :
425 : /* Check to make sure extending the lifetimes of all operands is ok. */
426 14127 : if (!is_factor_profitable (arg0_def_stmt, merge,
427 : arg0_op.ops, arg0_op.num_ops))
428 : return false;
429 13064 : if (!is_factor_profitable (arg1_def_stmt, merge,
430 : arg1_op.ops, arg1_op.num_ops))
431 : return false;
432 :
433 10136 : tree args[2] = { new_arg0, new_arg1 };
434 10136 : location_t locs[2];
435 10136 : locs[0] = gimple_location (arg0_def_stmt);
436 10136 : locs[1] = gimple_location (arg1_def_stmt);
437 10136 : if (!factor_operation_ok (arg1_op.code, opnum, args, locs, 2, false, !early_p))
438 : return false;
439 :
440 8568 : if (gimple_has_location (arg1_def_stmt))
441 8318 : narg1_loc = gimple_location (arg1_def_stmt);
442 :
443 : /* Chose the location for the new statement if the phi location is unknown. */
444 8568 : if (locus == UNKNOWN_LOCATION)
445 : {
446 8568 : if (narg0_loc == UNKNOWN_LOCATION
447 8568 : && narg1_loc != UNKNOWN_LOCATION)
448 : locus = narg1_loc;
449 8568 : else if (narg0_loc != UNKNOWN_LOCATION
450 8568 : && narg1_loc == UNKNOWN_LOCATION)
451 49 : locus = narg0_loc;
452 : }
453 : }
454 178251 : else if (arg0_op.num_ops != 1)
455 : return false;
456 : else
457 : {
458 52250 : new_arg0 = arg0_op.ops[0];
459 52250 : opnum = 0;
460 : /* For constants only handle if the phi was the only one. */
461 52250 : if (single_non_singleton_phi_for_edges (phi_nodes (merge), e0, e1) == NULL)
462 : return false;
463 : /* TODO: handle more than just casts and ~/- here. */
464 38918 : if (!gimple_assign_cast_p (arg0_def_stmt)
465 6569 : && arg0_op.code != NEGATE_EXPR
466 44998 : && arg0_op.code != BIT_NOT_EXPR)
467 : return false;
468 34078 : if (!is_factor_profitable (arg0_def_stmt, merge, arg0_op.ops, arg0_op.num_ops))
469 : return false;
470 :
471 : // Heuristics for ~/-, is about being able to being able to handle
472 : // `if (a) t = -1; else t = -(CMP);`
473 : // and the like. - is usually used for a mask to emulate a
474 : // vector.
475 33197 : if (arg0_op.code == NEGATE_EXPR
476 33197 : || arg0_op.code == BIT_NOT_EXPR)
477 : {
478 1696 : if (TREE_CODE (arg1) != INTEGER_CST
479 1696 : || TREE_CODE (new_arg0) != SSA_NAME)
480 : return false;
481 :
482 : // For neg, only allow -1, 0 as those
483 : // the only ones which will reduce.
484 1696 : if (arg0_op.code == NEGATE_EXPR
485 477 : && !integer_zerop (arg1)
486 1983 : && !integer_minus_onep (arg1))
487 : return false;
488 : // For ~, only allow -2 (~1), -1 (~0) as those
489 : // the only ones which will reduce.
490 2872 : if (arg0_op.code == BIT_NOT_EXPR
491 1219 : && !integer_minus_onep (arg1)
492 3438 : && ~wi::to_wide (arg1) != 1)
493 : return false;
494 :
495 : // Look to see if the -/~ comes from a cast from a boolean.
496 654 : gimple *arg0_def_def_stmt = SSA_NAME_DEF_STMT (new_arg0);
497 654 : if (gimple_bb (arg0_def_def_stmt) != gimple_bb (arg0_def_stmt))
498 : return false;
499 434 : if (!gimple_assign_cast_p (arg0_def_def_stmt))
500 : return false;
501 140 : tree_code ass_code = gimple_assign_rhs_code (arg0_def_def_stmt);
502 140 : if (!CONVERT_EXPR_CODE_P (ass_code))
503 : return false;
504 136 : tree rhs_type = TREE_TYPE (gimple_assign_rhs1 (arg0_def_def_stmt));
505 136 : if (!INTEGRAL_TYPE_P (rhs_type)
506 136 : || !TYPE_UNSIGNED (rhs_type)
507 228 : || TYPE_PRECISION (rhs_type) != 1)
508 : return false;
509 : }
510 :
511 : /* If arg1 is an INTEGER_CST, fold it to new type if it fits, or else
512 : if the bits will not be modified during the conversion, except for
513 : boolean types whose precision is not 1 (see int_fits_type_p). */
514 62989 : else if (!INTEGRAL_TYPE_P (TREE_TYPE (new_arg0))
515 62725 : || !(int_fits_type_p (arg1, TREE_TYPE (new_arg0))
516 1603 : || (TYPE_PRECISION (TREE_TYPE (new_arg0))
517 1603 : == TYPE_PRECISION (TREE_TYPE (arg1))
518 708 : && (TREE_CODE (TREE_TYPE (new_arg0)) != BOOLEAN_TYPE
519 0 : || TYPE_PRECISION (TREE_TYPE (new_arg0)) == 1))))
520 : return false;
521 :
522 : /* For the INTEGER_CST case, we are just moving the
523 : conversion from one place to another, which can often
524 : hurt as the conversion moves further away from the
525 : statement that computes the value. So, perform this
526 : only if new_arg0 is an operand of COND_STMT, or
527 : if arg0_def_stmt is the only non-debug stmt in
528 : its basic block, because then it is possible this
529 : could enable further optimizations (minmax replacement
530 : etc.). See PR71016.
531 : Note no-op conversions don't have this issue as
532 : it will not generate any zero/sign extend in that case. */
533 30342 : else if ((TYPE_PRECISION (TREE_TYPE (new_arg0))
534 30342 : != TYPE_PRECISION (TREE_TYPE (arg1)))
535 14677 : && new_arg0 != gimple_cond_lhs (cond_stmt)
536 13976 : && new_arg0 != gimple_cond_rhs (cond_stmt)
537 44312 : && gimple_bb (arg0_def_stmt) == e0->src)
538 : {
539 13970 : gsi = gsi_for_stmt (arg0_def_stmt);
540 13970 : gsi_prev_nondebug (&gsi);
541 : /* Ignore nops, predicates and labels. */
542 27952 : while (!gsi_end_p (gsi)
543 13982 : && (gimple_code (gsi_stmt (gsi)) == GIMPLE_NOP
544 : || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT
545 : || gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL))
546 12 : gsi_prev_nondebug (&gsi);
547 :
548 13970 : if (!gsi_end_p (gsi))
549 : {
550 10539 : gimple *stmt = gsi_stmt (gsi);
551 10539 : if (gassign *assign = dyn_cast <gassign *> (stmt))
552 : {
553 9906 : tree lhs = gimple_assign_lhs (assign);
554 9906 : tree lhst = TREE_TYPE (lhs);
555 9906 : enum tree_code ass_code
556 9906 : = gimple_assign_rhs_code (assign);
557 9906 : if (ass_code != MAX_EXPR && ass_code != MIN_EXPR
558 : /* Conversions from boolean like types is ok
559 : as `a?1:b` and `a?0:b` will always simplify
560 : to `a & b` or `a | b`.
561 : See PR 116890. */
562 9906 : && !(INTEGRAL_TYPE_P (lhst)
563 9427 : && TYPE_UNSIGNED (lhst)
564 7062 : && TYPE_PRECISION (lhst) == 1))
565 : return false;
566 4804 : if (lhs != gimple_assign_rhs1 (arg0_def_stmt))
567 : return false;
568 4762 : gsi_prev_nondebug (&gsi);
569 4762 : if (!gsi_end_p (gsi))
570 : return false;
571 : }
572 : else
573 : return false;
574 : }
575 : }
576 :
577 : // - is still the opposite of -, likewise for ~.
578 20230 : if (arg0_op.code == NEGATE_EXPR
579 20230 : || arg0_op.code == BIT_NOT_EXPR)
580 91 : new_arg1 = fold_build1 ((tree_code)arg0_op.code,
581 : TREE_TYPE (new_arg0), arg1);
582 : else
583 20139 : new_arg1 = fold_convert (TREE_TYPE (new_arg0), arg1);
584 :
585 : /* Drop the overflow that fold_convert might add. */
586 20230 : if (TREE_OVERFLOW (new_arg1))
587 0 : new_arg1 = drop_tree_overflow (new_arg1);
588 :
589 : /* The locus of the new statement is arg0 defining statement. */
590 20230 : if (gimple_has_location (arg0_def_stmt))
591 19756 : locus = gimple_location (arg0_def_stmt);
592 : }
593 :
594 : /* Create a new PHI stmt. */
595 28798 : result = gimple_phi_result (phi);
596 28798 : temp = make_ssa_name (TREE_TYPE (new_arg0), NULL);
597 :
598 28798 : gimple_match_op new_op = arg0_op;
599 :
600 : /* Create the operation stmt if possible and insert it. */
601 28798 : new_op.ops[opnum] = temp;
602 28798 : gimple_seq seq = NULL;
603 28798 : result = maybe_push_res_to_seq (&new_op, &seq, result);
604 :
605 : /* If we can't create the new statement, release the temp name
606 : and return back. */
607 28798 : if (!result)
608 : {
609 257 : release_ssa_name (temp);
610 257 : return false;
611 : }
612 :
613 28541 : if (locus != UNKNOWN_LOCATION)
614 19805 : annotate_all_with_location (seq, locus);
615 28541 : gsi = gsi_after_labels (gimple_bb (phi));
616 28541 : gsi_insert_seq_before (&gsi, seq, GSI_CONTINUE_LINKING);
617 :
618 28541 : newphi = create_phi_node (temp, gimple_bb (phi));
619 :
620 28541 : if (dump_file && (dump_flags & TDF_DETAILS))
621 : {
622 38 : fprintf (dump_file, "PHI ");
623 38 : print_generic_expr (dump_file, gimple_phi_result (phi));
624 38 : fprintf (dump_file,
625 : " changed to factor operation out from COND_EXPR.\n");
626 38 : fprintf (dump_file, "New stmt with OPERATION that defines ");
627 38 : print_generic_expr (dump_file, result);
628 38 : fprintf (dump_file, ".\n");
629 : }
630 :
631 : /* Remove the old operation(s) that has single use. */
632 28541 : gsi_for_def = gsi_for_stmt (arg0_def_stmt);
633 28541 : gsi_remove (&gsi_for_def, true);
634 28541 : release_defs (arg0_def_stmt);
635 :
636 28541 : if (arg1_def_stmt)
637 : {
638 8311 : gsi_for_def = gsi_for_stmt (arg1_def_stmt);
639 8311 : gsi_remove (&gsi_for_def, true);
640 8311 : release_defs (arg1_def_stmt);
641 : }
642 :
643 28541 : add_phi_arg (newphi, new_arg0, e0, narg0_loc);
644 28541 : add_phi_arg (newphi, new_arg1, e1, narg1_loc);
645 :
646 : /* Remove the original PHI stmt. */
647 28541 : gsi = gsi_for_stmt (phi);
648 28541 : remove_phi_node (&gsi, false);
649 :
650 28541 : statistics_counter_event (cfun, "factored out operation", 1);
651 :
652 28541 : return true;
653 : }
654 :
655 :
656 : /* Return TRUE if SEQ/OP pair should be allowed during early phiopt.
657 : Currently this is to allow MIN/MAX and ABS/NEGATE and constants. */
658 : static bool
659 184525 : phiopt_early_allow (gimple_seq &seq, gimple_match_op &op)
660 : {
661 : /* Don't allow functions. */
662 184525 : if (!op.code.is_tree_code ())
663 : return false;
664 184464 : tree_code code = (tree_code)op.code;
665 :
666 : /* For non-empty sequence, only allow one statement
667 : a MIN/MAX and an original MIN/MAX. */
668 184464 : if (!gimple_seq_empty_p (seq))
669 : {
670 149027 : if (code == MIN_EXPR || code == MAX_EXPR)
671 : {
672 151022 : if (!gimple_seq_singleton_p (seq))
673 : return false;
674 :
675 3 : gimple *stmt = gimple_seq_first_stmt (seq);
676 : /* Only allow assignments. */
677 3 : if (!is_gimple_assign (stmt))
678 : return false;
679 3 : code = gimple_assign_rhs_code (stmt);
680 3 : return code == MIN_EXPR || code == MAX_EXPR;
681 : }
682 : return false;
683 : }
684 :
685 35437 : switch (code)
686 : {
687 : case MIN_EXPR:
688 : case MAX_EXPR:
689 : case ABS_EXPR:
690 : case ABSU_EXPR:
691 : case NEGATE_EXPR:
692 : case SSA_NAME:
693 : return true;
694 : case INTEGER_CST:
695 : case REAL_CST:
696 : case VECTOR_CST:
697 : case FIXED_CST:
698 : return true;
699 : default:
700 : return false;
701 : }
702 : }
703 :
704 : /* gimple_simplify_phiopt is like gimple_simplify but designed for PHIOPT.
705 : Return NULL if nothing can be simplified or the resulting simplified value
706 : with parts pushed if EARLY_P was true. Also rejects non allowed tree code
707 : if EARLY_P is set.
708 : Takes the comparison from COMP_STMT and two args, ARG0 and ARG1 and tries
709 : to simplify CMP ? ARG0 : ARG1.
710 : Also try to simplify (!CMP) ? ARG1 : ARG0 if the non-inverse failed. */
711 : static tree
712 548835 : gimple_simplify_phiopt (bool early_p, tree type, gimple *comp_stmt,
713 : tree arg0, tree arg1,
714 : gimple_seq *seq)
715 : {
716 548835 : gimple_seq seq1 = NULL;
717 548835 : enum tree_code comp_code = gimple_cond_code (comp_stmt);
718 548835 : location_t loc = gimple_location (comp_stmt);
719 548835 : tree cmp0 = gimple_cond_lhs (comp_stmt);
720 548835 : tree cmp1 = gimple_cond_rhs (comp_stmt);
721 : /* To handle special cases like floating point comparison, it is easier and
722 : less error-prone to build a tree and gimplify it on the fly though it is
723 : less efficient.
724 : Don't use fold_build2 here as that might create (bool)a instead of just
725 : "a != 0". */
726 548835 : tree cond = build2_loc (loc, comp_code, boolean_type_node,
727 : cmp0, cmp1);
728 :
729 548835 : if (dump_file && (dump_flags & TDF_FOLDING))
730 : {
731 1 : fprintf (dump_file, "\nphiopt match-simplify trying:\n\t");
732 1 : print_generic_expr (dump_file, cond);
733 1 : fprintf (dump_file, " ? ");
734 1 : print_generic_expr (dump_file, arg0);
735 1 : fprintf (dump_file, " : ");
736 1 : print_generic_expr (dump_file, arg1);
737 1 : fprintf (dump_file, "\n");
738 : }
739 :
740 548835 : gimple_match_op op (gimple_match_cond::UNCOND,
741 548835 : COND_EXPR, type, cond, arg0, arg1);
742 :
743 548835 : if (op.resimplify (&seq1, follow_all_ssa_edges))
744 : {
745 164522 : bool allowed = !early_p || phiopt_early_allow (seq1, op);
746 164522 : tree result = maybe_push_res_to_seq (&op, &seq1);
747 164522 : if (dump_file && (dump_flags & TDF_FOLDING))
748 : {
749 1 : fprintf (dump_file, "\nphiopt match-simplify back:\n");
750 1 : if (seq1)
751 0 : print_gimple_seq (dump_file, seq1, 0, TDF_VOPS|TDF_MEMSYMS);
752 1 : fprintf (dump_file, "result: ");
753 1 : if (result)
754 1 : print_generic_expr (dump_file, result);
755 : else
756 0 : fprintf (dump_file, " (none)");
757 1 : fprintf (dump_file, "\n");
758 1 : if (!allowed)
759 0 : fprintf (dump_file, "rejected because early\n");
760 : }
761 : /* Early we want only to allow some generated tree codes. */
762 164522 : if (allowed && result)
763 : {
764 87891 : if (loc != UNKNOWN_LOCATION)
765 87420 : annotate_all_with_location (seq1, loc);
766 87891 : gimple_seq_add_seq_without_update (seq, seq1);
767 87891 : return result;
768 : }
769 : }
770 460944 : gimple_seq_discard (seq1);
771 460944 : seq1 = NULL;
772 :
773 : /* Try the inverted comparison, that is !COMP ? ARG1 : ARG0. */
774 460944 : comp_code = invert_tree_comparison (comp_code, HONOR_NANS (cmp0));
775 :
776 460944 : if (comp_code == ERROR_MARK)
777 : return NULL;
778 :
779 443619 : cond = build2_loc (loc,
780 : comp_code, boolean_type_node,
781 : cmp0, cmp1);
782 :
783 443619 : if (dump_file && (dump_flags & TDF_FOLDING))
784 : {
785 0 : fprintf (dump_file, "\nphiopt match-simplify trying:\n\t");
786 0 : print_generic_expr (dump_file, cond);
787 0 : fprintf (dump_file, " ? ");
788 0 : print_generic_expr (dump_file, arg1);
789 0 : fprintf (dump_file, " : ");
790 0 : print_generic_expr (dump_file, arg0);
791 0 : fprintf (dump_file, "\n");
792 : }
793 :
794 443619 : gimple_match_op op1 (gimple_match_cond::UNCOND,
795 443619 : COND_EXPR, type, cond, arg1, arg0);
796 :
797 443619 : if (op1.resimplify (&seq1, follow_all_ssa_edges))
798 : {
799 79678 : bool allowed = !early_p || phiopt_early_allow (seq1, op1);
800 79678 : tree result = maybe_push_res_to_seq (&op1, &seq1);
801 79678 : if (dump_file && (dump_flags & TDF_FOLDING))
802 : {
803 0 : fprintf (dump_file, "\nphiopt match-simplify back:\n");
804 0 : if (seq1)
805 0 : print_gimple_seq (dump_file, seq1, 0, TDF_VOPS|TDF_MEMSYMS);
806 0 : fprintf (dump_file, "result: ");
807 0 : if (result)
808 0 : print_generic_expr (dump_file, result);
809 : else
810 0 : fprintf (dump_file, " (none)");
811 0 : fprintf (dump_file, "\n");
812 0 : if (!allowed)
813 0 : fprintf (dump_file, "rejected because early\n");
814 : }
815 : /* Early we want only to allow some generated tree codes. */
816 79678 : if (allowed && result)
817 : {
818 5258 : if (loc != UNKNOWN_LOCATION)
819 5258 : annotate_all_with_location (seq1, loc);
820 5258 : gimple_seq_add_seq_without_update (seq, seq1);
821 5258 : return result;
822 : }
823 : }
824 438361 : gimple_seq_discard (seq1);
825 :
826 438361 : return NULL;
827 : }
828 :
829 : /* one_feeding_comparison_into_p returns true if BB has one comparison
830 : statement and it sets STMT to that statement. Note the comparison can
831 : be trapping too. */
832 : static bool
833 1284 : one_feeding_comparison_into_p (basic_block bb,
834 : gimple *phi,
835 : gassign *&assign)
836 : {
837 1284 : assign = nullptr;
838 1284 : gimple *stmt = nullptr;
839 :
840 1284 : if (empty_block_p (bb))
841 : return false;
842 :
843 1266 : if (!single_pred_p (bb))
844 : return false;
845 :
846 1248 : if (!gimple_seq_empty_p (phi_nodes (bb)))
847 : return false;
848 :
849 1248 : gimple_stmt_iterator gsi;
850 1248 : gsi = gsi_start_nondebug_after_labels_bb (bb);
851 2498 : while (!gsi_end_p (gsi))
852 : {
853 2023 : gimple *s = gsi_stmt (gsi);
854 2023 : gsi_next_nondebug (&gsi);
855 : /* Skip over Predict and nop statements. */
856 2023 : if (gimple_code (s) == GIMPLE_PREDICT
857 2023 : || gimple_code (s) == GIMPLE_NOP)
858 2 : continue;
859 : /* If there is more one statement return false. */
860 2021 : if (stmt)
861 : return false;
862 : stmt = s;
863 : }
864 :
865 475 : if (!stmt)
866 : return false;
867 :
868 950 : if (gimple_vuse (stmt))
869 : return false;
870 :
871 469 : gassign *a = dyn_cast<gassign*>(stmt);
872 469 : if (!a || TREE_CODE_CLASS (gimple_assign_rhs_code (a)) != tcc_comparison)
873 : return false;
874 :
875 469 : tree lhs = gimple_assign_lhs (a);
876 :
877 469 : gimple *use_stmt;
878 469 : use_operand_p use_p;
879 : /* Allow only a statement which feeds into the other stmt. */
880 469 : if (!lhs || TREE_CODE (lhs) != SSA_NAME
881 469 : || !single_imm_use (lhs, &use_p, &use_stmt)
882 938 : || use_stmt != phi)
883 : return false;
884 :
885 : // Don't handle non-call exceptions
886 469 : if (stmt_could_throw_p (cfun, a))
887 : return false;
888 :
889 463 : assign = a;
890 463 : return true;
891 : }
892 :
893 : /* empty_bb_or_one_feeding_into_p returns true if bb was empty basic block
894 : or it has one cheap preparation statement that feeds into the PHI
895 : statement and it sets STMT to that statement. */
896 : static bool
897 894167 : empty_bb_or_one_feeding_into_p (basic_block bb,
898 : gimple *phi,
899 : gimple *&stmt)
900 : {
901 894167 : stmt = nullptr;
902 894167 : gimple *stmt_to_move = nullptr;
903 894167 : tree lhs;
904 :
905 894167 : if (empty_block_p (bb))
906 : return true;
907 :
908 470370 : if (!single_pred_p (bb))
909 : return false;
910 :
911 : /* The middle bb cannot have phi nodes as we don't
912 : move those assignments yet. */
913 456767 : if (!gimple_seq_empty_p (phi_nodes (bb)))
914 : return false;
915 :
916 456747 : gimple_stmt_iterator gsi;
917 :
918 456747 : gsi = gsi_start_nondebug_after_labels_bb (bb);
919 916926 : while (!gsi_end_p (gsi))
920 : {
921 674902 : gimple *s = gsi_stmt (gsi);
922 674902 : gsi_next_nondebug (&gsi);
923 : /* Skip over Predict and nop statements. */
924 674902 : if (gimple_code (s) == GIMPLE_PREDICT
925 674902 : || gimple_code (s) == GIMPLE_NOP)
926 3432 : continue;
927 : /* If there is more one statement return false. */
928 671470 : if (stmt_to_move)
929 : return false;
930 : stmt_to_move = s;
931 : }
932 :
933 : /* The only statement here was a Predict or a nop statement
934 : so return true. */
935 242024 : if (!stmt_to_move)
936 : return true;
937 :
938 484048 : if (gimple_vuse (stmt_to_move))
939 : return false;
940 :
941 168426 : if (gimple_could_trap_p (stmt_to_move)
942 168426 : || gimple_has_side_effects (stmt_to_move))
943 : return false;
944 :
945 162862 : ssa_op_iter it;
946 162862 : tree use;
947 356282 : FOR_EACH_SSA_TREE_OPERAND (use, stmt_to_move, it, SSA_OP_USE)
948 194087 : if (ssa_name_maybe_undef_p (use))
949 : return false;
950 :
951 : /* Allow assignments but allow some builtin/internal calls.
952 : As const calls don't match any of the above, yet they could
953 : still have some side-effects - they could contain
954 : gimple_could_trap_p statements, like floating point
955 : exceptions or integer division by zero. See PR70586.
956 : FIXME: perhaps gimple_has_side_effects or gimple_could_trap_p
957 : should handle this.
958 : Allow some known builtin/internal calls that are known not to
959 : trap: logical functions (e.g. bswap and bit counting). */
960 162195 : if (!is_gimple_assign (stmt_to_move))
961 : {
962 6006 : if (!is_gimple_call (stmt_to_move))
963 : return false;
964 5759 : combined_fn cfn = gimple_call_combined_fn (stmt_to_move);
965 5759 : switch (cfn)
966 : {
967 : default:
968 : return false;
969 4811 : CASE_CFN_BSWAP:
970 4811 : CASE_CFN_BITREVERSE:
971 4811 : CASE_CFN_FFS:
972 4811 : CASE_CFN_PARITY:
973 4811 : CASE_CFN_POPCOUNT:
974 4811 : CASE_CFN_CLZ:
975 4811 : CASE_CFN_CTZ:
976 4811 : case CFN_BUILT_IN_CLRSB:
977 4811 : case CFN_BUILT_IN_CLRSBL:
978 4811 : case CFN_BUILT_IN_CLRSBLL:
979 4811 : lhs = gimple_call_lhs (stmt_to_move);
980 4811 : break;
981 : }
982 : }
983 : else
984 156189 : lhs = gimple_assign_lhs (stmt_to_move);
985 :
986 161000 : gimple *use_stmt;
987 161000 : use_operand_p use_p;
988 :
989 : /* Allow only a statement which feeds into the other stmt. */
990 161000 : if (!lhs || TREE_CODE (lhs) != SSA_NAME
991 161000 : || !single_imm_use (lhs, &use_p, &use_stmt)
992 321995 : || use_stmt != phi)
993 : return false;
994 :
995 160995 : stmt = stmt_to_move;
996 160995 : return true;
997 : }
998 :
999 : /* Move STMT to before GSI and insert its defining
1000 : name into INSERTED_EXPRS bitmap.
1001 : Also rewrite its if it might be undefined when unconditionalized. */
1002 : static void
1003 194390 : move_stmt (gimple *stmt, gimple_stmt_iterator *gsi, auto_bitmap &inserted_exprs)
1004 : {
1005 194390 : if (!stmt)
1006 188394 : return;
1007 5996 : if (dump_file && (dump_flags & TDF_DETAILS))
1008 : {
1009 9 : fprintf (dump_file, "statement un-sinked:\n");
1010 9 : print_gimple_stmt (dump_file, stmt, 0,
1011 : TDF_VOPS|TDF_MEMSYMS);
1012 : }
1013 :
1014 5996 : tree name = gimple_get_lhs (stmt);
1015 : // Mark the name to be renamed if there is one.
1016 5996 : bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (name));
1017 5996 : gimple_stmt_iterator gsi1 = gsi_for_stmt (stmt);
1018 5996 : gsi_move_before (&gsi1, gsi, GSI_NEW_STMT);
1019 5996 : reset_flow_sensitive_info (name);
1020 :
1021 : /* Rewrite some code which might be undefined when
1022 : unconditionalized. */
1023 5996 : if (gimple_needing_rewrite_undefined (stmt))
1024 1151 : rewrite_to_defined_unconditional (gsi);
1025 : }
1026 :
1027 : /* RAII style class to temporarily remove flow sensitive
1028 : from ssa names defined by a gimple statement. */
1029 : class auto_flow_sensitive
1030 : {
1031 : public:
1032 : auto_flow_sensitive (gimple *s);
1033 : ~auto_flow_sensitive ();
1034 : private:
1035 : auto_vec<std::pair<tree, flow_sensitive_info_storage>, 2> stack;
1036 : };
1037 :
1038 : /* Constructor for auto_flow_sensitive. Saves
1039 : off the ssa names' flow sensitive information
1040 : that was defined by gimple statement S and
1041 : resets it to be non-flow based ones. */
1042 :
1043 1097670 : auto_flow_sensitive::auto_flow_sensitive (gimple *s)
1044 : {
1045 1097670 : if (!s)
1046 945406 : return;
1047 152264 : ssa_op_iter it;
1048 152264 : tree def;
1049 304528 : FOR_EACH_SSA_TREE_OPERAND (def, s, it, SSA_OP_DEF)
1050 : {
1051 152264 : flow_sensitive_info_storage storage;
1052 152264 : storage.save_and_clear (def);
1053 152264 : stack.safe_push (std::make_pair (def, storage));
1054 : }
1055 : }
1056 :
1057 : /* Deconstructor, restores the flow sensitive information
1058 : for the SSA names that had been saved off. */
1059 :
1060 1097670 : auto_flow_sensitive::~auto_flow_sensitive ()
1061 : {
1062 3445274 : for (auto p : stack)
1063 152264 : p.second.restore (p.first);
1064 1097670 : }
1065 :
1066 : /* Returns true if BB contains an user provided predictor
1067 : (PRED_HOT_LABEL/PRED_COLD_LABEL). */
1068 :
1069 : static bool
1070 6814 : contains_hot_cold_predict (basic_block bb)
1071 : {
1072 6814 : gimple_stmt_iterator gsi;
1073 6814 : gsi = gsi_start_nondebug_after_labels_bb (bb);
1074 9386 : for (; !gsi_end_p (gsi); gsi_next_nondebug (&gsi))
1075 : {
1076 2573 : gimple *s = gsi_stmt (gsi);
1077 2573 : if (gimple_code (s) != GIMPLE_PREDICT)
1078 1 : continue;
1079 2572 : auto predict = gimple_predict_predictor (s);
1080 2572 : if (predict == PRED_HOT_LABEL
1081 2572 : || predict == PRED_COLD_LABEL)
1082 : return true;
1083 : }
1084 : return false;
1085 : }
1086 :
1087 : /* The function match_simplify_replacement does the main work of doing the
1088 : replacement using match and simplify. Return true if the replacement is done.
1089 : Otherwise return false.
1090 : BB is the basic block where the replacement is going to be done on. ARG0
1091 : is argument 0 from PHI. Likewise for ARG1. */
1092 :
1093 : static bool
1094 862787 : match_simplify_replacement (basic_block cond_bb, basic_block middle_bb,
1095 : basic_block middle_bb_alt,
1096 : edge e0, edge e1, gphi *phi,
1097 : tree arg0, tree arg1, bool early_p,
1098 : bool threeway_p)
1099 : {
1100 862787 : gimple *stmt;
1101 862787 : gimple_stmt_iterator gsi;
1102 862787 : edge true_edge, false_edge;
1103 862787 : gimple_seq seq = NULL;
1104 862787 : tree result;
1105 862787 : gimple *stmt_to_move = NULL;
1106 862787 : gimple *stmt_to_move_alt = NULL;
1107 862787 : tree arg_true, arg_false;
1108 :
1109 : /* Special case A ? B : B as this will always simplify to B. */
1110 862787 : if (operand_equal_for_phi_arg_p (arg0, arg1))
1111 : return false;
1112 :
1113 : /* If the basic block only has a cheap preparation statement,
1114 : allow it and move it once the transformation is done. */
1115 862787 : if (!empty_bb_or_one_feeding_into_p (middle_bb, phi, stmt_to_move))
1116 : return false;
1117 :
1118 567309 : if (threeway_p
1119 567309 : && middle_bb != middle_bb_alt
1120 567309 : && !empty_bb_or_one_feeding_into_p (middle_bb_alt, phi,
1121 : stmt_to_move_alt))
1122 : return false;
1123 :
1124 : /* Do not make conditional undefs unconditional. */
1125 553412 : if ((TREE_CODE (arg0) == SSA_NAME
1126 282600 : && ssa_name_maybe_undef_p (arg0))
1127 835692 : || (TREE_CODE (arg1) == SSA_NAME
1128 246920 : && ssa_name_maybe_undef_p (arg1)))
1129 : return false;
1130 :
1131 : /* At this point we know we have a GIMPLE_COND with two successors.
1132 : One successor is BB, the other successor is an empty block which
1133 : falls through into BB.
1134 :
1135 : There is a single PHI node at the join point (BB).
1136 :
1137 : So, given the condition COND, and the two PHI arguments, match and simplify
1138 : can happen on (COND) ? arg0 : arg1. */
1139 :
1140 548835 : stmt = last_nondebug_stmt (cond_bb);
1141 :
1142 : /* We need to know which is the true edge and which is the false
1143 : edge so that we know when to invert the condition below. */
1144 548835 : extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
1145 :
1146 : /* Forward the edges over the middle basic block. */
1147 548835 : if (true_edge->dest == middle_bb)
1148 358352 : true_edge = EDGE_SUCC (true_edge->dest, 0);
1149 548835 : if (false_edge->dest == middle_bb)
1150 190483 : false_edge = EDGE_SUCC (false_edge->dest, 0);
1151 :
1152 : /* When THREEWAY_P then e1 will point to the edge of the final transition
1153 : from middle-bb to end. */
1154 548835 : if (true_edge == e0)
1155 : {
1156 358352 : if (!threeway_p)
1157 341449 : gcc_assert (false_edge == e1);
1158 : arg_true = arg0;
1159 : arg_false = arg1;
1160 : }
1161 : else
1162 : {
1163 190483 : gcc_assert (false_edge == e0);
1164 190483 : if (!threeway_p)
1165 190025 : gcc_assert (true_edge == e1);
1166 : arg_true = arg1;
1167 : arg_false = arg0;
1168 : }
1169 :
1170 548835 : tree type = TREE_TYPE (gimple_phi_result (phi));
1171 548835 : {
1172 548835 : auto_flow_sensitive s1(stmt_to_move);
1173 548835 : auto_flow_sensitive s_alt(stmt_to_move_alt);
1174 :
1175 548835 : result = gimple_simplify_phiopt (early_p, type, stmt,
1176 : arg_true, arg_false,
1177 : &seq);
1178 548835 : }
1179 :
1180 : /* For early phiopt, we don't want to lose user generated predictors
1181 : if the phiopt is converting `if (a)` into `a` as that might
1182 : be jump threaded later on so we want to keep around the
1183 : predictors. */
1184 548835 : if (early_p && result && TREE_CODE (result) == SSA_NAME)
1185 : {
1186 33491 : bool check_it = false;
1187 33491 : tree cmp0 = gimple_cond_lhs (stmt);
1188 33491 : tree cmp1 = gimple_cond_rhs (stmt);
1189 33491 : if (result == cmp0 || result == cmp1)
1190 : check_it = true;
1191 27065 : else if (gimple_seq_singleton_p (seq))
1192 : {
1193 26900 : gimple *stmt = gimple_seq_first_stmt (seq);
1194 26900 : if (is_gimple_assign (stmt)
1195 26900 : && result == gimple_assign_lhs (stmt)
1196 53800 : && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
1197 : == tcc_comparison)
1198 : check_it = true;
1199 : }
1200 : if (!check_it)
1201 : ;
1202 6426 : else if (contains_hot_cold_predict (middle_bb))
1203 : return false;
1204 6425 : else if (threeway_p
1205 : && middle_bb != middle_bb_alt
1206 6425 : && contains_hot_cold_predict (middle_bb_alt))
1207 : return false;
1208 : }
1209 :
1210 548819 : if (!result)
1211 : {
1212 : /* If we don't get back a MIN/MAX_EXPR still make sure the expression
1213 : stays in a form to be recognized by ISA that map to IEEE x > y ? x : y
1214 : semantics (that's not IEEE max semantics). */
1215 455686 : if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type))
1216 : return false;
1217 17334 : if (stmt_to_move || stmt_to_move_alt)
1218 : return false;
1219 14393 : tree_code cmp = gimple_cond_code (stmt);
1220 14393 : if (cmp != LT_EXPR && cmp != LE_EXPR
1221 14393 : && cmp != GT_EXPR && cmp != GE_EXPR)
1222 : return false;
1223 7002 : tree lhs = gimple_cond_lhs (stmt);
1224 7002 : tree rhs = gimple_cond_rhs (stmt);
1225 : /* `lhs CMP rhs ? lhs : rhs` or `lhs CMP rhs ? rhs : lhs`
1226 : are only acceptable case here. */
1227 7002 : if ((!operand_equal_for_phi_arg_p (lhs, arg_false)
1228 2708 : || !operand_equal_for_phi_arg_p (rhs, arg_true))
1229 7081 : && (!operand_equal_for_phi_arg_p (rhs, arg_false)
1230 1580 : || !operand_equal_for_phi_arg_p (lhs, arg_true)))
1231 : return false;
1232 4047 : seq = nullptr;
1233 4047 : result = gimple_build (&seq, cmp, boolean_type_node, lhs, rhs);
1234 4047 : result = gimple_build (&seq, COND_EXPR, type, result,
1235 : arg_true, arg_false);
1236 4047 : statistics_counter_event (cfun, "Non-IEEE FP MIN/MAX PHI replacement",
1237 : 1);
1238 : }
1239 97195 : if (dump_file && (dump_flags & TDF_FOLDING))
1240 1 : fprintf (dump_file, "accepted the phiopt match-simplify.\n");
1241 :
1242 97195 : auto_bitmap exprs_maybe_dce;
1243 :
1244 : /* Mark the cond statements' lhs/rhs as maybe dce. */
1245 97195 : if (TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME
1246 97195 : && !SSA_NAME_IS_DEFAULT_DEF (gimple_cond_lhs (stmt)))
1247 91592 : bitmap_set_bit (exprs_maybe_dce,
1248 91592 : SSA_NAME_VERSION (gimple_cond_lhs (stmt)));
1249 97195 : if (TREE_CODE (gimple_cond_rhs (stmt)) == SSA_NAME
1250 97195 : && !SSA_NAME_IS_DEFAULT_DEF (gimple_cond_rhs (stmt)))
1251 28522 : bitmap_set_bit (exprs_maybe_dce,
1252 28522 : SSA_NAME_VERSION (gimple_cond_rhs (stmt)));
1253 :
1254 97195 : gsi = gsi_last_bb (cond_bb);
1255 : /* Insert the sequence generated from gimple_simplify_phiopt. */
1256 97195 : if (seq)
1257 : {
1258 : // Mark the lhs of the new statements maybe for dce
1259 88302 : mark_lhs_in_seq_for_dce (exprs_maybe_dce, seq);
1260 88302 : gsi_insert_seq_before (&gsi, seq, GSI_CONTINUE_LINKING);
1261 : }
1262 :
1263 : /* If there was a statement to move, move it to right before
1264 : the original conditional. */
1265 97195 : move_stmt (stmt_to_move, &gsi, exprs_maybe_dce);
1266 97195 : move_stmt (stmt_to_move_alt, &gsi, exprs_maybe_dce);
1267 :
1268 97195 : replace_phi_edge_with_variable (cond_bb, e1, phi, result, exprs_maybe_dce);
1269 :
1270 : /* Add Statistic here even though replace_phi_edge_with_variable already
1271 : does it as we want to be able to count when match-simplify happens vs
1272 : the others. */
1273 97195 : statistics_counter_event (cfun, "match-simplify PHI replacement", 1);
1274 :
1275 : /* Note that we optimized this PHI. */
1276 97195 : return true;
1277 97195 : }
1278 :
1279 : /* The function comparison_combine tries to handle cases like:
1280 : if (a CMP0 b)
1281 : d = a CMP1 b;
1282 : PHI<d, [0,1]>
1283 : This has to be seperately as `a CMP1 b` might be trapping and
1284 : match_simplify_replacement does not handle trapping statements.
1285 : Returns true if a replacement happens. */
1286 :
1287 : static bool
1288 765592 : comparison_combine (basic_block cond_bb, basic_block middle_bb,
1289 : basic_block middle_bb_alt,
1290 : edge e0, edge e1, gphi *phi,
1291 : tree arg0, tree arg1, bool threeway_p)
1292 : {
1293 765592 : gcond *stmt;
1294 765592 : gimple_stmt_iterator gsi;
1295 765592 : edge true_edge, false_edge;
1296 765592 : tree arg_true, arg_false;
1297 :
1298 765592 : if (!types_compatible_p (boolean_type_node, TREE_TYPE (arg0)))
1299 : return false;
1300 :
1301 : /* Do not make conditional undefs unconditional. */
1302 112155 : if ((TREE_CODE (arg0) == SSA_NAME
1303 79427 : && ssa_name_maybe_undef_p (arg0))
1304 191582 : || (TREE_CODE (arg1) == SSA_NAME
1305 12254 : && ssa_name_maybe_undef_p (arg1)))
1306 : return false;
1307 :
1308 112136 : stmt = as_a<gcond*>(last_nondebug_stmt (cond_bb));
1309 :
1310 : // Handle only floating point types as they only trap.
1311 : // The match and simplify will handle the non-trapping case.
1312 112136 : if (!FLOAT_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt))))
1313 : return false;
1314 :
1315 : /* Needs to be PHI<[1,0],arg1> PHI<arg0,[1,0]>. */
1316 5102 : if (((!integer_onep (arg0) && !integer_zerop (arg0))
1317 1234 : || TREE_CODE (arg1) != SSA_NAME)
1318 5242 : && ((!integer_onep (arg1) && !integer_zerop (arg1))
1319 2470 : || TREE_CODE (arg0) != SSA_NAME))
1320 : return false;
1321 :
1322 1272 : gassign *other_cmp = nullptr;
1323 1272 : if (!one_feeding_comparison_into_p (middle_bb, phi, other_cmp))
1324 : {
1325 811 : if (!threeway_p || middle_bb == middle_bb_alt)
1326 : return false;
1327 12 : if (!empty_block_p (middle_bb))
1328 : return false;
1329 12 : if (!one_feeding_comparison_into_p (middle_bb_alt, phi, other_cmp))
1330 : return false;
1331 : }
1332 461 : else if (threeway_p
1333 461 : && middle_bb != middle_bb_alt
1334 461 : && !empty_block_p (middle_bb_alt))
1335 : return false;
1336 :
1337 : /* We need to know which is the true edge and which is the false
1338 : edge so that we know when to invert the condition below. */
1339 463 : extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
1340 :
1341 : /* Forward the edges over the middle basic block. */
1342 463 : if (true_edge->dest == middle_bb)
1343 340 : true_edge = EDGE_SUCC (true_edge->dest, 0);
1344 463 : if (false_edge->dest == middle_bb)
1345 123 : false_edge = EDGE_SUCC (false_edge->dest, 0);
1346 : /* When THREEWAY_P then e1 will point to the edge of the final transition
1347 : from middle-bb to end. */
1348 463 : if (true_edge == e0)
1349 : {
1350 340 : if (!threeway_p)
1351 338 : gcc_assert (false_edge == e1);
1352 : arg_true = arg0;
1353 : arg_false = arg1;
1354 : }
1355 : else
1356 : {
1357 123 : gcc_assert (false_edge == e0);
1358 123 : if (!threeway_p)
1359 123 : gcc_assert (true_edge == e1);
1360 : arg_true = arg1;
1361 : arg_false = arg0;
1362 : }
1363 463 : if (TREE_CODE (arg_true) == SSA_NAME
1364 463 : && arg_true != gimple_assign_lhs (other_cmp))
1365 : return false;
1366 463 : if (TREE_CODE (arg_false) == SSA_NAME
1367 463 : && arg_false != gimple_assign_lhs (other_cmp))
1368 : return false;
1369 :
1370 463 : tree larg = gimple_cond_lhs (stmt);
1371 463 : tree rarg = gimple_cond_rhs (stmt);
1372 463 : if (!operand_equal_p (larg, gimple_assign_rhs1 (other_cmp))
1373 787 : || !operand_equal_p (rarg, gimple_assign_rhs2 (other_cmp)))
1374 : return false;
1375 :
1376 171 : tree_code logical;
1377 : // a CMP0 b ? 1 : a CMP1 b -> `a CMP0 b || a CMP1 b`
1378 : // a CMP0 b ? a CMP1 b : 1 -> `!(a CMP0 b) || a CMP1 b`
1379 :
1380 : // a CMP0 b ? a CMP1 b : 0 -> `a CMP0 b && a CMP1 b`
1381 : // a CMP0 b ? 0 : a CMP1 b -> `!(a CMP0 b) && a CMP1 b`
1382 171 : if (integer_onep (arg_true) || integer_onep (arg_false))
1383 : logical = TRUTH_ORIF_EXPR;
1384 : else
1385 : logical = TRUTH_ANDIF_EXPR;
1386 171 : tree_code outer_code = gimple_cond_code (stmt);
1387 171 : tree_code inner_code = gimple_assign_rhs_code (other_cmp);
1388 : // Invert the outter if needed.
1389 171 : if (integer_onep (arg_false) || integer_zerop (arg_true))
1390 : {
1391 0 : outer_code = invert_tree_comparison (outer_code,
1392 : HONOR_NANS (larg));
1393 : // In theory could handle it as !((a CMP0 b) LOGICAL' !(a CMP1 b))
1394 : // Most likely the outer comparison will be EQ/NE which is invertable.
1395 0 : if (outer_code == ERROR_MARK)
1396 : return false;
1397 : }
1398 171 : tree result;
1399 171 : tree_code newcmp_code;
1400 171 : newcmp_code = combine_comparisons (logical, outer_code, inner_code,
1401 : boolean_type_node,
1402 : HONOR_NANS (larg), &result);
1403 171 : if (newcmp_code == ERROR_MARK)
1404 : return false;
1405 16 : gimple_seq seq = nullptr;
1406 16 : if (newcmp_code != INTEGER_CST)
1407 16 : result = gimple_build (&seq, newcmp_code, boolean_type_node,
1408 : larg, rarg);
1409 16 : gsi = gsi_last_bb (cond_bb);
1410 16 : gsi_insert_seq_before (&gsi, seq, GSI_CONTINUE_LINKING);
1411 16 : replace_phi_edge_with_variable (cond_bb, e1, phi, result);
1412 16 : return true;
1413 : }
1414 :
1415 : /* Update *ARG which is defined in STMT so that it contains the
1416 : computed value if that seems profitable. Return true if the
1417 : statement is made dead by that rewriting. */
1418 :
1419 : static bool
1420 339707 : jump_function_from_stmt (tree *arg, gimple *stmt)
1421 : {
1422 339707 : enum tree_code code = gimple_assign_rhs_code (stmt);
1423 339707 : if (code == ADDR_EXPR)
1424 : {
1425 : /* For arg = &p->i transform it to p, if possible. */
1426 4911 : tree rhs1 = gimple_assign_rhs1 (stmt);
1427 4911 : poly_int64 offset;
1428 4911 : tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (rhs1, 0),
1429 : &offset);
1430 4911 : if (tem
1431 4825 : && TREE_CODE (tem) == MEM_REF
1432 9736 : && known_eq (mem_ref_offset (tem) + offset, 0))
1433 : {
1434 2103 : *arg = TREE_OPERAND (tem, 0);
1435 2103 : return true;
1436 : }
1437 : }
1438 : /* TODO: Much like IPA-CP jump-functions we want to handle constant
1439 : additions symbolically here, and we'd need to update the comparison
1440 : code that compares the arg + cst tuples in our caller. For now the
1441 : code above exactly handles the VEC_BASE pattern from vec.h. */
1442 : return false;
1443 : }
1444 :
1445 : /* RHS is a source argument in a BIT_AND_EXPR or BIT_IOR_EXPR which feeds
1446 : a conditional of the form SSA_NAME NE 0.
1447 :
1448 : If RHS is fed by a simple EQ_EXPR or NE_EXPR comparison of two values,
1449 : see if the two input values of the comparison match arg0 and arg1.
1450 :
1451 : If so update *code and return TRUE. Otherwise return FALSE. */
1452 :
1453 : static bool
1454 165834 : rhs_is_fed_for_value_replacement (const_tree arg0, const_tree arg1,
1455 : enum tree_code *code, const_tree rhs,
1456 : enum tree_code bit_expression_code)
1457 : {
1458 : /* Obviously if RHS is not an SSA_NAME, we can't look at the defining
1459 : statement. */
1460 165834 : if (TREE_CODE (rhs) == SSA_NAME)
1461 : {
1462 130031 : gimple *def1 = SSA_NAME_DEF_STMT (rhs);
1463 :
1464 : /* Verify the defining statement has an EQ_EXPR or NE_EXPR on the RHS. */
1465 130031 : if (is_gimple_assign (def1)
1466 130031 : && ((bit_expression_code == BIT_AND_EXPR
1467 79983 : && gimple_assign_rhs_code (def1) == EQ_EXPR)
1468 97061 : || (bit_expression_code == BIT_IOR_EXPR
1469 39969 : && gimple_assign_rhs_code (def1) == NE_EXPR)))
1470 : {
1471 : /* Finally verify the source operands of the EQ_EXPR or NE_EXPR
1472 : are equal to arg0 and arg1. */
1473 28229 : tree op0 = gimple_assign_rhs1 (def1);
1474 28229 : tree op1 = gimple_assign_rhs2 (def1);
1475 28229 : if ((operand_equal_for_phi_arg_p (arg0, op0)
1476 718 : && operand_equal_for_phi_arg_p (arg1, op1))
1477 28844 : || (operand_equal_for_phi_arg_p (arg0, op1)
1478 661 : && operand_equal_for_phi_arg_p (arg1, op0)))
1479 : {
1480 : /* We will perform the optimization. */
1481 533 : *code = gimple_assign_rhs_code (def1);
1482 533 : return true;
1483 : }
1484 : }
1485 : }
1486 : return false;
1487 : }
1488 :
1489 : /* Return TRUE if arg0/arg1 are equal to the rhs/lhs or lhs/rhs of COND.
1490 :
1491 : Also return TRUE if arg0/arg1 are equal to the source arguments of an
1492 : EQ comparison feeding a BIT_AND_EXPR, or NE comparison feeding a
1493 : BIT_IOR_EXPR which feeds COND.
1494 :
1495 : Return FALSE otherwise. */
1496 :
1497 : static bool
1498 688226 : operand_equal_for_value_replacement (const_tree arg0, const_tree arg1,
1499 : enum tree_code *code, gimple *cond)
1500 : {
1501 688226 : gimple *def;
1502 688226 : tree lhs = gimple_cond_lhs (cond);
1503 688226 : tree rhs = gimple_cond_rhs (cond);
1504 :
1505 688226 : if ((operand_equal_for_phi_arg_p (arg0, lhs)
1506 27938 : && operand_equal_for_phi_arg_p (arg1, rhs))
1507 706672 : || (operand_equal_for_phi_arg_p (arg1, lhs)
1508 49362 : && operand_equal_for_phi_arg_p (arg0, rhs)))
1509 : return true;
1510 :
1511 : /* Now handle more complex case where we have an EQ comparison
1512 : feeding a BIT_AND_EXPR, or a NE comparison feeding a BIT_IOR_EXPR,
1513 : which then feeds into COND.
1514 :
1515 : First verify that COND is of the form SSA_NAME NE 0. */
1516 394157 : if (*code != NE_EXPR || !integer_zerop (rhs)
1517 960316 : || TREE_CODE (lhs) != SSA_NAME)
1518 : return false;
1519 :
1520 : /* Now ensure that SSA_NAME is set by a BIT_AND_EXPR or BIT_OR_EXPR. */
1521 285158 : def = SSA_NAME_DEF_STMT (lhs);
1522 285158 : if (!is_gimple_assign (def)
1523 285158 : || (gimple_assign_rhs_code (def) != BIT_AND_EXPR
1524 138943 : && gimple_assign_rhs_code (def) != BIT_IOR_EXPR))
1525 : return false;
1526 :
1527 : /* Now verify arg0/arg1 correspond to the source arguments of an EQ
1528 : comparison feeding the BIT_AND_EXPR or a NE comparison feeding the
1529 : BIT_IOR_EXPR. */
1530 :
1531 83109 : tree tmp = gimple_assign_rhs1 (def);
1532 83109 : if (rhs_is_fed_for_value_replacement (arg0, arg1, code, tmp,
1533 : gimple_assign_rhs_code (def)))
1534 : return true;
1535 :
1536 82725 : tmp = gimple_assign_rhs2 (def);
1537 82725 : if (rhs_is_fed_for_value_replacement (arg0, arg1, code, tmp,
1538 : gimple_assign_rhs_code (def)))
1539 : return true;
1540 :
1541 : return false;
1542 : }
1543 :
1544 : /* Returns true if ARG is a neutral element for operation CODE
1545 : on the RIGHT side. */
1546 :
1547 : static bool
1548 733 : neutral_element_p (tree_code code, tree arg, bool right)
1549 : {
1550 733 : switch (code)
1551 : {
1552 33 : case PLUS_EXPR:
1553 33 : case BIT_IOR_EXPR:
1554 33 : case BIT_XOR_EXPR:
1555 33 : return integer_zerop (arg);
1556 :
1557 198 : case LROTATE_EXPR:
1558 198 : case RROTATE_EXPR:
1559 198 : case LSHIFT_EXPR:
1560 198 : case RSHIFT_EXPR:
1561 198 : case MINUS_EXPR:
1562 198 : case POINTER_PLUS_EXPR:
1563 198 : return right && integer_zerop (arg);
1564 :
1565 327 : case MULT_EXPR:
1566 327 : return integer_onep (arg);
1567 :
1568 31 : case TRUNC_DIV_EXPR:
1569 31 : case CEIL_DIV_EXPR:
1570 31 : case FLOOR_DIV_EXPR:
1571 31 : case ROUND_DIV_EXPR:
1572 31 : case EXACT_DIV_EXPR:
1573 31 : return right && integer_onep (arg);
1574 :
1575 0 : case BIT_AND_EXPR:
1576 0 : return integer_all_onesp (arg);
1577 :
1578 : default:
1579 : return false;
1580 : }
1581 : }
1582 :
1583 : /* Returns true if ARG is an absorbing element for operation CODE. */
1584 :
1585 : static bool
1586 838 : absorbing_element_p (tree_code code, tree arg, bool right, tree rval)
1587 : {
1588 838 : switch (code)
1589 : {
1590 18 : case BIT_IOR_EXPR:
1591 18 : return integer_all_onesp (arg);
1592 :
1593 47 : case MULT_EXPR:
1594 47 : case BIT_AND_EXPR:
1595 47 : return integer_zerop (arg);
1596 :
1597 3 : case LSHIFT_EXPR:
1598 3 : case RSHIFT_EXPR:
1599 3 : case LROTATE_EXPR:
1600 3 : case RROTATE_EXPR:
1601 3 : return !right && integer_zerop (arg);
1602 :
1603 166 : case TRUNC_DIV_EXPR:
1604 166 : case CEIL_DIV_EXPR:
1605 166 : case FLOOR_DIV_EXPR:
1606 166 : case ROUND_DIV_EXPR:
1607 166 : case EXACT_DIV_EXPR:
1608 166 : case TRUNC_MOD_EXPR:
1609 166 : case CEIL_MOD_EXPR:
1610 166 : case FLOOR_MOD_EXPR:
1611 166 : case ROUND_MOD_EXPR:
1612 166 : return (!right
1613 8 : && integer_zerop (arg)
1614 174 : && tree_single_nonzero_p (rval));
1615 :
1616 : default:
1617 : return false;
1618 : }
1619 : }
1620 :
1621 : /* The function value_replacement does the main work of doing the value
1622 : replacement. Return non-zero if the replacement is done. Otherwise return
1623 : 0. If we remove the middle basic block, return 2.
1624 : BB is the basic block where the replacement is going to be done on. ARG0
1625 : is argument 0 from the PHI. Likewise for ARG1. */
1626 :
1627 : static int
1628 2506591 : value_replacement (basic_block cond_bb, basic_block middle_bb,
1629 : edge e0, edge e1, gphi *phi, tree arg0, tree arg1)
1630 : {
1631 2506591 : gimple_stmt_iterator gsi;
1632 2506591 : edge true_edge, false_edge;
1633 2506591 : enum tree_code code;
1634 2506591 : bool empty_or_with_defined_p = true;
1635 :
1636 : /* Virtual operands don't need to be handled. */
1637 4468237 : if (virtual_operand_p (arg1))
1638 : return 0;
1639 :
1640 : /* Special case A ? B : B as this will always simplify to B. */
1641 1325705 : if (operand_equal_for_phi_arg_p (arg0, arg1))
1642 : return 0;
1643 :
1644 2352690 : gcond *cond = as_a <gcond *> (*gsi_last_bb (cond_bb));
1645 1176345 : code = gimple_cond_code (cond);
1646 :
1647 : /* This transformation is only valid for equality comparisons. */
1648 1176345 : if (code != NE_EXPR && code != EQ_EXPR)
1649 : return 0;
1650 :
1651 : /* Do not make conditional undefs unconditional. */
1652 717715 : if ((TREE_CODE (arg0) == SSA_NAME
1653 552513 : && ssa_name_maybe_undef_p (arg0))
1654 1268472 : || (TREE_CODE (arg1) == SSA_NAME
1655 309893 : && ssa_name_maybe_undef_p (arg1)))
1656 : return false;
1657 :
1658 : /* If the type says honor signed zeros we cannot do this
1659 : optimization. */
1660 701526 : if (HONOR_SIGNED_ZEROS (arg1))
1661 : return 0;
1662 :
1663 : /* If there is a statement in MIDDLE_BB that defines one of the PHI
1664 : arguments, then adjust arg0 or arg1. */
1665 688226 : gsi = gsi_start_nondebug_after_labels_bb (middle_bb);
1666 2212827 : while (!gsi_end_p (gsi))
1667 : {
1668 1524601 : gimple *stmt = gsi_stmt (gsi);
1669 1524601 : tree lhs;
1670 1524601 : gsi_next_nondebug (&gsi);
1671 1524601 : if (!is_gimple_assign (stmt))
1672 : {
1673 212190 : if (gimple_code (stmt) != GIMPLE_PREDICT
1674 212190 : && gimple_code (stmt) != GIMPLE_NOP)
1675 : empty_or_with_defined_p = false;
1676 212190 : continue;
1677 : }
1678 : /* Now try to adjust arg0 or arg1 according to the computation
1679 : in the statement. */
1680 1312411 : lhs = gimple_assign_lhs (stmt);
1681 339707 : if (!(lhs == arg0
1682 339707 : && jump_function_from_stmt (&arg0, stmt))
1683 1314514 : || (lhs == arg1
1684 0 : && jump_function_from_stmt (&arg1, stmt)))
1685 1524601 : empty_or_with_defined_p = false;
1686 : }
1687 :
1688 : /* The middle bb is not empty if there are any phi nodes. */
1689 688226 : if (phi_nodes (middle_bb))
1690 80717 : empty_or_with_defined_p = false;
1691 :
1692 : /* We need to know which is the true edge and which is the false
1693 : edge so that we know if have abs or negative abs. */
1694 688226 : extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
1695 :
1696 : /* At this point we know we have a COND_EXPR with two successors.
1697 : One successor is BB, the other successor is an empty block which
1698 : falls through into BB.
1699 :
1700 : The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
1701 :
1702 : There is a single PHI node at the join point (BB) with two arguments.
1703 :
1704 : We now need to verify that the two arguments in the PHI node match
1705 : the two arguments to the equality comparison. */
1706 :
1707 688226 : bool equal_p = operand_equal_for_value_replacement (arg0, arg1, &code, cond);
1708 688226 : bool maybe_equal_p = false;
1709 688226 : if (!equal_p
1710 688226 : && empty_or_with_defined_p
1711 191084 : && TREE_CODE (gimple_cond_rhs (cond)) == INTEGER_CST
1712 838300 : && (operand_equal_for_phi_arg_p (gimple_cond_lhs (cond), arg0)
1713 150074 : ? TREE_CODE (arg1) == INTEGER_CST
1714 142293 : : (operand_equal_for_phi_arg_p (gimple_cond_lhs (cond), arg1)
1715 23908 : && TREE_CODE (arg0) == INTEGER_CST)))
1716 : maybe_equal_p = true;
1717 667958 : if (equal_p || maybe_equal_p)
1718 : {
1719 34270 : edge e;
1720 34270 : tree arg;
1721 :
1722 : /* For NE_EXPR, we want to build an assignment result = arg where
1723 : arg is the PHI argument associated with the true edge. For
1724 : EQ_EXPR we want the PHI argument associated with the false edge. */
1725 34270 : e = (code == NE_EXPR ? true_edge : false_edge);
1726 :
1727 : /* Unfortunately, E may not reach BB (it may instead have gone to
1728 : OTHER_BLOCK). If that is the case, then we want the single outgoing
1729 : edge from OTHER_BLOCK which reaches BB and represents the desired
1730 : path from COND_BLOCK. */
1731 34270 : if (e->dest == middle_bb)
1732 13732 : e = single_succ_edge (e->dest);
1733 :
1734 : /* Now we know the incoming edge to BB that has the argument for the
1735 : RHS of our new assignment statement. */
1736 34270 : if (e0 == e)
1737 : arg = arg0;
1738 : else
1739 20538 : arg = arg1;
1740 :
1741 : /* If the middle basic block was empty or is defining the
1742 : PHI arguments and this is a single phi where the args are different
1743 : for the edges e0 and e1 then we can remove the middle basic block. */
1744 34270 : if (empty_or_with_defined_p
1745 34270 : && single_non_singleton_phi_for_edges (phi_nodes (gimple_bb (phi)),
1746 : e0, e1) == phi)
1747 : {
1748 20562 : use_operand_p use_p;
1749 20562 : gimple *use_stmt;
1750 :
1751 : /* Even if arg0/arg1 isn't equal to second operand of cond, we
1752 : can optimize away the bb if we can prove it doesn't care whether
1753 : phi result is arg0/arg1 or second operand of cond. Consider:
1754 : <bb 2> [local count: 118111600]:
1755 : if (i_2(D) == 4)
1756 : goto <bb 4>; [97.00%]
1757 : else
1758 : goto <bb 3>; [3.00%]
1759 :
1760 : <bb 3> [local count: 3540129]:
1761 :
1762 : <bb 4> [local count: 118111600]:
1763 : # i_6 = PHI <i_2(D)(3), 6(2)>
1764 : _3 = i_6 != 0;
1765 : Here, carg is 4, oarg is 6, crhs is 0, and because
1766 : (4 != 0) == (6 != 0), we don't care if i_6 is 4 or 6, both
1767 : have the same outcome. So, we can optimize this to:
1768 : _3 = i_2(D) != 0;
1769 : If the single imm use of phi result >, >=, < or <=, similarly
1770 : we can check if both carg and oarg compare the same against
1771 : crhs using ccode. */
1772 20562 : if (maybe_equal_p
1773 18662 : && TREE_CODE (arg) != INTEGER_CST
1774 39208 : && single_imm_use (gimple_phi_result (phi), &use_p, &use_stmt))
1775 : {
1776 10484 : enum tree_code ccode = ERROR_MARK;
1777 10484 : tree clhs = NULL_TREE, crhs = NULL_TREE;
1778 10484 : tree carg = gimple_cond_rhs (cond);
1779 10484 : tree oarg = e0 == e ? arg1 : arg0;
1780 10484 : if (is_gimple_assign (use_stmt)
1781 10484 : && (TREE_CODE_CLASS (gimple_assign_rhs_code (use_stmt))
1782 : == tcc_comparison))
1783 : {
1784 57 : ccode = gimple_assign_rhs_code (use_stmt);
1785 57 : clhs = gimple_assign_rhs1 (use_stmt);
1786 57 : crhs = gimple_assign_rhs2 (use_stmt);
1787 : }
1788 10427 : else if (gimple_code (use_stmt) == GIMPLE_COND)
1789 : {
1790 61 : ccode = gimple_cond_code (use_stmt);
1791 61 : clhs = gimple_cond_lhs (use_stmt);
1792 61 : crhs = gimple_cond_rhs (use_stmt);
1793 : }
1794 118 : if (ccode != ERROR_MARK
1795 118 : && clhs == gimple_phi_result (phi)
1796 207 : && TREE_CODE (crhs) == INTEGER_CST)
1797 45 : switch (ccode)
1798 : {
1799 26 : case EQ_EXPR:
1800 26 : case NE_EXPR:
1801 26 : if (!tree_int_cst_equal (crhs, carg)
1802 26 : && !tree_int_cst_equal (crhs, oarg))
1803 : equal_p = true;
1804 : break;
1805 2 : case GT_EXPR:
1806 4 : if (tree_int_cst_lt (crhs, carg)
1807 2 : == tree_int_cst_lt (crhs, oarg))
1808 : equal_p = true;
1809 : break;
1810 0 : case GE_EXPR:
1811 0 : if (tree_int_cst_le (crhs, carg)
1812 0 : == tree_int_cst_le (crhs, oarg))
1813 : equal_p = true;
1814 : break;
1815 13 : case LT_EXPR:
1816 26 : if (tree_int_cst_lt (carg, crhs)
1817 13 : == tree_int_cst_lt (oarg, crhs))
1818 : equal_p = true;
1819 : break;
1820 4 : case LE_EXPR:
1821 8 : if (tree_int_cst_le (carg, crhs)
1822 4 : == tree_int_cst_le (oarg, crhs))
1823 : equal_p = true;
1824 : break;
1825 : default:
1826 : break;
1827 : }
1828 10468 : if (equal_p)
1829 : {
1830 16 : tree phires = gimple_phi_result (phi);
1831 16 : if (SSA_NAME_RANGE_INFO (phires))
1832 : {
1833 : /* After the optimization PHI result can have value
1834 : which it couldn't have previously. */
1835 15 : value_range r (TREE_TYPE (phires));
1836 15 : if (get_global_range_query ()->range_of_expr (r, phires,
1837 : phi))
1838 : {
1839 15 : value_range tmp (carg, carg);
1840 15 : r.union_ (tmp);
1841 15 : reset_flow_sensitive_info (phires);
1842 15 : set_range_info (phires, r);
1843 15 : }
1844 : else
1845 0 : reset_flow_sensitive_info (phires);
1846 15 : }
1847 : }
1848 16 : if (equal_p && MAY_HAVE_DEBUG_BIND_STMTS)
1849 : {
1850 13 : imm_use_iterator imm_iter;
1851 13 : tree phires = gimple_phi_result (phi);
1852 13 : tree temp = NULL_TREE;
1853 13 : bool reset_p = false;
1854 :
1855 : /* Add # DEBUG D#1 => arg != carg ? arg : oarg. */
1856 42 : FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, phires)
1857 : {
1858 30 : if (!is_gimple_debug (use_stmt))
1859 13 : continue;
1860 17 : if (temp == NULL_TREE)
1861 : {
1862 12 : if (!single_pred_p (middle_bb)
1863 12 : || EDGE_COUNT (gimple_bb (phi)->preds) != 2)
1864 : {
1865 : /* But only if middle_bb has a single
1866 : predecessor and phi bb has two, otherwise
1867 : we could use a SSA_NAME not usable in that
1868 : place or wrong-debug. */
1869 1 : reset_p = true;
1870 1 : break;
1871 : }
1872 11 : gimple_stmt_iterator gsi
1873 11 : = gsi_after_labels (gimple_bb (phi));
1874 11 : tree type = TREE_TYPE (phires);
1875 11 : temp = build_debug_expr_decl (type);
1876 11 : tree t = build2 (NE_EXPR, boolean_type_node,
1877 : arg, carg);
1878 11 : t = build3 (COND_EXPR, type, t, arg, oarg);
1879 11 : gimple *g = gimple_build_debug_bind (temp, t, phi);
1880 11 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1881 : }
1882 32 : FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
1883 16 : replace_exp (use_p, temp);
1884 16 : update_stmt (use_stmt);
1885 13 : }
1886 13 : if (reset_p)
1887 1 : reset_debug_uses (phi);
1888 : }
1889 : }
1890 10094 : if (equal_p)
1891 : {
1892 1916 : replace_phi_edge_with_variable (cond_bb, e1, phi, arg);
1893 : /* Note that we optimized this PHI. */
1894 1916 : return 2;
1895 : }
1896 : }
1897 13708 : else if (equal_p)
1898 : {
1899 12102 : if (!single_pred_p (middle_bb))
1900 : return 0;
1901 11161 : statistics_counter_event (cfun, "Replace PHI with "
1902 : "variable/value_replacement", 1);
1903 :
1904 : /* Replace the PHI arguments with arg. */
1905 11161 : SET_PHI_ARG_DEF (phi, e0->dest_idx, arg);
1906 11161 : SET_PHI_ARG_DEF (phi, e1->dest_idx, arg);
1907 11161 : if (dump_file && (dump_flags & TDF_DETAILS))
1908 : {
1909 0 : fprintf (dump_file, "PHI ");
1910 0 : print_generic_expr (dump_file, gimple_phi_result (phi));
1911 0 : fprintf (dump_file, " reduced for COND_EXPR in block %d to ",
1912 : cond_bb->index);
1913 0 : print_generic_expr (dump_file, arg);
1914 0 : fprintf (dump_file, ".\n");
1915 : }
1916 : return 1;
1917 : }
1918 : }
1919 :
1920 674208 : if (!single_pred_p (middle_bb))
1921 : return 0;
1922 :
1923 : /* Now optimize (x != 0) ? x + y : y to just x + y. */
1924 567815 : gsi = gsi_last_nondebug_bb (middle_bb);
1925 567815 : if (gsi_end_p (gsi))
1926 : return 0;
1927 :
1928 394375 : gimple *assign = gsi_stmt (gsi);
1929 394375 : if (!is_gimple_assign (assign)
1930 394375 : || (!INTEGRAL_TYPE_P (TREE_TYPE (arg0))
1931 109419 : && !POINTER_TYPE_P (TREE_TYPE (arg0))))
1932 : return 0;
1933 :
1934 332829 : if (gimple_assign_rhs_class (assign) != GIMPLE_BINARY_RHS)
1935 : {
1936 : /* If last stmt of the middle_bb is a conversion, handle it like
1937 : a preparation statement through constant evaluation with
1938 : checking for UB. */
1939 144779 : enum tree_code sc = gimple_assign_rhs_code (assign);
1940 144779 : if (CONVERT_EXPR_CODE_P (sc))
1941 : assign = NULL;
1942 : else
1943 : return 0;
1944 : }
1945 :
1946 : /* Punt if there are (degenerate) PHIs in middle_bb, there should not be. */
1947 211314 : if (!gimple_seq_empty_p (phi_nodes (middle_bb)))
1948 : return 0;
1949 :
1950 : /* Allow up to 2 cheap preparation statements that prepare argument
1951 : for assign, e.g.:
1952 : if (y_4 != 0)
1953 : goto <bb 3>;
1954 : else
1955 : goto <bb 4>;
1956 : <bb 3>:
1957 : _1 = (int) y_4;
1958 : iftmp.0_6 = x_5(D) r<< _1;
1959 : <bb 4>:
1960 : # iftmp.0_2 = PHI <iftmp.0_6(3), x_5(D)(2)>
1961 : or:
1962 : if (y_3(D) == 0)
1963 : goto <bb 4>;
1964 : else
1965 : goto <bb 3>;
1966 : <bb 3>:
1967 : y_4 = y_3(D) & 31;
1968 : _1 = (int) y_4;
1969 : _6 = x_5(D) r<< _1;
1970 : <bb 4>:
1971 : # _2 = PHI <x_5(D)(2), _6(3)> */
1972 211314 : gimple *prep_stmt[2] = { NULL, NULL };
1973 211314 : int prep_cnt;
1974 211314 : for (prep_cnt = 0; ; prep_cnt++)
1975 : {
1976 272621 : if (prep_cnt || assign)
1977 249357 : gsi_prev_nondebug (&gsi);
1978 272621 : if (gsi_end_p (gsi))
1979 : break;
1980 :
1981 208042 : gimple *g = gsi_stmt (gsi);
1982 208042 : if (gimple_code (g) == GIMPLE_LABEL)
1983 : break;
1984 :
1985 207684 : if (prep_cnt == 2 || !is_gimple_assign (g))
1986 146377 : return 0;
1987 :
1988 183039 : tree lhs = gimple_assign_lhs (g);
1989 183039 : tree rhs1 = gimple_assign_rhs1 (g);
1990 183039 : use_operand_p use_p;
1991 183039 : gimple *use_stmt;
1992 183039 : if (TREE_CODE (lhs) != SSA_NAME
1993 176103 : || TREE_CODE (rhs1) != SSA_NAME
1994 112234 : || !INTEGRAL_TYPE_P (TREE_TYPE (lhs))
1995 108734 : || !INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
1996 104826 : || !single_imm_use (lhs, &use_p, &use_stmt)
1997 286713 : || ((prep_cnt || assign)
1998 81921 : && use_stmt != (prep_cnt ? prep_stmt[prep_cnt - 1] : assign)))
1999 : return 0;
2000 96258 : switch (gimple_assign_rhs_code (g))
2001 : {
2002 : CASE_CONVERT:
2003 : break;
2004 20949 : case PLUS_EXPR:
2005 20949 : case BIT_AND_EXPR:
2006 20949 : case BIT_IOR_EXPR:
2007 20949 : case BIT_XOR_EXPR:
2008 20949 : if (TREE_CODE (gimple_assign_rhs2 (g)) != INTEGER_CST)
2009 : return 0;
2010 : break;
2011 : default:
2012 : return 0;
2013 : }
2014 61307 : prep_stmt[prep_cnt] = g;
2015 61307 : }
2016 :
2017 : /* Only transform if it removes the condition. */
2018 64937 : if (!single_non_singleton_phi_for_edges (phi_nodes (gimple_bb (phi)), e0, e1))
2019 : return 0;
2020 :
2021 : /* Size-wise, this is always profitable. */
2022 48747 : if (optimize_bb_for_speed_p (cond_bb)
2023 : /* The special case is useless if it has a low probability. */
2024 45979 : && profile_status_for_fn (cfun) != PROFILE_ABSENT
2025 54724 : && EDGE_PRED (middle_bb, 0)->probability < profile_probability::even ()
2026 : /* If assign is cheap, there is no point avoiding it. */
2027 57511 : && estimate_num_insns_seq (bb_seq (middle_bb), &eni_time_weights)
2028 8764 : >= 3 * estimate_num_insns (cond, &eni_time_weights))
2029 91 : return 0;
2030 :
2031 48656 : tree cond_lhs = gimple_cond_lhs (cond);
2032 48656 : tree cond_rhs = gimple_cond_rhs (cond);
2033 :
2034 : /* Propagate the cond_rhs constant through preparation stmts,
2035 : make sure UB isn't invoked while doing that. */
2036 49929 : for (int i = prep_cnt - 1; i >= 0; --i)
2037 : {
2038 13095 : gimple *g = prep_stmt[i];
2039 13095 : tree grhs1 = gimple_assign_rhs1 (g);
2040 13095 : if (!operand_equal_for_phi_arg_p (cond_lhs, grhs1))
2041 : return 0;
2042 6770 : cond_lhs = gimple_assign_lhs (g);
2043 6770 : cond_rhs = fold_convert (TREE_TYPE (grhs1), cond_rhs);
2044 6770 : if (TREE_CODE (cond_rhs) != INTEGER_CST
2045 6770 : || TREE_OVERFLOW (cond_rhs))
2046 : return 0;
2047 1273 : if (gimple_assign_rhs_class (g) == GIMPLE_BINARY_RHS)
2048 : {
2049 566 : cond_rhs = int_const_binop (gimple_assign_rhs_code (g), cond_rhs,
2050 566 : gimple_assign_rhs2 (g));
2051 566 : if (TREE_OVERFLOW (cond_rhs))
2052 : return 0;
2053 : }
2054 1273 : cond_rhs = fold_convert (TREE_TYPE (cond_lhs), cond_rhs);
2055 1273 : if (TREE_CODE (cond_rhs) != INTEGER_CST
2056 1273 : || TREE_OVERFLOW (cond_rhs))
2057 : return 0;
2058 : }
2059 :
2060 36834 : tree lhs, rhs1, rhs2;
2061 36834 : enum tree_code code_def;
2062 36834 : if (assign)
2063 : {
2064 36566 : lhs = gimple_assign_lhs (assign);
2065 36566 : rhs1 = gimple_assign_rhs1 (assign);
2066 36566 : rhs2 = gimple_assign_rhs2 (assign);
2067 36566 : code_def = gimple_assign_rhs_code (assign);
2068 : }
2069 : else
2070 : {
2071 268 : gcc_assert (prep_cnt > 0);
2072 : lhs = cond_lhs;
2073 : rhs1 = NULL_TREE;
2074 : rhs2 = NULL_TREE;
2075 : code_def = ERROR_MARK;
2076 : }
2077 :
2078 23291 : if (((code == NE_EXPR && e1 == false_edge)
2079 16531 : || (code == EQ_EXPR && e1 == true_edge))
2080 22743 : && arg0 == lhs
2081 59577 : && ((assign == NULL
2082 267 : && operand_equal_for_phi_arg_p (arg1, cond_rhs))
2083 : || (assign
2084 22476 : && arg1 == rhs1
2085 14977 : && operand_equal_for_phi_arg_p (rhs2, cond_lhs)
2086 401 : && neutral_element_p (code_def, cond_rhs, true))
2087 22405 : || (assign
2088 22405 : && arg1 == rhs2
2089 1060 : && operand_equal_for_phi_arg_p (rhs1, cond_lhs)
2090 332 : && neutral_element_p (code_def, cond_rhs, false))
2091 : || (assign
2092 22405 : && operand_equal_for_phi_arg_p (arg1, cond_rhs)
2093 2798 : && ((operand_equal_for_phi_arg_p (rhs2, cond_lhs)
2094 193 : && absorbing_element_p (code_def, cond_rhs, true, rhs2))
2095 2797 : || (operand_equal_for_phi_arg_p (rhs1, cond_lhs)
2096 645 : && absorbing_element_p (code_def,
2097 : cond_rhs, false, rhs2))))))
2098 : {
2099 112 : gsi = gsi_for_stmt (cond);
2100 : /* Moving ASSIGN might change VR of lhs, e.g. when moving u_6
2101 : def-stmt in:
2102 : if (n_5 != 0)
2103 : goto <bb 3>;
2104 : else
2105 : goto <bb 4>;
2106 :
2107 : <bb 3>:
2108 : # RANGE [0, 4294967294]
2109 : u_6 = n_5 + 4294967295;
2110 :
2111 : <bb 4>:
2112 : # u_3 = PHI <u_6(3), 4294967295(2)> */
2113 112 : reset_flow_sensitive_info (lhs);
2114 112 : gimple_stmt_iterator gsi_from;
2115 309 : for (int i = prep_cnt - 1; i >= 0; --i)
2116 : {
2117 85 : tree plhs = gimple_assign_lhs (prep_stmt[i]);
2118 85 : reset_flow_sensitive_info (plhs);
2119 85 : gsi_from = gsi_for_stmt (prep_stmt[i]);
2120 85 : gsi_move_before (&gsi_from, &gsi);
2121 : }
2122 112 : if (assign)
2123 : {
2124 110 : gsi_from = gsi_for_stmt (assign);
2125 110 : gsi_move_before (&gsi_from, &gsi);
2126 : }
2127 112 : replace_phi_edge_with_variable (cond_bb, e1, phi, lhs);
2128 112 : return 2;
2129 : }
2130 :
2131 : return 0;
2132 : }
2133 :
2134 : /* Attempt to optimize (x <=> y) cmp 0 and similar comparisons.
2135 : For strong ordering <=> try to match something like:
2136 : <bb 2> : // cond3_bb (== cond2_bb)
2137 : if (x_4(D) != y_5(D))
2138 : goto <bb 3>; [INV]
2139 : else
2140 : goto <bb 6>; [INV]
2141 :
2142 : <bb 3> : // cond_bb
2143 : if (x_4(D) < y_5(D))
2144 : goto <bb 6>; [INV]
2145 : else
2146 : goto <bb 4>; [INV]
2147 :
2148 : <bb 4> : // middle_bb
2149 :
2150 : <bb 6> : // phi_bb
2151 : # iftmp.0_2 = PHI <1(4), 0(2), -1(3)>
2152 : _1 = iftmp.0_2 == 0;
2153 :
2154 : and for partial ordering <=> something like:
2155 :
2156 : <bb 2> : // cond3_bb
2157 : if (a_3(D) == b_5(D))
2158 : goto <bb 6>; [50.00%]
2159 : else
2160 : goto <bb 3>; [50.00%]
2161 :
2162 : <bb 3> [local count: 536870913]: // cond2_bb
2163 : if (a_3(D) < b_5(D))
2164 : goto <bb 6>; [50.00%]
2165 : else
2166 : goto <bb 4>; [50.00%]
2167 :
2168 : <bb 4> [local count: 268435456]: // cond_bb
2169 : if (a_3(D) > b_5(D))
2170 : goto <bb 6>; [50.00%]
2171 : else
2172 : goto <bb 5>; [50.00%]
2173 :
2174 : <bb 5> [local count: 134217728]: // middle_bb
2175 :
2176 : <bb 6> [local count: 1073741824]: // phi_bb
2177 : # SR.27_4 = PHI <0(2), -1(3), 1(4), -128(5)>
2178 : _2 = SR.27_4 > 0; */
2179 :
2180 : static bool
2181 651151 : spaceship_replacement (basic_block cond_bb, basic_block middle_bb,
2182 : edge e0, edge e1, gphi *phi,
2183 : tree arg0, tree arg1)
2184 : {
2185 651151 : tree phires = gimple_phi_result (phi);
2186 1295203 : if (!INTEGRAL_TYPE_P (TREE_TYPE (phires))
2187 515068 : || TYPE_UNSIGNED (TREE_TYPE (phires))
2188 258640 : || !tree_fits_shwi_p (arg0)
2189 75124 : || !tree_fits_shwi_p (arg1)
2190 41346 : || (!IN_RANGE (tree_to_shwi (arg0), -1, 1)
2191 19030 : && tree_to_shwi (arg0) != -128)
2192 673938 : || (!IN_RANGE (tree_to_shwi (arg1), -1, 1)
2193 2815 : && tree_to_shwi (arg1) != -128))
2194 : return false;
2195 :
2196 20030 : basic_block phi_bb = gimple_bb (phi);
2197 20030 : gcc_assert (phi_bb == e0->dest && phi_bb == e1->dest);
2198 20030 : if (!IN_RANGE (EDGE_COUNT (phi_bb->preds), 3, 4))
2199 : return false;
2200 :
2201 7716 : use_operand_p use_p;
2202 7716 : gimple *use_stmt;
2203 7716 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (phires))
2204 : return false;
2205 7711 : if (!single_imm_use (phires, &use_p, &use_stmt))
2206 : return false;
2207 7036 : enum tree_code cmp;
2208 7036 : tree lhs, rhs;
2209 7036 : gimple *orig_use_stmt = use_stmt;
2210 7036 : tree orig_use_lhs = NULL_TREE;
2211 7036 : tree temps[2] = { NULL_TREE, NULL_TREE };
2212 :
2213 : /* Handle std::partial_ordering::_M_reverse(), i.e.
2214 : _1 = (unsigned char) phires;
2215 : _2 = -_1;
2216 : _3 = (signed char) _2;
2217 : and uses of _3 in comparison instead of phires. */
2218 7036 : if (gimple_assign_cast_p (use_stmt))
2219 : {
2220 236 : orig_use_lhs = gimple_assign_lhs (use_stmt);
2221 236 : temps[0] = orig_use_lhs;
2222 236 : tree ty1 = TREE_TYPE (gimple_assign_rhs1 (use_stmt));
2223 236 : tree ty2 = TREE_TYPE (orig_use_lhs);
2224 :
2225 236 : if (!TYPE_UNSIGNED (ty2) || !INTEGRAL_TYPE_P (ty2))
2226 : return false;
2227 197 : if (TYPE_PRECISION (ty2) != 8 || TYPE_PRECISION (ty1) < 8)
2228 : return false;
2229 94 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig_use_lhs))
2230 : return false;
2231 94 : if (!single_imm_use (orig_use_lhs, &use_p, &use_stmt))
2232 : return false;
2233 :
2234 93 : if (!is_gimple_assign (use_stmt)
2235 93 : || gimple_assign_rhs_code (use_stmt) != NEGATE_EXPR)
2236 : return false;
2237 :
2238 78 : orig_use_lhs = gimple_assign_lhs (use_stmt);
2239 78 : temps[1] = orig_use_lhs;
2240 78 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig_use_lhs))
2241 : return false;
2242 78 : if (!single_imm_use (orig_use_lhs, &use_p, &use_stmt))
2243 : return false;
2244 :
2245 78 : if (!gimple_assign_cast_p (use_stmt))
2246 : return false;
2247 :
2248 78 : orig_use_lhs = gimple_assign_lhs (use_stmt);
2249 78 : tree ty3 = TREE_TYPE (orig_use_lhs);
2250 :
2251 78 : if (!useless_type_conversion_p (ty3, ty1))
2252 : return false;
2253 78 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig_use_lhs))
2254 : return false;
2255 78 : if (!single_imm_use (orig_use_lhs, &use_p, &use_stmt))
2256 : return false;
2257 : }
2258 6878 : if (gimple_code (use_stmt) == GIMPLE_COND)
2259 : {
2260 2516 : cmp = gimple_cond_code (use_stmt);
2261 2516 : lhs = gimple_cond_lhs (use_stmt);
2262 2516 : rhs = gimple_cond_rhs (use_stmt);
2263 : }
2264 4362 : else if (is_gimple_assign (use_stmt))
2265 : {
2266 2503 : if (gimple_assign_rhs_class (use_stmt) == GIMPLE_BINARY_RHS)
2267 : {
2268 1340 : cmp = gimple_assign_rhs_code (use_stmt);
2269 1340 : lhs = gimple_assign_rhs1 (use_stmt);
2270 1340 : rhs = gimple_assign_rhs2 (use_stmt);
2271 : }
2272 1163 : else if (gimple_assign_rhs_code (use_stmt) == COND_EXPR)
2273 : {
2274 0 : tree cond = gimple_assign_rhs1 (use_stmt);
2275 0 : if (!COMPARISON_CLASS_P (cond))
2276 : return false;
2277 0 : cmp = TREE_CODE (cond);
2278 0 : lhs = TREE_OPERAND (cond, 0);
2279 0 : rhs = TREE_OPERAND (cond, 1);
2280 : }
2281 : else
2282 : return false;
2283 : }
2284 : else
2285 : return false;
2286 3856 : switch (cmp)
2287 : {
2288 3367 : case EQ_EXPR:
2289 3367 : case NE_EXPR:
2290 3367 : case LT_EXPR:
2291 3367 : case GT_EXPR:
2292 3367 : case LE_EXPR:
2293 3367 : case GE_EXPR:
2294 3367 : break;
2295 : default:
2296 : return false;
2297 : }
2298 6656 : if (lhs != (orig_use_lhs ? orig_use_lhs : phires)
2299 3004 : || !tree_fits_shwi_p (rhs)
2300 2736 : || !IN_RANGE (tree_to_shwi (rhs), -1, 1))
2301 : return false;
2302 :
2303 2724 : if (!empty_block_p (middle_bb))
2304 : return false;
2305 :
2306 5448 : gcond *cond1 = as_a <gcond *> (*gsi_last_bb (cond_bb));
2307 2724 : enum tree_code cmp1 = gimple_cond_code (cond1);
2308 2724 : switch (cmp1)
2309 : {
2310 2587 : case LT_EXPR:
2311 2587 : case LE_EXPR:
2312 2587 : case GT_EXPR:
2313 2587 : case GE_EXPR:
2314 2587 : break;
2315 : default:
2316 : return false;
2317 : }
2318 2587 : tree lhs1 = gimple_cond_lhs (cond1);
2319 2587 : tree rhs1 = gimple_cond_rhs (cond1);
2320 2587 : if (TREE_CODE (lhs1) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs1))
2321 : return false;
2322 2587 : if (TREE_CODE (rhs1) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
2323 : return false;
2324 :
2325 2587 : if (!single_pred_p (cond_bb) || !cond_only_block_p (cond_bb))
2326 : return false;
2327 :
2328 2563 : basic_block cond2_bb = single_pred (cond_bb);
2329 2563 : if (EDGE_COUNT (cond2_bb->succs) != 2)
2330 : return false;
2331 2563 : edge cond2_phi_edge;
2332 2563 : if (EDGE_SUCC (cond2_bb, 0)->dest == cond_bb)
2333 : {
2334 2110 : if (EDGE_SUCC (cond2_bb, 1)->dest != phi_bb)
2335 : return false;
2336 : cond2_phi_edge = EDGE_SUCC (cond2_bb, 1);
2337 : }
2338 453 : else if (EDGE_SUCC (cond2_bb, 0)->dest != phi_bb)
2339 : return false;
2340 : else
2341 : cond2_phi_edge = EDGE_SUCC (cond2_bb, 0);
2342 2563 : tree arg2 = gimple_phi_arg_def (phi, cond2_phi_edge->dest_idx);
2343 2563 : if (!tree_fits_shwi_p (arg2))
2344 : return false;
2345 5126 : gcond *cond2 = safe_dyn_cast <gcond *> (*gsi_last_bb (cond2_bb));
2346 2563 : if (!cond2)
2347 : return false;
2348 2563 : enum tree_code cmp2 = gimple_cond_code (cond2);
2349 2563 : tree lhs2 = gimple_cond_lhs (cond2);
2350 2563 : tree rhs2 = gimple_cond_rhs (cond2);
2351 2563 : if (lhs2 == lhs1)
2352 : {
2353 2561 : if (!operand_equal_p (rhs2, rhs1, 0))
2354 : {
2355 341 : if ((cmp2 == EQ_EXPR || cmp2 == NE_EXPR)
2356 341 : && TREE_CODE (rhs1) == INTEGER_CST
2357 341 : && TREE_CODE (rhs2) == INTEGER_CST)
2358 : {
2359 : /* For integers, we can have cond2 x == 5
2360 : and cond1 x < 5, x <= 4, x <= 5, x < 6,
2361 : x > 5, x >= 6, x >= 5 or x > 4. */
2362 341 : if (tree_int_cst_lt (rhs1, rhs2))
2363 : {
2364 341 : if (wi::ne_p (wi::to_wide (rhs1) + 1, wi::to_wide (rhs2)))
2365 : return false;
2366 341 : if (cmp1 == LE_EXPR)
2367 : cmp1 = LT_EXPR;
2368 0 : else if (cmp1 == GT_EXPR)
2369 : cmp1 = GE_EXPR;
2370 : else
2371 : return false;
2372 : }
2373 : else
2374 : {
2375 0 : gcc_checking_assert (tree_int_cst_lt (rhs2, rhs1));
2376 0 : if (wi::ne_p (wi::to_wide (rhs2) + 1, wi::to_wide (rhs1)))
2377 : return false;
2378 0 : if (cmp1 == LT_EXPR)
2379 : cmp1 = LE_EXPR;
2380 0 : else if (cmp1 == GE_EXPR)
2381 : cmp1 = GT_EXPR;
2382 : else
2383 : return false;
2384 : }
2385 : rhs1 = rhs2;
2386 : }
2387 : else
2388 : return false;
2389 : }
2390 : }
2391 2 : else if (lhs2 == rhs1)
2392 : {
2393 0 : if (rhs2 != lhs1)
2394 : return false;
2395 : }
2396 : else
2397 : return false;
2398 :
2399 2561 : tree arg3 = arg2;
2400 2561 : basic_block cond3_bb = cond2_bb;
2401 2561 : edge cond3_phi_edge = cond2_phi_edge;
2402 2561 : gcond *cond3 = cond2;
2403 2561 : enum tree_code cmp3 = cmp2;
2404 2561 : tree lhs3 = lhs2;
2405 2561 : tree rhs3 = rhs2;
2406 2561 : if (EDGE_COUNT (phi_bb->preds) == 4)
2407 : {
2408 424 : if (absu_hwi (tree_to_shwi (arg2)) != 1)
2409 : return false;
2410 416 : if ((cond2_phi_edge->flags & EDGE_FALSE_VALUE)
2411 416 : && HONOR_NANS (TREE_TYPE (lhs1)))
2412 : return false;
2413 320 : if (e1->flags & EDGE_TRUE_VALUE)
2414 : {
2415 318 : if (tree_to_shwi (arg0) != -128
2416 318 : || absu_hwi (tree_to_shwi (arg1)) != 1
2417 636 : || wi::to_widest (arg1) == wi::to_widest (arg2))
2418 : return false;
2419 : }
2420 2 : else if (tree_to_shwi (arg1) != -128
2421 2 : || absu_hwi (tree_to_shwi (arg0)) != 1
2422 4 : || wi::to_widest (arg0) == wi::to_widest (arg2))
2423 : return false;
2424 320 : switch (cmp2)
2425 : {
2426 320 : case LT_EXPR:
2427 320 : case LE_EXPR:
2428 320 : case GT_EXPR:
2429 320 : case GE_EXPR:
2430 320 : break;
2431 : default:
2432 : return false;
2433 : }
2434 : /* if (x < y) goto phi_bb; else fallthru;
2435 : if (x > y) goto phi_bb; else fallthru;
2436 : bbx:;
2437 : phi_bb:;
2438 : is ok, but if x and y are swapped in one of the comparisons,
2439 : or the comparisons are the same and operands not swapped,
2440 : or the true and false edges are swapped, it is not.
2441 : For HONOR_NANS, the edge flags are irrelevant and the comparisons
2442 : must be different for non-swapped operands and same for swapped
2443 : operands. */
2444 320 : if ((lhs2 == lhs1)
2445 320 : ^ ((cmp2 == LT_EXPR || cmp2 == LE_EXPR)
2446 320 : != (cmp1 == LT_EXPR || cmp1 == LE_EXPR))
2447 320 : ^ ((cond2_phi_edge->flags & EDGE_FALSE_VALUE) != 0))
2448 : return false;
2449 318 : if (!single_pred_p (cond2_bb) || !cond_only_block_p (cond2_bb))
2450 : return false;
2451 318 : cond3_bb = single_pred (cond2_bb);
2452 318 : if (EDGE_COUNT (cond2_bb->succs) != 2)
2453 : return false;
2454 318 : if (EDGE_SUCC (cond3_bb, 0)->dest == cond2_bb)
2455 : {
2456 150 : if (EDGE_SUCC (cond3_bb, 1)->dest != phi_bb)
2457 : return false;
2458 : cond3_phi_edge = EDGE_SUCC (cond3_bb, 1);
2459 : }
2460 168 : else if (EDGE_SUCC (cond3_bb, 0)->dest != phi_bb)
2461 : return false;
2462 : else
2463 : cond3_phi_edge = EDGE_SUCC (cond3_bb, 0);
2464 318 : arg3 = gimple_phi_arg_def (phi, cond3_phi_edge->dest_idx);
2465 636 : cond3 = safe_dyn_cast <gcond *> (*gsi_last_bb (cond3_bb));
2466 318 : if (!cond3)
2467 : return false;
2468 318 : cmp3 = gimple_cond_code (cond3);
2469 318 : lhs3 = gimple_cond_lhs (cond3);
2470 318 : rhs3 = gimple_cond_rhs (cond3);
2471 318 : if (lhs3 == lhs1)
2472 : {
2473 318 : if (!operand_equal_p (rhs3, rhs1, 0))
2474 : return false;
2475 : }
2476 0 : else if (lhs3 == rhs1)
2477 : {
2478 0 : if (rhs3 != lhs1)
2479 : return false;
2480 : }
2481 : else
2482 : return false;
2483 : }
2484 2137 : else if (absu_hwi (tree_to_shwi (arg0)) != 1
2485 2116 : || absu_hwi (tree_to_shwi (arg1)) != 1
2486 4253 : || wi::to_widest (arg0) == wi::to_widest (arg1)
2487 4253 : || HONOR_NANS (TREE_TYPE (lhs1)))
2488 : return false;
2489 :
2490 2434 : if (!integer_zerop (arg3) || (cmp3 != EQ_EXPR && cmp3 != NE_EXPR))
2491 : return false;
2492 2434 : if ((cond3_phi_edge->flags & (cmp3 == EQ_EXPR
2493 2434 : ? EDGE_TRUE_VALUE : EDGE_FALSE_VALUE)) == 0)
2494 : return false;
2495 :
2496 : /* lhs1 one_cmp rhs1 results in phires of 1. */
2497 2434 : enum tree_code one_cmp;
2498 4868 : if ((cmp1 == LT_EXPR || cmp1 == LE_EXPR)
2499 2578 : ^ (!integer_onep ((e1->flags & EDGE_TRUE_VALUE) ? arg1 : arg0)))
2500 : one_cmp = LT_EXPR;
2501 : else
2502 1791 : one_cmp = GT_EXPR;
2503 :
2504 2434 : enum tree_code res_cmp;
2505 2434 : bool negate_p = false;
2506 2434 : switch (cmp)
2507 : {
2508 1330 : case EQ_EXPR:
2509 1330 : if (integer_zerop (rhs) && !HONOR_NANS (TREE_TYPE (lhs1)))
2510 : res_cmp = EQ_EXPR;
2511 1246 : else if (integer_minus_onep (rhs))
2512 779 : res_cmp = one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR;
2513 467 : else if (integer_onep (rhs))
2514 : res_cmp = one_cmp;
2515 : else
2516 : return false;
2517 : break;
2518 1014 : case NE_EXPR:
2519 1014 : if (integer_zerop (rhs) && !HONOR_NANS (TREE_TYPE (lhs1)))
2520 : res_cmp = NE_EXPR;
2521 976 : else if (integer_minus_onep (rhs))
2522 492 : res_cmp = one_cmp == LT_EXPR ? LE_EXPR : GE_EXPR;
2523 484 : else if (integer_onep (rhs))
2524 699 : res_cmp = one_cmp == LT_EXPR ? GE_EXPR : LE_EXPR;
2525 : else
2526 : return false;
2527 984 : if (HONOR_NANS (TREE_TYPE (lhs1)))
2528 : negate_p = true;
2529 : break;
2530 28 : case LT_EXPR:
2531 28 : if (integer_onep (rhs))
2532 0 : res_cmp = one_cmp == LT_EXPR ? GE_EXPR : LE_EXPR;
2533 28 : else if (integer_zerop (rhs))
2534 28 : res_cmp = one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR;
2535 : else
2536 : return false;
2537 28 : if (HONOR_NANS (TREE_TYPE (lhs1)))
2538 : negate_p = true;
2539 : break;
2540 5 : case LE_EXPR:
2541 5 : if (integer_zerop (rhs))
2542 5 : res_cmp = one_cmp == LT_EXPR ? GE_EXPR : LE_EXPR;
2543 0 : else if (integer_minus_onep (rhs))
2544 0 : res_cmp = one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR;
2545 : else
2546 : return false;
2547 5 : if (HONOR_NANS (TREE_TYPE (lhs1)))
2548 : negate_p = true;
2549 : break;
2550 0 : case GT_EXPR:
2551 0 : if (integer_minus_onep (rhs))
2552 0 : res_cmp = one_cmp == LT_EXPR ? LE_EXPR : GE_EXPR;
2553 0 : else if (integer_zerop (rhs))
2554 : res_cmp = one_cmp;
2555 : else
2556 : return false;
2557 : break;
2558 57 : case GE_EXPR:
2559 57 : if (integer_zerop (rhs))
2560 57 : res_cmp = one_cmp == LT_EXPR ? LE_EXPR : GE_EXPR;
2561 0 : else if (integer_onep (rhs))
2562 : res_cmp = one_cmp;
2563 : else
2564 : return false;
2565 : break;
2566 : default:
2567 : gcc_unreachable ();
2568 : }
2569 2362 : if (orig_use_lhs)
2570 60 : res_cmp = swap_tree_comparison (res_cmp);
2571 :
2572 2362 : tree clhs1 = lhs1, crhs1 = rhs1;
2573 2362 : if (negate_p)
2574 : {
2575 72 : if (cfun->can_throw_non_call_exceptions)
2576 0 : return false;
2577 72 : res_cmp = invert_tree_comparison (res_cmp, false);
2578 72 : clhs1 = make_ssa_name (boolean_type_node);
2579 72 : gimple *g = gimple_build_assign (clhs1, res_cmp, lhs1, rhs1);
2580 72 : gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
2581 72 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2582 72 : crhs1 = boolean_false_node;
2583 72 : res_cmp = EQ_EXPR;
2584 : }
2585 :
2586 2362 : if (gimple_code (use_stmt) == GIMPLE_COND)
2587 : {
2588 1703 : gcond *use_cond = as_a <gcond *> (use_stmt);
2589 1703 : gimple_cond_set_code (use_cond, res_cmp);
2590 1703 : gimple_cond_set_lhs (use_cond, clhs1);
2591 1703 : gimple_cond_set_rhs (use_cond, crhs1);
2592 : }
2593 659 : else if (gimple_assign_rhs_class (use_stmt) == GIMPLE_BINARY_RHS)
2594 : {
2595 659 : gimple_assign_set_rhs_code (use_stmt, res_cmp);
2596 659 : gimple_assign_set_rhs1 (use_stmt, clhs1);
2597 659 : gimple_assign_set_rhs2 (use_stmt, crhs1);
2598 : }
2599 : else
2600 : {
2601 0 : tree cond = build2 (res_cmp, TREE_TYPE (gimple_assign_rhs1 (use_stmt)),
2602 : clhs1, crhs1);
2603 0 : gimple_assign_set_rhs1 (use_stmt, cond);
2604 : }
2605 2362 : update_stmt (use_stmt);
2606 :
2607 2362 : if (MAY_HAVE_DEBUG_BIND_STMTS)
2608 : {
2609 1964 : use_operand_p use_p;
2610 1964 : imm_use_iterator iter;
2611 1964 : bool has_debug_uses = false;
2612 1964 : bool has_cast1_debug_uses = false;
2613 1964 : bool has_neg_debug_uses = false;
2614 1964 : bool has_cast2_debug_uses = false;
2615 1986 : FOR_EACH_IMM_USE_FAST (use_p, iter, phires)
2616 : {
2617 1986 : gimple *use_stmt = USE_STMT (use_p);
2618 1986 : if (is_gimple_debug (use_stmt))
2619 : {
2620 : has_debug_uses = true;
2621 : break;
2622 : }
2623 1964 : }
2624 1964 : if (orig_use_lhs)
2625 : {
2626 44 : FOR_EACH_IMM_USE_FAST (use_p, iter, temps[0])
2627 : {
2628 38 : gimple *use_stmt = USE_STMT (use_p);
2629 38 : if (is_gimple_debug (use_stmt))
2630 : {
2631 : has_debug_uses = true;
2632 : has_cast1_debug_uses = true;
2633 : break;
2634 : }
2635 22 : }
2636 44 : FOR_EACH_IMM_USE_FAST (use_p, iter, temps[1])
2637 : {
2638 38 : gimple *use_stmt = USE_STMT (use_p);
2639 38 : if (is_gimple_debug (use_stmt))
2640 : {
2641 : has_debug_uses = true;
2642 : has_cast1_debug_uses = true;
2643 : has_neg_debug_uses = true;
2644 : break;
2645 : }
2646 22 : }
2647 22 : FOR_EACH_IMM_USE_FAST (use_p, iter, orig_use_lhs)
2648 : {
2649 16 : gimple *use_stmt = USE_STMT (use_p);
2650 16 : if (is_gimple_debug (use_stmt))
2651 : {
2652 : has_debug_uses = true;
2653 : has_cast1_debug_uses = true;
2654 : has_neg_debug_uses = true;
2655 : has_cast2_debug_uses = true;
2656 : break;
2657 : }
2658 22 : }
2659 22 : if (has_debug_uses)
2660 : {
2661 22 : gimple_stmt_iterator gsi = gsi_for_stmt (orig_use_stmt);
2662 22 : tree zero = build_zero_cst (TREE_TYPE (temps[0]));
2663 22 : gimple_assign_set_rhs_with_ops (&gsi, INTEGER_CST, zero);
2664 22 : update_stmt (orig_use_stmt);
2665 22 : gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (temps[1]));
2666 22 : zero = build_zero_cst (TREE_TYPE (temps[1]));
2667 22 : gimple_assign_set_rhs_with_ops (&gsi, INTEGER_CST, zero);
2668 22 : update_stmt (SSA_NAME_DEF_STMT (temps[1]));
2669 22 : gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (orig_use_lhs));
2670 22 : zero = build_zero_cst (TREE_TYPE (orig_use_lhs));
2671 22 : gimple_assign_set_rhs_with_ops (&gsi, INTEGER_CST, zero);
2672 22 : update_stmt (SSA_NAME_DEF_STMT (orig_use_lhs));
2673 : }
2674 : }
2675 :
2676 1964 : if (has_debug_uses)
2677 : {
2678 : /* If there are debug uses, emit something like:
2679 : # DEBUG D#1 => i_2(D) > j_3(D) ? 1 : -1
2680 : # DEBUG D#2 => i_2(D) == j_3(D) ? 0 : D#1
2681 : where > stands for the comparison that yielded 1
2682 : and replace debug uses of phi result with that D#2.
2683 : Ignore the value of -128 if !HONOR_NANS, because if NaNs
2684 : aren't expected, all floating point numbers should be
2685 : comparable. If HONOR_NANS, emit something like:
2686 : # DEBUG D#1 => i_2(D) < j_3(D) ? -1 : -128
2687 : # DEBUG D#2 => i_2(D) > j_3(D) ? 1 : D#1
2688 : # DEBUG D#3 => i_2(D) == j_3(D) ? 0 : D#2
2689 : instead. */
2690 1964 : gimple_stmt_iterator gsi = gsi_after_labels (gimple_bb (phi));
2691 1964 : tree type = TREE_TYPE (phires);
2692 1964 : tree minus_one = build_int_cst (type, -1);
2693 1964 : if (HONOR_NANS (TREE_TYPE (lhs1)))
2694 : {
2695 102 : tree temp3 = build_debug_expr_decl (type);
2696 204 : tree t = build2 (one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR,
2697 : boolean_type_node, lhs1, rhs2);
2698 102 : t = build3 (COND_EXPR, type, t, minus_one,
2699 : build_int_cst (type, -128));
2700 102 : gimple *g = gimple_build_debug_bind (temp3, t, phi);
2701 102 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2702 102 : minus_one = temp3;
2703 : }
2704 1964 : tree temp1 = build_debug_expr_decl (type);
2705 1964 : tree t = build2 (one_cmp, boolean_type_node, lhs1, rhs2);
2706 1964 : t = build3 (COND_EXPR, type, t, build_one_cst (type),
2707 : minus_one);
2708 1964 : gimple *g = gimple_build_debug_bind (temp1, t, phi);
2709 1964 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2710 1964 : tree temp2 = build_debug_expr_decl (type);
2711 1964 : t = build2 (EQ_EXPR, boolean_type_node, lhs1, rhs2);
2712 1964 : t = build3 (COND_EXPR, type, t, build_zero_cst (type), temp1);
2713 1964 : g = gimple_build_debug_bind (temp2, t, phi);
2714 1964 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2715 1964 : replace_uses_by (phires, temp2);
2716 1964 : if (has_cast1_debug_uses)
2717 : {
2718 16 : tree temp3 = build_debug_expr_decl (TREE_TYPE (temps[0]));
2719 16 : t = fold_convert (TREE_TYPE (temps[0]), temp2);
2720 16 : g = gimple_build_debug_bind (temp3, t, phi);
2721 16 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2722 16 : replace_uses_by (temps[0], temp3);
2723 16 : temp2 = temp3;
2724 : }
2725 1964 : if (has_neg_debug_uses)
2726 : {
2727 16 : tree temp3 = build_debug_expr_decl (TREE_TYPE (temps[1]));
2728 16 : t = fold_build1 (NEGATE_EXPR, TREE_TYPE (temps[1]), temp2);
2729 16 : g = gimple_build_debug_bind (temp3, t, phi);
2730 16 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2731 16 : replace_uses_by (temps[1], temp3);
2732 16 : temp2 = temp3;
2733 : }
2734 1964 : if (has_cast2_debug_uses)
2735 : {
2736 16 : tree temp3 = build_debug_expr_decl (TREE_TYPE (orig_use_lhs));
2737 16 : t = fold_convert (TREE_TYPE (orig_use_lhs), temp2);
2738 16 : g = gimple_build_debug_bind (temp3, t, phi);
2739 16 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2740 16 : replace_uses_by (orig_use_lhs, temp3);
2741 : }
2742 : }
2743 : }
2744 :
2745 2362 : if (orig_use_lhs)
2746 : {
2747 60 : gimple_stmt_iterator gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (orig_use_lhs));
2748 60 : gsi_remove (&gsi, true);
2749 60 : gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (temps[1]));
2750 60 : gsi_remove (&gsi, true);
2751 60 : gsi = gsi_for_stmt (orig_use_stmt);
2752 60 : gsi_remove (&gsi, true);
2753 60 : release_ssa_name (orig_use_lhs);
2754 60 : release_ssa_name (temps[1]);
2755 60 : release_ssa_name (temps[0]);
2756 : }
2757 :
2758 2362 : gimple_stmt_iterator psi = gsi_for_stmt (phi);
2759 2362 : remove_phi_node (&psi, true);
2760 2362 : statistics_counter_event (cfun, "spaceship replacement", 1);
2761 :
2762 2362 : return true;
2763 : }
2764 :
2765 : /* Optimize x ? __builtin_fun (x) : C, where C is __builtin_fun (0).
2766 : Convert
2767 :
2768 : <bb 2>
2769 : if (b_4(D) != 0)
2770 : goto <bb 3>
2771 : else
2772 : goto <bb 4>
2773 :
2774 : <bb 3>
2775 : _2 = (unsigned long) b_4(D);
2776 : _9 = __builtin_popcountl (_2);
2777 : OR
2778 : _9 = __builtin_popcountl (b_4(D));
2779 :
2780 : <bb 4>
2781 : c_12 = PHI <0(2), _9(3)>
2782 :
2783 : Into
2784 : <bb 2>
2785 : _2 = (unsigned long) b_4(D);
2786 : _9 = __builtin_popcountl (_2);
2787 : OR
2788 : _9 = __builtin_popcountl (b_4(D));
2789 :
2790 : <bb 4>
2791 : c_12 = PHI <_9(2)>
2792 :
2793 : Similarly for __builtin_clz or __builtin_ctz if
2794 : C?Z_DEFINED_VALUE_AT_ZERO is 2, optab is present and
2795 : instead of 0 above it uses the value from that macro. */
2796 :
2797 : static bool
2798 448320 : cond_removal_in_builtin_zero_pattern (basic_block cond_bb,
2799 : basic_block middle_bb,
2800 : edge e1, edge e2, gphi *phi,
2801 : tree arg0, tree arg1)
2802 : {
2803 448320 : gimple_stmt_iterator gsi, gsi_from;
2804 448320 : gimple *call;
2805 448320 : gimple *cast = NULL;
2806 448320 : tree lhs, arg;
2807 :
2808 : /* Check that
2809 : _2 = (unsigned long) b_4(D);
2810 : _9 = __builtin_popcountl (_2);
2811 : OR
2812 : _9 = __builtin_popcountl (b_4(D));
2813 : are the only stmts in the middle_bb. */
2814 :
2815 448320 : gsi = gsi_start_nondebug_after_labels_bb (middle_bb);
2816 448320 : if (gsi_end_p (gsi))
2817 : return false;
2818 281082 : cast = gsi_stmt (gsi);
2819 281082 : gsi_next_nondebug (&gsi);
2820 281082 : if (!gsi_end_p (gsi))
2821 : {
2822 140755 : call = gsi_stmt (gsi);
2823 140755 : gsi_next_nondebug (&gsi);
2824 140755 : if (!gsi_end_p (gsi))
2825 : return false;
2826 : }
2827 : else
2828 : {
2829 : call = cast;
2830 : cast = NULL;
2831 : }
2832 :
2833 : /* Check that we have a popcount/clz/ctz builtin. */
2834 188286 : if (!is_gimple_call (call))
2835 : return false;
2836 :
2837 6296 : lhs = gimple_get_lhs (call);
2838 :
2839 6296 : if (lhs == NULL_TREE)
2840 : return false;
2841 :
2842 6270 : combined_fn cfn = gimple_call_combined_fn (call);
2843 6270 : if (gimple_call_num_args (call) != 1
2844 6270 : && (gimple_call_num_args (call) != 2
2845 : || cfn == CFN_CLZ
2846 590 : || cfn == CFN_CTZ))
2847 : return false;
2848 :
2849 4762 : arg = gimple_call_arg (call, 0);
2850 :
2851 4762 : internal_fn ifn = IFN_LAST;
2852 4762 : int val = 0;
2853 4762 : bool any_val = false;
2854 4762 : switch (cfn)
2855 : {
2856 : CASE_CFN_BSWAP:
2857 : CASE_CFN_BITREVERSE:
2858 : CASE_CFN_FFS:
2859 : CASE_CFN_PARITY:
2860 : CASE_CFN_POPCOUNT:
2861 : break;
2862 849 : CASE_CFN_CLZ:
2863 849 : if (INTEGRAL_TYPE_P (TREE_TYPE (arg)))
2864 : {
2865 849 : tree type = TREE_TYPE (arg);
2866 849 : if (BITINT_TYPE_P (type))
2867 : {
2868 4 : if (gimple_call_num_args (call) == 1)
2869 : {
2870 : any_val = true;
2871 : ifn = IFN_CLZ;
2872 : break;
2873 : }
2874 0 : if (!tree_fits_shwi_p (gimple_call_arg (call, 1)))
2875 : return false;
2876 0 : HOST_WIDE_INT at_zero = tree_to_shwi (gimple_call_arg (call, 1));
2877 0 : if ((int) at_zero != at_zero)
2878 : return false;
2879 0 : ifn = IFN_CLZ;
2880 0 : val = at_zero;
2881 0 : break;
2882 : }
2883 845 : if (direct_internal_fn_supported_p (IFN_CLZ, type, OPTIMIZE_FOR_BOTH)
2884 1665 : && CLZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (type),
2885 : val) == 2)
2886 : {
2887 : ifn = IFN_CLZ;
2888 : break;
2889 : }
2890 : }
2891 : return false;
2892 334 : CASE_CFN_CTZ:
2893 334 : if (INTEGRAL_TYPE_P (TREE_TYPE (arg)))
2894 : {
2895 334 : tree type = TREE_TYPE (arg);
2896 334 : if (BITINT_TYPE_P (type))
2897 : {
2898 4 : if (gimple_call_num_args (call) == 1)
2899 : {
2900 : any_val = true;
2901 : ifn = IFN_CTZ;
2902 : break;
2903 : }
2904 0 : if (!tree_fits_shwi_p (gimple_call_arg (call, 1)))
2905 : return false;
2906 0 : HOST_WIDE_INT at_zero = tree_to_shwi (gimple_call_arg (call, 1));
2907 0 : if ((int) at_zero != at_zero)
2908 : return false;
2909 0 : ifn = IFN_CTZ;
2910 0 : val = at_zero;
2911 0 : break;
2912 : }
2913 330 : if (direct_internal_fn_supported_p (IFN_CTZ, type, OPTIMIZE_FOR_BOTH)
2914 639 : && CTZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (type),
2915 : val) == 2)
2916 : {
2917 : ifn = IFN_CTZ;
2918 : break;
2919 : }
2920 : }
2921 : return false;
2922 3 : case CFN_BUILT_IN_CLRSB:
2923 3 : val = TYPE_PRECISION (integer_type_node) - 1;
2924 3 : break;
2925 3 : case CFN_BUILT_IN_CLRSBL:
2926 3 : val = TYPE_PRECISION (long_integer_type_node) - 1;
2927 3 : break;
2928 3 : case CFN_BUILT_IN_CLRSBLL:
2929 3 : val = TYPE_PRECISION (long_long_integer_type_node) - 1;
2930 3 : break;
2931 : default:
2932 : return false;
2933 : }
2934 :
2935 152 : if (cast)
2936 : {
2937 : /* We have a cast stmt feeding popcount/clz/ctz builtin. */
2938 : /* Check that we have a cast prior to that. */
2939 55 : if (gimple_code (cast) != GIMPLE_ASSIGN
2940 55 : || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (cast)))
2941 : return false;
2942 : /* Result of the cast stmt is the argument to the builtin. */
2943 25 : if (arg != gimple_assign_lhs (cast))
2944 : return false;
2945 25 : arg = gimple_assign_rhs1 (cast);
2946 : }
2947 :
2948 244 : gcond *cond = dyn_cast <gcond *> (*gsi_last_bb (cond_bb));
2949 :
2950 : /* Cond_bb has a check for b_4 [!=|==] 0 before calling the popcount/clz/ctz
2951 : builtin. */
2952 122 : if (!cond
2953 122 : || (gimple_cond_code (cond) != NE_EXPR
2954 23 : && gimple_cond_code (cond) != EQ_EXPR)
2955 122 : || !integer_zerop (gimple_cond_rhs (cond))
2956 119 : || arg != gimple_cond_lhs (cond))
2957 : return false;
2958 :
2959 41 : edge true_edge, false_edge;
2960 : /* We need to know which is the true edge and which is the false
2961 : edge so that we know when to invert the condition below. */
2962 41 : extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
2963 :
2964 : /* Forward the edges over the middle basic block. */
2965 41 : if (true_edge->dest == middle_bb)
2966 41 : true_edge = EDGE_SUCC (true_edge->dest, 0);
2967 41 : if (false_edge->dest == middle_bb)
2968 0 : false_edge = EDGE_SUCC (false_edge->dest, 0);
2969 :
2970 : /* Canonicalize the args with respect to the edges,
2971 : arg0 is from the true edge and arg1 is from the
2972 : false edge.
2973 : That is `cond ? arg0 : arg1`.*/
2974 41 : if (true_edge == e1)
2975 41 : gcc_assert (false_edge == e2);
2976 : else
2977 : {
2978 0 : gcc_assert (false_edge == e1);
2979 0 : gcc_assert (true_edge == e2);
2980 : std::swap (arg0, arg1);
2981 : }
2982 :
2983 : /* Canonicalize the args such that we get:
2984 : `arg != 0 ? arg0 : arg1`. So swap arg0/arg1
2985 : around if cond was an equals. */
2986 41 : if (gimple_cond_code (cond) == EQ_EXPR)
2987 2 : std::swap (arg0, arg1);
2988 :
2989 : /* Check PHI arguments. */
2990 41 : if (lhs != arg0
2991 39 : || TREE_CODE (arg1) != INTEGER_CST)
2992 : return false;
2993 31 : if (any_val)
2994 : {
2995 0 : if (!tree_fits_shwi_p (arg1))
2996 : return false;
2997 0 : HOST_WIDE_INT at_zero = tree_to_shwi (arg1);
2998 0 : if ((int) at_zero != at_zero)
2999 : return false;
3000 0 : val = at_zero;
3001 : }
3002 31 : else if (wi::to_wide (arg1) != val)
3003 : return false;
3004 :
3005 : /* And insert the popcount/clz/ctz builtin and cast stmt before the
3006 : cond_bb. */
3007 13 : gsi = gsi_last_bb (cond_bb);
3008 13 : if (cast)
3009 : {
3010 13 : gsi_from = gsi_for_stmt (cast);
3011 13 : gsi_move_before (&gsi_from, &gsi);
3012 13 : reset_flow_sensitive_info (gimple_get_lhs (cast));
3013 : }
3014 13 : gsi_from = gsi_for_stmt (call);
3015 13 : if (ifn == IFN_LAST
3016 13 : || (gimple_call_internal_p (call) && gimple_call_num_args (call) == 2))
3017 8 : gsi_move_before (&gsi_from, &gsi);
3018 : else
3019 : {
3020 : /* For __builtin_c[lt]z* force .C[LT]Z ifn, because only
3021 : the latter is well defined at zero. */
3022 5 : call = gimple_build_call_internal (ifn, 2, gimple_call_arg (call, 0),
3023 5 : build_int_cst (integer_type_node, val));
3024 5 : gimple_call_set_lhs (call, lhs);
3025 5 : gsi_insert_before (&gsi, call, GSI_SAME_STMT);
3026 5 : gsi_remove (&gsi_from, true);
3027 : }
3028 13 : reset_flow_sensitive_info (lhs);
3029 :
3030 : /* Now update the PHI and remove unneeded bbs. */
3031 13 : replace_phi_edge_with_variable (cond_bb, e2, phi, lhs);
3032 13 : return true;
3033 : }
3034 :
3035 : /* Auxiliary functions to determine the set of memory accesses which
3036 : can't trap because they are preceded by accesses to the same memory
3037 : portion. We do that for MEM_REFs, so we only need to track
3038 : the SSA_NAME of the pointer indirectly referenced. The algorithm
3039 : simply is a walk over all instructions in dominator order. When
3040 : we see an MEM_REF we determine if we've already seen a same
3041 : ref anywhere up to the root of the dominator tree. If we do the
3042 : current access can't trap. If we don't see any dominating access
3043 : the current access might trap, but might also make later accesses
3044 : non-trapping, so we remember it. We need to be careful with loads
3045 : or stores, for instance a load might not trap, while a store would,
3046 : so if we see a dominating read access this doesn't mean that a later
3047 : write access would not trap. Hence we also need to differentiate the
3048 : type of access(es) seen.
3049 :
3050 : ??? We currently are very conservative and assume that a load might
3051 : trap even if a store doesn't (write-only memory). This probably is
3052 : overly conservative.
3053 :
3054 : We currently support a special case that for !TREE_ADDRESSABLE automatic
3055 : variables, it could ignore whether something is a load or store because the
3056 : local stack should be always writable. */
3057 :
3058 : /* A hash-table of references (MEM_REF/ARRAY_REF/COMPONENT_REF), and in which
3059 : basic block an *_REF through it was seen, which would constitute a
3060 : no-trap region for same accesses.
3061 :
3062 : Size is needed to support 2 MEM_REFs of different types, like
3063 : MEM<double>(s_1) and MEM<long>(s_1), which would compare equal with
3064 : OEP_ADDRESS_OF. */
3065 : struct ref_to_bb
3066 : {
3067 : tree exp;
3068 : HOST_WIDE_INT size;
3069 : unsigned int phase;
3070 : basic_block bb;
3071 : };
3072 :
3073 : /* Hashtable helpers. */
3074 :
3075 : struct refs_hasher : free_ptr_hash<ref_to_bb>
3076 : {
3077 : static inline hashval_t hash (const ref_to_bb *);
3078 : static inline bool equal (const ref_to_bb *, const ref_to_bb *);
3079 : };
3080 :
3081 : /* Used for quick clearing of the hash-table when we see calls.
3082 : Hash entries with phase < nt_call_phase are invalid. */
3083 : static unsigned int nt_call_phase;
3084 :
3085 : /* The hash function. */
3086 :
3087 : inline hashval_t
3088 20178365 : refs_hasher::hash (const ref_to_bb *n)
3089 : {
3090 20178365 : inchash::hash hstate;
3091 20178365 : inchash::add_expr (n->exp, hstate, OEP_ADDRESS_OF);
3092 20178365 : hstate.add_hwi (n->size);
3093 20178365 : return hstate.end ();
3094 : }
3095 :
3096 : /* The equality function of *P1 and *P2. */
3097 :
3098 : inline bool
3099 14742144 : refs_hasher::equal (const ref_to_bb *n1, const ref_to_bb *n2)
3100 : {
3101 14742144 : return operand_equal_p (n1->exp, n2->exp, OEP_ADDRESS_OF)
3102 14742144 : && n1->size == n2->size;
3103 : }
3104 :
3105 : class nontrapping_dom_walker : public dom_walker
3106 : {
3107 : public:
3108 1068089 : nontrapping_dom_walker (cdi_direction direction, hash_set<tree> *ps)
3109 1068089 : : dom_walker (direction), m_nontrapping (ps), m_seen_refs (128)
3110 1068089 : {}
3111 :
3112 : edge before_dom_children (basic_block) final override;
3113 : void after_dom_children (basic_block) final override;
3114 :
3115 : private:
3116 :
3117 : /* We see the expression EXP in basic block BB. If it's an interesting
3118 : expression (an MEM_REF through an SSA_NAME) possibly insert the
3119 : expression into the set NONTRAP or the hash table of seen expressions.
3120 : STORE is true if this expression is on the LHS, otherwise it's on
3121 : the RHS. */
3122 : void add_or_mark_expr (basic_block, tree, bool);
3123 :
3124 : hash_set<tree> *m_nontrapping;
3125 :
3126 : /* The hash table for remembering what we've seen. */
3127 : hash_table<refs_hasher> m_seen_refs;
3128 : };
3129 :
3130 : /* Called by walk_dominator_tree, when entering the block BB. */
3131 : edge
3132 12020441 : nontrapping_dom_walker::before_dom_children (basic_block bb)
3133 : {
3134 12020441 : edge e;
3135 12020441 : edge_iterator ei;
3136 12020441 : gimple_stmt_iterator gsi;
3137 :
3138 : /* If we haven't seen all our predecessors, clear the hash-table. */
3139 26443011 : FOR_EACH_EDGE (e, ei, bb->preds)
3140 15124088 : if ((((size_t)e->src->aux) & 2) == 0)
3141 : {
3142 701518 : nt_call_phase++;
3143 701518 : break;
3144 : }
3145 :
3146 : /* Mark this BB as being on the path to dominator root and as visited. */
3147 12020441 : bb->aux = (void*)(1 | 2);
3148 :
3149 : /* And walk the statements in order. */
3150 109982711 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3151 : {
3152 85941829 : gimple *stmt = gsi_stmt (gsi);
3153 :
3154 85941829 : if ((gimple_code (stmt) == GIMPLE_ASM && gimple_vdef (stmt))
3155 85977766 : || (is_gimple_call (stmt)
3156 5786700 : && (!nonfreeing_call_p (stmt) || !nonbarrier_call_p (stmt))))
3157 5173155 : nt_call_phase++;
3158 96293946 : else if (gimple_assign_single_p (stmt) && !gimple_has_volatile_ops (stmt))
3159 : {
3160 13544619 : add_or_mark_expr (bb, gimple_assign_lhs (stmt), true);
3161 13544619 : add_or_mark_expr (bb, gimple_assign_rhs1 (stmt), false);
3162 : }
3163 : }
3164 12020441 : return NULL;
3165 : }
3166 :
3167 : /* Called by walk_dominator_tree, when basic block BB is exited. */
3168 : void
3169 12020441 : nontrapping_dom_walker::after_dom_children (basic_block bb)
3170 : {
3171 : /* This BB isn't on the path to dominator root anymore. */
3172 12020441 : bb->aux = (void*)2;
3173 12020441 : }
3174 :
3175 : /* We see the expression EXP in basic block BB. If it's an interesting
3176 : expression of:
3177 : 1) MEM_REF
3178 : 2) ARRAY_REF
3179 : 3) COMPONENT_REF
3180 : possibly insert the expression into the set NONTRAP or the hash table
3181 : of seen expressions. STORE is true if this expression is on the LHS,
3182 : otherwise it's on the RHS. */
3183 : void
3184 27089238 : nontrapping_dom_walker::add_or_mark_expr (basic_block bb, tree exp, bool store)
3185 : {
3186 27089238 : HOST_WIDE_INT size;
3187 :
3188 27089238 : if ((TREE_CODE (exp) == MEM_REF || TREE_CODE (exp) == ARRAY_REF
3189 22691806 : || TREE_CODE (exp) == COMPONENT_REF)
3190 34405513 : && (size = int_size_in_bytes (TREE_TYPE (exp))) > 0)
3191 : {
3192 11713702 : struct ref_to_bb map;
3193 11713702 : ref_to_bb **slot;
3194 11713702 : struct ref_to_bb *r2bb;
3195 11713702 : basic_block found_bb = 0;
3196 :
3197 11713702 : if (!store)
3198 : {
3199 5402533 : tree base = get_base_address (exp);
3200 : /* Only record a LOAD of a local variable without address-taken, as
3201 : the local stack is always writable. This allows cselim on a STORE
3202 : with a dominating LOAD. */
3203 5402533 : if (!auto_var_p (base) || TREE_ADDRESSABLE (base))
3204 4435764 : return;
3205 : }
3206 :
3207 : /* Try to find the last seen *_REF, which can trap. */
3208 7277938 : map.exp = exp;
3209 7277938 : map.size = size;
3210 7277938 : slot = m_seen_refs.find_slot (&map, INSERT);
3211 7277938 : r2bb = *slot;
3212 7277938 : if (r2bb && r2bb->phase >= nt_call_phase)
3213 292596 : found_bb = r2bb->bb;
3214 :
3215 : /* If we've found a trapping *_REF, _and_ it dominates EXP
3216 : (it's in a basic block on the path from us to the dominator root)
3217 : then we can't trap. */
3218 292596 : if (found_bb && (((size_t)found_bb->aux) & 1) == 1)
3219 : {
3220 75470 : m_nontrapping->add (exp);
3221 : }
3222 : else
3223 : {
3224 : /* EXP might trap, so insert it into the hash table. */
3225 7202468 : if (r2bb)
3226 : {
3227 998963 : r2bb->phase = nt_call_phase;
3228 998963 : r2bb->bb = bb;
3229 : }
3230 : else
3231 : {
3232 6203505 : r2bb = XNEW (struct ref_to_bb);
3233 6203505 : r2bb->phase = nt_call_phase;
3234 6203505 : r2bb->bb = bb;
3235 6203505 : r2bb->exp = exp;
3236 6203505 : r2bb->size = size;
3237 6203505 : *slot = r2bb;
3238 : }
3239 : }
3240 : }
3241 : }
3242 :
3243 : /* This is the entry point of gathering non trapping memory accesses.
3244 : It will do a dominator walk over the whole function, and it will
3245 : make use of the bb->aux pointers. It returns a set of trees
3246 : (the MEM_REFs itself) which can't trap. */
3247 : static hash_set<tree> *
3248 1068089 : get_non_trapping (void)
3249 : {
3250 1068089 : nt_call_phase = 0;
3251 1068089 : hash_set<tree> *nontrap = new hash_set<tree>;
3252 :
3253 2136178 : nontrapping_dom_walker (CDI_DOMINATORS, nontrap)
3254 1068089 : .walk (cfun->cfg->x_entry_block_ptr);
3255 :
3256 1068089 : clear_aux_for_blocks ();
3257 1068089 : return nontrap;
3258 : }
3259 :
3260 : /* Do the main work of conditional store replacement. We already know
3261 : that the recognized pattern looks like so:
3262 :
3263 : split:
3264 : if (cond) goto MIDDLE_BB; else goto JOIN_BB (edge E1)
3265 : MIDDLE_BB:
3266 : something
3267 : fallthrough (edge E0)
3268 : JOIN_BB:
3269 : some more
3270 :
3271 : ASSIGN is a store in MIDDLE_BB which is the candidate for cselim. We check
3272 : that MIDDLE_BB contains only one store (i.e., ASSIGN), that that store
3273 : doesn't trap (not via NOTRAP, but via checking if an access to the same
3274 : memory location dominates us, or the store is to a local addressable object)
3275 : and that the store has a "simple" RHS. */
3276 :
3277 : static bool
3278 433371 : cond_store_replacement (basic_block middle_bb, basic_block join_bb, edge e0,
3279 : edge e1, gimple *assign, hash_set<tree> *nontrap)
3280 : {
3281 433371 : tree lhs, rhs, name, name2;
3282 433371 : gphi *newphi;
3283 433371 : gassign *new_stmt;
3284 433371 : gimple_stmt_iterator gsi;
3285 433371 : location_t locus;
3286 :
3287 : /* Check if middle_bb contains of only one store. */
3288 433371 : if (!assign
3289 27533 : || !gimple_assign_single_p (assign)
3290 460904 : || gimple_has_volatile_ops (assign))
3291 : return false;
3292 :
3293 27317 : locus = gimple_location (assign);
3294 27317 : lhs = gimple_assign_lhs (assign);
3295 27317 : rhs = gimple_assign_rhs1 (assign);
3296 27317 : if ((!REFERENCE_CLASS_P (lhs)
3297 27317 : && !DECL_P (lhs))
3298 27317 : || !is_gimple_reg_type (TREE_TYPE (lhs)))
3299 : return false;
3300 :
3301 : /* Make sure all uses (except the rhs) in the single stmt are also available
3302 : where we insert to. */
3303 26863 : ssa_op_iter iter;
3304 26863 : tree use;
3305 52633 : FOR_EACH_SSA_TREE_OPERAND (use, assign, iter, SSA_OP_USE)
3306 : {
3307 30221 : if (use == rhs)
3308 13607 : continue;
3309 :
3310 16614 : gimple *stmt = SSA_NAME_DEF_STMT (use);
3311 16614 : if (stmt && gimple_bb (stmt) == middle_bb)
3312 : return false;
3313 : }
3314 :
3315 : /* Prove that we can move the store down. We could also check
3316 : TREE_THIS_NOTRAP here, but in that case we also could move stores,
3317 : whose value is not available readily, which we want to avoid. */
3318 22412 : if (nontrap->contains (lhs))
3319 : {
3320 : /* For local non-addressable variables, a load in the same bb
3321 : (though before) will cause the lhs to be in the nontrap hashset.
3322 : So need to check if there are no other loads in the middle bb.
3323 : FIXME: this is over conserative, this check could be made to
3324 : allow loads unrelated to lhs. */
3325 380 : tree vuse = gimple_vuse (assign);
3326 380 : imm_use_iterator iter;
3327 380 : gimple *use_stmt;
3328 1137 : FOR_EACH_IMM_USE_STMT (use_stmt, iter, vuse)
3329 : {
3330 958 : if (use_stmt == assign)
3331 379 : continue;
3332 579 : if (gimple_bb (use_stmt) == middle_bb)
3333 201 : return false;
3334 380 : }
3335 : }
3336 : else
3337 : {
3338 : /* If LHS is an access to a local variable without address-taken
3339 : (or when we allow data races) and known not to trap, we could
3340 : always safely move down the store. */
3341 22032 : if (ref_can_have_store_data_races (lhs)
3342 22032 : || lhs_could_trap_p (lhs))
3343 : return false;
3344 : }
3345 :
3346 : /* Now we've checked the constraints, so do the transformation:
3347 : 1) Remove the single store. */
3348 179 : gsi = gsi_for_stmt (assign);
3349 179 : unlink_stmt_vdef (assign);
3350 179 : gsi_remove (&gsi, true);
3351 179 : release_defs (assign);
3352 :
3353 : /* Make both store and load use alias-set zero as we have to
3354 : deal with the case of the store being a conditional change
3355 : of the dynamic type. */
3356 179 : lhs = unshare_expr (lhs);
3357 179 : tree *basep = &lhs;
3358 368 : while (handled_component_p (*basep))
3359 189 : basep = &TREE_OPERAND (*basep, 0);
3360 179 : if (TREE_CODE (*basep) == MEM_REF
3361 179 : || TREE_CODE (*basep) == TARGET_MEM_REF)
3362 94 : TREE_OPERAND (*basep, 1)
3363 188 : = fold_convert (ptr_type_node, TREE_OPERAND (*basep, 1));
3364 : else
3365 85 : *basep = build2 (MEM_REF, TREE_TYPE (*basep),
3366 : build_fold_addr_expr (*basep),
3367 : build_zero_cst (ptr_type_node));
3368 :
3369 : /* 2) Insert a load from the memory of the store to the temporary
3370 : on the edge which did not contain the store. */
3371 179 : gphi *vphi = get_virtual_phi (join_bb);
3372 179 : name = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
3373 179 : new_stmt = gimple_build_assign (name, lhs);
3374 179 : gimple_set_location (new_stmt, locus);
3375 : /* Set the vuse for the new load. */
3376 179 : gimple_set_vuse (new_stmt, gimple_phi_arg_def (vphi, e1->dest_idx));
3377 179 : lhs = unshare_expr (lhs);
3378 179 : {
3379 : /* Set the no-warning bit on the rhs of the load to avoid uninit
3380 : warnings. */
3381 179 : tree rhs1 = gimple_assign_rhs1 (new_stmt);
3382 179 : suppress_warning (rhs1, OPT_Wuninitialized);
3383 : }
3384 179 : gsi_insert_on_edge (e1, new_stmt);
3385 :
3386 : /* 3) Create a PHI node at the join block, with one argument
3387 : holding the old RHS, and the other holding the temporary
3388 : where we stored the old memory contents. */
3389 179 : name2 = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
3390 179 : newphi = create_phi_node (name2, join_bb);
3391 179 : add_phi_arg (newphi, rhs, e0, locus);
3392 179 : add_phi_arg (newphi, name, e1, locus);
3393 :
3394 179 : new_stmt = gimple_build_assign (lhs, gimple_phi_result (newphi));
3395 :
3396 : /* Update the vdef for the new store statement. */
3397 179 : tree newvphilhs = make_ssa_name (gimple_vop (cfun));
3398 179 : tree vdef = gimple_phi_result (vphi);
3399 179 : gimple_set_vuse (new_stmt, newvphilhs);
3400 179 : gimple_set_vdef (new_stmt, vdef);
3401 179 : gimple_phi_set_result (vphi, newvphilhs);
3402 179 : SSA_NAME_DEF_STMT (vdef) = new_stmt;
3403 179 : update_stmt (vphi);
3404 :
3405 : /* 4) Insert that PHI node. */
3406 179 : gsi = gsi_after_labels (join_bb);
3407 179 : gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
3408 :
3409 179 : if (dump_file && (dump_flags & TDF_DETAILS))
3410 : {
3411 1 : fprintf (dump_file, "\nConditional store replacement happened!");
3412 1 : fprintf (dump_file, "\nReplaced the store with a load.");
3413 1 : fprintf (dump_file, "\nInserted a new PHI statement in joint block:\n");
3414 1 : print_gimple_stmt (dump_file, new_stmt, 0, TDF_VOPS|TDF_MEMSYMS);
3415 : }
3416 179 : statistics_counter_event (cfun, "conditional store replacement", 1);
3417 :
3418 179 : return true;
3419 : }
3420 :
3421 : /* Do the main work of conditional store replacement. */
3422 :
3423 : static bool
3424 111311 : cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb,
3425 : basic_block join_bb, gimple *then_assign,
3426 : gimple *else_assign,
3427 : gphi *vphi)
3428 : {
3429 111311 : tree lhs_base, lhs, then_rhs, else_rhs, name;
3430 111311 : location_t then_locus, else_locus;
3431 111311 : gimple_stmt_iterator gsi;
3432 111311 : gphi *newphi = nullptr;
3433 111311 : gassign *new_stmt;
3434 :
3435 111311 : if (then_assign == NULL
3436 111311 : || !gimple_assign_single_p (then_assign)
3437 111311 : || else_assign == NULL
3438 111311 : || !gimple_assign_single_p (else_assign)
3439 111311 : || stmt_references_abnormal_ssa_name (then_assign)
3440 222608 : || stmt_references_abnormal_ssa_name (else_assign))
3441 : return false;
3442 :
3443 : /* Allow both being clobbers but no other volatile operations. */
3444 111297 : if (gimple_clobber_p (then_assign)
3445 111297 : && gimple_clobber_p (else_assign))
3446 : ;
3447 204326 : else if (gimple_has_volatile_ops (then_assign)
3448 204326 : || gimple_has_volatile_ops (else_assign))
3449 : return false;
3450 :
3451 93879 : lhs = gimple_assign_lhs (then_assign);
3452 93879 : if (!operand_equal_p (lhs, gimple_assign_lhs (else_assign), 0))
3453 : return false;
3454 :
3455 33916 : lhs_base = get_base_address (lhs);
3456 33916 : if (lhs_base == NULL_TREE
3457 33916 : || (!DECL_P (lhs_base) && TREE_CODE (lhs_base) != MEM_REF))
3458 : return false;
3459 :
3460 33871 : then_rhs = gimple_assign_rhs1 (then_assign);
3461 33871 : else_rhs = gimple_assign_rhs1 (else_assign);
3462 33871 : then_locus = gimple_location (then_assign);
3463 33871 : else_locus = gimple_location (else_assign);
3464 :
3465 33871 : if (!is_gimple_reg_type (TREE_TYPE (lhs)))
3466 : {
3467 : /* Handle clobbers separately as operand_equal_p does not check
3468 : the kind of the clobbers being the same. */
3469 7257 : if (TREE_CLOBBER_P (then_rhs) && TREE_CLOBBER_P (else_rhs))
3470 : {
3471 3077 : if (CLOBBER_KIND (then_rhs) != CLOBBER_KIND (else_rhs))
3472 : return false;
3473 : }
3474 4180 : else if (!operand_equal_p (then_rhs, else_rhs))
3475 : return false;
3476 : /* Currently only handle commoning of `= {}`. */
3477 3637 : if (TREE_CODE (then_rhs) != CONSTRUCTOR)
3478 : return false;
3479 : }
3480 :
3481 29827 : if (dump_file && (dump_flags & TDF_DETAILS))
3482 : {
3483 11 : if (TREE_CLOBBER_P (then_rhs))
3484 3 : fprintf(dump_file, "factoring out clobber:\n\tthen:\n");
3485 : else
3486 8 : fprintf(dump_file, "factoring out stores:\n\tthen:\n");
3487 11 : print_gimple_stmt (dump_file, then_assign, 0,
3488 : TDF_VOPS|TDF_MEMSYMS);
3489 11 : fprintf(dump_file, "\telse:\n");
3490 11 : print_gimple_stmt (dump_file, else_assign, 0,
3491 : TDF_VOPS|TDF_MEMSYMS);
3492 11 : fprintf (dump_file, "\n");
3493 : }
3494 :
3495 : /* Now we've checked the constraints, so do the transformation:
3496 : 1) Remove the stores. */
3497 29827 : gsi = gsi_for_stmt (then_assign);
3498 29827 : unlink_stmt_vdef (then_assign);
3499 29827 : gsi_remove (&gsi, true);
3500 29827 : release_defs (then_assign);
3501 :
3502 29827 : gsi = gsi_for_stmt (else_assign);
3503 29827 : unlink_stmt_vdef (else_assign);
3504 29827 : gsi_remove (&gsi, true);
3505 29827 : release_defs (else_assign);
3506 :
3507 : /* 2) Create a PHI node at the join block, with one argument
3508 : holding the old RHS, and the other holding the temporary
3509 : where we stored the old memory contents. */
3510 29827 : if (operand_equal_p (then_rhs, else_rhs))
3511 : name = then_rhs;
3512 : else
3513 : {
3514 24330 : name = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
3515 24330 : newphi = create_phi_node (name, join_bb);
3516 24330 : add_phi_arg (newphi, then_rhs, EDGE_SUCC (then_bb, 0), then_locus);
3517 24330 : add_phi_arg (newphi, else_rhs, EDGE_SUCC (else_bb, 0), else_locus);
3518 : }
3519 :
3520 29827 : new_stmt = gimple_build_assign (lhs, name);
3521 : /* Update the vdef for the new store statement. */
3522 29827 : tree newvphilhs = make_ssa_name (gimple_vop (cfun));
3523 29827 : tree vdef = gimple_phi_result (vphi);
3524 29827 : gimple_set_vuse (new_stmt, newvphilhs);
3525 29827 : gimple_set_vdef (new_stmt, vdef);
3526 29827 : gimple_phi_set_result (vphi, newvphilhs);
3527 29827 : SSA_NAME_DEF_STMT (vdef) = new_stmt;
3528 29827 : update_stmt (vphi);
3529 29827 : if (dump_file && (dump_flags & TDF_DETAILS))
3530 : {
3531 11 : if (newphi)
3532 : {
3533 4 : fprintf(dump_file, "to use phi:\n");
3534 4 : print_gimple_stmt (dump_file, newphi, 0,
3535 : TDF_VOPS|TDF_MEMSYMS);
3536 4 : fprintf(dump_file, "\n");
3537 : }
3538 : else
3539 7 : fprintf(dump_file, "to:\n");
3540 11 : print_gimple_stmt (dump_file, new_stmt, 0,
3541 : TDF_VOPS|TDF_MEMSYMS);
3542 11 : fprintf(dump_file, "\n\n");
3543 : }
3544 :
3545 : /* 3) Insert that new store. */
3546 29827 : gsi = gsi_after_labels (join_bb);
3547 29827 : gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
3548 :
3549 29827 : statistics_counter_event (cfun, "if-then-else store replacement", 1);
3550 :
3551 29827 : return true;
3552 : }
3553 :
3554 : /* Return the last store in BB with VDEF or NULL if there are
3555 : loads following the store. VUSE_ONLY is where the only use of the
3556 : vdef should be. If ONLYONESTORE is true, then the store is
3557 : the only store in the BB. */
3558 :
3559 : static gimple *
3560 3458435 : trailing_store_in_bb (basic_block bb, tree vdef, gimple *vuse_only, bool onlyonestore)
3561 : {
3562 3458435 : if (SSA_NAME_IS_DEFAULT_DEF (vdef))
3563 : return NULL;
3564 3427954 : gimple *store = SSA_NAME_DEF_STMT (vdef);
3565 3427954 : if (gimple_bb (store) != bb
3566 3427954 : || gimple_code (store) == GIMPLE_PHI)
3567 : return NULL;
3568 :
3569 : /* Verify there is no other store in this BB if requested. */
3570 3326247 : if (onlyonestore
3571 1661165 : && !SSA_NAME_IS_DEFAULT_DEF (gimple_vuse (store))
3572 1261744 : && gimple_bb (SSA_NAME_DEF_STMT (gimple_vuse (store))) == bb
3573 3802566 : && gimple_code (SSA_NAME_DEF_STMT (gimple_vuse (store))) != GIMPLE_PHI)
3574 : return NULL;
3575 :
3576 : // Needs to be an simple store and not a call.
3577 2850210 : if (!gimple_assign_single_p (store))
3578 : return NULL;
3579 :
3580 : /* Verify there is no load or store after the store, the vdef of the store
3581 : should only be used by the vuse_only. */
3582 1085814 : use_operand_p use_p;
3583 1085814 : gimple *use_stmt;
3584 2171628 : if (!single_imm_use (gimple_vdef (store), &use_p, &use_stmt))
3585 : return NULL;
3586 1060688 : if (use_stmt != vuse_only)
3587 0 : return NULL;
3588 :
3589 : return store;
3590 : }
3591 :
3592 : /* Takes a MEM and changes the aliasing set to be zero on it.
3593 : This handles all variants include decls. */
3594 : static tree
3595 1541 : copy_mem_with_alias_set_zero (tree mem)
3596 : {
3597 1541 : mem = unshare_expr (mem);
3598 1541 : tree *basep = &mem;
3599 3180 : while (handled_component_p (*basep))
3600 1639 : basep = &TREE_OPERAND (*basep, 0);
3601 1541 : if (TREE_CODE (*basep) == MEM_REF
3602 1541 : || TREE_CODE (*basep) == TARGET_MEM_REF)
3603 178 : TREE_OPERAND (*basep, 1)
3604 356 : = fold_convert (ptr_type_node, TREE_OPERAND (*basep, 1));
3605 : else
3606 1363 : *basep = build2 (MEM_REF, TREE_TYPE (*basep),
3607 : build_fold_addr_expr (*basep),
3608 : build_zero_cst (ptr_type_node));
3609 1541 : return mem;
3610 : }
3611 :
3612 : /* Do the main work of a limited conditional store replacement.
3613 : This recognized pattern like so:
3614 :
3615 : COND_BB:
3616 : store = a_1;
3617 : // no loads
3618 : if (cond) goto MIDDLE_BB; else goto JOIN_BB (edge E1)
3619 : MIDDLE_BB:
3620 : something // no loads
3621 : store = a_2;
3622 : something // no loads
3623 : fallthrough (edge E0)
3624 : JOIN_BB:
3625 : some more
3626 :
3627 : This is a limited form of the full cond_store_replacement
3628 : to be allowed from use from phiopt and can be done
3629 : without calculating the non-trapping cases. */
3630 : static bool
3631 1478271 : cond_store_replacement_limited (basic_block middle_bb, basic_block join_bb,
3632 : basic_block cond_bb,
3633 : edge e0, edge e1,
3634 : bool caninsert_edge)
3635 : {
3636 1478271 : tree lhs, rhs;
3637 1478271 : location_t locus;
3638 : /* Currently don't handle more than 2 incoming edges
3639 : into the merge bb. */
3640 1478271 : if (EDGE_COUNT (join_bb->preds) > 2)
3641 : return false;
3642 : /* The middle bb needs to have a single predecessor of the cond_bb. */
3643 1478271 : if (!single_pred_p (middle_bb))
3644 : return false;
3645 1478271 : gphi *vphi = get_virtual_phi (join_bb);
3646 1478271 : if (!vphi)
3647 : return false;
3648 1310393 : tree middle_vdef = gimple_phi_arg_def_from_edge (vphi, e0);
3649 : /* Check if middle_bb contains of only one store. */
3650 1310393 : gimple *store_middle;
3651 1310393 : store_middle = trailing_store_in_bb (middle_bb, middle_vdef,
3652 : vphi, true);
3653 :
3654 1310393 : if (!store_middle
3655 142558 : || !gimple_assign_single_p (store_middle)
3656 142558 : || gimple_has_volatile_ops (store_middle)
3657 : // Rejects clobbers too.
3658 1452089 : || gimple_clobber_p (store_middle))
3659 : return false;
3660 :
3661 141696 : locus = gimple_location (store_middle);
3662 141696 : lhs = gimple_assign_lhs (store_middle);
3663 141696 : rhs = gimple_assign_rhs1 (store_middle);
3664 141696 : if ((!REFERENCE_CLASS_P (lhs)
3665 141696 : && !DECL_P (lhs))
3666 141696 : || !is_gimple_reg_type (TREE_TYPE (lhs)))
3667 : return false;
3668 :
3669 : /* Three cases that can be handled:
3670 : 1) the lhs is stored to right before the condition.
3671 : Will remove the store before the condition.
3672 : 2) Or the lhs is loaded from right before the condition.
3673 : 3) Neither of these. (this will insert a load in the other edge)
3674 : For case 2 and 3, check for data races.
3675 : For case 2, the load can either be based on a local variable
3676 : or a known non-trapping decl.
3677 : For case 3, the store needs to known to be non-trapping. */
3678 139498 : tree vuse = gimple_vuse (store_middle);
3679 139498 : gimple *beforestore = nullptr;
3680 139498 : gimple *vdef_before = SSA_NAME_DEF_STMT (vuse);
3681 139498 : tree other_rhs = nullptr;
3682 :
3683 : /* See if there is a store before the condition case. */
3684 139498 : if (gimple_assign_single_p (vdef_before))
3685 : {
3686 34984 : tree beforelhs = gimple_assign_lhs (vdef_before);
3687 : /* Only allow the store to be right before the condition. */
3688 34984 : if (gimple_bb (vdef_before) == cond_bb
3689 : /* This can't be a clobber */
3690 29627 : && !gimple_clobber_p (vdef_before)
3691 : /* An exact match is only supported.
3692 : FIXME: Allow for clique/base mismatch? */
3693 60334 : && operand_equal_p (lhs, beforelhs))
3694 : {
3695 : /* The vuse of the of store in the middle should be also
3696 : the entry in the phi for the other edge. */
3697 5408 : gcc_assert (vuse == gimple_phi_arg_def_from_edge (vphi, e1));
3698 5408 : tree vuse = gimple_vuse (store_middle);
3699 5408 : imm_use_iterator iter;
3700 5408 : gimple *use_stmt;
3701 5408 : bool has_load = false;
3702 : /* If there is a load, then just reuse the value and not
3703 : remove the old store as that might be used by the load. */
3704 15659 : FOR_EACH_IMM_USE_STMT (use_stmt, iter, vuse)
3705 : {
3706 10846 : if (use_stmt != store_middle
3707 10846 : && use_stmt != vphi)
3708 : {
3709 : has_load = true;
3710 : break;
3711 : }
3712 5408 : }
3713 5408 : other_rhs = gimple_assign_rhs1 (vdef_before);
3714 : /* If there is no load, then keep the reference to the store stmt. */
3715 5408 : if (!has_load)
3716 4813 : beforestore = vdef_before;
3717 : }
3718 : }
3719 : /*
3720 : case 2:
3721 : a = local_var[n];
3722 : if (b)
3723 : local_var[n] = c;
3724 :
3725 : case 3:
3726 : if (b)
3727 : nontrapping = c;
3728 :
3729 : For case 3, nontrapping needs to satisfy tree_could_trap_p.
3730 : In both cases ref_can_have_store_data_races needs to be satisfy.
3731 : */
3732 :
3733 : /* Maybe the load/local non-escaped variable case. */
3734 5408 : if (!other_rhs)
3735 : {
3736 134090 : tree lhsbase = get_base_address (lhs);
3737 : /* If this store ref can't have data races, a store
3738 : that was conditional can't become unconditional. */
3739 134090 : if (ref_can_have_store_data_races (lhs))
3740 132549 : return false;
3741 8039 : tree vuse = gimple_vuse (store_middle);
3742 8039 : imm_use_iterator iter;
3743 8039 : gimple *use_stmt;
3744 : /* Try to find the load before the store that matches
3745 : if we have a local variable or a non trapping store. */
3746 15365 : if ((auto_var_p (lhsbase) && !TREE_ADDRESSABLE (lhsbase))
3747 8075 : || !lhs_could_trap_p (lhs))
3748 : {
3749 35625 : FOR_EACH_IMM_USE_STMT (use_stmt, iter, vuse)
3750 : {
3751 29149 : if (gimple_bb (use_stmt) != cond_bb)
3752 20655 : continue;
3753 : /* Looking for a load only. */
3754 8494 : if (!gimple_assign_load_p (use_stmt))
3755 0 : continue;
3756 8494 : tree rhs = gimple_assign_rhs1 (use_stmt);
3757 8494 : if (!operand_equal_p (rhs, lhs))
3758 7613 : continue;
3759 881 : other_rhs = gimple_assign_lhs (use_stmt);
3760 881 : lhs = copy_mem_with_alias_set_zero (lhs);
3761 881 : break;
3762 7357 : }
3763 : }
3764 8039 : if (!other_rhs)
3765 : {
3766 7158 : gassign *new_stmt;
3767 : /* If not allowing inserting on the edge, then don't. */
3768 7158 : if (!caninsert_edge)
3769 : return false;
3770 : /* If LHS is an access to a local variable without address-taken
3771 : (or when we allow data races) and known not to trap, we could
3772 : always safely move down the store. */
3773 2141 : if (lhs_could_trap_p (lhs))
3774 : return false;
3775 660 : lhs = copy_mem_with_alias_set_zero (lhs);
3776 : /* Insert a load from the memory of the store to the temporary
3777 : on the edge which did not contain the store. */
3778 660 : other_rhs = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
3779 660 : new_stmt = gimple_build_assign (other_rhs, lhs);
3780 660 : gimple_set_location (new_stmt, locus);
3781 : /* Set the vuse for the new load. */
3782 660 : gimple_set_vuse (new_stmt,
3783 660 : gimple_phi_arg_def (vphi, e1->dest_idx));
3784 660 : lhs = unshare_expr (lhs);
3785 660 : {
3786 : /* Set the no-warning bit on the rhs of the load to avoid
3787 : uninit warnings. */
3788 660 : tree rhs1 = gimple_assign_rhs1 (new_stmt);
3789 660 : suppress_warning (rhs1, OPT_Wuninitialized);
3790 : }
3791 660 : gsi_insert_on_edge (e1, new_stmt);
3792 : }
3793 : }
3794 :
3795 6949 : gphi *newphi;
3796 6949 : gassign *new_stmt;
3797 6949 : gimple_stmt_iterator gsi;
3798 : /* Now we've checked the constraints, so do the transformation:
3799 : 1) Remove the store(s). */
3800 6949 : gsi = gsi_for_stmt (store_middle);
3801 6949 : unlink_stmt_vdef (store_middle);
3802 6949 : gsi_remove (&gsi, true);
3803 6949 : release_defs (store_middle);
3804 :
3805 : /* Remove the store before the conditional if possible. */
3806 6949 : if (beforestore)
3807 : {
3808 4813 : gsi = gsi_for_stmt (beforestore);
3809 4813 : unlink_stmt_vdef (beforestore);
3810 4813 : gsi_remove (&gsi, true);
3811 4813 : release_defs (beforestore);
3812 : }
3813 :
3814 :
3815 : /* 2) Create a PHI node at the join block, with one argument
3816 : holding the old RHS, and the other holding the temporary
3817 : where we stored the old memory contents. */
3818 6949 : tree phiname = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
3819 6949 : newphi = create_phi_node (phiname, join_bb);
3820 6949 : add_phi_arg (newphi, rhs, e0, locus);
3821 6949 : add_phi_arg (newphi, other_rhs, e1, locus);
3822 :
3823 : /* 3. Create the new store. */
3824 6949 : new_stmt = gimple_build_assign (lhs, phiname);
3825 :
3826 : /* Update the vdef for the new store statement. */
3827 6949 : tree newvphilhs = make_ssa_name (gimple_vop (cfun));
3828 6949 : tree vdef = gimple_phi_result (vphi);
3829 6949 : gimple_set_vuse (new_stmt, newvphilhs);
3830 6949 : gimple_set_vdef (new_stmt, vdef);
3831 6949 : gimple_phi_set_result (vphi, newvphilhs);
3832 6949 : SSA_NAME_DEF_STMT (vdef) = new_stmt;
3833 6949 : update_stmt (vphi);
3834 :
3835 6949 : gsi = gsi_after_labels (join_bb);
3836 6949 : gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
3837 :
3838 6949 : if (dump_file && (dump_flags & TDF_DETAILS))
3839 : {
3840 14 : fprintf (dump_file, "\nConditional store replacement happened!");
3841 14 : if (beforestore)
3842 5 : fprintf (dump_file, "\nRemoved the store before the condition.");
3843 14 : fprintf (dump_file, "\nInserted a new PHI statement in joint block:\n");
3844 14 : print_gimple_stmt (dump_file, new_stmt, 0, TDF_VOPS|TDF_MEMSYMS);
3845 : }
3846 6949 : statistics_counter_event (cfun, "conditional store replacement", 1);
3847 6949 : return true;
3848 : }
3849 :
3850 :
3851 : /* Return the only store in MIDDLE_BB as the candidate store for cselim. Return
3852 : NULL if no candidate can be found. */
3853 :
3854 : static gimple *
3855 433371 : cselim_candidate (basic_block middle_bb, basic_block join_bb, edge e0)
3856 : {
3857 433371 : gphi *vphi = get_virtual_phi (join_bb);
3858 433371 : if (!vphi)
3859 : return NULL;
3860 :
3861 265493 : tree middle_vdef = PHI_ARG_DEF_FROM_EDGE (vphi, e0);
3862 265493 : return trailing_store_in_bb (middle_bb, middle_vdef, vphi, true);
3863 : }
3864 :
3865 : /* Limited Conditional store replacement. We already know
3866 : that the recognized pattern looks like so:
3867 :
3868 : split:
3869 : if (cond) goto THEN_BB; else goto ELSE_BB (edge E1)
3870 : THEN_BB:
3871 : ...
3872 : STORE = Y;
3873 : ...
3874 : goto JOIN_BB;
3875 : ELSE_BB:
3876 : ...
3877 : STORE = Z;
3878 : ...
3879 : fallthrough (edge E0)
3880 : JOIN_BB:
3881 : some more
3882 :
3883 : Handles only the case with store in THEN_BB and ELSE_BB. That is
3884 : cheap enough due to in phiopt and not worry about heurstics. Moving the store
3885 : out might provide an opportunity for a phiopt to happen.
3886 : At -O1 (!flag_expensive_optimizations), this only handles the only store in
3887 : the BBs. */
3888 :
3889 : static bool
3890 963546 : cond_if_else_store_replacement_limited (basic_block then_bb, basic_block else_bb,
3891 : basic_block join_bb)
3892 : {
3893 963546 : gphi *vphi = get_virtual_phi (join_bb);
3894 963546 : if (!vphi)
3895 : return false;
3896 :
3897 963546 : tree then_vdef = PHI_ARG_DEF_FROM_EDGE (vphi, single_succ_edge (then_bb));
3898 1927092 : gimple *then_assign = trailing_store_in_bb (then_bb, then_vdef, vphi,
3899 963546 : !flag_expensive_optimizations);
3900 963546 : if (!then_assign)
3901 : return false;
3902 :
3903 779691 : tree else_vdef = PHI_ARG_DEF_FROM_EDGE (vphi, single_succ_edge (else_bb));
3904 1559382 : gimple *else_assign = trailing_store_in_bb (else_bb, else_vdef, vphi,
3905 779691 : !flag_expensive_optimizations);
3906 779691 : if (!else_assign)
3907 : return false;
3908 :
3909 99464 : if (!cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb,
3910 : then_assign, else_assign, vphi))
3911 : {
3912 71240 : gimple *then_n, *else_n;
3913 :
3914 : // Try to see if one "store" can be skipped on either side.
3915 71240 : if (!flag_expensive_optimizations)
3916 : return false;
3917 139312 : then_n = trailing_store_in_bb (then_bb, gimple_vuse (then_assign),
3918 : then_assign, true);
3919 69656 : if (then_n)
3920 : {
3921 7434 : ao_ref then_ref_n;
3922 7434 : ao_ref_init (&then_ref_n, gimple_assign_lhs (then_n));
3923 7434 : if (stmt_may_clobber_ref_p_1 (then_assign, &then_ref_n, false)
3924 7434 : || ref_maybe_used_by_stmt_p (then_assign, &then_ref_n, false))
3925 : then_n = nullptr;
3926 : }
3927 139312 : else_n = trailing_store_in_bb (else_bb, gimple_vuse (else_assign),
3928 : else_assign, true);
3929 69656 : if (else_n)
3930 : {
3931 4008 : ao_ref else_ref_n;
3932 4008 : ao_ref_init (&else_ref_n, gimple_assign_lhs (else_n));
3933 4008 : if (stmt_may_clobber_ref_p_1 (else_assign, &else_ref_n, false)
3934 4008 : || ref_maybe_used_by_stmt_p (else_assign, &else_ref_n, false))
3935 : else_n = nullptr;
3936 : }
3937 69656 : if (then_n
3938 69656 : && cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb,
3939 : then_n, else_assign, vphi))
3940 : return true;
3941 69322 : if (else_n
3942 69322 : && cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb,
3943 : then_assign, else_n, vphi))
3944 : return true;
3945 69263 : if (else_n && then_n
3946 69263 : && cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb,
3947 : then_n, else_n, vphi))
3948 99 : return true;
3949 : return false;
3950 : }
3951 : return true;
3952 : }
3953 :
3954 : /* Conditional store replacement. We already know
3955 : that the recognized pattern looks like so:
3956 :
3957 : split:
3958 : if (cond) goto THEN_BB; else goto ELSE_BB (edge E1)
3959 : THEN_BB:
3960 : ...
3961 : X = Y;
3962 : ...
3963 : goto JOIN_BB;
3964 : ELSE_BB:
3965 : ...
3966 : X = Z;
3967 : ...
3968 : fallthrough (edge E0)
3969 : JOIN_BB:
3970 : some more
3971 :
3972 : We check that it is safe to sink the store to JOIN_BB by verifying that
3973 : there are no read-after-write or write-after-write dependencies in
3974 : THEN_BB and ELSE_BB. */
3975 :
3976 : static bool
3977 242110 : cond_if_else_store_replacement (basic_block then_bb, basic_block else_bb,
3978 : basic_block join_bb)
3979 : {
3980 242110 : vec<data_reference_p> then_datarefs, else_datarefs;
3981 242110 : vec<ddr_p> then_ddrs, else_ddrs;
3982 242110 : gimple *then_store, *else_store;
3983 242110 : bool found, ok = false, res;
3984 242110 : tree then_lhs, else_lhs;
3985 242110 : basic_block blocks[3];
3986 242110 : gphi *vphi = get_virtual_phi (join_bb);
3987 242110 : if (!vphi)
3988 : return false;
3989 :
3990 : /* Handle the case with trailing stores in THEN_BB and ELSE_BB. That is
3991 : cheap enough to always handle as it allows us to elide dependence
3992 : checking. */
3993 241033 : while (cond_if_else_store_replacement_limited (then_bb, else_bb, join_bb))
3994 : ;
3995 :
3996 : /* If vectorization is disabled then do not sink any stores. */
3997 226251 : if (param_max_stores_to_sink == 0
3998 226250 : || (!flag_tree_loop_vectorize && !flag_tree_slp_vectorize))
3999 : return false;
4000 :
4001 : /* Find data references. */
4002 220568 : then_datarefs.create (1);
4003 220568 : else_datarefs.create (1);
4004 220568 : if ((find_data_references_in_bb (NULL, then_bb, &then_datarefs)
4005 220568 : == chrec_dont_know)
4006 194688 : || !then_datarefs.length ()
4007 188420 : || (find_data_references_in_bb (NULL, else_bb, &else_datarefs)
4008 188420 : == chrec_dont_know)
4009 236436 : || !else_datarefs.length ())
4010 : {
4011 205872 : free_data_refs (then_datarefs);
4012 205872 : free_data_refs (else_datarefs);
4013 205872 : return false;
4014 : }
4015 :
4016 : /* Clear visited on else stores, we want to make sure to pick each store
4017 : at most once to avoid quadratic behavior. */
4018 67060 : for (auto else_dr : else_datarefs)
4019 : {
4020 37668 : if (DR_IS_READ (else_dr))
4021 19554 : continue;
4022 18114 : gimple_set_visited (DR_STMT (else_dr), false);
4023 : }
4024 :
4025 : /* Find pairs of stores with equal LHS. Work from the end to avoid
4026 : re-ordering stores unnecessarily. */
4027 14696 : auto_vec<std::pair<gimple *, gimple *>, 1> stores_pairs;
4028 14696 : unsigned i;
4029 14696 : data_reference_p then_dr;
4030 61984 : FOR_EACH_VEC_ELT_REVERSE (then_datarefs, i, then_dr)
4031 : {
4032 32592 : if (DR_IS_READ (then_dr))
4033 32592 : continue;
4034 :
4035 19360 : then_store = DR_STMT (then_dr);
4036 19360 : then_lhs = gimple_get_lhs (then_store);
4037 19360 : if (then_lhs == NULL_TREE)
4038 0 : continue;
4039 19360 : found = false;
4040 :
4041 19360 : unsigned j;
4042 19360 : data_reference_p else_dr;
4043 91830 : FOR_EACH_VEC_ELT_REVERSE (else_datarefs, j, else_dr)
4044 : {
4045 56611 : if (DR_IS_READ (else_dr))
4046 20369 : continue;
4047 :
4048 36242 : else_store = DR_STMT (else_dr);
4049 36242 : if (gimple_visited_p (else_store))
4050 3338 : continue;
4051 32904 : else_lhs = gimple_get_lhs (else_store);
4052 32904 : if (else_lhs == NULL_TREE)
4053 0 : continue;
4054 :
4055 32904 : if (operand_equal_p (then_lhs, else_lhs, 0))
4056 : {
4057 : found = true;
4058 : break;
4059 : }
4060 : }
4061 :
4062 19360 : if (!found)
4063 15859 : continue;
4064 :
4065 3501 : gimple_set_visited (else_store, true);
4066 3501 : stores_pairs.safe_push (std::make_pair (then_store, else_store));
4067 : }
4068 :
4069 : /* No pairs of stores found. */
4070 14696 : if (!stores_pairs.length ()
4071 14696 : || stores_pairs.length () > (unsigned) param_max_stores_to_sink)
4072 : {
4073 12702 : free_data_refs (then_datarefs);
4074 12702 : free_data_refs (else_datarefs);
4075 12702 : return false;
4076 : }
4077 :
4078 : /* Compute and check data dependencies in both basic blocks. */
4079 1994 : then_ddrs.create (1);
4080 1994 : else_ddrs.create (1);
4081 1994 : if (!compute_all_dependences (then_datarefs, &then_ddrs,
4082 1994 : vNULL, false)
4083 3988 : || !compute_all_dependences (else_datarefs, &else_ddrs,
4084 1994 : vNULL, false))
4085 : {
4086 0 : free_dependence_relations (then_ddrs);
4087 0 : free_dependence_relations (else_ddrs);
4088 0 : free_data_refs (then_datarefs);
4089 0 : free_data_refs (else_datarefs);
4090 0 : return false;
4091 : }
4092 1994 : blocks[0] = then_bb;
4093 1994 : blocks[1] = else_bb;
4094 1994 : blocks[2] = join_bb;
4095 1994 : renumber_gimple_stmt_uids_in_blocks (blocks, 3);
4096 :
4097 : /* Check that there are no read-after-write or write-after-write dependencies
4098 : in THEN_BB. */
4099 12360 : for (auto ddr : then_ddrs)
4100 : {
4101 7139 : struct data_reference *dra = DDR_A (ddr);
4102 7139 : struct data_reference *drb = DDR_B (ddr);
4103 :
4104 7139 : if (DDR_ARE_DEPENDENT (ddr) != chrec_known
4105 7139 : && ((DR_IS_READ (dra) && DR_IS_WRITE (drb)
4106 771 : && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT (drb)))
4107 1532 : || (DR_IS_READ (drb) && DR_IS_WRITE (dra)
4108 495 : && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT (dra)))
4109 1037 : || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb))))
4110 : {
4111 761 : free_dependence_relations (then_ddrs);
4112 761 : free_dependence_relations (else_ddrs);
4113 761 : free_data_refs (then_datarefs);
4114 761 : free_data_refs (else_datarefs);
4115 761 : return false;
4116 : }
4117 : }
4118 :
4119 : /* Check that there are no read-after-write or write-after-write dependencies
4120 : in ELSE_BB. */
4121 8055 : for (auto ddr : else_ddrs)
4122 : {
4123 4526 : struct data_reference *dra = DDR_A (ddr);
4124 4526 : struct data_reference *drb = DDR_B (ddr);
4125 :
4126 4526 : if (DDR_ARE_DEPENDENT (ddr) != chrec_known
4127 4526 : && ((DR_IS_READ (dra) && DR_IS_WRITE (drb)
4128 395 : && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT (drb)))
4129 565 : || (DR_IS_READ (drb) && DR_IS_WRITE (dra)
4130 146 : && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT (dra)))
4131 419 : || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb))))
4132 : {
4133 170 : free_dependence_relations (then_ddrs);
4134 170 : free_dependence_relations (else_ddrs);
4135 170 : free_data_refs (then_datarefs);
4136 170 : free_data_refs (else_datarefs);
4137 170 : return false;
4138 : }
4139 : }
4140 :
4141 : /* Sink stores with same LHS. */
4142 4576 : for (auto &store_pair : stores_pairs)
4143 : {
4144 1387 : then_store = store_pair.first;
4145 1387 : else_store = store_pair.second;
4146 1387 : res = cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb,
4147 : then_store, else_store, vphi);
4148 1387 : ok = ok || res;
4149 : }
4150 :
4151 1063 : free_dependence_relations (then_ddrs);
4152 1063 : free_dependence_relations (else_ddrs);
4153 1063 : free_data_refs (then_datarefs);
4154 1063 : free_data_refs (else_datarefs);
4155 :
4156 1063 : return ok;
4157 14696 : }
4158 :
4159 : /* Returns true when P is based on an induction variable
4160 : inside MERGE's inner most loop. */
4161 : static bool
4162 1240 : induction_based (tree p, basic_block merge)
4163 : {
4164 1240 : if (TREE_CODE (p) != SSA_NAME)
4165 : return false;
4166 534 : tree ev = analyze_scalar_evolution (merge->loop_father, p);
4167 534 : if (chrec_contains_undetermined (ev)
4168 534 : || chrec_contains_symbols_defined_in_loop (ev, merge->loop_father->num))
4169 : return false;
4170 140 : if (tree_does_not_contain_chrecs (ev))
4171 : return false;
4172 : return true;
4173 : }
4174 :
4175 : /* If PHI at MERGE is a "load PHI", PHI <*P, *Q> whose two arguments are
4176 : single-use, non-volatile scalar MEM_REF loads reading the same memory state
4177 : (same VUSE), factor the load out: introduce P' = PHI <P, Q> and a single
4178 : load *P' replacing the PHI. No speculative load is introduced (the load uses
4179 : whichever pointer the taken edge selected).
4180 : E0/E1 are the middle bbs to MERGE edges.
4181 : EARLY_P is set when the first phiopt is run.
4182 : BEFORE_VECT is true if this is before vectorization, where some extra checks
4183 : are needed for profitability.
4184 : Returns true if a load was factored out. */
4185 :
4186 : static bool
4187 1005905 : factor_out_conditional_load (edge e0, edge e1, basic_block merge, gphi *phi,
4188 : bool early_p, bool before_vect)
4189 : {
4190 : /* Not a virtual operand. */
4191 1305205 : if (virtual_operand_p (gimple_phi_result (phi))
4192 : /* can only handle the merge bb having 2 predecessors. */
4193 1305205 : || gimple_phi_num_args (phi) != 2)
4194 : return false;
4195 :
4196 299300 : tree arg0 = gimple_phi_arg_def (phi, e0->dest_idx);
4197 299300 : tree arg1 = gimple_phi_arg_def (phi, e1->dest_idx);
4198 : /* The load needs to be only used in the phi. */
4199 254971 : if (TREE_CODE (arg0) != SSA_NAME || TREE_CODE (arg1) != SSA_NAME
4200 535461 : || !has_single_use (arg0) || !has_single_use (arg1))
4201 : return false;
4202 :
4203 : /* Re-derive the loads and pointers validated by the predicate above. */
4204 126105 : gimple *load0 = SSA_NAME_DEF_STMT (arg0);
4205 126105 : gimple *load1 = SSA_NAME_DEF_STMT (arg1);
4206 :
4207 : /* Load have to need to be in the middle bbs. */
4208 126105 : if (gimple_bb (load0) != e0->src
4209 126105 : || gimple_bb (load1) != e1->src)
4210 : return false;
4211 :
4212 : /* The load needs to be a load with NO volatile ops. */
4213 150739 : if (!gimple_assign_load_p (load0) || !gimple_assign_load_p (load1)
4214 169992 : || gimple_has_volatile_ops (load0) || gimple_has_volatile_ops (load1))
4215 : return false;
4216 :
4217 : /* Allow for stores/calls before the load. */
4218 25779 : if (gphi *vphi = get_virtual_phi (merge))
4219 : {
4220 29810 : if (gimple_vuse (load0) != gimple_phi_arg_def (vphi, e0->dest_idx)
4221 25995 : || gimple_vuse (load1) != gimple_phi_arg_def (vphi, e1->dest_idx))
4222 : return false;
4223 : }
4224 : /* Sometimes due to not removing dead statements,
4225 : a virtual phi does not show up going into an infinite loop
4226 : so just reject that case. */
4227 32622 : else if (gimple_vuse (load0) != gimple_vuse (load1))
4228 : return false;
4229 :
4230 21901 : tree ref0 = gimple_assign_rhs1 (load0);
4231 21901 : tree ref1 = gimple_assign_rhs1 (load1);
4232 21901 : tree index = nullptr;
4233 21901 : tree step = nullptr;
4234 21901 : tree index2 = nullptr;
4235 21901 : bool rev_order = false;
4236 :
4237 : /* Both must be *P loads of a compatible value type. The
4238 : TBAA alias-ptr type carried by MEM_REF operand 1 need not match; it is
4239 : merged the way get_alias_type_for_stmts does when the load is built. */
4240 21901 : if (TREE_CODE (ref0) == MEM_REF)
4241 6208 : rev_order = REF_REVERSE_STORAGE_ORDER (ref0);
4242 : else
4243 : {
4244 15693 : if (TREE_CODE (ref0) != TARGET_MEM_REF)
4245 : return false;
4246 318 : index = TMR_INDEX (ref0);
4247 318 : step = TMR_STEP (ref0);
4248 318 : index2 = TMR_INDEX2 (ref0);
4249 : }
4250 6526 : if (TREE_CODE (ref1) == MEM_REF)
4251 : {
4252 5968 : if (index || step || index2)
4253 : return false;
4254 5968 : if (rev_order != REF_REVERSE_STORAGE_ORDER (ref1))
4255 : return false;
4256 : }
4257 : else
4258 : {
4259 558 : if (TREE_CODE (ref1) != TARGET_MEM_REF)
4260 : return false;
4261 328 : if (rev_order)
4262 : return false;
4263 328 : if (!safe_operand_equal_p (index, TMR_INDEX (ref1)))
4264 : return false;
4265 315 : if (!safe_operand_equal_p (step, TMR_STEP (ref1)))
4266 : return false;
4267 315 : if (!safe_operand_equal_p (index2, TMR_INDEX2 (ref1)))
4268 : return false;
4269 : }
4270 :
4271 6268 : if (!types_compatible_p (TREE_TYPE (ref0), TREE_TYPE (ref1)))
4272 : return false;
4273 :
4274 : /* The alignment of the two accesses need to be the same. */
4275 6268 : if (TYPE_ALIGN (TREE_TYPE (ref0)) != TYPE_ALIGN (TREE_TYPE (ref1)))
4276 : return false;
4277 :
4278 6007 : tree p0 = TREE_OPERAND (ref0, 0);
4279 6007 : tree p1 = TREE_OPERAND (ref1, 0);
4280 6007 : if (!is_factor_profitable (load0, merge, &p0, 1))
4281 : return false;
4282 6007 : if (!is_factor_profitable (load1, merge, &p1, 1))
4283 : return false;
4284 :
4285 : /* Merge the two arms' TBAA info as get_alias_type_for_stmts does: keep the
4286 : common alias-ptr type and dependence clique/base when the arms agree,
4287 : otherwise fall back to ptr_type_node (alias-everything) and drop the
4288 : clique/base, so the combined load conservatively conflicts with any store
4289 : either original arm could. */
4290 6007 : unsigned short clique = MR_DEPENDENCE_CLIQUE (ref0);
4291 6007 : unsigned short base = MR_DEPENDENCE_BASE (ref0);
4292 6007 : if (clique != MR_DEPENDENCE_CLIQUE (ref1) || base != MR_DEPENDENCE_BASE (ref1))
4293 : clique = base = 0;
4294 6007 : tree atype = TREE_TYPE (TREE_OPERAND (ref0, 1));
4295 6007 : if (!alias_ptr_types_compatible_p (atype, TREE_TYPE (TREE_OPERAND (ref1, 1))))
4296 : {
4297 640 : atype = ptr_type_node;
4298 640 : clique = base = 0;
4299 : }
4300 :
4301 6007 : tree index0 = TREE_OPERAND (ref0, 1);
4302 6007 : tree index1 = TREE_OPERAND (ref1, 1);
4303 6007 : tree newindex;
4304 6007 : gimple_stmt_iterator gsi;
4305 6007 : gsi = gsi_after_labels (merge);
4306 :
4307 : // factoring of the same pointer should be allowed
4308 : // irrespect to loops.
4309 6007 : if (p0 == p1 && operand_equal_p (index0, index1))
4310 : ;
4311 : // Before inlining, we can't tell if different
4312 : // pointers are going to be induction variable based
4313 : // or not.
4314 4595 : else if (early_p)
4315 : return false;
4316 : // Before vectorization, don't factor out
4317 : // pointers which are based on induction variables.
4318 4071 : else if (before_vect
4319 2369 : && bb_loop_depth (merge) != 0
4320 4743 : && (induction_based (p0, merge)
4321 568 : || induction_based (p1, merge)))
4322 : return false;
4323 :
4324 : /* Try to handle different indices. */
4325 5379 : if (operand_equal_p (index0, index1))
4326 4829 : newindex = fold_convert (atype, index0);
4327 : /* FIXME: right now non ssa names with different indices are not handled. */
4328 550 : else if (TREE_CODE (p0) != SSA_NAME || TREE_CODE (p1) != SSA_NAME)
4329 : return false;
4330 : /* If we have the same base already, just create a phi for the index
4331 : and the pointer plus will be done in the merge. */
4332 84 : else if (p0 == p1)
4333 : {
4334 60 : index0 = fold_convert (sizetype, index0);
4335 60 : index1 = fold_convert (sizetype, index1);
4336 60 : tree index = make_ssa_name (sizetype);
4337 60 : gphi *pphi = create_phi_node (index, merge);
4338 60 : add_phi_arg (pphi, index0, e0, gimple_phi_arg_location (phi, e0->dest_idx));
4339 60 : add_phi_arg (pphi, index1, e1, gimple_phi_arg_location (phi, e1->dest_idx));
4340 60 : p0 = gimple_build (&gsi, true, GSI_SAME_STMT,
4341 : UNKNOWN_LOCATION,
4342 : POINTER_PLUS_EXPR, atype, p0, index);
4343 : /* Since we already have the same pointer for both, just set that way.
4344 : Also the index offset is already 0 because we just did the add. */
4345 60 : p1 = p0;
4346 60 : newindex = build_zero_cst (atype);
4347 60 : if (dump_file && (dump_flags & TDF_DETAILS))
4348 : {
4349 2 : fprintf (dump_file, "new PHI ");
4350 2 : print_generic_expr (dump_file, index);
4351 2 : fprintf (dump_file,
4352 : " was created for the index.\n");
4353 : }
4354 : }
4355 : else
4356 : {
4357 24 : gimple_stmt_iterator gsi_index;
4358 : /* When the indices are different create 2 new pointers on each
4359 : of the middle bb right after the original load.
4360 : Note in the case of 0 index, gimple_build just returns
4361 : the original pointer. */
4362 24 : gsi_index = gsi_for_stmt (load0);
4363 24 : index0 = fold_convert (sizetype, index0);
4364 24 : p0 = gimple_build (&gsi_index, false, GSI_SAME_STMT,
4365 : gimple_location (load0),
4366 : POINTER_PLUS_EXPR, atype, p0, index0);
4367 :
4368 24 : gsi_index = gsi_for_stmt (load1);
4369 24 : index1 = fold_convert (sizetype, index1);
4370 24 : p1 = gimple_build (&gsi_index, false, GSI_SAME_STMT,
4371 : gimple_location (load1),
4372 : POINTER_PLUS_EXPR, atype, p1, index1);
4373 24 : newindex = build_zero_cst (atype);
4374 24 : if (dump_file && (dump_flags & TDF_DETAILS))
4375 : {
4376 1 : fprintf (dump_file, "new ptrs ");
4377 1 : print_generic_expr (dump_file, p0);
4378 1 : fprintf (dump_file, " and ");
4379 1 : print_generic_expr (dump_file, p1);
4380 1 : fprintf (dump_file,
4381 : " was created due to different offsets.\n");
4382 : }
4383 : }
4384 :
4385 4913 : tree newptr;
4386 4913 : if (p0 != p1)
4387 : {
4388 : /* We can't factor out a non-ssa named based load
4389 : as it might cause a variable not taken an
4390 : address to become needing the address taken.
4391 : An example is in go.
4392 : Were we produce:
4393 : _24 = PHI <&crypto/tls.cipherSuitesPreferenceOrder(36), &crypto/tls.cipherSuitesPreferenceOrderNoAES(37)>
4394 : And &crypto/tls.cipherSuitesPreferenceOrder address bit was not set.
4395 : FIXME: Refine to check ADDRESSABLE bit. */
4396 3441 : if (TREE_CODE (p0) != SSA_NAME || TREE_CODE (p1) != SSA_NAME)
4397 : return false;
4398 : // Incompatible address spaces or differnt function pointers could show up here.
4399 368 : if (!types_compatible_p (TREE_TYPE (p0), TREE_TYPE (p1)))
4400 : return false;
4401 : /* Build P' = PHI <P, Q> and the single load result = *P'. */
4402 350 : newptr = make_ssa_name (TREE_TYPE (p0));
4403 350 : gphi *pphi = create_phi_node (newptr, merge);
4404 350 : add_phi_arg (pphi, p0, e0, gimple_phi_arg_location (phi, e0->dest_idx));
4405 350 : add_phi_arg (pphi, p1, e1, gimple_phi_arg_location (phi, e1->dest_idx));
4406 : }
4407 : else
4408 : newptr = p0;
4409 :
4410 : /* Build the combined load RES = *PTR, reusing the PHI result so any range
4411 : info on it is preserved (as factor_out_conditional_operation does). */
4412 1822 : tree nref;
4413 1822 : if (index || step || index2)
4414 28 : nref = build5 (TARGET_MEM_REF, TREE_TYPE (ref0), newptr,
4415 : newindex, index, step, index2);
4416 : else
4417 : {
4418 1794 : nref = build2 (MEM_REF, TREE_TYPE (ref0), newptr, newindex);
4419 1794 : REF_REVERSE_STORAGE_ORDER (nref) = rev_order;
4420 : }
4421 1822 : MR_DEPENDENCE_CLIQUE (nref) = clique;
4422 1822 : MR_DEPENDENCE_BASE (nref) = base;
4423 1822 : tree res = gimple_phi_result (phi);
4424 1822 : gassign *load = gimple_build_assign (res, nref);
4425 1822 : if (gphi *vphi = get_virtual_phi (merge))
4426 1474 : gimple_set_vuse (load, gimple_phi_result (vphi));
4427 : else
4428 696 : gimple_set_vuse (load, gimple_vuse (load0));
4429 1822 : gsi_insert_before (&gsi, load, GSI_SAME_STMT);
4430 :
4431 : /* RES is now defined by the load; drop the original PHI. */
4432 1822 : gsi = gsi_for_stmt (phi);
4433 1822 : remove_phi_node (&gsi, false);
4434 :
4435 : /* The two arm loads are now dead. */
4436 1822 : gsi = gsi_for_stmt (load0);
4437 1822 : gsi_remove (&gsi, true);
4438 1822 : release_defs (load0);
4439 1822 : gsi = gsi_for_stmt (load1);
4440 1822 : gsi_remove (&gsi, true);
4441 1822 : release_defs (load1);
4442 :
4443 1822 : if (dump_file && (dump_flags & TDF_DETAILS))
4444 : {
4445 15 : fprintf (dump_file, "PHI ");
4446 15 : print_generic_expr (dump_file, res);
4447 15 : fprintf (dump_file,
4448 : " changed to factor out load from COND_EXPR.\n");
4449 15 : if (p0 != p1)
4450 : {
4451 13 : fprintf (dump_file, "new PHI ");
4452 13 : print_generic_expr (dump_file, newptr);
4453 13 : fprintf (dump_file,
4454 : " was created for the pointers.\n");
4455 : }
4456 : }
4457 :
4458 1822 : statistics_counter_event (cfun, "factored load out of COND_EXPR", 1);
4459 1822 : return true;
4460 : }
4461 :
4462 : /* Factor out operations and stores from the phi of the MERGE block coming
4463 : in from the edges E1 and E2 if possible. COND_STMT is the conditional
4464 : statement of the origin block. DIAMOND_P says that both E1 and E2 src
4465 : are not the origin block but rather 2 middle BBs. EARLY_P is true if
4466 : this was the early phi-opt.
4467 : Returns true if a factoring happened. */
4468 : static bool
4469 2559146 : factor_out_all (edge e1, edge e2, basic_block merge,
4470 : gcond *cond_stmt, bool diamond_p, bool early_p)
4471 : {
4472 2559146 : bool changed = false;
4473 2559146 : bool do_over;
4474 2559146 : bool before_vect = !fold_before_rtl_expansion_p ();
4475 : // If vectorization is disable, then we are never before the vectorizer.
4476 2559146 : if (!flag_tree_loop_vectorize
4477 189033 : && !merge->loop_father->force_vectorize)
4478 2559146 : before_vect = false;
4479 2559146 : basic_block bb1 = e1->src;
4480 2559146 : basic_block bb2 = e2->src;
4481 2537219 : do
4482 : {
4483 2609423 : do_over = false;
4484 2609423 : if (diamond_p && get_virtual_phi (merge))
4485 : {
4486 722513 : if (cond_if_else_store_replacement_limited (bb1, bb2, merge))
4487 : {
4488 13934 : changed = true;
4489 13934 : do_over = true;
4490 19914 : continue;
4491 : }
4492 : }
4493 2595489 : if (!single_pred_p (bb1))
4494 : break;
4495 1736995 : if (!diamond_p && get_virtual_phi (merge)
4496 3567216 : && cond_store_replacement_limited (bb1, merge, bb2,
4497 : e1, e2, false))
4498 : {
4499 5980 : changed = true;
4500 5980 : do_over = true;
4501 5980 : continue;
4502 : }
4503 2517305 : gphi_iterator gsi;
4504 5586217 : for (gsi = gsi_start_phis (merge); !gsi_end_p (gsi); gsi_next (&gsi))
4505 : {
4506 3099275 : gphi *phi = *gsi;
4507 : /* Conditional load elimination can only be on a diamond. */
4508 3099275 : if ((diamond_p
4509 1005905 : && factor_out_conditional_load (e1, e2, merge, phi, early_p,
4510 : before_vect))
4511 4103358 : || factor_out_conditional_operation (e1, e2, merge, phi,
4512 : cond_stmt, early_p))
4513 : {
4514 : changed = true;
4515 : do_over = true;
4516 : break;
4517 : }
4518 : }
4519 : } while (do_over);
4520 2559146 : return changed;
4521 : }
4522 :
4523 : /* Return TRUE if STMT has a VUSE whose corresponding VDEF is in BB. */
4524 :
4525 : static bool
4526 12592 : local_mem_dependence (gimple *stmt, basic_block bb)
4527 : {
4528 25184 : tree vuse = gimple_vuse (stmt);
4529 12592 : gimple *def;
4530 :
4531 12592 : if (!vuse)
4532 : return false;
4533 :
4534 12592 : def = SSA_NAME_DEF_STMT (vuse);
4535 12592 : return (def && gimple_bb (def) == bb);
4536 : }
4537 :
4538 : /* Given a "diamond" control-flow pattern where BB0 tests a condition,
4539 : BB1 and BB2 are "then" and "else" blocks dependent on this test,
4540 : and BB3 rejoins control flow following BB1 and BB2, look for
4541 : opportunities to hoist loads as follows. If BB3 contains a PHI of
4542 : two loads, one each occurring in BB1 and BB2, and the loads are
4543 : provably of adjacent fields in the same structure, then move both
4544 : loads into BB0. Of course this can only be done if there are no
4545 : dependencies preventing such motion.
4546 :
4547 : One of the hoisted loads will always be speculative, so the
4548 : transformation is currently conservative:
4549 :
4550 : - The fields must be strictly adjacent.
4551 : - The two fields must occupy a single memory block that is
4552 : guaranteed to not cross a page boundary.
4553 :
4554 : The last is difficult to prove, as such memory blocks should be
4555 : aligned on the minimum of the stack alignment boundary and the
4556 : alignment guaranteed by heap allocation interfaces. Thus we rely
4557 : on a parameter for the alignment value.
4558 :
4559 : Provided a good value is used for the last case, the first
4560 : restriction could possibly be relaxed. */
4561 :
4562 : static void
4563 605043 : hoist_adjacent_loads (basic_block bb0, basic_block bb1,
4564 : basic_block bb2, basic_block bb3)
4565 : {
4566 605043 : unsigned HOST_WIDE_INT param_align = param_l1_cache_line_size;
4567 605043 : unsigned HOST_WIDE_INT param_align_bits = param_align * BITS_PER_UNIT;
4568 605043 : gphi_iterator gsi;
4569 :
4570 : /* Walk the phis in bb3 looking for an opportunity. We are looking
4571 : for phis of two SSA names, one each of which is defined in bb1 and
4572 : bb2. */
4573 1361515 : for (gsi = gsi_start_phis (bb3); !gsi_end_p (gsi); gsi_next (&gsi))
4574 : {
4575 756472 : gphi *phi_stmt = gsi.phi ();
4576 756472 : gimple *def1, *def2;
4577 756472 : tree arg1, arg2, ref1, ref2, field1, field2;
4578 756472 : tree tree_offset1, tree_offset2, tree_size2, next;
4579 756472 : unsigned HOST_WIDE_INT offset1, offset2, size2, align1;
4580 756472 : gimple_stmt_iterator gsi2;
4581 756472 : basic_block bb_for_def1, bb_for_def2;
4582 :
4583 756472 : if (gimple_phi_num_args (phi_stmt) != 2
4584 1512944 : || virtual_operand_p (gimple_phi_result (phi_stmt)))
4585 750176 : continue;
4586 :
4587 193786 : arg1 = gimple_phi_arg_def (phi_stmt, 0);
4588 193786 : arg2 = gimple_phi_arg_def (phi_stmt, 1);
4589 :
4590 227616 : if (TREE_CODE (arg1) != SSA_NAME
4591 176167 : || TREE_CODE (arg2) != SSA_NAME
4592 161207 : || SSA_NAME_IS_DEFAULT_DEF (arg1)
4593 354662 : || SSA_NAME_IS_DEFAULT_DEF (arg2))
4594 33830 : continue;
4595 :
4596 159956 : def1 = SSA_NAME_DEF_STMT (arg1);
4597 159956 : def2 = SSA_NAME_DEF_STMT (arg2);
4598 :
4599 159956 : if ((gimple_bb (def1) != bb1 || gimple_bb (def2) != bb2)
4600 174144 : && (gimple_bb (def2) != bb1 || gimple_bb (def1) != bb2))
4601 41568 : continue;
4602 :
4603 : /* Check the mode of the arguments to be sure a conditional move
4604 : can be generated for it. */
4605 236776 : if (optab_handler (movcc_optab, TYPE_MODE (TREE_TYPE (arg1)))
4606 : == CODE_FOR_nothing)
4607 4986 : continue;
4608 :
4609 : /* Both statements must be assignments whose RHS is a COMPONENT_REF. */
4610 113402 : if (!gimple_assign_single_p (def1)
4611 53190 : || !gimple_assign_single_p (def2)
4612 71040 : || gimple_has_volatile_ops (def1)
4613 184396 : || gimple_has_volatile_ops (def2))
4614 77905 : continue;
4615 :
4616 35497 : ref1 = gimple_assign_rhs1 (def1);
4617 35497 : ref2 = gimple_assign_rhs1 (def2);
4618 :
4619 35497 : if (TREE_CODE (ref1) != COMPONENT_REF
4620 24449 : || TREE_CODE (ref2) != COMPONENT_REF)
4621 11218 : continue;
4622 :
4623 : /* The zeroth operand of the two component references must be
4624 : identical. It is not sufficient to compare get_base_address of
4625 : the two references, because this could allow for different
4626 : elements of the same array in the two trees. It is not safe to
4627 : assume that the existence of one array element implies the
4628 : existence of a different one. */
4629 24279 : if (!operand_equal_p (TREE_OPERAND (ref1, 0), TREE_OPERAND (ref2, 0), 0))
4630 4630 : continue;
4631 :
4632 19649 : field1 = TREE_OPERAND (ref1, 1);
4633 19649 : field2 = TREE_OPERAND (ref2, 1);
4634 :
4635 : /* Check for field adjacency, and ensure field1 comes first. */
4636 19649 : for (next = DECL_CHAIN (field1);
4637 34313 : next && TREE_CODE (next) != FIELD_DECL;
4638 14664 : next = DECL_CHAIN (next))
4639 : ;
4640 :
4641 19649 : if (next != field2)
4642 : {
4643 15923 : for (next = DECL_CHAIN (field2);
4644 17963 : next && TREE_CODE (next) != FIELD_DECL;
4645 2040 : next = DECL_CHAIN (next))
4646 : ;
4647 :
4648 15923 : if (next != field1)
4649 13353 : continue;
4650 :
4651 : std::swap (field1, field2);
4652 : std::swap (def1, def2);
4653 : }
4654 :
4655 6296 : bb_for_def1 = gimple_bb (def1);
4656 6296 : bb_for_def2 = gimple_bb (def2);
4657 :
4658 : /* Check for proper alignment of the first field. */
4659 6296 : tree_offset1 = bit_position (field1);
4660 6296 : tree_offset2 = bit_position (field2);
4661 6296 : tree_size2 = DECL_SIZE (field2);
4662 :
4663 6296 : if (!tree_fits_uhwi_p (tree_offset1)
4664 6296 : || !tree_fits_uhwi_p (tree_offset2)
4665 6296 : || !tree_fits_uhwi_p (tree_size2))
4666 0 : continue;
4667 :
4668 6296 : offset1 = tree_to_uhwi (tree_offset1);
4669 6296 : offset2 = tree_to_uhwi (tree_offset2);
4670 6296 : size2 = tree_to_uhwi (tree_size2);
4671 6296 : align1 = DECL_ALIGN (field1) % param_align_bits;
4672 :
4673 6296 : if (offset1 % BITS_PER_UNIT != 0)
4674 0 : continue;
4675 :
4676 : /* For profitability, the two field references should fit within
4677 : a single cache line. */
4678 6296 : if (align1 + offset2 - offset1 + size2 > param_align_bits)
4679 0 : continue;
4680 :
4681 : /* The two expressions cannot be dependent upon vdefs defined
4682 : in bb1/bb2. */
4683 6296 : if (local_mem_dependence (def1, bb_for_def1)
4684 6296 : || local_mem_dependence (def2, bb_for_def2))
4685 0 : continue;
4686 :
4687 : /* The conditions are satisfied; hoist the loads from bb1 and bb2 into
4688 : bb0. We hoist the first one first so that a cache miss is handled
4689 : efficiently regardless of hardware cache-fill policy. */
4690 6296 : gsi2 = gsi_for_stmt (def1);
4691 6296 : gsi_move_to_bb_end (&gsi2, bb0);
4692 6296 : gsi2 = gsi_for_stmt (def2);
4693 6296 : gsi_move_to_bb_end (&gsi2, bb0);
4694 : /* Clear range info from the defs we've moved from under the
4695 : condition. */
4696 6296 : reset_flow_sensitive_info (gimple_assign_lhs (def1));
4697 6296 : reset_flow_sensitive_info (gimple_assign_lhs (def2));
4698 6296 : statistics_counter_event (cfun, "hoisted loads", 1);
4699 :
4700 6296 : if (dump_file && (dump_flags & TDF_DETAILS))
4701 : {
4702 0 : fprintf (dump_file,
4703 : "\nHoisting adjacent loads from %d and %d into %d: \n",
4704 : bb_for_def1->index, bb_for_def2->index, bb0->index);
4705 0 : print_gimple_stmt (dump_file, def1, 0, TDF_VOPS|TDF_MEMSYMS);
4706 0 : print_gimple_stmt (dump_file, def2, 0, TDF_VOPS|TDF_MEMSYMS);
4707 : }
4708 : }
4709 605043 : }
4710 :
4711 : /* Determine whether we should attempt to hoist adjacent loads out of
4712 : diamond patterns in pass_phiopt. Always hoist loads if
4713 : -fhoist-adjacent-loads is specified and the target machine has
4714 : both a conditional move instruction and a defined cache line size. */
4715 :
4716 : static bool
4717 3204175 : gate_hoist_loads (void)
4718 : {
4719 3204175 : return (flag_hoist_adjacent_loads == 1
4720 3204175 : && param_l1_cache_line_size
4721 0 : && HAVE_conditional_move);
4722 : }
4723 :
4724 : template <class func_type>
4725 : static void
4726 6838676 : execute_over_cond_phis (func_type func)
4727 : {
4728 : unsigned n, i;
4729 : basic_block *bb_order;
4730 : basic_block bb;
4731 : /* Search every basic block for COND_EXPR we may be able to optimize.
4732 :
4733 : We walk the blocks in order that guarantees that a block with
4734 : a single predecessor is processed before the predecessor.
4735 : This ensures that we collapse inner ifs before visiting the
4736 : outer ones, and also that we do not try to visit a removed
4737 : block. */
4738 6838676 : bb_order = single_pred_before_succ_order ();
4739 6838676 : n = n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS;
4740 :
4741 62570215 : for (i = 0; i < n; i++)
4742 : {
4743 : basic_block bb1, bb2;
4744 : edge e1, e2;
4745 55731539 : bool diamond_p = false;
4746 :
4747 55731539 : bb = bb_order[i];
4748 :
4749 : /* Check to see if the last statement is a GIMPLE_COND. */
4750 55731539 : gcond *cond_stmt = safe_dyn_cast <gcond *> (*gsi_last_bb (bb));
4751 33792618 : if (!cond_stmt)
4752 55731539 : continue;
4753 :
4754 21938921 : e1 = EDGE_SUCC (bb, 0);
4755 21938921 : bb1 = e1->dest;
4756 21938921 : e2 = EDGE_SUCC (bb, 1);
4757 21938921 : bb2 = e2->dest;
4758 :
4759 : /* We cannot do the optimization on abnormal edges. */
4760 21938921 : if ((e1->flags & EDGE_ABNORMAL) != 0
4761 21938921 : || (e2->flags & EDGE_ABNORMAL) != 0)
4762 0 : continue;
4763 :
4764 : /* If either bb1's succ or bb2 or bb2's succ is non NULL. */
4765 21938921 : if (EDGE_COUNT (bb1->succs) == 0
4766 20566131 : || EDGE_COUNT (bb2->succs) == 0)
4767 5028203 : continue;
4768 :
4769 : /* Find the bb which is the fall through to the other. */
4770 16910718 : if (EDGE_SUCC (bb1, 0)->dest == bb2)
4771 : ;
4772 14388781 : else if (EDGE_SUCC (bb2, 0)->dest == bb1)
4773 : {
4774 : std::swap (bb1, bb2);
4775 : std::swap (e1, e2);
4776 : }
4777 11074122 : else if (EDGE_SUCC (bb1, 0)->dest == EDGE_SUCC (bb2, 0)->dest
4778 12662432 : && single_succ_p (bb2))
4779 : {
4780 1588310 : diamond_p = true;
4781 1588310 : e2 = EDGE_SUCC (bb2, 0);
4782 : /* Make sure bb2 is just a fall through. */
4783 1588310 : if ((e2->flags & EDGE_FALLTHRU) == 0)
4784 52209 : continue;
4785 : }
4786 : else
4787 11074122 : continue;
4788 :
4789 5784387 : e1 = EDGE_SUCC (bb1, 0);
4790 :
4791 : /* Make sure that bb1 is just a fall through. */
4792 5784387 : if (!single_succ_p (bb1)
4793 5784387 : || (e1->flags & EDGE_FALLTHRU) == 0)
4794 1284368 : continue;
4795 :
4796 4500019 : func (bb, bb1, bb2, e1, e2, diamond_p, cond_stmt);
4797 : }
4798 6838676 : free (bb_order);
4799 6838676 : }
4800 :
4801 : /* This pass tries to replaces an if-then-else block with an
4802 : assignment. We have different kinds of transformations.
4803 : Some of these transformations are also performed by the ifcvt
4804 : RTL optimizer.
4805 :
4806 : PHI-OPT using Match-and-simplify infrastructure
4807 : -----------------------
4808 :
4809 : The PHI-OPT pass will try to use match-and-simplify infrastructure
4810 : (gimple_simplify) to do transformations. This is implemented in
4811 : match_simplify_replacement.
4812 :
4813 : The way it works is it replaces:
4814 : bb0:
4815 : if (cond) goto bb2; else goto bb1;
4816 : bb1:
4817 : bb2:
4818 : x = PHI <a (bb1), b (bb0), ...>;
4819 :
4820 : with a statement if it gets simplified from `cond ? b : a`.
4821 :
4822 : bb0:
4823 : x1 = cond ? b : a;
4824 : bb2:
4825 : x = PHI <a (bb1), x1 (bb0), ...>;
4826 : Bb1 might be removed as it becomes unreachable when doing the replacement.
4827 : Though bb1 does not have to be considered a forwarding basic block from bb0.
4828 :
4829 : Will try to see if `(!cond) ? a : b` gets simplified (iff !cond simplifies);
4830 : this is done not to have an explosion of patterns in match.pd.
4831 : Note bb1 does not need to be completely empty, it can contain
4832 : one statement which is known not to trap.
4833 :
4834 : It also can handle the case where we have two forwarding bbs (diamond):
4835 : bb0:
4836 : if (cond) goto bb2; else goto bb1;
4837 : bb1: goto bb3;
4838 : bb2: goto bb3;
4839 : bb3:
4840 : x = PHI <a (bb1), b (bb2), ...>;
4841 : And that is replaced with a statement if it is simplified
4842 : from `cond ? b : a`.
4843 : Again bb1 and bb2 does not have to be completely empty but
4844 : each can contain one statement which is known not to trap.
4845 : But in this case bb1/bb2 can only be forwarding basic blocks.
4846 :
4847 : This fully replaces the old "Conditional Replacement",
4848 : "ABS Replacement" and "MIN/MAX Replacement" transformations as they are now
4849 : implemented in match.pd.
4850 :
4851 : Value Replacement
4852 : -----------------
4853 :
4854 : This transformation, implemented in value_replacement, replaces
4855 :
4856 : bb0:
4857 : if (a != b) goto bb2; else goto bb1;
4858 : bb1:
4859 : bb2:
4860 : x = PHI <a (bb1), b (bb0), ...>;
4861 :
4862 : with
4863 :
4864 : bb0:
4865 : bb2:
4866 : x = PHI <b (bb0), ...>;
4867 :
4868 : This opportunity can sometimes occur as a result of other
4869 : optimizations.
4870 :
4871 :
4872 : Another case caught by value replacement looks like this:
4873 :
4874 : bb0:
4875 : t1 = a == CONST;
4876 : t2 = b > c;
4877 : t3 = t1 & t2;
4878 : if (t3 != 0) goto bb1; else goto bb2;
4879 : bb1:
4880 : bb2:
4881 : x = PHI (CONST, a)
4882 :
4883 : Gets replaced with:
4884 : bb0:
4885 : bb2:
4886 : t1 = a == CONST;
4887 : t2 = b > c;
4888 : t3 = t1 & t2;
4889 : x = a;
4890 :
4891 :
4892 : This pass also performs a fifth transformation of a slightly different
4893 : flavor.
4894 :
4895 : Factor operations in COND_EXPR
4896 : ------------------------------
4897 :
4898 : This transformation factors the unary operations out of COND_EXPR with
4899 : factor_out_conditional_operation.
4900 :
4901 : For example:
4902 : if (a <= CST) goto <bb 3>; else goto <bb 4>;
4903 : <bb 3>:
4904 : tmp = (int) a;
4905 : <bb 4>:
4906 : tmp = PHI <tmp, CST>
4907 :
4908 : Into:
4909 : if (a <= CST) goto <bb 3>; else goto <bb 4>;
4910 : <bb 3>:
4911 : <bb 4>:
4912 : a = PHI <a, CST>
4913 : tmp = (int) a;
4914 :
4915 : Adjacent Load Hoisting
4916 : ----------------------
4917 :
4918 : This transformation replaces
4919 :
4920 : bb0:
4921 : if (...) goto bb2; else goto bb1;
4922 : bb1:
4923 : x1 = (<expr>).field1;
4924 : goto bb3;
4925 : bb2:
4926 : x2 = (<expr>).field2;
4927 : bb3:
4928 : # x = PHI <x1, x2>;
4929 :
4930 : with
4931 :
4932 : bb0:
4933 : x1 = (<expr>).field1;
4934 : x2 = (<expr>).field2;
4935 : if (...) goto bb2; else goto bb1;
4936 : bb1:
4937 : goto bb3;
4938 : bb2:
4939 : bb3:
4940 : # x = PHI <x1, x2>;
4941 :
4942 : The purpose of this transformation is to enable generation of conditional
4943 : move instructions such as Intel CMOVE or PowerPC ISEL. Because one of
4944 : the loads is speculative, the transformation is restricted to very
4945 : specific cases to avoid introducing a page fault. We are looking for
4946 : the common idiom:
4947 :
4948 : if (...)
4949 : x = y->left;
4950 : else
4951 : x = y->right;
4952 :
4953 : where left and right are typically adjacent pointers in a tree structure. */
4954 :
4955 : /* Replicate the join block at E's destination into E's source. The copy's
4956 : PHIs degenerate to their argument on E, so the copied conditional tests the
4957 : predecessor's own value. The net effect after cleanups, for edge (3, 5)
4958 : would be:
4959 :
4960 : <bb 3>: <bb 3>:
4961 : t_9 = a < b; t_9 = a < b;
4962 : goto <bb 5>; if (t_9 != 0)
4963 :
4964 : <bb 4>: -> <bb 4>:
4965 : t_6 = c < d; t_6 = c < d;
4966 : goto <bb 5>; goto <bb 5>;
4967 :
4968 : <bb 5>: <bb 5>:
4969 : # t_1 = PHI <t_9(3), t_6(4)> # t_1 = PHI <t_6(4)>
4970 : if (t_1 != 0) if (t_1 != 0)
4971 :
4972 : Return TRUE if the replication was performed. */
4973 :
4974 : static bool
4975 51110 : replicate_cond_into_pred (edge e)
4976 : {
4977 51110 : basic_block bb = e->dest;
4978 :
4979 51110 : if (!can_duplicate_block_on_edge_p (e))
4980 : return false;
4981 :
4982 51110 : if (dump_file && (dump_flags & TDF_DETAILS))
4983 2 : fprintf (dump_file,
4984 : "replicating conditional in bb%d into predecessor bb%d\n",
4985 2 : bb->index, e->src->index);
4986 :
4987 51110 : basic_block copy = duplicate_block (bb, e, e->src);
4988 51110 : flush_pending_stmts (e);
4989 51110 : add_phi_args_after_copy (©, 1, NULL);
4990 51110 : return true;
4991 : }
4992 :
4993 : /* Replicate conditionals over a PHI of comparisons into the
4994 : qualifying predecessors of every join block in the function, so
4995 : each arm branches directly on its own comparison instead of merging
4996 : into a boolean that is tested again:
4997 :
4998 : <bb 3>: <bb 3>:
4999 : t_9 = a < b; t_9 = a < b;
5000 : goto <bb 5>; if (t_9 != 0)
5001 :
5002 : <bb 4>: -> <bb 4>:
5003 : t_6 = c < d; t_6 = c < d;
5004 : goto <bb 5>; if (t_6 != 0)
5005 :
5006 : <bb 5>:
5007 : # t_1 = PHI <t_9(3), t_6(4)>
5008 : if (t_1 != 0)
5009 : */
5010 :
5011 : static bool
5012 5770587 : replicate_conds_over_phis (void)
5013 : {
5014 5770587 : bool cfgchanged = false;
5015 5770587 : basic_block bb;
5016 :
5017 5770587 : initialize_original_copy_tables ();
5018 50460736 : FOR_EACH_BB_FN (bb, cfun)
5019 : {
5020 44690149 : gcond *cond;
5021 44690149 : gphi *phi;
5022 : /* Never duplicate loop headers. */
5023 89145121 : if (bb->loop_father->header == bb
5024 41971769 : || EDGE_COUNT (bb->preds) < 2
5025 52505156 : || !cond_on_phi_p (bb, &cond, &phi))
5026 44454972 : continue;
5027 :
5028 235177 : edge e;
5029 235177 : edge_iterator ei = ei_start (bb->preds);
5030 764735 : while ((e = ei_safe_edge (ei)))
5031 : {
5032 529558 : if (phi_arg_from_cmp_p (phi, e)
5033 529558 : && replicate_cond_into_pred (e))
5034 : cfgchanged = true;
5035 : else
5036 478448 : ei_next (&ei);
5037 : }
5038 : }
5039 5770587 : free_original_copy_tables ();
5040 :
5041 : /* Removing an entry of an irreducible region can make it reducible, creating
5042 : a new loop. */
5043 5770587 : if (cfgchanged)
5044 25472 : loops_state_set (LOOPS_NEED_FIXUP);
5045 :
5046 5770587 : return cfgchanged;
5047 : }
5048 :
5049 : namespace {
5050 :
5051 : const pass_data pass_data_phiopt =
5052 : {
5053 : GIMPLE_PASS, /* type */
5054 : "phiopt", /* name */
5055 : OPTGROUP_NONE, /* optinfo_flags */
5056 : TV_TREE_PHIOPT, /* tv_id */
5057 : ( PROP_cfg | PROP_ssa ), /* properties_required */
5058 : 0, /* properties_provided */
5059 : 0, /* properties_destroyed */
5060 : 0, /* todo_flags_start */
5061 : 0, /* todo_flags_finish */
5062 : };
5063 :
5064 : class pass_phiopt : public gimple_opt_pass
5065 : {
5066 : public:
5067 1178144 : pass_phiopt (gcc::context *ctxt)
5068 2356288 : : gimple_opt_pass (pass_data_phiopt, ctxt), early_p (false)
5069 : {}
5070 :
5071 : /* opt_pass methods: */
5072 883608 : opt_pass * clone () final override { return new pass_phiopt (m_ctxt); }
5073 1178144 : void set_pass_param (unsigned n, bool param) final override
5074 : {
5075 1178144 : gcc_assert (n == 0);
5076 1178144 : early_p = param;
5077 1178144 : }
5078 5773958 : bool gate (function *) final override { return flag_ssa_phiopt; }
5079 : unsigned int execute (function *) final override;
5080 :
5081 : private:
5082 : bool early_p;
5083 : }; // class pass_phiopt
5084 :
5085 : } // anon namespace
5086 :
5087 : gimple_opt_pass *
5088 294536 : make_pass_phiopt (gcc::context *ctxt)
5089 : {
5090 294536 : return new pass_phiopt (ctxt);
5091 : }
5092 :
5093 : unsigned int
5094 5770587 : pass_phiopt::execute (function *)
5095 : {
5096 5770587 : bool do_hoist_loads = !early_p ? gate_hoist_loads () : false;
5097 5770587 : bool cfgchanged = false;
5098 5770587 : bool need_loop_finalize = false;
5099 :
5100 5770587 : if (!early_p
5101 3204175 : && !fold_before_rtl_expansion_p ()
5102 2136567 : && (flag_tree_loop_vectorize
5103 272422 : || cfun->has_force_vectorize_loops)
5104 9506877 : && number_of_loops (cfun) > 1)
5105 : {
5106 425974 : loop_optimizer_init (LOOPS_NORMAL);
5107 425974 : scev_initialize ();
5108 425974 : need_loop_finalize = true;
5109 : }
5110 :
5111 5770587 : calculate_dominance_info (CDI_DOMINATORS);
5112 5770587 : mark_ssa_maybe_undefs ();
5113 :
5114 9331709 : auto phiopt_exec = [&] (basic_block bb, basic_block bb1,
5115 : basic_block bb2, edge e1, edge e2,
5116 : bool diamond_p, gcond *cond_stmt)
5117 : {
5118 3561122 : if (diamond_p)
5119 : {
5120 1138818 : basic_block bb3 = e1->dest;
5121 :
5122 1138818 : if (!single_pred_p (bb1)
5123 2216941 : || !single_pred_p (bb2))
5124 3561122 : return;
5125 :
5126 1015434 : if (do_hoist_loads
5127 797010 : && !FLOAT_TYPE_P (TREE_TYPE (gimple_cond_lhs (cond_stmt)))
5128 788865 : && EDGE_COUNT (bb->succs) == 2
5129 788865 : && EDGE_COUNT (bb3->preds) == 2
5130 : /* If one edge or the other is dominant, a conditional move
5131 : is likely to perform worse than the well-predicted branch. */
5132 609638 : && !predictable_edge_p (EDGE_SUCC (bb, 0))
5133 1620477 : && !predictable_edge_p (EDGE_SUCC (bb, 1)))
5134 605043 : hoist_adjacent_loads (bb, bb1, bb2, bb3);
5135 : }
5136 :
5137 1015434 : gimple_stmt_iterator gsi;
5138 :
5139 : /* Check that we're looking for nested phis. */
5140 1015434 : basic_block merge = diamond_p ? EDGE_SUCC (bb2, 0)->dest : bb2;
5141 :
5142 : /* Factor out operations from the phi if possible. */
5143 3437738 : if (EDGE_COUNT (merge->preds) == 2
5144 3437738 : && !optimize_debug && factor_out_all (e1, e2, merge, cond_stmt, diamond_p, early_p))
5145 43113 : cfgchanged = true;
5146 :
5147 3437738 : gimple_seq phis = phi_nodes (merge);
5148 :
5149 3437738 : if (gimple_seq_empty_p (phis))
5150 : return;
5151 :
5152 : /* Value replacement can work with more than one PHI
5153 : so try that first. */
5154 3423459 : if (!early_p && !diamond_p)
5155 4296919 : for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
5156 : {
5157 2506591 : gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
5158 2506591 : tree arg0 = gimple_phi_arg_def (phi, e1->dest_idx);
5159 2506591 : tree arg1 = gimple_phi_arg_def (phi, e2->dest_idx);
5160 2506591 : if (value_replacement (bb, bb1, e1, e2, phi, arg0, arg1) == 2)
5161 : {
5162 2028 : cfgchanged = true;
5163 2028 : return;
5164 : }
5165 : }
5166 :
5167 3421431 : gphi *phi = single_non_singleton_phi_for_edges (phis, e1, e2);
5168 3421431 : if (!phi)
5169 : return;
5170 :
5171 862787 : tree arg0 = gimple_phi_arg_def (phi, e1->dest_idx);
5172 862787 : tree arg1 = gimple_phi_arg_def (phi, e2->dest_idx);
5173 :
5174 : /* Something is wrong if we cannot find the arguments in the PHI
5175 : node. */
5176 862787 : gcc_assert (arg0 != NULL_TREE && arg1 != NULL_TREE);
5177 :
5178 :
5179 : /* Do the replacement of conditional if it can be done. */
5180 862787 : if (match_simplify_replacement (bb, bb1, bb2, e1, e2, phi,
5181 : arg0, arg1, early_p, diamond_p))
5182 97195 : cfgchanged = true;
5183 765592 : else if (comparison_combine (bb, bb1, bb2, e1, e2, phi,
5184 : arg0, arg1, diamond_p))
5185 16 : cfgchanged = true;
5186 765576 : else if (!early_p
5187 501964 : && !diamond_p
5188 469106 : && single_pred_p (bb1)
5189 1213896 : && cond_removal_in_builtin_zero_pattern (bb, bb1, e1, e2,
5190 : phi, arg0, arg1))
5191 13 : cfgchanged = true;
5192 765563 : else if (single_pred_p (bb1)
5193 713979 : && !diamond_p
5194 1416714 : && spaceship_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
5195 2362 : cfgchanged = true;
5196 5770587 : };
5197 :
5198 5770587 : execute_over_cond_phis (phiopt_exec);
5199 :
5200 5770587 : if (need_loop_finalize)
5201 : {
5202 425974 : loop_optimizer_finalize ();
5203 425974 : scev_finalize ();
5204 : }
5205 5770587 : if (replicate_conds_over_phis ())
5206 : {
5207 25472 : free_dominance_info (CDI_DOMINATORS);
5208 25472 : return TODO_cleanup_cfg | TODO_update_ssa;
5209 : }
5210 :
5211 5745115 : if (cfgchanged)
5212 86269 : return TODO_cleanup_cfg;
5213 : return 0;
5214 : }
5215 :
5216 : /* This pass tries to transform conditional stores into unconditional
5217 : ones, enabling further simplifications with the simpler then and else
5218 : blocks. In particular it replaces this:
5219 :
5220 : bb0:
5221 : if (cond) goto bb2; else goto bb1;
5222 : bb1:
5223 : *p = RHS;
5224 : bb2:
5225 :
5226 : with
5227 :
5228 : bb0:
5229 : if (cond) goto bb1; else goto bb2;
5230 : bb1:
5231 : condtmp' = *p;
5232 : bb2:
5233 : condtmp = PHI <RHS, condtmp'>
5234 : *p = condtmp;
5235 :
5236 : This transformation can only be done under several constraints,
5237 : documented below. It also replaces:
5238 :
5239 : bb0:
5240 : if (cond) goto bb2; else goto bb1;
5241 : bb1:
5242 : *p = RHS1;
5243 : goto bb3;
5244 : bb2:
5245 : *p = RHS2;
5246 : bb3:
5247 :
5248 : with
5249 :
5250 : bb0:
5251 : if (cond) goto bb3; else goto bb1;
5252 : bb1:
5253 : bb3:
5254 : condtmp = PHI <RHS1, RHS2>
5255 : *p = condtmp; */
5256 :
5257 : namespace {
5258 :
5259 : const pass_data pass_data_cselim =
5260 : {
5261 : GIMPLE_PASS, /* type */
5262 : "cselim", /* name */
5263 : OPTGROUP_NONE, /* optinfo_flags */
5264 : TV_TREE_PHIOPT, /* tv_id */
5265 : ( PROP_cfg | PROP_ssa ), /* properties_required */
5266 : 0, /* properties_provided */
5267 : 0, /* properties_destroyed */
5268 : 0, /* todo_flags_start */
5269 : 0, /* todo_flags_finish */
5270 : };
5271 :
5272 : class pass_cselim : public gimple_opt_pass
5273 : {
5274 : public:
5275 294536 : pass_cselim (gcc::context *ctxt)
5276 589072 : : gimple_opt_pass (pass_data_cselim, ctxt)
5277 : {}
5278 :
5279 : /* opt_pass methods: */
5280 1068219 : bool gate (function *) final override { return flag_tree_cselim; }
5281 : unsigned int execute (function *) final override;
5282 :
5283 : }; // class pass_cselim
5284 :
5285 : } // anon namespace
5286 :
5287 : gimple_opt_pass *
5288 294536 : make_pass_cselim (gcc::context *ctxt)
5289 : {
5290 294536 : return new pass_cselim (ctxt);
5291 : }
5292 :
5293 : unsigned int
5294 1068089 : pass_cselim::execute (function *)
5295 : {
5296 1068089 : bool cfgchanged = false;
5297 1068089 : hash_set<tree> *nontrap = 0;
5298 1068089 : unsigned todo = 0;
5299 :
5300 : /* ??? We are not interested in loop related info, but the following
5301 : will create it, ICEing as we didn't init loops with pre-headers.
5302 : An interfacing issue of find_data_references_in_bb. */
5303 1068089 : loop_optimizer_init (LOOPS_NORMAL);
5304 1068089 : scev_initialize ();
5305 :
5306 1068089 : calculate_dominance_info (CDI_DOMINATORS);
5307 :
5308 : /* Calculate the set of non-trapping memory accesses. */
5309 1068089 : nontrap = get_non_trapping ();
5310 :
5311 2006986 : auto cselim_exec = [&] (basic_block bb, basic_block bb1,
5312 : basic_block bb2, edge e1, edge e2,
5313 : bool diamond_p, gcond *)
5314 : {
5315 938897 : if (diamond_p)
5316 : {
5317 328877 : basic_block bb3 = e1->dest;
5318 :
5319 : /* Only handle sinking of store from 2 bbs only,
5320 : The middle bbs don't need to come from the
5321 : if always since we are sinking rather than
5322 : hoisting. */
5323 328877 : if (EDGE_COUNT (bb3->preds) != 2)
5324 : return;
5325 242110 : if (cond_if_else_store_replacement (bb1, bb2, bb3))
5326 789 : cfgchanged = true;
5327 : return;
5328 : }
5329 :
5330 : /* Also make sure that bb1 only have one predecessor and that it
5331 : is bb. */
5332 610020 : if (!single_pred_p (bb1)
5333 1171734 : || single_pred (bb1) != bb)
5334 : return;
5335 :
5336 : /* bb1 is the middle block, bb2 the join block, bb the split block,
5337 : e1 the fallthrough edge from bb1 to bb2. We can't do the
5338 : optimization if the join block has more than two predecessors. */
5339 561714 : if (EDGE_COUNT (bb2->preds) > 2)
5340 : return;
5341 :
5342 434340 : if (cond_store_replacement_limited (bb1, bb2, bb, e1, e2, true))
5343 : {
5344 969 : cfgchanged = true;
5345 969 : return;
5346 : }
5347 433371 : gimple *assign = cselim_candidate (bb1, bb2, e1);
5348 433371 : if (cond_store_replacement (bb1, bb2, e1, e2, assign, nontrap))
5349 179 : cfgchanged = true;
5350 1068089 : };
5351 :
5352 1068089 : execute_over_cond_phis (cselim_exec);
5353 :
5354 2136178 : delete nontrap;
5355 : /* If the CFG has changed, we should cleanup the CFG. */
5356 1068089 : if (cfgchanged)
5357 : {
5358 1427 : gsi_commit_edge_inserts ();
5359 1427 : todo = TODO_cleanup_cfg;
5360 : }
5361 1068089 : scev_finalize ();
5362 1068089 : loop_optimizer_finalize ();
5363 1068089 : return todo;
5364 : }
|