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 "gimplify.h"
39 : #include "gimple-iterator.h"
40 : #include "gimplify-me.h"
41 : #include "tree-cfg.h"
42 : #include "tree-dfa.h"
43 : #include "domwalk.h"
44 : #include "cfgloop.h"
45 : #include "tree-data-ref.h"
46 : #include "tree-scalar-evolution.h"
47 : #include "tree-inline.h"
48 : #include "case-cfn-macros.h"
49 : #include "tree-eh.h"
50 : #include "gimple-fold.h"
51 : #include "internal-fn.h"
52 : #include "gimple-range.h"
53 : #include "gimple-match.h"
54 : #include "dbgcnt.h"
55 : #include "tree-ssa-propagate.h"
56 : #include "tree-ssa-dce.h"
57 : #include "tree-ssa-loop-niter.h"
58 : #include "gimple-predict.h"
59 :
60 : /* Return the singleton PHI in the SEQ of PHIs for edges E0 and E1. */
61 :
62 : static gphi *
63 3472053 : single_non_singleton_phi_for_edges (gimple_seq seq, edge e0, edge e1)
64 : {
65 3472053 : gimple_stmt_iterator i;
66 3472053 : gphi *phi = NULL;
67 5159673 : for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
68 : {
69 4231377 : gphi *p = as_a <gphi *> (gsi_stmt (i));
70 : /* If the PHI arguments are equal then we can skip this PHI. */
71 4231377 : if (operand_equal_for_phi_arg_p (gimple_phi_arg_def (p, e0->dest_idx),
72 4231377 : gimple_phi_arg_def (p, e1->dest_idx)))
73 257433 : continue;
74 :
75 : /* Punt on virtual phis with different arguments from the edges. */
76 7947888 : 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 1696961 : 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 89333 : 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 89333 : basic_block bb = gimple_bb (phi);
99 89333 : gimple_stmt_iterator gsi;
100 89333 : tree phi_result = gimple_phi_result (phi);
101 89333 : 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 assignement 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 89333 : if (TREE_CODE (new_tree) == SSA_NAME
121 89309 : && EDGE_COUNT (gimple_bb (phi)->preds) == 2
122 59304 : && INTEGRAL_TYPE_P (TREE_TYPE (phi_result))
123 54443 : && !SSA_NAME_RANGE_INFO (new_tree)
124 54361 : && SSA_NAME_RANGE_INFO (phi_result)
125 32961 : && gimple_bb (SSA_NAME_DEF_STMT (new_tree)) == cond_block
126 122294 : && dbg_cnt (phiopt_edge_range))
127 32961 : duplicate_ssa_name_range_info (new_tree, phi_result);
128 :
129 : /* Change the PHI argument to new. */
130 89333 : SET_USE (PHI_ARG_DEF_PTR (phi, e->dest_idx), new_tree);
131 :
132 : /* Remove the empty basic block. */
133 89333 : edge edge_to_remove = NULL, keep_edge = NULL;
134 89333 : if (EDGE_SUCC (cond_block, 0)->dest == bb)
135 : {
136 36296 : edge_to_remove = EDGE_SUCC (cond_block, 1);
137 36296 : keep_edge = EDGE_SUCC (cond_block, 0);
138 : }
139 53037 : 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 743 : else if ((keep_edge = find_edge (cond_block, e->src)))
145 : {
146 743 : basic_block bb1 = EDGE_SUCC (cond_block, 0)->dest;
147 743 : basic_block bb2 = EDGE_SUCC (cond_block, 1)->dest;
148 1486 : if (single_pred_p (bb1) && single_pred_p (bb2)
149 90819 : && single_succ_p (bb1) && single_succ_p (bb2)
150 1486 : && 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 89333 : if (loop_exits_from_bb_p (cond_block->loop_father, cond_block))
159 : {
160 1 : auto loop = cond_block->loop_father;
161 1 : free_numbers_of_iterations_estimates (loop);
162 1 : loop->any_upper_bound = false;
163 1 : loop->any_likely_upper_bound = false;
164 : }
165 :
166 89333 : if (edge_to_remove && EDGE_COUNT (edge_to_remove->dest->preds) == 1)
167 : {
168 77873 : e->flags |= EDGE_FALLTHRU;
169 77873 : e->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
170 77873 : e->probability = profile_probability::always ();
171 77873 : delete_basic_block (edge_to_remove->dest);
172 :
173 : /* Eliminate the COND_EXPR at the end of COND_BLOCK. */
174 77873 : gsi = gsi_last_bb (cond_block);
175 77873 : gsi_remove (&gsi, true);
176 : }
177 11460 : else if (deleteboth)
178 : {
179 743 : basic_block bb1 = EDGE_SUCC (cond_block, 0)->dest;
180 743 : basic_block bb2 = EDGE_SUCC (cond_block, 1)->dest;
181 :
182 743 : edge newedge = redirect_edge_and_branch (keep_edge, bb);
183 :
184 : /* The new edge should be the same. */
185 743 : gcc_assert (newedge == keep_edge);
186 :
187 743 : keep_edge->flags |= EDGE_FALLTHRU;
188 743 : keep_edge->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
189 743 : keep_edge->probability = profile_probability::always ();
190 :
191 : /* Copy the edge's phi entry from the old one. */
192 743 : copy_phi_arg_into_existing_phi (e, keep_edge);
193 :
194 : /* Delete the old 2 empty basic blocks */
195 743 : delete_basic_block (bb1);
196 743 : delete_basic_block (bb2);
197 :
198 : /* Eliminate the COND_EXPR at the end of COND_BLOCK. */
199 743 : gsi = gsi_last_bb (cond_block);
200 743 : 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 21434 : gcond *cond = as_a <gcond *> (*gsi_last_bb (cond_block));
208 10717 : if (keep_edge->flags & EDGE_FALSE_VALUE)
209 7476 : gimple_cond_make_false (cond);
210 3241 : else if (keep_edge->flags & EDGE_TRUE_VALUE)
211 3241 : gimple_cond_make_true (cond);
212 : }
213 :
214 89333 : if (dce_ssa_names)
215 87377 : simple_dce_from_worklist (dce_ssa_names);
216 :
217 89333 : statistics_counter_event (cfun, "Replace PHI with variable", 1);
218 :
219 89333 : if (dump_file && (dump_flags & TDF_DETAILS))
220 16 : 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 89333 : }
225 :
226 : /* Returns true if the ARG used from DEF_STMT is profitable to move
227 : to a PHI node of the basic block MERGE where the new statement
228 : will be located. */
229 : static bool
230 101357 : is_factor_profitable (gimple *def_stmt, basic_block merge, tree arg)
231 : {
232 : /* The defining statement should be conditional. */
233 101357 : if (dominated_by_p (CDI_DOMINATORS, merge,
234 101357 : gimple_bb (def_stmt)))
235 : return false;
236 :
237 : /* If the arg is invariant, then there is
238 : no extending of the live range. */
239 99323 : if (is_gimple_min_invariant (arg))
240 : return true;
241 :
242 : /* Otherwise, the arg needs to be a ssa name. */
243 95132 : if (TREE_CODE (arg) != SSA_NAME)
244 : return false;
245 :
246 : /* We should not increase the live range of arg
247 : across too many statements or calls. */
248 95132 : gimple_stmt_iterator gsi = gsi_for_stmt (def_stmt);
249 95132 : gsi_next_nondebug (&gsi);
250 :
251 : /* Skip past nops and predicates. */
252 190896 : while (!gsi_end_p (gsi)
253 95764 : && (gimple_code (gsi_stmt (gsi)) == GIMPLE_NOP
254 11573 : || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
255 632 : gsi_next_nondebug (&gsi);
256 :
257 : /* If the defining statement is at the end of the bb, then it is
258 : always profitable to be to move. */
259 95132 : if (gsi_end_p (gsi))
260 : return true;
261 :
262 : /* Check if the uses of arg is dominated by merge block, this is a quick and
263 : rough estimate if arg is still alive at the merge bb. */
264 : /* FIXME: extend to a more complete live range detection. */
265 10941 : use_operand_p use_p;
266 10941 : imm_use_iterator iter;
267 37026 : FOR_EACH_IMM_USE_FAST (use_p, iter, arg)
268 : {
269 17320 : gimple *use_stmt = USE_STMT (use_p);
270 17320 : basic_block use_bb = gimple_bb (use_stmt);
271 17320 : if (dominated_by_p (CDI_DOMINATORS, merge, use_bb))
272 2176 : return true;
273 2176 : }
274 :
275 : /* If there are a few (non-call/asm) statements between
276 : the old defining statement and end of the bb, then
277 : the live range of new arg does not increase enough. */
278 8765 : int max_statements = param_phiopt_factor_max_stmts_live;
279 :
280 24450 : while (!gsi_end_p (gsi))
281 : {
282 17017 : gimple *stmt = gsi_stmt (gsi);
283 17017 : auto gcode = gimple_code (stmt);
284 : /* Skip over NOPs and predicts. */
285 17017 : if (gcode == GIMPLE_NOP
286 17017 : || gcode == GIMPLE_PREDICT)
287 : {
288 0 : gsi_next_nondebug (&gsi);
289 0 : continue;
290 : }
291 : /* Non-assigns will extend the live range too much. */
292 17017 : if (gcode != GIMPLE_ASSIGN)
293 : return false;
294 16804 : max_statements --;
295 16804 : if (max_statements == 0)
296 : return false;
297 15685 : gsi_next_nondebug (&gsi);
298 : }
299 : return true;
300 : }
301 :
302 : /* PR66726: Factor operations out of COND_EXPR. If the arguments of the PHI
303 : stmt are Unary operator, factor out the operation and perform the operation
304 : to the result of PHI stmt. COND_STMT is the controlling predicate.
305 : Return true if the operation was factored out; false otherwise. */
306 :
307 : static bool
308 2997734 : factor_out_conditional_operation (edge e0, edge e1, basic_block merge,
309 : gphi *phi, gimple *cond_stmt)
310 : {
311 2997734 : gimple *arg0_def_stmt = NULL, *arg1_def_stmt = NULL;
312 2997734 : tree temp, result;
313 2997734 : gphi *newphi;
314 2997734 : gimple_stmt_iterator gsi, gsi_for_def;
315 2997734 : location_t locus = gimple_location (phi);
316 2997734 : gimple_match_op arg0_op, arg1_op;
317 :
318 : /* We should only get here if the phi had two arguments. */
319 2997734 : gcc_assert (gimple_phi_num_args (phi) == 2);
320 :
321 : /* Virtual operands are never handled. */
322 5995468 : if (virtual_operand_p (gimple_phi_result (phi)))
323 : return false;
324 :
325 1299661 : tree arg0 = gimple_phi_arg_def (phi, e0->dest_idx);
326 1299661 : tree arg1 = gimple_phi_arg_def (phi, e1->dest_idx);
327 1299661 : location_t narg0_loc = gimple_location (phi);
328 1299661 : location_t narg1_loc = gimple_location (phi);
329 1299661 : if (gimple_phi_arg_location (phi, e0->dest_idx) != UNKNOWN_LOCATION)
330 1104652 : narg0_loc = gimple_phi_arg_location (phi, e0->dest_idx);
331 1299661 : if (gimple_phi_arg_location (phi, e1->dest_idx) != UNKNOWN_LOCATION)
332 927654 : narg1_loc = gimple_phi_arg_location (phi, e1->dest_idx);
333 :
334 1299661 : gcc_assert (arg0 != NULL_TREE && arg1 != NULL_TREE);
335 :
336 : /* Arugments that are the same don't have anything to be
337 : done to them. */
338 1299661 : if (operand_equal_for_phi_arg_p (arg0, arg1))
339 : return false;
340 :
341 : /* First canonicalize to simplify tests. */
342 1297989 : if (TREE_CODE (arg0) != SSA_NAME)
343 : {
344 248078 : std::swap (arg0, arg1);
345 248078 : std::swap (e0, e1);
346 : }
347 :
348 1297989 : if (TREE_CODE (arg0) != SSA_NAME
349 1178730 : || (TREE_CODE (arg1) != SSA_NAME
350 499491 : && TREE_CODE (arg1) != INTEGER_CST))
351 : return false;
352 :
353 : /* Check if arg0 is an SSA_NAME and the stmt which defines arg0 is
354 : an unary operation. */
355 1146475 : arg0_def_stmt = SSA_NAME_DEF_STMT (arg0);
356 1146475 : if (!gimple_extract_op (arg0_def_stmt, &arg0_op))
357 : return false;
358 :
359 : /* Check to make sure none of the operands are in abnormal phis. */
360 578860 : if (arg0_op.operands_occurs_in_abnormal_phi ())
361 : return false;
362 :
363 : /* Currently just support one operand expressions. */
364 578860 : if (arg0_op.num_ops != 1)
365 : return false;
366 :
367 118208 : tree new_arg0 = arg0_op.ops[0];
368 118208 : tree new_arg1;
369 :
370 : /* If arg0 have > 1 use, then this transformation actually increases
371 : the number of expressions evaluated at runtime. */
372 118208 : if (!has_single_use (arg0))
373 : return false;
374 96692 : if (!is_factor_profitable (arg0_def_stmt, merge, new_arg0))
375 : return false;
376 93835 : if (gimple_has_location (arg0_def_stmt))
377 91523 : narg0_loc = gimple_location (arg0_def_stmt);
378 :
379 93835 : if (TREE_CODE (arg1) == SSA_NAME)
380 : {
381 : /* Check if arg1 is an SSA_NAME. */
382 47271 : arg1_def_stmt = SSA_NAME_DEF_STMT (arg1);
383 47271 : if (!gimple_extract_op (arg1_def_stmt, &arg1_op))
384 : return false;
385 31572 : if (arg1_op.code != arg0_op.code)
386 : return false;
387 7502 : if (arg1_op.num_ops != arg0_op.num_ops)
388 : return false;
389 7502 : if (arg1_op.operands_occurs_in_abnormal_phi ())
390 : return false;
391 :
392 : /* If arg1 have > 1 use, then this transformation actually increases
393 : the number of expressions evaluated at runtime. */
394 7502 : if (!has_single_use (arg1))
395 : return false;
396 :
397 4665 : new_arg1 = arg1_op.ops[0];
398 4665 : if (!is_factor_profitable (arg1_def_stmt, merge, new_arg1))
399 : return false;
400 4156 : if (gimple_has_location (arg1_def_stmt))
401 4059 : narg1_loc = gimple_location (arg1_def_stmt);
402 :
403 : /* Chose the location for the new statement if the phi location is unknown. */
404 4156 : if (locus == UNKNOWN_LOCATION)
405 : {
406 4156 : if (narg0_loc == UNKNOWN_LOCATION
407 4156 : && narg1_loc != UNKNOWN_LOCATION)
408 : locus = narg1_loc;
409 4156 : else if (narg0_loc != UNKNOWN_LOCATION
410 4156 : && narg1_loc == UNKNOWN_LOCATION)
411 46 : locus = narg0_loc;
412 : }
413 : }
414 : else
415 : {
416 : /* For constants only handle if the phi was the only one. */
417 46564 : if (single_non_singleton_phi_for_edges (phi_nodes (merge), e0, e1) == NULL)
418 : return false;
419 : /* TODO: handle more than just casts here. */
420 34899 : if (!gimple_assign_cast_p (arg0_def_stmt))
421 : return false;
422 :
423 : /* arg0_def_stmt should be conditional. */
424 28380 : if (dominated_by_p (CDI_DOMINATORS, gimple_bb (phi), gimple_bb (arg0_def_stmt)))
425 : return false;
426 :
427 : /* If arg1 is an INTEGER_CST, fold it to new type if it fits, or else
428 : if the bits will not be modified during the conversion, except for
429 : boolean types whose precision is not 1 (see int_fits_type_p). */
430 56750 : if (!INTEGRAL_TYPE_P (TREE_TYPE (new_arg0))
431 56490 : || !(int_fits_type_p (arg1, TREE_TYPE (new_arg0))
432 1683 : || (TYPE_PRECISION (TREE_TYPE (new_arg0))
433 1683 : == TYPE_PRECISION (TREE_TYPE (arg1))
434 1112 : && (TREE_CODE (TREE_TYPE (new_arg0)) != BOOLEAN_TYPE
435 0 : || TYPE_PRECISION (TREE_TYPE (new_arg0)) == 1))))
436 : return false;
437 :
438 : /* For the INTEGER_CST case, we are just moving the
439 : conversion from one place to another, which can often
440 : hurt as the conversion moves further away from the
441 : statement that computes the value. So, perform this
442 : only if new_arg0 is an operand of COND_STMT, or
443 : if arg0_def_stmt is the only non-debug stmt in
444 : its basic block, because then it is possible this
445 : could enable further optimizations (minmax replacement
446 : etc.). See PR71016.
447 : Note no-op conversions don't have this issue as
448 : it will not generate any zero/sign extend in that case. */
449 27549 : if ((TYPE_PRECISION (TREE_TYPE (new_arg0))
450 27549 : != TYPE_PRECISION (TREE_TYPE (arg1)))
451 12182 : && new_arg0 != gimple_cond_lhs (cond_stmt)
452 11464 : && new_arg0 != gimple_cond_rhs (cond_stmt)
453 39007 : && gimple_bb (arg0_def_stmt) == e0->src)
454 : {
455 11458 : gsi = gsi_for_stmt (arg0_def_stmt);
456 11458 : gsi_prev_nondebug (&gsi);
457 : /* Ignore nops, predicates and labels. */
458 22936 : while (!gsi_end_p (gsi)
459 11478 : && (gimple_code (gsi_stmt (gsi)) == GIMPLE_NOP
460 : || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT
461 : || gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL))
462 20 : gsi_prev_nondebug (&gsi);
463 :
464 11458 : if (!gsi_end_p (gsi))
465 : {
466 8093 : gimple *stmt = gsi_stmt (gsi);
467 2982272 : if (gassign *assign = dyn_cast <gassign *> (stmt))
468 : {
469 7694 : tree lhs = gimple_assign_lhs (assign);
470 7694 : tree lhst = TREE_TYPE (lhs);
471 7694 : enum tree_code ass_code
472 7694 : = gimple_assign_rhs_code (assign);
473 7694 : if (ass_code != MAX_EXPR && ass_code != MIN_EXPR
474 : /* Conversions from boolean like types is ok
475 : as `a?1:b` and `a?0:b` will always simplify
476 : to `a & b` or `a | b`.
477 : See PR 116890. */
478 7694 : && !(INTEGRAL_TYPE_P (lhst)
479 7269 : && TYPE_UNSIGNED (lhst)
480 5131 : && TYPE_PRECISION (lhst) == 1))
481 : return false;
482 4445 : if (lhs != gimple_assign_rhs1 (arg0_def_stmt))
483 : return false;
484 4403 : gsi_prev_nondebug (&gsi);
485 4403 : if (!gsi_end_p (gsi))
486 : return false;
487 : }
488 : else
489 : return false;
490 : }
491 : }
492 19759 : new_arg1 = fold_convert (TREE_TYPE (new_arg0), arg1);
493 :
494 : /* Drop the overlow that fold_convert might add. */
495 19759 : if (TREE_OVERFLOW (new_arg1))
496 0 : new_arg1 = drop_tree_overflow (new_arg1);
497 :
498 : /* The locus of the new statement is arg0 defining statement. */
499 19759 : if (gimple_has_location (arg0_def_stmt))
500 19336 : locus = gimple_location (arg0_def_stmt);
501 : }
502 :
503 : /* If types of new_arg0 and new_arg1 are different bailout. */
504 23915 : if (!types_compatible_p (TREE_TYPE (new_arg0), TREE_TYPE (new_arg1)))
505 : return false;
506 :
507 : /* Create a new PHI stmt. */
508 23289 : result = gimple_phi_result (phi);
509 23289 : temp = make_ssa_name (TREE_TYPE (new_arg0), NULL);
510 :
511 23289 : gimple_match_op new_op = arg0_op;
512 :
513 : /* Create the operation stmt if possible and insert it. */
514 23289 : new_op.ops[0] = temp;
515 23289 : gimple_seq seq = NULL;
516 23289 : result = maybe_push_res_to_seq (&new_op, &seq, result);
517 :
518 : /* If we can't create the new statement, release the temp name
519 : and return back. */
520 23289 : if (!result)
521 : {
522 133 : release_ssa_name (temp);
523 133 : return false;
524 : }
525 :
526 23156 : if (locus != UNKNOWN_LOCATION)
527 19378 : annotate_all_with_location (seq, locus);
528 23156 : gsi = gsi_after_labels (gimple_bb (phi));
529 23156 : gsi_insert_seq_before (&gsi, seq, GSI_CONTINUE_LINKING);
530 :
531 23156 : newphi = create_phi_node (temp, gimple_bb (phi));
532 :
533 23156 : if (dump_file && (dump_flags & TDF_DETAILS))
534 : {
535 14 : fprintf (dump_file, "PHI ");
536 14 : print_generic_expr (dump_file, gimple_phi_result (phi));
537 14 : fprintf (dump_file,
538 : " changed to factor operation out from COND_EXPR.\n");
539 14 : fprintf (dump_file, "New stmt with OPERATION that defines ");
540 14 : print_generic_expr (dump_file, result);
541 14 : fprintf (dump_file, ".\n");
542 : }
543 :
544 : /* Remove the old operation(s) that has single use. */
545 23156 : gsi_for_def = gsi_for_stmt (arg0_def_stmt);
546 23156 : gsi_remove (&gsi_for_def, true);
547 23156 : release_defs (arg0_def_stmt);
548 :
549 23156 : if (arg1_def_stmt)
550 : {
551 3397 : gsi_for_def = gsi_for_stmt (arg1_def_stmt);
552 3397 : gsi_remove (&gsi_for_def, true);
553 3397 : release_defs (arg1_def_stmt);
554 : }
555 :
556 23156 : add_phi_arg (newphi, new_arg0, e0, narg0_loc);
557 23156 : add_phi_arg (newphi, new_arg1, e1, narg1_loc);
558 :
559 : /* Remove the original PHI stmt. */
560 23156 : gsi = gsi_for_stmt (phi);
561 23156 : gsi_remove (&gsi, true);
562 :
563 23156 : statistics_counter_event (cfun, "factored out operation", 1);
564 :
565 23156 : return true;
566 : }
567 :
568 :
569 : /* Return TRUE if SEQ/OP pair should be allowed during early phiopt.
570 : Currently this is to allow MIN/MAX and ABS/NEGATE and constants. */
571 : static bool
572 168030 : phiopt_early_allow (gimple_seq &seq, gimple_match_op &op)
573 : {
574 : /* Don't allow functions. */
575 168030 : if (!op.code.is_tree_code ())
576 : return false;
577 167981 : tree_code code = (tree_code)op.code;
578 :
579 : /* For non-empty sequence, only allow one statement
580 : a MIN/MAX and an original MIN/MAX. */
581 167981 : if (!gimple_seq_empty_p (seq))
582 : {
583 139462 : if (code == MIN_EXPR || code == MAX_EXPR)
584 : {
585 143794 : if (!gimple_seq_singleton_p (seq))
586 : return false;
587 :
588 11 : gimple *stmt = gimple_seq_first_stmt (seq);
589 : /* Only allow assignments. */
590 11 : if (!is_gimple_assign (stmt))
591 : return false;
592 11 : code = gimple_assign_rhs_code (stmt);
593 11 : return code == MIN_EXPR || code == MAX_EXPR;
594 : }
595 : return false;
596 : }
597 :
598 28519 : switch (code)
599 : {
600 : case MIN_EXPR:
601 : case MAX_EXPR:
602 : case ABS_EXPR:
603 : case ABSU_EXPR:
604 : case NEGATE_EXPR:
605 : case SSA_NAME:
606 : return true;
607 : case INTEGER_CST:
608 : case REAL_CST:
609 : case VECTOR_CST:
610 : case FIXED_CST:
611 : return true;
612 : default:
613 : return false;
614 : }
615 : }
616 :
617 : /* gimple_simplify_phiopt is like gimple_simplify but designed for PHIOPT.
618 : Return NULL if nothing can be simplified or the resulting simplified value
619 : with parts pushed if EARLY_P was true. Also rejects non allowed tree code
620 : if EARLY_P is set.
621 : Takes the comparison from COMP_STMT and two args, ARG0 and ARG1 and tries
622 : to simplify CMP ? ARG0 : ARG1.
623 : Also try to simplify (!CMP) ? ARG1 : ARG0 if the non-inverse failed. */
624 : static tree
625 514290 : gimple_simplify_phiopt (bool early_p, tree type, gimple *comp_stmt,
626 : tree arg0, tree arg1,
627 : gimple_seq *seq)
628 : {
629 514290 : gimple_seq seq1 = NULL;
630 514290 : enum tree_code comp_code = gimple_cond_code (comp_stmt);
631 514290 : location_t loc = gimple_location (comp_stmt);
632 514290 : tree cmp0 = gimple_cond_lhs (comp_stmt);
633 514290 : tree cmp1 = gimple_cond_rhs (comp_stmt);
634 : /* To handle special cases like floating point comparison, it is easier and
635 : less error-prone to build a tree and gimplify it on the fly though it is
636 : less efficient.
637 : Don't use fold_build2 here as that might create (bool)a instead of just
638 : "a != 0". */
639 514290 : tree cond = build2_loc (loc, comp_code, boolean_type_node,
640 : cmp0, cmp1);
641 :
642 514290 : if (dump_file && (dump_flags & TDF_FOLDING))
643 : {
644 1 : fprintf (dump_file, "\nphiopt match-simplify trying:\n\t");
645 1 : print_generic_expr (dump_file, cond);
646 1 : fprintf (dump_file, " ? ");
647 1 : print_generic_expr (dump_file, arg0);
648 1 : fprintf (dump_file, " : ");
649 1 : print_generic_expr (dump_file, arg1);
650 1 : fprintf (dump_file, "\n");
651 : }
652 :
653 514290 : gimple_match_op op (gimple_match_cond::UNCOND,
654 514290 : COND_EXPR, type, cond, arg0, arg1);
655 :
656 514290 : if (op.resimplify (&seq1, follow_all_ssa_edges))
657 : {
658 153059 : bool allowed = !early_p || phiopt_early_allow (seq1, op);
659 153059 : tree result = maybe_push_res_to_seq (&op, &seq1);
660 153059 : if (dump_file && (dump_flags & TDF_FOLDING))
661 : {
662 1 : fprintf (dump_file, "\nphiopt match-simplify back:\n");
663 1 : if (seq1)
664 0 : print_gimple_seq (dump_file, seq1, 0, TDF_VOPS|TDF_MEMSYMS);
665 1 : fprintf (dump_file, "result: ");
666 1 : if (result)
667 1 : print_generic_expr (dump_file, result);
668 : else
669 0 : fprintf (dump_file, " (none)");
670 1 : fprintf (dump_file, "\n");
671 1 : if (!allowed)
672 0 : fprintf (dump_file, "rejected because early\n");
673 : }
674 : /* Early we want only to allow some generated tree codes. */
675 153059 : if (allowed && result)
676 : {
677 80208 : if (loc != UNKNOWN_LOCATION)
678 79742 : annotate_all_with_location (seq1, loc);
679 80208 : gimple_seq_add_seq_without_update (seq, seq1);
680 80208 : return result;
681 : }
682 : }
683 434082 : gimple_seq_discard (seq1);
684 434082 : seq1 = NULL;
685 :
686 : /* Try the inverted comparison, that is !COMP ? ARG1 : ARG0. */
687 434082 : comp_code = invert_tree_comparison (comp_code, HONOR_NANS (cmp0));
688 :
689 434082 : if (comp_code == ERROR_MARK)
690 : return NULL;
691 :
692 420345 : cond = build2_loc (loc,
693 : comp_code, boolean_type_node,
694 : cmp0, cmp1);
695 :
696 420345 : if (dump_file && (dump_flags & TDF_FOLDING))
697 : {
698 0 : fprintf (dump_file, "\nphiopt match-simplify trying:\n\t");
699 0 : print_generic_expr (dump_file, cond);
700 0 : fprintf (dump_file, " ? ");
701 0 : print_generic_expr (dump_file, arg1);
702 0 : fprintf (dump_file, " : ");
703 0 : print_generic_expr (dump_file, arg0);
704 0 : fprintf (dump_file, "\n");
705 : }
706 :
707 420345 : gimple_match_op op1 (gimple_match_cond::UNCOND,
708 420345 : COND_EXPR, type, cond, arg1, arg0);
709 :
710 420345 : if (op1.resimplify (&seq1, follow_all_ssa_edges))
711 : {
712 74210 : bool allowed = !early_p || phiopt_early_allow (seq1, op1);
713 74210 : tree result = maybe_push_res_to_seq (&op1, &seq1);
714 74210 : if (dump_file && (dump_flags & TDF_FOLDING))
715 : {
716 0 : fprintf (dump_file, "\nphiopt match-simplify back:\n");
717 0 : if (seq1)
718 0 : print_gimple_seq (dump_file, seq1, 0, TDF_VOPS|TDF_MEMSYMS);
719 0 : fprintf (dump_file, "result: ");
720 0 : if (result)
721 0 : print_generic_expr (dump_file, result);
722 : else
723 0 : fprintf (dump_file, " (none)");
724 0 : fprintf (dump_file, "\n");
725 0 : if (!allowed)
726 0 : fprintf (dump_file, "rejected because early\n");
727 : }
728 : /* Early we want only to allow some generated tree codes. */
729 74210 : if (allowed && result)
730 : {
731 3236 : if (loc != UNKNOWN_LOCATION)
732 3236 : annotate_all_with_location (seq1, loc);
733 3236 : gimple_seq_add_seq_without_update (seq, seq1);
734 3236 : return result;
735 : }
736 : }
737 417109 : gimple_seq_discard (seq1);
738 :
739 417109 : return NULL;
740 : }
741 :
742 : /* empty_bb_or_one_feeding_into_p returns true if bb was empty basic block
743 : or it has one cheap preparation statement that feeds into the PHI
744 : statement and it sets STMT to that statement. */
745 : static bool
746 849075 : empty_bb_or_one_feeding_into_p (basic_block bb,
747 : gimple *phi,
748 : gimple *&stmt)
749 : {
750 849075 : stmt = nullptr;
751 849075 : gimple *stmt_to_move = nullptr;
752 849075 : tree lhs;
753 :
754 849075 : if (empty_block_p (bb))
755 : return true;
756 :
757 733529 : if (!single_pred_p (bb))
758 : return false;
759 :
760 : /* The middle bb cannot have phi nodes as we don't
761 : move those assignments yet. */
762 431604 : if (!gimple_seq_empty_p (phi_nodes (bb)))
763 : return false;
764 :
765 431578 : gimple_stmt_iterator gsi;
766 :
767 431578 : gsi = gsi_start_nondebug_after_labels_bb (bb);
768 866133 : while (!gsi_end_p (gsi))
769 : {
770 644767 : gimple *s = gsi_stmt (gsi);
771 644767 : gsi_next_nondebug (&gsi);
772 : /* Skip over Predict and nop statements. */
773 644767 : if (gimple_code (s) == GIMPLE_PREDICT
774 644767 : || gimple_code (s) == GIMPLE_NOP)
775 2977 : continue;
776 : /* If there is more one statement return false. */
777 641790 : if (stmt_to_move)
778 : return false;
779 : stmt_to_move = s;
780 : }
781 :
782 : /* The only statement here was a Predict or a nop statement
783 : so return true. */
784 221366 : if (!stmt_to_move)
785 : return true;
786 :
787 442732 : if (gimple_vuse (stmt_to_move))
788 : return false;
789 :
790 148503 : if (gimple_could_trap_p (stmt_to_move)
791 148503 : || gimple_has_side_effects (stmt_to_move))
792 5074 : return false;
793 :
794 143429 : ssa_op_iter it;
795 143429 : tree use;
796 321398 : FOR_EACH_SSA_TREE_OPERAND (use, stmt_to_move, it, SSA_OP_USE)
797 178603 : if (ssa_name_maybe_undef_p (use))
798 : return false;
799 :
800 : /* Allow assignments but allow some builtin/internal calls.
801 : As const calls don't match any of the above, yet they could
802 : still have some side-effects - they could contain
803 : gimple_could_trap_p statements, like floating point
804 : exceptions or integer division by zero. See PR70586.
805 : FIXME: perhaps gimple_has_side_effects or gimple_could_trap_p
806 : should handle this.
807 : Allow some known builtin/internal calls that are known not to
808 : trap: logical functions (e.g. bswap and bit counting). */
809 142795 : if (!is_gimple_assign (stmt_to_move))
810 : {
811 5123 : if (!is_gimple_call (stmt_to_move))
812 : return false;
813 4872 : combined_fn cfn = gimple_call_combined_fn (stmt_to_move);
814 4872 : switch (cfn)
815 : {
816 : default:
817 : return false;
818 3994 : case CFN_BUILT_IN_BSWAP16:
819 3994 : case CFN_BUILT_IN_BSWAP32:
820 3994 : case CFN_BUILT_IN_BSWAP64:
821 3994 : case CFN_BUILT_IN_BSWAP128:
822 3994 : CASE_CFN_FFS:
823 3994 : CASE_CFN_PARITY:
824 3994 : CASE_CFN_POPCOUNT:
825 3994 : CASE_CFN_CLZ:
826 3994 : CASE_CFN_CTZ:
827 3994 : case CFN_BUILT_IN_CLRSB:
828 3994 : case CFN_BUILT_IN_CLRSBL:
829 3994 : case CFN_BUILT_IN_CLRSBLL:
830 3994 : lhs = gimple_call_lhs (stmt_to_move);
831 3994 : break;
832 : }
833 : }
834 : else
835 137672 : lhs = gimple_assign_lhs (stmt_to_move);
836 :
837 141666 : gimple *use_stmt;
838 141666 : use_operand_p use_p;
839 :
840 : /* Allow only a statement which feeds into the other stmt. */
841 141666 : if (!lhs || TREE_CODE (lhs) != SSA_NAME
842 141666 : || !single_imm_use (lhs, &use_p, &use_stmt)
843 283327 : || use_stmt != phi)
844 5 : return false;
845 :
846 141661 : stmt = stmt_to_move;
847 141661 : return true;
848 : }
849 :
850 : /* Move STMT to before GSI and insert its defining
851 : name into INSERTED_EXPRS bitmap.
852 : Also rewrite its if it might be undefined when unconditionalized. */
853 : static void
854 174754 : move_stmt (gimple *stmt, gimple_stmt_iterator *gsi, auto_bitmap &inserted_exprs)
855 : {
856 174754 : if (!stmt)
857 169365 : return;
858 5389 : if (dump_file && (dump_flags & TDF_DETAILS))
859 : {
860 7 : fprintf (dump_file, "statement un-sinked:\n");
861 7 : print_gimple_stmt (dump_file, stmt, 0,
862 : TDF_VOPS|TDF_MEMSYMS);
863 : }
864 :
865 5389 : tree name = gimple_get_lhs (stmt);
866 : // Mark the name to be renamed if there is one.
867 5389 : bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (name));
868 5389 : gimple_stmt_iterator gsi1 = gsi_for_stmt (stmt);
869 5389 : gsi_move_before (&gsi1, gsi, GSI_NEW_STMT);
870 5389 : reset_flow_sensitive_info (name);
871 :
872 : /* Rewrite some code which might be undefined when
873 : unconditionalized. */
874 5389 : if (gimple_needing_rewrite_undefined (stmt))
875 1065 : rewrite_to_defined_unconditional (gsi);
876 : }
877 :
878 : /* RAII style class to temporarily remove flow sensitive
879 : from ssa names defined by a gimple statement. */
880 : class auto_flow_sensitive
881 : {
882 : public:
883 : auto_flow_sensitive (gimple *s);
884 : ~auto_flow_sensitive ();
885 : private:
886 : auto_vec<std::pair<tree, flow_sensitive_info_storage>, 2> stack;
887 : };
888 :
889 : /* Constructor for auto_flow_sensitive. Saves
890 : off the ssa names' flow sensitive information
891 : that was defined by gimple statement S and
892 : resets it to be non-flow based ones. */
893 :
894 1028580 : auto_flow_sensitive::auto_flow_sensitive (gimple *s)
895 : {
896 1028580 : if (!s)
897 893619 : return;
898 134961 : ssa_op_iter it;
899 134961 : tree def;
900 269922 : FOR_EACH_SSA_TREE_OPERAND (def, s, it, SSA_OP_DEF)
901 : {
902 134961 : flow_sensitive_info_storage storage;
903 134961 : storage.save_and_clear (def);
904 134961 : stack.safe_push (std::make_pair (def, storage));
905 : }
906 : }
907 :
908 : /* Deconstructor, restores the flow sensitive information
909 : for the SSA names that had been saved off. */
910 :
911 1028580 : auto_flow_sensitive::~auto_flow_sensitive ()
912 : {
913 3220701 : for (auto p : stack)
914 134961 : p.second.restore (p.first);
915 1028580 : }
916 :
917 : /* Returns true if BB contains an user provided predictor
918 : (PRED_HOT_LABEL/PRED_COLD_LABEL). */
919 :
920 : static bool
921 6179 : contains_hot_cold_predict (basic_block bb)
922 : {
923 6179 : gimple_stmt_iterator gsi;
924 6179 : gsi = gsi_start_nondebug_after_labels_bb (bb);
925 8648 : for (; !gsi_end_p (gsi); gsi_next_nondebug (&gsi))
926 : {
927 2470 : gimple *s = gsi_stmt (gsi);
928 2470 : if (gimple_code (s) != GIMPLE_PREDICT)
929 2 : continue;
930 2468 : auto predict = gimple_predict_predictor (s);
931 2468 : if (predict == PRED_HOT_LABEL
932 2468 : || predict == PRED_COLD_LABEL)
933 : return true;
934 : }
935 : return false;
936 : }
937 :
938 : /* The function match_simplify_replacement does the main work of doing the
939 : replacement using match and simplify. Return true if the replacement is done.
940 : Otherwise return false.
941 : BB is the basic block where the replacement is going to be done on. ARG0
942 : is argument 0 from PHI. Likewise for ARG1. */
943 :
944 : static bool
945 820766 : match_simplify_replacement (basic_block cond_bb, basic_block middle_bb,
946 : basic_block middle_bb_alt,
947 : edge e0, edge e1, gphi *phi,
948 : tree arg0, tree arg1, bool early_p,
949 : bool threeway_p)
950 : {
951 820766 : gimple *stmt;
952 820766 : gimple_stmt_iterator gsi;
953 820766 : edge true_edge, false_edge;
954 820766 : gimple_seq seq = NULL;
955 820766 : tree result;
956 820766 : gimple *stmt_to_move = NULL;
957 820766 : gimple *stmt_to_move_alt = NULL;
958 820766 : tree arg_true, arg_false;
959 :
960 : /* Special case A ? B : B as this will always simplify to B. */
961 820766 : if (operand_equal_for_phi_arg_p (arg0, arg1))
962 : return false;
963 :
964 : /* If the basic block only has a cheap preparation statement,
965 : allow it and move it once the transformation is done. */
966 820766 : if (!empty_bb_or_one_feeding_into_p (middle_bb, phi, stmt_to_move))
967 : return false;
968 :
969 530201 : if (threeway_p
970 530201 : && middle_bb != middle_bb_alt
971 530201 : && !empty_bb_or_one_feeding_into_p (middle_bb_alt, phi,
972 : stmt_to_move_alt))
973 : return false;
974 :
975 : /* Do not make conditional undefs unconditional. */
976 518841 : if ((TREE_CODE (arg0) == SSA_NAME
977 265425 : && ssa_name_maybe_undef_p (arg0))
978 783919 : || (TREE_CODE (arg1) == SSA_NAME
979 216643 : && ssa_name_maybe_undef_p (arg1)))
980 : return false;
981 :
982 : /* At this point we know we have a GIMPLE_COND with two successors.
983 : One successor is BB, the other successor is an empty block which
984 : falls through into BB.
985 :
986 : There is a single PHI node at the join point (BB).
987 :
988 : So, given the condition COND, and the two PHI arguments, match and simplify
989 : can happen on (COND) ? arg0 : arg1. */
990 :
991 514290 : stmt = last_nondebug_stmt (cond_bb);
992 :
993 : /* We need to know which is the true edge and which is the false
994 : edge so that we know when to invert the condition below. */
995 514290 : extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
996 :
997 : /* Forward the edges over the middle basic block. */
998 514290 : if (true_edge->dest == middle_bb)
999 322405 : true_edge = EDGE_SUCC (true_edge->dest, 0);
1000 514290 : if (false_edge->dest == middle_bb)
1001 191885 : false_edge = EDGE_SUCC (false_edge->dest, 0);
1002 :
1003 : /* When THREEWAY_P then e1 will point to the edge of the final transition
1004 : from middle-bb to end. */
1005 514290 : if (true_edge == e0)
1006 : {
1007 322405 : if (!threeway_p)
1008 305972 : gcc_assert (false_edge == e1);
1009 : arg_true = arg0;
1010 : arg_false = arg1;
1011 : }
1012 : else
1013 : {
1014 191885 : gcc_assert (false_edge == e0);
1015 191885 : if (!threeway_p)
1016 191489 : gcc_assert (true_edge == e1);
1017 : arg_true = arg1;
1018 : arg_false = arg0;
1019 : }
1020 :
1021 514290 : tree type = TREE_TYPE (gimple_phi_result (phi));
1022 514290 : {
1023 514290 : auto_flow_sensitive s1(stmt_to_move);
1024 514290 : auto_flow_sensitive s_alt(stmt_to_move_alt);
1025 :
1026 514290 : result = gimple_simplify_phiopt (early_p, type, stmt,
1027 : arg_true, arg_false,
1028 : &seq);
1029 514290 : }
1030 :
1031 : /* For early phiopt, we don't want to lose user generated predictors
1032 : if the phiopt is converting `if (a)` into `a` as that might
1033 : be jump threaded later on so we want to keep around the
1034 : predictors. */
1035 514290 : if (early_p && result && TREE_CODE (result) == SSA_NAME)
1036 : {
1037 24241 : bool check_it = false;
1038 24241 : tree cmp0 = gimple_cond_lhs (stmt);
1039 24241 : tree cmp1 = gimple_cond_rhs (stmt);
1040 24241 : if (result == cmp0 || result == cmp1)
1041 : check_it = true;
1042 18415 : else if (gimple_seq_singleton_p (seq))
1043 : {
1044 18317 : gimple *stmt = gimple_seq_first_stmt (seq);
1045 18317 : if (is_gimple_assign (stmt)
1046 18317 : && result == gimple_assign_lhs (stmt)
1047 36634 : && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
1048 : == tcc_comparison)
1049 : check_it = true;
1050 : }
1051 : if (!check_it)
1052 : ;
1053 5826 : else if (contains_hot_cold_predict (middle_bb))
1054 : return false;
1055 5825 : else if (threeway_p
1056 : && middle_bb != middle_bb_alt
1057 5825 : && contains_hot_cold_predict (middle_bb_alt))
1058 : return false;
1059 : }
1060 :
1061 514283 : if (!result)
1062 : {
1063 : /* If we don't get back a MIN/MAX_EXPR still make sure the expression
1064 : stays in a form to be recognized by ISA that map to IEEE x > y ? x : y
1065 : semantics (that's not IEEE max semantics). */
1066 430846 : if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type))
1067 : return false;
1068 16569 : if (stmt_to_move || stmt_to_move_alt)
1069 : return false;
1070 13735 : tree_code cmp = gimple_cond_code (stmt);
1071 13735 : if (cmp != LT_EXPR && cmp != LE_EXPR
1072 13735 : && cmp != GT_EXPR && cmp != GE_EXPR)
1073 : return false;
1074 6574 : tree lhs = gimple_cond_lhs (stmt);
1075 6574 : tree rhs = gimple_cond_rhs (stmt);
1076 : /* `lhs CMP rhs ? lhs : rhs` or `lhs CMP rhs ? rhs : lhs`
1077 : are only acceptable case here. */
1078 6574 : if ((!operand_equal_for_phi_arg_p (lhs, arg_false)
1079 2568 : || !operand_equal_for_phi_arg_p (rhs, arg_true))
1080 6634 : && (!operand_equal_for_phi_arg_p (rhs, arg_false)
1081 1603 : || !operand_equal_for_phi_arg_p (lhs, arg_true)))
1082 2640 : return false;
1083 3934 : seq = nullptr;
1084 3934 : result = gimple_build (&seq, cmp, boolean_type_node, lhs, rhs);
1085 3934 : result = gimple_build (&seq, COND_EXPR, type, result,
1086 : arg_true, arg_false);
1087 3934 : statistics_counter_event (cfun, "Non-IEEE FP MIN/MAX PHI replacement",
1088 : 1);
1089 : }
1090 87377 : if (dump_file && (dump_flags & TDF_FOLDING))
1091 1 : fprintf (dump_file, "accepted the phiopt match-simplify.\n");
1092 :
1093 87377 : auto_bitmap exprs_maybe_dce;
1094 :
1095 : /* Mark the cond statements' lhs/rhs as maybe dce. */
1096 87377 : if (TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME
1097 87377 : && !SSA_NAME_IS_DEFAULT_DEF (gimple_cond_lhs (stmt)))
1098 82384 : bitmap_set_bit (exprs_maybe_dce,
1099 82384 : SSA_NAME_VERSION (gimple_cond_lhs (stmt)));
1100 87377 : if (TREE_CODE (gimple_cond_rhs (stmt)) == SSA_NAME
1101 87377 : && !SSA_NAME_IS_DEFAULT_DEF (gimple_cond_rhs (stmt)))
1102 27681 : bitmap_set_bit (exprs_maybe_dce,
1103 27681 : SSA_NAME_VERSION (gimple_cond_rhs (stmt)));
1104 :
1105 87377 : gsi = gsi_last_bb (cond_bb);
1106 : /* Insert the sequence generated from gimple_simplify_phiopt. */
1107 87377 : if (seq)
1108 : {
1109 : // Mark the lhs of the new statements maybe for dce
1110 79741 : mark_lhs_in_seq_for_dce (exprs_maybe_dce, seq);
1111 79741 : gsi_insert_seq_before (&gsi, seq, GSI_CONTINUE_LINKING);
1112 : }
1113 :
1114 : /* If there was a statement to move, move it to right before
1115 : the original conditional. */
1116 87377 : move_stmt (stmt_to_move, &gsi, exprs_maybe_dce);
1117 87377 : move_stmt (stmt_to_move_alt, &gsi, exprs_maybe_dce);
1118 :
1119 87377 : replace_phi_edge_with_variable (cond_bb, e1, phi, result, exprs_maybe_dce);
1120 :
1121 : /* Add Statistic here even though replace_phi_edge_with_variable already
1122 : does it as we want to be able to count when match-simplify happens vs
1123 : the others. */
1124 87377 : statistics_counter_event (cfun, "match-simplify PHI replacement", 1);
1125 :
1126 : /* Note that we optimized this PHI. */
1127 87377 : return true;
1128 87377 : }
1129 :
1130 : /* Update *ARG which is defined in STMT so that it contains the
1131 : computed value if that seems profitable. Return true if the
1132 : statement is made dead by that rewriting. */
1133 :
1134 : static bool
1135 338306 : jump_function_from_stmt (tree *arg, gimple *stmt)
1136 : {
1137 338306 : enum tree_code code = gimple_assign_rhs_code (stmt);
1138 338306 : if (code == ADDR_EXPR)
1139 : {
1140 : /* For arg = &p->i transform it to p, if possible. */
1141 4733 : tree rhs1 = gimple_assign_rhs1 (stmt);
1142 4733 : poly_int64 offset;
1143 4733 : tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (rhs1, 0),
1144 : &offset);
1145 4733 : if (tem
1146 4652 : && TREE_CODE (tem) == MEM_REF
1147 9385 : && known_eq (mem_ref_offset (tem) + offset, 0))
1148 : {
1149 1873 : *arg = TREE_OPERAND (tem, 0);
1150 1873 : return true;
1151 : }
1152 : }
1153 : /* TODO: Much like IPA-CP jump-functions we want to handle constant
1154 : additions symbolically here, and we'd need to update the comparison
1155 : code that compares the arg + cst tuples in our caller. For now the
1156 : code above exactly handles the VEC_BASE pattern from vec.h. */
1157 : return false;
1158 : }
1159 :
1160 : /* RHS is a source argument in a BIT_AND_EXPR or BIT_IOR_EXPR which feeds
1161 : a conditional of the form SSA_NAME NE 0.
1162 :
1163 : If RHS is fed by a simple EQ_EXPR or NE_EXPR comparison of two values,
1164 : see if the two input values of the comparison match arg0 and arg1.
1165 :
1166 : If so update *code and return TRUE. Otherwise return FALSE. */
1167 :
1168 : static bool
1169 165350 : rhs_is_fed_for_value_replacement (const_tree arg0, const_tree arg1,
1170 : enum tree_code *code, const_tree rhs,
1171 : enum tree_code bit_expression_code)
1172 : {
1173 : /* Obviously if RHS is not an SSA_NAME, we can't look at the defining
1174 : statement. */
1175 165350 : if (TREE_CODE (rhs) == SSA_NAME)
1176 : {
1177 127420 : gimple *def1 = SSA_NAME_DEF_STMT (rhs);
1178 :
1179 : /* Verify the defining statement has an EQ_EXPR or NE_EXPR on the RHS. */
1180 127420 : if (is_gimple_assign (def1)
1181 127420 : && ((bit_expression_code == BIT_AND_EXPR
1182 80939 : && gimple_assign_rhs_code (def1) == EQ_EXPR)
1183 98002 : || (bit_expression_code == BIT_IOR_EXPR
1184 36707 : && gimple_assign_rhs_code (def1) == NE_EXPR)))
1185 : {
1186 : /* Finally verify the source operands of the EQ_EXPR or NE_EXPR
1187 : are equal to arg0 and arg1. */
1188 24376 : tree op0 = gimple_assign_rhs1 (def1);
1189 24376 : tree op1 = gimple_assign_rhs2 (def1);
1190 24376 : if ((operand_equal_for_phi_arg_p (arg0, op0)
1191 576 : && operand_equal_for_phi_arg_p (arg1, op1))
1192 24895 : || (operand_equal_for_phi_arg_p (arg0, op1)
1193 676 : && operand_equal_for_phi_arg_p (arg1, op0)))
1194 : {
1195 : /* We will perform the optimization. */
1196 473 : *code = gimple_assign_rhs_code (def1);
1197 473 : return true;
1198 : }
1199 : }
1200 : }
1201 : return false;
1202 : }
1203 :
1204 : /* Return TRUE if arg0/arg1 are equal to the rhs/lhs or lhs/rhs of COND.
1205 :
1206 : Also return TRUE if arg0/arg1 are equal to the source arguments of an
1207 : EQ comparison feeding a BIT_AND_EXPR, or NE comparison feeding a
1208 : BIT_IOR_EXPR which feeds COND.
1209 :
1210 : Return FALSE otherwise. */
1211 :
1212 : static bool
1213 690398 : operand_equal_for_value_replacement (const_tree arg0, const_tree arg1,
1214 : enum tree_code *code, gimple *cond)
1215 : {
1216 690398 : gimple *def;
1217 690398 : tree lhs = gimple_cond_lhs (cond);
1218 690398 : tree rhs = gimple_cond_rhs (cond);
1219 :
1220 690398 : if ((operand_equal_for_phi_arg_p (arg0, lhs)
1221 27991 : && operand_equal_for_phi_arg_p (arg1, rhs))
1222 710285 : || (operand_equal_for_phi_arg_p (arg1, lhs)
1223 47775 : && operand_equal_for_phi_arg_p (arg0, rhs)))
1224 15727 : return true;
1225 :
1226 : /* Now handle more complex case where we have an EQ comparison
1227 : feeding a BIT_AND_EXPR, or a NE comparison feeding a BIT_IOR_EXPR,
1228 : which then feeds into COND.
1229 :
1230 : First verify that COND is of the form SSA_NAME NE 0. */
1231 387987 : if (*code != NE_EXPR || !integer_zerop (rhs)
1232 951367 : || TREE_CODE (lhs) != SSA_NAME)
1233 398094 : return false;
1234 :
1235 : /* Now ensure that SSA_NAME is set by a BIT_AND_EXPR or BIT_OR_EXPR. */
1236 276577 : def = SSA_NAME_DEF_STMT (lhs);
1237 276577 : if (!is_gimple_assign (def)
1238 276577 : || (gimple_assign_rhs_code (def) != BIT_AND_EXPR
1239 128317 : && gimple_assign_rhs_code (def) != BIT_IOR_EXPR))
1240 : return false;
1241 :
1242 : /* Now verify arg0/arg1 correspond to the source arguments of an EQ
1243 : comparison feeding the BIT_AND_EXPR or a NE comparison feeding the
1244 : BIT_IOR_EXPR. */
1245 :
1246 82844 : tree tmp = gimple_assign_rhs1 (def);
1247 82844 : if (rhs_is_fed_for_value_replacement (arg0, arg1, code, tmp,
1248 : gimple_assign_rhs_code (def)))
1249 : return true;
1250 :
1251 82506 : tmp = gimple_assign_rhs2 (def);
1252 82506 : if (rhs_is_fed_for_value_replacement (arg0, arg1, code, tmp,
1253 : gimple_assign_rhs_code (def)))
1254 : return true;
1255 :
1256 : return false;
1257 : }
1258 :
1259 : /* Returns true if ARG is a neutral element for operation CODE
1260 : on the RIGHT side. */
1261 :
1262 : static bool
1263 1130 : neutral_element_p (tree_code code, tree arg, bool right)
1264 : {
1265 1130 : switch (code)
1266 : {
1267 41 : case PLUS_EXPR:
1268 41 : case BIT_IOR_EXPR:
1269 41 : case BIT_XOR_EXPR:
1270 41 : return integer_zerop (arg);
1271 :
1272 193 : case LROTATE_EXPR:
1273 193 : case RROTATE_EXPR:
1274 193 : case LSHIFT_EXPR:
1275 193 : case RSHIFT_EXPR:
1276 193 : case MINUS_EXPR:
1277 193 : case POINTER_PLUS_EXPR:
1278 193 : return right && integer_zerop (arg);
1279 :
1280 608 : case MULT_EXPR:
1281 608 : return integer_onep (arg);
1282 :
1283 31 : case TRUNC_DIV_EXPR:
1284 31 : case CEIL_DIV_EXPR:
1285 31 : case FLOOR_DIV_EXPR:
1286 31 : case ROUND_DIV_EXPR:
1287 31 : case EXACT_DIV_EXPR:
1288 31 : return right && integer_onep (arg);
1289 :
1290 0 : case BIT_AND_EXPR:
1291 0 : return integer_all_onesp (arg);
1292 :
1293 : default:
1294 : return false;
1295 : }
1296 : }
1297 :
1298 : /* Returns true if ARG is an absorbing element for operation CODE. */
1299 :
1300 : static bool
1301 860 : absorbing_element_p (tree_code code, tree arg, bool right, tree rval)
1302 : {
1303 860 : switch (code)
1304 : {
1305 18 : case BIT_IOR_EXPR:
1306 18 : return integer_all_onesp (arg);
1307 :
1308 37 : case MULT_EXPR:
1309 37 : case BIT_AND_EXPR:
1310 37 : return integer_zerop (arg);
1311 :
1312 2 : case LSHIFT_EXPR:
1313 2 : case RSHIFT_EXPR:
1314 2 : case LROTATE_EXPR:
1315 2 : case RROTATE_EXPR:
1316 2 : return !right && integer_zerop (arg);
1317 :
1318 169 : case TRUNC_DIV_EXPR:
1319 169 : case CEIL_DIV_EXPR:
1320 169 : case FLOOR_DIV_EXPR:
1321 169 : case ROUND_DIV_EXPR:
1322 169 : case EXACT_DIV_EXPR:
1323 169 : case TRUNC_MOD_EXPR:
1324 169 : case CEIL_MOD_EXPR:
1325 169 : case FLOOR_MOD_EXPR:
1326 169 : case ROUND_MOD_EXPR:
1327 169 : return (!right
1328 11 : && integer_zerop (arg)
1329 179 : && tree_single_nonzero_warnv_p (rval, NULL));
1330 :
1331 : default:
1332 : return false;
1333 : }
1334 : }
1335 :
1336 : /* The function value_replacement does the main work of doing the value
1337 : replacement. Return non-zero if the replacement is done. Otherwise return
1338 : 0. If we remove the middle basic block, return 2.
1339 : BB is the basic block where the replacement is going to be done on. ARG0
1340 : is argument 0 from the PHI. Likewise for ARG1. */
1341 :
1342 : static int
1343 2506886 : value_replacement (basic_block cond_bb, basic_block middle_bb,
1344 : edge e0, edge e1, gphi *phi, tree arg0, tree arg1)
1345 : {
1346 2506886 : gimple_stmt_iterator gsi;
1347 2506886 : edge true_edge, false_edge;
1348 2506886 : enum tree_code code;
1349 2506886 : bool empty_or_with_defined_p = true;
1350 :
1351 : /* Virtual operands don't need to be handled. */
1352 4426942 : if (virtual_operand_p (arg1))
1353 : return 0;
1354 :
1355 : /* Special case A ? B : B as this will always simplify to B. */
1356 1346540 : if (operand_equal_for_phi_arg_p (arg0, arg1))
1357 : return 0;
1358 :
1359 2383946 : gcond *cond = as_a <gcond *> (*gsi_last_bb (cond_bb));
1360 1191973 : code = gimple_cond_code (cond);
1361 :
1362 : /* This transformation is only valid for equality comparisons. */
1363 1191973 : if (code != NE_EXPR && code != EQ_EXPR)
1364 : return 0;
1365 :
1366 : /* Do not make conditional undefs unconditional. */
1367 718962 : if ((TREE_CODE (arg0) == SSA_NAME
1368 546739 : && ssa_name_maybe_undef_p (arg0))
1369 1263896 : || (TREE_CODE (arg1) == SSA_NAME
1370 316261 : && ssa_name_maybe_undef_p (arg1)))
1371 : return false;
1372 :
1373 : /* If the type says honor signed zeros we cannot do this
1374 : optimization. */
1375 703200 : if (HONOR_SIGNED_ZEROS (arg1))
1376 : return 0;
1377 :
1378 : /* If there is a statement in MIDDLE_BB that defines one of the PHI
1379 : arguments, then adjust arg0 or arg1. */
1380 690398 : gsi = gsi_start_nondebug_after_labels_bb (middle_bb);
1381 2151231 : while (!gsi_end_p (gsi))
1382 : {
1383 1460833 : gimple *stmt = gsi_stmt (gsi);
1384 1460833 : tree lhs;
1385 1460833 : gsi_next_nondebug (&gsi);
1386 1460833 : if (!is_gimple_assign (stmt))
1387 : {
1388 211770 : if (gimple_code (stmt) != GIMPLE_PREDICT
1389 211770 : && gimple_code (stmt) != GIMPLE_NOP)
1390 : empty_or_with_defined_p = false;
1391 211770 : continue;
1392 : }
1393 : /* Now try to adjust arg0 or arg1 according to the computation
1394 : in the statement. */
1395 1249063 : lhs = gimple_assign_lhs (stmt);
1396 338306 : if (!(lhs == arg0
1397 338306 : && jump_function_from_stmt (&arg0, stmt))
1398 1250936 : || (lhs == arg1
1399 0 : && jump_function_from_stmt (&arg1, stmt)))
1400 : empty_or_with_defined_p = false;
1401 : }
1402 :
1403 : /* The middle bb is not empty if there are any phi nodes. */
1404 690398 : if (phi_nodes (middle_bb))
1405 84904 : empty_or_with_defined_p = false;
1406 :
1407 : /* We need to know which is the true edge and which is the false
1408 : edge so that we know if have abs or negative abs. */
1409 690398 : extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
1410 :
1411 : /* At this point we know we have a COND_EXPR with two successors.
1412 : One successor is BB, the other successor is an empty block which
1413 : falls through into BB.
1414 :
1415 : The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
1416 :
1417 : There is a single PHI node at the join point (BB) with two arguments.
1418 :
1419 : We now need to verify that the two arguments in the PHI node match
1420 : the two arguments to the equality comparison. */
1421 :
1422 690398 : bool equal_p = operand_equal_for_value_replacement (arg0, arg1, &code, cond);
1423 690398 : bool maybe_equal_p = false;
1424 690398 : if (!equal_p
1425 690398 : && empty_or_with_defined_p
1426 194706 : && TREE_CODE (gimple_cond_rhs (cond)) == INTEGER_CST
1427 845216 : && (operand_equal_for_phi_arg_p (gimple_cond_lhs (cond), arg0)
1428 154818 : ? TREE_CODE (arg1) == INTEGER_CST
1429 145533 : : (operand_equal_for_phi_arg_p (gimple_cond_lhs (cond), arg1)
1430 20284 : && TREE_CODE (arg0) == INTEGER_CST)))
1431 : maybe_equal_p = true;
1432 672440 : if (equal_p || maybe_equal_p)
1433 : {
1434 34158 : edge e;
1435 34158 : tree arg;
1436 :
1437 : /* For NE_EXPR, we want to build an assignment result = arg where
1438 : arg is the PHI argument associated with the true edge. For
1439 : EQ_EXPR we want the PHI argument associated with the false edge. */
1440 34158 : e = (code == NE_EXPR ? true_edge : false_edge);
1441 :
1442 : /* Unfortunately, E may not reach BB (it may instead have gone to
1443 : OTHER_BLOCK). If that is the case, then we want the single outgoing
1444 : edge from OTHER_BLOCK which reaches BB and represents the desired
1445 : path from COND_BLOCK. */
1446 34158 : if (e->dest == middle_bb)
1447 13300 : e = single_succ_edge (e->dest);
1448 :
1449 : /* Now we know the incoming edge to BB that has the argument for the
1450 : RHS of our new assignment statement. */
1451 34158 : if (e0 == e)
1452 : arg = arg0;
1453 : else
1454 20858 : arg = arg1;
1455 :
1456 : /* If the middle basic block was empty or is defining the
1457 : PHI arguments and this is a single phi where the args are different
1458 : for the edges e0 and e1 then we can remove the middle basic block. */
1459 34158 : if (empty_or_with_defined_p
1460 34158 : && single_non_singleton_phi_for_edges (phi_nodes (gimple_bb (phi)),
1461 : e0, e1) == phi)
1462 : {
1463 18186 : use_operand_p use_p;
1464 18186 : gimple *use_stmt;
1465 :
1466 : /* Even if arg0/arg1 isn't equal to second operand of cond, we
1467 : can optimize away the bb if we can prove it doesn't care whether
1468 : phi result is arg0/arg1 or second operand of cond. Consider:
1469 : <bb 2> [local count: 118111600]:
1470 : if (i_2(D) == 4)
1471 : goto <bb 4>; [97.00%]
1472 : else
1473 : goto <bb 3>; [3.00%]
1474 :
1475 : <bb 3> [local count: 3540129]:
1476 :
1477 : <bb 4> [local count: 118111600]:
1478 : # i_6 = PHI <i_2(D)(3), 6(2)>
1479 : _3 = i_6 != 0;
1480 : Here, carg is 4, oarg is 6, crhs is 0, and because
1481 : (4 != 0) == (6 != 0), we don't care if i_6 is 4 or 6, both
1482 : have the same outcome. So, we can optimize this to:
1483 : _3 = i_2(D) != 0;
1484 : If the single imm use of phi result >, >=, < or <=, similarly
1485 : we can check if both carg and oarg compare the same against
1486 : crhs using ccode. */
1487 18186 : if (maybe_equal_p
1488 16365 : && TREE_CODE (arg) != INTEGER_CST
1489 34536 : && single_imm_use (gimple_phi_result (phi), &use_p, &use_stmt))
1490 : {
1491 9579 : enum tree_code ccode = ERROR_MARK;
1492 9579 : tree clhs = NULL_TREE, crhs = NULL_TREE;
1493 9579 : tree carg = gimple_cond_rhs (cond);
1494 9579 : tree oarg = e0 == e ? arg1 : arg0;
1495 9579 : if (is_gimple_assign (use_stmt)
1496 9579 : && (TREE_CODE_CLASS (gimple_assign_rhs_code (use_stmt))
1497 : == tcc_comparison))
1498 : {
1499 58 : ccode = gimple_assign_rhs_code (use_stmt);
1500 58 : clhs = gimple_assign_rhs1 (use_stmt);
1501 58 : crhs = gimple_assign_rhs2 (use_stmt);
1502 : }
1503 9521 : else if (gimple_code (use_stmt) == GIMPLE_COND)
1504 : {
1505 78 : ccode = gimple_cond_code (use_stmt);
1506 78 : clhs = gimple_cond_lhs (use_stmt);
1507 78 : crhs = gimple_cond_rhs (use_stmt);
1508 : }
1509 136 : if (ccode != ERROR_MARK
1510 136 : && clhs == gimple_phi_result (phi)
1511 233 : && TREE_CODE (crhs) == INTEGER_CST)
1512 45 : switch (ccode)
1513 : {
1514 26 : case EQ_EXPR:
1515 26 : case NE_EXPR:
1516 26 : if (!tree_int_cst_equal (crhs, carg)
1517 26 : && !tree_int_cst_equal (crhs, oarg))
1518 : equal_p = true;
1519 : break;
1520 2 : case GT_EXPR:
1521 4 : if (tree_int_cst_lt (crhs, carg)
1522 2 : == tree_int_cst_lt (crhs, oarg))
1523 : equal_p = true;
1524 : break;
1525 0 : case GE_EXPR:
1526 0 : if (tree_int_cst_le (crhs, carg)
1527 0 : == tree_int_cst_le (crhs, oarg))
1528 : equal_p = true;
1529 : break;
1530 13 : case LT_EXPR:
1531 26 : if (tree_int_cst_lt (carg, crhs)
1532 13 : == tree_int_cst_lt (oarg, crhs))
1533 : equal_p = true;
1534 : break;
1535 4 : case LE_EXPR:
1536 8 : if (tree_int_cst_le (carg, crhs)
1537 4 : == tree_int_cst_le (oarg, crhs))
1538 : equal_p = true;
1539 : break;
1540 : default:
1541 : break;
1542 : }
1543 9563 : if (equal_p)
1544 : {
1545 16 : tree phires = gimple_phi_result (phi);
1546 16 : if (SSA_NAME_RANGE_INFO (phires))
1547 : {
1548 : /* After the optimization PHI result can have value
1549 : which it couldn't have previously. */
1550 15 : value_range r (TREE_TYPE (phires));
1551 15 : if (get_global_range_query ()->range_of_expr (r, phires,
1552 : phi))
1553 : {
1554 15 : value_range tmp (carg, carg);
1555 15 : r.union_ (tmp);
1556 15 : reset_flow_sensitive_info (phires);
1557 15 : set_range_info (phires, r);
1558 15 : }
1559 : else
1560 0 : reset_flow_sensitive_info (phires);
1561 15 : }
1562 : }
1563 16 : if (equal_p && MAY_HAVE_DEBUG_BIND_STMTS)
1564 : {
1565 13 : imm_use_iterator imm_iter;
1566 13 : tree phires = gimple_phi_result (phi);
1567 13 : tree temp = NULL_TREE;
1568 13 : bool reset_p = false;
1569 :
1570 : /* Add # DEBUG D#1 => arg != carg ? arg : oarg. */
1571 42 : FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, phires)
1572 : {
1573 30 : if (!is_gimple_debug (use_stmt))
1574 13 : continue;
1575 17 : if (temp == NULL_TREE)
1576 : {
1577 12 : if (!single_pred_p (middle_bb)
1578 12 : || EDGE_COUNT (gimple_bb (phi)->preds) != 2)
1579 : {
1580 : /* But only if middle_bb has a single
1581 : predecessor and phi bb has two, otherwise
1582 : we could use a SSA_NAME not usable in that
1583 : place or wrong-debug. */
1584 1 : reset_p = true;
1585 1 : break;
1586 : }
1587 11 : gimple_stmt_iterator gsi
1588 11 : = gsi_after_labels (gimple_bb (phi));
1589 11 : tree type = TREE_TYPE (phires);
1590 11 : temp = build_debug_expr_decl (type);
1591 11 : tree t = build2 (NE_EXPR, boolean_type_node,
1592 : arg, carg);
1593 11 : t = build3 (COND_EXPR, type, t, arg, oarg);
1594 11 : gimple *g = gimple_build_debug_bind (temp, t, phi);
1595 11 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
1596 : }
1597 32 : FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
1598 16 : replace_exp (use_p, temp);
1599 16 : update_stmt (use_stmt);
1600 13 : }
1601 13 : if (reset_p)
1602 1 : reset_debug_uses (phi);
1603 : }
1604 : }
1605 8623 : if (equal_p)
1606 : {
1607 1837 : replace_phi_edge_with_variable (cond_bb, e1, phi, arg);
1608 : /* Note that we optimized this PHI. */
1609 1837 : return 2;
1610 : }
1611 : }
1612 15972 : else if (equal_p)
1613 : {
1614 14379 : if (!single_pred_p (middle_bb))
1615 : return 0;
1616 12400 : statistics_counter_event (cfun, "Replace PHI with "
1617 : "variable/value_replacement", 1);
1618 :
1619 : /* Replace the PHI arguments with arg. */
1620 12400 : SET_PHI_ARG_DEF (phi, e0->dest_idx, arg);
1621 12400 : SET_PHI_ARG_DEF (phi, e1->dest_idx, arg);
1622 12400 : if (dump_file && (dump_flags & TDF_DETAILS))
1623 : {
1624 0 : fprintf (dump_file, "PHI ");
1625 0 : print_generic_expr (dump_file, gimple_phi_result (phi));
1626 0 : fprintf (dump_file, " reduced for COND_EXPR in block %d to ",
1627 : cond_bb->index);
1628 0 : print_generic_expr (dump_file, arg);
1629 0 : fprintf (dump_file, ".\n");
1630 : }
1631 12400 : return 1;
1632 : }
1633 : }
1634 :
1635 3057683 : if (!single_pred_p (middle_bb))
1636 : return 0;
1637 :
1638 : /* Now optimize (x != 0) ? x + y : y to just x + y. */
1639 565140 : gsi = gsi_last_nondebug_bb (middle_bb);
1640 565140 : if (gsi_end_p (gsi))
1641 : return 0;
1642 :
1643 387629 : gimple *assign = gsi_stmt (gsi);
1644 387629 : if (!is_gimple_assign (assign)
1645 387629 : || (!INTEGRAL_TYPE_P (TREE_TYPE (arg0))
1646 110435 : && !POINTER_TYPE_P (TREE_TYPE (arg0))))
1647 : return 0;
1648 :
1649 330341 : if (gimple_assign_rhs_class (assign) != GIMPLE_BINARY_RHS)
1650 : {
1651 : /* If last stmt of the middle_bb is a conversion, handle it like
1652 : a preparation statement through constant evaluation with
1653 : checking for UB. */
1654 142546 : enum tree_code sc = gimple_assign_rhs_code (assign);
1655 142546 : if (CONVERT_EXPR_CODE_P (sc))
1656 : assign = NULL;
1657 : else
1658 : return 0;
1659 : }
1660 :
1661 : /* Punt if there are (degenerate) PHIs in middle_bb, there should not be. */
1662 209430 : if (!gimple_seq_empty_p (phi_nodes (middle_bb)))
1663 : return 0;
1664 :
1665 : /* Allow up to 2 cheap preparation statements that prepare argument
1666 : for assign, e.g.:
1667 : if (y_4 != 0)
1668 : goto <bb 3>;
1669 : else
1670 : goto <bb 4>;
1671 : <bb 3>:
1672 : _1 = (int) y_4;
1673 : iftmp.0_6 = x_5(D) r<< _1;
1674 : <bb 4>:
1675 : # iftmp.0_2 = PHI <iftmp.0_6(3), x_5(D)(2)>
1676 : or:
1677 : if (y_3(D) == 0)
1678 : goto <bb 4>;
1679 : else
1680 : goto <bb 3>;
1681 : <bb 3>:
1682 : y_4 = y_3(D) & 31;
1683 : _1 = (int) y_4;
1684 : _6 = x_5(D) r<< _1;
1685 : <bb 4>:
1686 : # _2 = PHI <x_5(D)(2), _6(3)> */
1687 209430 : gimple *prep_stmt[2] = { NULL, NULL };
1688 209430 : int prep_cnt;
1689 209430 : for (prep_cnt = 0; ; prep_cnt++)
1690 : {
1691 269104 : if (prep_cnt || assign)
1692 247469 : gsi_prev_nondebug (&gsi);
1693 269104 : if (gsi_end_p (gsi))
1694 : break;
1695 :
1696 201525 : gimple *g = gsi_stmt (gsi);
1697 201525 : if (gimple_code (g) == GIMPLE_LABEL)
1698 : break;
1699 :
1700 201170 : if (prep_cnt == 2 || !is_gimple_assign (g))
1701 141496 : return 0;
1702 :
1703 178031 : tree lhs = gimple_assign_lhs (g);
1704 178031 : tree rhs1 = gimple_assign_rhs1 (g);
1705 178031 : use_operand_p use_p;
1706 178031 : gimple *use_stmt;
1707 178031 : if (TREE_CODE (lhs) != SSA_NAME
1708 171123 : || TREE_CODE (rhs1) != SSA_NAME
1709 108529 : || !INTEGRAL_TYPE_P (TREE_TYPE (lhs))
1710 105014 : || !INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
1711 100742 : || !single_imm_use (lhs, &use_p, &use_stmt)
1712 277972 : || ((prep_cnt || assign)
1713 79848 : && use_stmt != (prep_cnt ? prep_stmt[prep_cnt - 1] : assign)))
1714 85763 : return 0;
1715 92268 : switch (gimple_assign_rhs_code (g))
1716 : {
1717 : CASE_CONVERT:
1718 : break;
1719 19784 : case PLUS_EXPR:
1720 19784 : case BIT_AND_EXPR:
1721 19784 : case BIT_IOR_EXPR:
1722 19784 : case BIT_XOR_EXPR:
1723 19784 : if (TREE_CODE (gimple_assign_rhs2 (g)) != INTEGER_CST)
1724 : return 0;
1725 : break;
1726 : default:
1727 : return 0;
1728 : }
1729 59674 : prep_stmt[prep_cnt] = g;
1730 59674 : }
1731 :
1732 : /* Only transform if it removes the condition. */
1733 67934 : if (!single_non_singleton_phi_for_edges (phi_nodes (gimple_bb (phi)), e0, e1))
1734 : return 0;
1735 :
1736 : /* Size-wise, this is always profitable. */
1737 52486 : if (optimize_bb_for_speed_p (cond_bb)
1738 : /* The special case is useless if it has a low probability. */
1739 49754 : && profile_status_for_fn (cfun) != PROFILE_ABSENT
1740 60993 : && EDGE_PRED (middle_bb, 0)->probability < profile_probability::even ()
1741 : /* If assign is cheap, there is no point avoiding it. */
1742 63745 : && estimate_num_insns_seq (bb_seq (middle_bb), &eni_time_weights)
1743 11259 : >= 3 * estimate_num_insns (cond, &eni_time_weights))
1744 78 : return 0;
1745 :
1746 52408 : tree cond_lhs = gimple_cond_lhs (cond);
1747 52408 : tree cond_rhs = gimple_cond_rhs (cond);
1748 :
1749 : /* Propagate the cond_rhs constant through preparation stmts,
1750 : make sure UB isn't invoked while doing that. */
1751 54192 : for (int i = prep_cnt - 1; i >= 0; --i)
1752 : {
1753 13539 : gimple *g = prep_stmt[i];
1754 13539 : tree grhs1 = gimple_assign_rhs1 (g);
1755 13539 : if (!operand_equal_for_phi_arg_p (cond_lhs, grhs1))
1756 : return 0;
1757 7390 : cond_lhs = gimple_assign_lhs (g);
1758 7390 : cond_rhs = fold_convert (TREE_TYPE (grhs1), cond_rhs);
1759 7390 : if (TREE_CODE (cond_rhs) != INTEGER_CST
1760 7390 : || TREE_OVERFLOW (cond_rhs))
1761 : return 0;
1762 1784 : if (gimple_assign_rhs_class (g) == GIMPLE_BINARY_RHS)
1763 : {
1764 737 : cond_rhs = int_const_binop (gimple_assign_rhs_code (g), cond_rhs,
1765 737 : gimple_assign_rhs2 (g));
1766 737 : if (TREE_OVERFLOW (cond_rhs))
1767 : return 0;
1768 : }
1769 1784 : cond_rhs = fold_convert (TREE_TYPE (cond_lhs), cond_rhs);
1770 1784 : if (TREE_CODE (cond_rhs) != INTEGER_CST
1771 1784 : || TREE_OVERFLOW (cond_rhs))
1772 : return 0;
1773 : }
1774 :
1775 40653 : tree lhs, rhs1, rhs2;
1776 40653 : enum tree_code code_def;
1777 40653 : if (assign)
1778 : {
1779 40395 : lhs = gimple_assign_lhs (assign);
1780 40395 : rhs1 = gimple_assign_rhs1 (assign);
1781 40395 : rhs2 = gimple_assign_rhs2 (assign);
1782 40395 : code_def = gimple_assign_rhs_code (assign);
1783 : }
1784 : else
1785 : {
1786 258 : gcc_assert (prep_cnt > 0);
1787 : lhs = cond_lhs;
1788 : rhs1 = NULL_TREE;
1789 : rhs2 = NULL_TREE;
1790 : code_def = ERROR_MARK;
1791 : }
1792 :
1793 23609 : if (((code == NE_EXPR && e1 == false_edge)
1794 19796 : || (code == EQ_EXPR && e1 == true_edge))
1795 23645 : && arg0 == lhs
1796 64298 : && ((assign == NULL
1797 257 : && operand_equal_for_phi_arg_p (arg1, cond_rhs))
1798 : || (assign
1799 23388 : && arg1 == rhs1
1800 14886 : && operand_equal_for_phi_arg_p (rhs2, cond_lhs)
1801 416 : && neutral_element_p (code_def, cond_rhs, true))
1802 23323 : || (assign
1803 23323 : && arg1 == rhs2
1804 1384 : && operand_equal_for_phi_arg_p (rhs1, cond_lhs)
1805 714 : && neutral_element_p (code_def, cond_rhs, false))
1806 : || (assign
1807 23316 : && operand_equal_for_phi_arg_p (arg1, cond_rhs)
1808 2837 : && ((operand_equal_for_phi_arg_p (rhs2, cond_lhs)
1809 236 : && absorbing_element_p (code_def, cond_rhs, true, rhs2))
1810 2836 : || (operand_equal_for_phi_arg_p (rhs1, cond_lhs)
1811 624 : && absorbing_element_p (code_def,
1812 : cond_rhs, false, rhs2))))))
1813 : {
1814 106 : gsi = gsi_for_stmt (cond);
1815 : /* Moving ASSIGN might change VR of lhs, e.g. when moving u_6
1816 : def-stmt in:
1817 : if (n_5 != 0)
1818 : goto <bb 3>;
1819 : else
1820 : goto <bb 4>;
1821 :
1822 : <bb 3>:
1823 : # RANGE [0, 4294967294]
1824 : u_6 = n_5 + 4294967295;
1825 :
1826 : <bb 4>:
1827 : # u_3 = PHI <u_6(3), 4294967295(2)> */
1828 106 : reset_flow_sensitive_info (lhs);
1829 106 : gimple_stmt_iterator gsi_from;
1830 179 : for (int i = prep_cnt - 1; i >= 0; --i)
1831 : {
1832 73 : tree plhs = gimple_assign_lhs (prep_stmt[i]);
1833 73 : reset_flow_sensitive_info (plhs);
1834 73 : gsi_from = gsi_for_stmt (prep_stmt[i]);
1835 73 : gsi_move_before (&gsi_from, &gsi);
1836 : }
1837 106 : if (assign)
1838 : {
1839 102 : gsi_from = gsi_for_stmt (assign);
1840 102 : gsi_move_before (&gsi_from, &gsi);
1841 : }
1842 106 : replace_phi_edge_with_variable (cond_bb, e1, phi, lhs);
1843 106 : return 2;
1844 : }
1845 :
1846 : return 0;
1847 : }
1848 :
1849 : /* Attempt to optimize (x <=> y) cmp 0 and similar comparisons.
1850 : For strong ordering <=> try to match something like:
1851 : <bb 2> : // cond3_bb (== cond2_bb)
1852 : if (x_4(D) != y_5(D))
1853 : goto <bb 3>; [INV]
1854 : else
1855 : goto <bb 6>; [INV]
1856 :
1857 : <bb 3> : // cond_bb
1858 : if (x_4(D) < y_5(D))
1859 : goto <bb 6>; [INV]
1860 : else
1861 : goto <bb 4>; [INV]
1862 :
1863 : <bb 4> : // middle_bb
1864 :
1865 : <bb 6> : // phi_bb
1866 : # iftmp.0_2 = PHI <1(4), 0(2), -1(3)>
1867 : _1 = iftmp.0_2 == 0;
1868 :
1869 : and for partial ordering <=> something like:
1870 :
1871 : <bb 2> : // cond3_bb
1872 : if (a_3(D) == b_5(D))
1873 : goto <bb 6>; [50.00%]
1874 : else
1875 : goto <bb 3>; [50.00%]
1876 :
1877 : <bb 3> [local count: 536870913]: // cond2_bb
1878 : if (a_3(D) < b_5(D))
1879 : goto <bb 6>; [50.00%]
1880 : else
1881 : goto <bb 4>; [50.00%]
1882 :
1883 : <bb 4> [local count: 268435456]: // cond_bb
1884 : if (a_3(D) > b_5(D))
1885 : goto <bb 6>; [50.00%]
1886 : else
1887 : goto <bb 5>; [50.00%]
1888 :
1889 : <bb 5> [local count: 134217728]: // middle_bb
1890 :
1891 : <bb 6> [local count: 1073741824]: // phi_bb
1892 : # SR.27_4 = PHI <0(2), -1(3), 1(4), -128(5)>
1893 : _2 = SR.27_4 > 0; */
1894 :
1895 : static bool
1896 628518 : spaceship_replacement (basic_block cond_bb, basic_block middle_bb,
1897 : edge e0, edge e1, gphi *phi,
1898 : tree arg0, tree arg1)
1899 : {
1900 628518 : tree phires = gimple_phi_result (phi);
1901 1250117 : if (!INTEGRAL_TYPE_P (TREE_TYPE (phires))
1902 491334 : || TYPE_UNSIGNED (TREE_TYPE (phires))
1903 256021 : || !tree_fits_shwi_p (arg0)
1904 72169 : || !tree_fits_shwi_p (arg1)
1905 41895 : || (!IN_RANGE (tree_to_shwi (arg0), -1, 1)
1906 22334 : && tree_to_shwi (arg0) != -128)
1907 648495 : || (!IN_RANGE (tree_to_shwi (arg1), -1, 1)
1908 2667 : && tree_to_shwi (arg1) != -128))
1909 : return false;
1910 :
1911 17366 : basic_block phi_bb = gimple_bb (phi);
1912 17366 : gcc_assert (phi_bb == e0->dest && phi_bb == e1->dest);
1913 17366 : if (!IN_RANGE (EDGE_COUNT (phi_bb->preds), 3, 4))
1914 : return false;
1915 :
1916 7282 : use_operand_p use_p;
1917 7282 : gimple *use_stmt;
1918 7282 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (phires))
1919 : return false;
1920 7282 : if (!single_imm_use (phires, &use_p, &use_stmt))
1921 : return false;
1922 6612 : enum tree_code cmp;
1923 6612 : tree lhs, rhs;
1924 6612 : gimple *orig_use_stmt = use_stmt;
1925 6612 : tree orig_use_lhs = NULL_TREE;
1926 6612 : tree temps[2] = { NULL_TREE, NULL_TREE };
1927 :
1928 : /* Handle std::partial_ordering::_M_reverse(), i.e.
1929 : _1 = (unsigned char) phires;
1930 : _2 = -_1;
1931 : _3 = (signed char) _2;
1932 : and uses of _3 in comparison instead of phires. */
1933 6612 : if (gimple_assign_cast_p (use_stmt))
1934 : {
1935 251 : orig_use_lhs = gimple_assign_lhs (use_stmt);
1936 251 : temps[0] = orig_use_lhs;
1937 251 : tree ty1 = TREE_TYPE (gimple_assign_rhs1 (use_stmt));
1938 251 : tree ty2 = TREE_TYPE (orig_use_lhs);
1939 :
1940 251 : if (!TYPE_UNSIGNED (ty2) || !INTEGRAL_TYPE_P (ty2))
1941 : return false;
1942 211 : if (TYPE_PRECISION (ty2) != 8 || TYPE_PRECISION (ty1) < 8)
1943 : return false;
1944 92 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig_use_lhs))
1945 : return false;
1946 92 : if (!single_imm_use (orig_use_lhs, &use_p, &use_stmt))
1947 : return false;
1948 :
1949 91 : if (!is_gimple_assign (use_stmt)
1950 91 : || gimple_assign_rhs_code (use_stmt) != NEGATE_EXPR)
1951 : return false;
1952 :
1953 88 : orig_use_lhs = gimple_assign_lhs (use_stmt);
1954 88 : temps[1] = orig_use_lhs;
1955 88 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig_use_lhs))
1956 : return false;
1957 88 : if (!single_imm_use (orig_use_lhs, &use_p, &use_stmt))
1958 : return false;
1959 :
1960 88 : if (!gimple_assign_cast_p (use_stmt))
1961 : return false;
1962 :
1963 88 : orig_use_lhs = gimple_assign_lhs (use_stmt);
1964 88 : tree ty3 = TREE_TYPE (orig_use_lhs);
1965 :
1966 88 : if (!useless_type_conversion_p (ty3, ty1))
1967 : return false;
1968 88 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig_use_lhs))
1969 : return false;
1970 88 : if (!single_imm_use (orig_use_lhs, &use_p, &use_stmt))
1971 : return false;
1972 : }
1973 6449 : if (gimple_code (use_stmt) == GIMPLE_COND)
1974 : {
1975 2381 : cmp = gimple_cond_code (use_stmt);
1976 2381 : lhs = gimple_cond_lhs (use_stmt);
1977 2381 : rhs = gimple_cond_rhs (use_stmt);
1978 : }
1979 4068 : else if (is_gimple_assign (use_stmt))
1980 : {
1981 2308 : if (gimple_assign_rhs_class (use_stmt) == GIMPLE_BINARY_RHS)
1982 : {
1983 1217 : cmp = gimple_assign_rhs_code (use_stmt);
1984 1217 : lhs = gimple_assign_rhs1 (use_stmt);
1985 1217 : rhs = gimple_assign_rhs2 (use_stmt);
1986 : }
1987 1091 : else if (gimple_assign_rhs_code (use_stmt) == COND_EXPR)
1988 : {
1989 0 : tree cond = gimple_assign_rhs1 (use_stmt);
1990 0 : if (!COMPARISON_CLASS_P (cond))
1991 : return false;
1992 0 : cmp = TREE_CODE (cond);
1993 0 : lhs = TREE_OPERAND (cond, 0);
1994 0 : rhs = TREE_OPERAND (cond, 1);
1995 : }
1996 : else
1997 : return false;
1998 : }
1999 : else
2000 : return false;
2001 3598 : switch (cmp)
2002 : {
2003 3127 : case EQ_EXPR:
2004 3127 : case NE_EXPR:
2005 3127 : case LT_EXPR:
2006 3127 : case GT_EXPR:
2007 3127 : case LE_EXPR:
2008 3127 : case GE_EXPR:
2009 3127 : break;
2010 : default:
2011 : return false;
2012 : }
2013 6166 : if (lhs != (orig_use_lhs ? orig_use_lhs : phires)
2014 2786 : || !tree_fits_shwi_p (rhs)
2015 2528 : || !IN_RANGE (tree_to_shwi (rhs), -1, 1))
2016 : return false;
2017 :
2018 2516 : if (!empty_block_p (middle_bb))
2019 : return false;
2020 :
2021 5032 : gcond *cond1 = as_a <gcond *> (*gsi_last_bb (cond_bb));
2022 2516 : enum tree_code cmp1 = gimple_cond_code (cond1);
2023 2516 : switch (cmp1)
2024 : {
2025 2382 : case LT_EXPR:
2026 2382 : case LE_EXPR:
2027 2382 : case GT_EXPR:
2028 2382 : case GE_EXPR:
2029 2382 : break;
2030 : default:
2031 : return false;
2032 : }
2033 2382 : tree lhs1 = gimple_cond_lhs (cond1);
2034 2382 : tree rhs1 = gimple_cond_rhs (cond1);
2035 2382 : if (TREE_CODE (lhs1) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs1))
2036 : return false;
2037 2382 : if (TREE_CODE (rhs1) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
2038 : return false;
2039 :
2040 2382 : if (!single_pred_p (cond_bb) || !cond_only_block_p (cond_bb))
2041 11 : return false;
2042 :
2043 2371 : basic_block cond2_bb = single_pred (cond_bb);
2044 2371 : if (EDGE_COUNT (cond2_bb->succs) != 2)
2045 : return false;
2046 2371 : edge cond2_phi_edge;
2047 2371 : if (EDGE_SUCC (cond2_bb, 0)->dest == cond_bb)
2048 : {
2049 1970 : if (EDGE_SUCC (cond2_bb, 1)->dest != phi_bb)
2050 : return false;
2051 : cond2_phi_edge = EDGE_SUCC (cond2_bb, 1);
2052 : }
2053 401 : else if (EDGE_SUCC (cond2_bb, 0)->dest != phi_bb)
2054 : return false;
2055 : else
2056 : cond2_phi_edge = EDGE_SUCC (cond2_bb, 0);
2057 2371 : tree arg2 = gimple_phi_arg_def (phi, cond2_phi_edge->dest_idx);
2058 2371 : if (!tree_fits_shwi_p (arg2))
2059 : return false;
2060 4742 : gcond *cond2 = safe_dyn_cast <gcond *> (*gsi_last_bb (cond2_bb));
2061 2371 : if (!cond2)
2062 : return false;
2063 2371 : enum tree_code cmp2 = gimple_cond_code (cond2);
2064 2371 : tree lhs2 = gimple_cond_lhs (cond2);
2065 2371 : tree rhs2 = gimple_cond_rhs (cond2);
2066 2371 : if (lhs2 == lhs1)
2067 : {
2068 2369 : if (!operand_equal_p (rhs2, rhs1, 0))
2069 : {
2070 327 : if ((cmp2 == EQ_EXPR || cmp2 == NE_EXPR)
2071 327 : && TREE_CODE (rhs1) == INTEGER_CST
2072 327 : && TREE_CODE (rhs2) == INTEGER_CST)
2073 : {
2074 : /* For integers, we can have cond2 x == 5
2075 : and cond1 x < 5, x <= 4, x <= 5, x < 6,
2076 : x > 5, x >= 6, x >= 5 or x > 4. */
2077 327 : if (tree_int_cst_lt (rhs1, rhs2))
2078 : {
2079 327 : if (wi::ne_p (wi::to_wide (rhs1) + 1, wi::to_wide (rhs2)))
2080 : return false;
2081 327 : if (cmp1 == LE_EXPR)
2082 : cmp1 = LT_EXPR;
2083 0 : else if (cmp1 == GT_EXPR)
2084 : cmp1 = GE_EXPR;
2085 : else
2086 : return false;
2087 : }
2088 : else
2089 : {
2090 0 : gcc_checking_assert (tree_int_cst_lt (rhs2, rhs1));
2091 0 : if (wi::ne_p (wi::to_wide (rhs2) + 1, wi::to_wide (rhs1)))
2092 : return false;
2093 0 : if (cmp1 == LT_EXPR)
2094 : cmp1 = LE_EXPR;
2095 0 : else if (cmp1 == GE_EXPR)
2096 : cmp1 = GT_EXPR;
2097 : else
2098 : return false;
2099 : }
2100 : rhs1 = rhs2;
2101 : }
2102 : else
2103 : return false;
2104 : }
2105 : }
2106 2 : else if (lhs2 == rhs1)
2107 : {
2108 0 : if (rhs2 != lhs1)
2109 : return false;
2110 : }
2111 : else
2112 : return false;
2113 :
2114 2369 : tree arg3 = arg2;
2115 2369 : basic_block cond3_bb = cond2_bb;
2116 2369 : edge cond3_phi_edge = cond2_phi_edge;
2117 2369 : gcond *cond3 = cond2;
2118 2369 : enum tree_code cmp3 = cmp2;
2119 2369 : tree lhs3 = lhs2;
2120 2369 : tree rhs3 = rhs2;
2121 2369 : if (EDGE_COUNT (phi_bb->preds) == 4)
2122 : {
2123 405 : if (absu_hwi (tree_to_shwi (arg2)) != 1)
2124 : return false;
2125 397 : if ((cond2_phi_edge->flags & EDGE_FALSE_VALUE)
2126 397 : && HONOR_NANS (TREE_TYPE (lhs1)))
2127 : return false;
2128 397 : if (e1->flags & EDGE_TRUE_VALUE)
2129 : {
2130 397 : if (tree_to_shwi (arg0) != -128
2131 397 : || absu_hwi (tree_to_shwi (arg1)) != 1
2132 794 : || wi::to_widest (arg1) == wi::to_widest (arg2))
2133 0 : return false;
2134 : }
2135 0 : else if (tree_to_shwi (arg1) != -128
2136 0 : || absu_hwi (tree_to_shwi (arg0)) != 1
2137 0 : || wi::to_widest (arg0) == wi::to_widest (arg2))
2138 0 : return false;
2139 397 : switch (cmp2)
2140 : {
2141 397 : case LT_EXPR:
2142 397 : case LE_EXPR:
2143 397 : case GT_EXPR:
2144 397 : case GE_EXPR:
2145 397 : break;
2146 : default:
2147 : return false;
2148 : }
2149 : /* if (x < y) goto phi_bb; else fallthru;
2150 : if (x > y) goto phi_bb; else fallthru;
2151 : bbx:;
2152 : phi_bb:;
2153 : is ok, but if x and y are swapped in one of the comparisons,
2154 : or the comparisons are the same and operands not swapped,
2155 : or the true and false edges are swapped, it is not.
2156 : For HONOR_NANS, the edge flags are irrelevant and the comparisons
2157 : must be different for non-swapped operands and same for swapped
2158 : operands. */
2159 397 : if ((lhs2 == lhs1)
2160 397 : ^ (HONOR_NANS (TREE_TYPE (lhs1))
2161 397 : ? ((cmp2 == LT_EXPR || cmp2 == LE_EXPR)
2162 269 : != (cmp1 == LT_EXPR || cmp1 == LE_EXPR))
2163 128 : : (((cond2_phi_edge->flags
2164 128 : & ((cmp2 == LT_EXPR || cmp2 == LE_EXPR)
2165 128 : ? EDGE_TRUE_VALUE : EDGE_FALSE_VALUE)) != 0)
2166 256 : != ((e1->flags
2167 128 : & ((cmp1 == LT_EXPR || cmp1 == LE_EXPR)
2168 128 : ? EDGE_TRUE_VALUE : EDGE_FALSE_VALUE)) != 0))))
2169 : return false;
2170 397 : if (!single_pred_p (cond2_bb) || !cond_only_block_p (cond2_bb))
2171 0 : return false;
2172 397 : cond3_bb = single_pred (cond2_bb);
2173 397 : if (EDGE_COUNT (cond2_bb->succs) != 2)
2174 : return false;
2175 397 : if (EDGE_SUCC (cond3_bb, 0)->dest == cond2_bb)
2176 : {
2177 221 : if (EDGE_SUCC (cond3_bb, 1)->dest != phi_bb)
2178 : return false;
2179 : cond3_phi_edge = EDGE_SUCC (cond3_bb, 1);
2180 : }
2181 176 : else if (EDGE_SUCC (cond3_bb, 0)->dest != phi_bb)
2182 : return false;
2183 : else
2184 : cond3_phi_edge = EDGE_SUCC (cond3_bb, 0);
2185 397 : arg3 = gimple_phi_arg_def (phi, cond3_phi_edge->dest_idx);
2186 627043 : cond3 = safe_dyn_cast <gcond *> (*gsi_last_bb (cond3_bb));
2187 397 : if (!cond3)
2188 : return false;
2189 397 : cmp3 = gimple_cond_code (cond3);
2190 397 : lhs3 = gimple_cond_lhs (cond3);
2191 397 : rhs3 = gimple_cond_rhs (cond3);
2192 397 : if (lhs3 == lhs1)
2193 : {
2194 397 : if (!operand_equal_p (rhs3, rhs1, 0))
2195 : return false;
2196 : }
2197 0 : else if (lhs3 == rhs1)
2198 : {
2199 0 : if (rhs3 != lhs1)
2200 : return false;
2201 : }
2202 : else
2203 : return false;
2204 : }
2205 1964 : else if (absu_hwi (tree_to_shwi (arg0)) != 1
2206 1944 : || absu_hwi (tree_to_shwi (arg1)) != 1
2207 3888 : || wi::to_widest (arg0) == wi::to_widest (arg1)
2208 3908 : || HONOR_NANS (TREE_TYPE (lhs1)))
2209 20 : return false;
2210 :
2211 2341 : if (!integer_zerop (arg3) || (cmp3 != EQ_EXPR && cmp3 != NE_EXPR))
2212 : return false;
2213 2341 : if ((cond3_phi_edge->flags & (cmp3 == EQ_EXPR
2214 2341 : ? EDGE_TRUE_VALUE : EDGE_FALSE_VALUE)) == 0)
2215 : return false;
2216 :
2217 : /* lhs1 one_cmp rhs1 results in phires of 1. */
2218 2341 : enum tree_code one_cmp;
2219 4682 : if ((cmp1 == LT_EXPR || cmp1 == LE_EXPR)
2220 2413 : ^ (!integer_onep ((e1->flags & EDGE_TRUE_VALUE) ? arg1 : arg0)))
2221 : one_cmp = LT_EXPR;
2222 : else
2223 1736 : one_cmp = GT_EXPR;
2224 :
2225 2341 : enum tree_code res_cmp;
2226 2341 : bool negate_p = false;
2227 2341 : switch (cmp)
2228 : {
2229 1275 : case EQ_EXPR:
2230 1275 : if (integer_zerop (rhs) && !HONOR_NANS (TREE_TYPE (lhs1)))
2231 : res_cmp = EQ_EXPR;
2232 1191 : else if (integer_minus_onep (rhs))
2233 758 : res_cmp = one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR;
2234 433 : else if (integer_onep (rhs))
2235 : res_cmp = one_cmp;
2236 : else
2237 : return false;
2238 : break;
2239 968 : case NE_EXPR:
2240 968 : if (integer_zerop (rhs) && !HONOR_NANS (TREE_TYPE (lhs1)))
2241 : res_cmp = NE_EXPR;
2242 930 : else if (integer_minus_onep (rhs))
2243 560 : res_cmp = one_cmp == LT_EXPR ? LE_EXPR : GE_EXPR;
2244 428 : else if (integer_onep (rhs))
2245 639 : res_cmp = one_cmp == LT_EXPR ? GE_EXPR : LE_EXPR;
2246 : else
2247 : return false;
2248 938 : if (HONOR_NANS (TREE_TYPE (lhs1)))
2249 : negate_p = true;
2250 : break;
2251 27 : case LT_EXPR:
2252 27 : if (integer_onep (rhs))
2253 0 : res_cmp = one_cmp == LT_EXPR ? GE_EXPR : LE_EXPR;
2254 27 : else if (integer_zerop (rhs))
2255 27 : res_cmp = one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR;
2256 : else
2257 : return false;
2258 27 : if (HONOR_NANS (TREE_TYPE (lhs1)))
2259 : negate_p = true;
2260 : break;
2261 4 : case LE_EXPR:
2262 4 : if (integer_zerop (rhs))
2263 4 : res_cmp = one_cmp == LT_EXPR ? GE_EXPR : LE_EXPR;
2264 0 : else if (integer_minus_onep (rhs))
2265 0 : res_cmp = one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR;
2266 : else
2267 : return false;
2268 4 : if (HONOR_NANS (TREE_TYPE (lhs1)))
2269 : negate_p = true;
2270 : break;
2271 0 : case GT_EXPR:
2272 0 : if (integer_minus_onep (rhs))
2273 0 : res_cmp = one_cmp == LT_EXPR ? LE_EXPR : GE_EXPR;
2274 0 : else if (integer_zerop (rhs))
2275 : res_cmp = one_cmp;
2276 : else
2277 : return false;
2278 : break;
2279 67 : case GE_EXPR:
2280 67 : if (integer_zerop (rhs))
2281 67 : res_cmp = one_cmp == LT_EXPR ? LE_EXPR : GE_EXPR;
2282 0 : else if (integer_onep (rhs))
2283 : res_cmp = one_cmp;
2284 : else
2285 : return false;
2286 : break;
2287 0 : default:
2288 0 : gcc_unreachable ();
2289 : }
2290 2269 : if (orig_use_lhs)
2291 88 : res_cmp = swap_tree_comparison (res_cmp);
2292 :
2293 2269 : tree clhs1 = lhs1, crhs1 = rhs1;
2294 2269 : if (negate_p)
2295 : {
2296 48 : if (cfun->can_throw_non_call_exceptions)
2297 0 : return false;
2298 48 : res_cmp = invert_tree_comparison (res_cmp, false);
2299 48 : clhs1 = make_ssa_name (boolean_type_node);
2300 48 : gimple *g = gimple_build_assign (clhs1, res_cmp, lhs1, rhs1);
2301 48 : gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
2302 48 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2303 48 : crhs1 = boolean_false_node;
2304 48 : res_cmp = EQ_EXPR;
2305 : }
2306 :
2307 2269 : if (gimple_code (use_stmt) == GIMPLE_COND)
2308 : {
2309 1641 : gcond *use_cond = as_a <gcond *> (use_stmt);
2310 1641 : gimple_cond_set_code (use_cond, res_cmp);
2311 1641 : gimple_cond_set_lhs (use_cond, clhs1);
2312 1641 : gimple_cond_set_rhs (use_cond, crhs1);
2313 : }
2314 628 : else if (gimple_assign_rhs_class (use_stmt) == GIMPLE_BINARY_RHS)
2315 : {
2316 628 : gimple_assign_set_rhs_code (use_stmt, res_cmp);
2317 628 : gimple_assign_set_rhs1 (use_stmt, clhs1);
2318 628 : gimple_assign_set_rhs2 (use_stmt, crhs1);
2319 : }
2320 : else
2321 : {
2322 0 : tree cond = build2 (res_cmp, TREE_TYPE (gimple_assign_rhs1 (use_stmt)),
2323 : clhs1, crhs1);
2324 0 : gimple_assign_set_rhs1 (use_stmt, cond);
2325 : }
2326 2269 : update_stmt (use_stmt);
2327 :
2328 2269 : if (MAY_HAVE_DEBUG_BIND_STMTS)
2329 : {
2330 1934 : use_operand_p use_p;
2331 1934 : imm_use_iterator iter;
2332 1934 : bool has_debug_uses = false;
2333 1934 : bool has_cast1_debug_uses = false;
2334 1934 : bool has_neg_debug_uses = false;
2335 1934 : bool has_cast2_debug_uses = false;
2336 3912 : FOR_EACH_IMM_USE_FAST (use_p, iter, phires)
2337 : {
2338 1978 : gimple *use_stmt = USE_STMT (use_p);
2339 1978 : if (is_gimple_debug (use_stmt))
2340 : {
2341 : has_debug_uses = true;
2342 : break;
2343 : }
2344 1934 : }
2345 1934 : if (orig_use_lhs)
2346 : {
2347 132 : FOR_EACH_IMM_USE_FAST (use_p, iter, temps[0])
2348 : {
2349 76 : gimple *use_stmt = USE_STMT (use_p);
2350 76 : if (is_gimple_debug (use_stmt))
2351 : {
2352 : has_debug_uses = true;
2353 : has_cast1_debug_uses = true;
2354 : break;
2355 : }
2356 44 : }
2357 132 : FOR_EACH_IMM_USE_FAST (use_p, iter, temps[1])
2358 : {
2359 76 : gimple *use_stmt = USE_STMT (use_p);
2360 76 : if (is_gimple_debug (use_stmt))
2361 : {
2362 : has_debug_uses = true;
2363 : has_cast1_debug_uses = true;
2364 : has_neg_debug_uses = true;
2365 : break;
2366 : }
2367 44 : }
2368 88 : FOR_EACH_IMM_USE_FAST (use_p, iter, orig_use_lhs)
2369 : {
2370 32 : gimple *use_stmt = USE_STMT (use_p);
2371 32 : if (is_gimple_debug (use_stmt))
2372 : {
2373 : has_debug_uses = true;
2374 : has_cast1_debug_uses = true;
2375 : has_neg_debug_uses = true;
2376 : has_cast2_debug_uses = true;
2377 : break;
2378 : }
2379 44 : }
2380 44 : if (has_debug_uses)
2381 : {
2382 44 : gimple_stmt_iterator gsi = gsi_for_stmt (orig_use_stmt);
2383 44 : tree zero = build_zero_cst (TREE_TYPE (temps[0]));
2384 44 : gimple_assign_set_rhs_with_ops (&gsi, INTEGER_CST, zero);
2385 44 : update_stmt (orig_use_stmt);
2386 44 : gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (temps[1]));
2387 44 : zero = build_zero_cst (TREE_TYPE (temps[1]));
2388 44 : gimple_assign_set_rhs_with_ops (&gsi, INTEGER_CST, zero);
2389 44 : update_stmt (SSA_NAME_DEF_STMT (temps[1]));
2390 44 : gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (orig_use_lhs));
2391 44 : zero = build_zero_cst (TREE_TYPE (orig_use_lhs));
2392 44 : gimple_assign_set_rhs_with_ops (&gsi, INTEGER_CST, zero);
2393 44 : update_stmt (SSA_NAME_DEF_STMT (orig_use_lhs));
2394 : }
2395 : }
2396 :
2397 1934 : if (has_debug_uses)
2398 : {
2399 : /* If there are debug uses, emit something like:
2400 : # DEBUG D#1 => i_2(D) > j_3(D) ? 1 : -1
2401 : # DEBUG D#2 => i_2(D) == j_3(D) ? 0 : D#1
2402 : where > stands for the comparison that yielded 1
2403 : and replace debug uses of phi result with that D#2.
2404 : Ignore the value of -128 if !HONOR_NANS, because if NaNs
2405 : aren't expected, all floating point numbers should be
2406 : comparable. If HONOR_NANS, emit something like:
2407 : # DEBUG D#1 => i_2(D) < j_3(D) ? -1 : -128
2408 : # DEBUG D#2 => i_2(D) > j_3(D) ? 1 : D#1
2409 : # DEBUG D#3 => i_2(D) == j_3(D) ? 0 : D#2
2410 : instead. */
2411 1934 : gimple_stmt_iterator gsi = gsi_after_labels (gimple_bb (phi));
2412 1934 : tree type = TREE_TYPE (phires);
2413 1934 : tree minus_one = build_int_cst (type, -1);
2414 1934 : if (HONOR_NANS (TREE_TYPE (lhs1)))
2415 : {
2416 101 : tree temp3 = build_debug_expr_decl (type);
2417 202 : tree t = build2 (one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR,
2418 : boolean_type_node, lhs1, rhs2);
2419 101 : t = build3 (COND_EXPR, type, t, minus_one,
2420 : build_int_cst (type, -128));
2421 101 : gimple *g = gimple_build_debug_bind (temp3, t, phi);
2422 101 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2423 101 : minus_one = temp3;
2424 : }
2425 1934 : tree temp1 = build_debug_expr_decl (type);
2426 1934 : tree t = build2 (one_cmp, boolean_type_node, lhs1, rhs2);
2427 1934 : t = build3 (COND_EXPR, type, t, build_one_cst (type),
2428 : minus_one);
2429 1934 : gimple *g = gimple_build_debug_bind (temp1, t, phi);
2430 1934 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2431 1934 : tree temp2 = build_debug_expr_decl (type);
2432 1934 : t = build2 (EQ_EXPR, boolean_type_node, lhs1, rhs2);
2433 1934 : t = build3 (COND_EXPR, type, t, build_zero_cst (type), temp1);
2434 1934 : g = gimple_build_debug_bind (temp2, t, phi);
2435 1934 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2436 1934 : replace_uses_by (phires, temp2);
2437 1934 : if (has_cast1_debug_uses)
2438 : {
2439 32 : tree temp3 = build_debug_expr_decl (TREE_TYPE (temps[0]));
2440 32 : t = fold_convert (TREE_TYPE (temps[0]), temp2);
2441 32 : g = gimple_build_debug_bind (temp3, t, phi);
2442 32 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2443 32 : replace_uses_by (temps[0], temp3);
2444 32 : temp2 = temp3;
2445 : }
2446 1934 : if (has_neg_debug_uses)
2447 : {
2448 32 : tree temp3 = build_debug_expr_decl (TREE_TYPE (temps[1]));
2449 32 : t = fold_build1 (NEGATE_EXPR, TREE_TYPE (temps[1]), temp2);
2450 32 : g = gimple_build_debug_bind (temp3, t, phi);
2451 32 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2452 32 : replace_uses_by (temps[1], temp3);
2453 32 : temp2 = temp3;
2454 : }
2455 1934 : if (has_cast2_debug_uses)
2456 : {
2457 32 : tree temp3 = build_debug_expr_decl (TREE_TYPE (orig_use_lhs));
2458 32 : t = fold_convert (TREE_TYPE (orig_use_lhs), temp2);
2459 32 : g = gimple_build_debug_bind (temp3, t, phi);
2460 32 : gsi_insert_before (&gsi, g, GSI_SAME_STMT);
2461 32 : replace_uses_by (orig_use_lhs, temp3);
2462 : }
2463 : }
2464 : }
2465 :
2466 2269 : if (orig_use_lhs)
2467 : {
2468 88 : gimple_stmt_iterator gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (orig_use_lhs));
2469 88 : gsi_remove (&gsi, true);
2470 88 : gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (temps[1]));
2471 88 : gsi_remove (&gsi, true);
2472 88 : gsi = gsi_for_stmt (orig_use_stmt);
2473 88 : gsi_remove (&gsi, true);
2474 88 : release_ssa_name (orig_use_lhs);
2475 88 : release_ssa_name (temps[1]);
2476 88 : release_ssa_name (temps[0]);
2477 : }
2478 :
2479 2269 : gimple_stmt_iterator psi = gsi_for_stmt (phi);
2480 2269 : remove_phi_node (&psi, true);
2481 2269 : statistics_counter_event (cfun, "spaceship replacement", 1);
2482 :
2483 2269 : return true;
2484 : }
2485 :
2486 : /* Optimize x ? __builtin_fun (x) : C, where C is __builtin_fun (0).
2487 : Convert
2488 :
2489 : <bb 2>
2490 : if (b_4(D) != 0)
2491 : goto <bb 3>
2492 : else
2493 : goto <bb 4>
2494 :
2495 : <bb 3>
2496 : _2 = (unsigned long) b_4(D);
2497 : _9 = __builtin_popcountl (_2);
2498 : OR
2499 : _9 = __builtin_popcountl (b_4(D));
2500 :
2501 : <bb 4>
2502 : c_12 = PHI <0(2), _9(3)>
2503 :
2504 : Into
2505 : <bb 2>
2506 : _2 = (unsigned long) b_4(D);
2507 : _9 = __builtin_popcountl (_2);
2508 : OR
2509 : _9 = __builtin_popcountl (b_4(D));
2510 :
2511 : <bb 4>
2512 : c_12 = PHI <_9(2)>
2513 :
2514 : Similarly for __builtin_clz or __builtin_ctz if
2515 : C?Z_DEFINED_VALUE_AT_ZERO is 2, optab is present and
2516 : instead of 0 above it uses the value from that macro. */
2517 :
2518 : static bool
2519 435937 : cond_removal_in_builtin_zero_pattern (basic_block cond_bb,
2520 : basic_block middle_bb,
2521 : edge e1, edge e2, gphi *phi,
2522 : tree arg0, tree arg1)
2523 : {
2524 435937 : gimple_stmt_iterator gsi, gsi_from;
2525 435937 : gimple *call;
2526 435937 : gimple *cast = NULL;
2527 435937 : tree lhs, arg;
2528 :
2529 : /* Check that
2530 : _2 = (unsigned long) b_4(D);
2531 : _9 = __builtin_popcountl (_2);
2532 : OR
2533 : _9 = __builtin_popcountl (b_4(D));
2534 : are the only stmts in the middle_bb. */
2535 :
2536 435937 : gsi = gsi_start_nondebug_after_labels_bb (middle_bb);
2537 435937 : if (gsi_end_p (gsi))
2538 : return false;
2539 268828 : cast = gsi_stmt (gsi);
2540 268828 : gsi_next_nondebug (&gsi);
2541 268828 : if (!gsi_end_p (gsi))
2542 : {
2543 137943 : call = gsi_stmt (gsi);
2544 137943 : gsi_next_nondebug (&gsi);
2545 137943 : if (!gsi_end_p (gsi))
2546 : return false;
2547 : }
2548 : else
2549 : {
2550 : call = cast;
2551 : cast = NULL;
2552 : }
2553 :
2554 : /* Check that we have a popcount/clz/ctz builtin. */
2555 178465 : if (!is_gimple_call (call))
2556 : return false;
2557 :
2558 5521 : lhs = gimple_get_lhs (call);
2559 :
2560 5521 : if (lhs == NULL_TREE)
2561 : return false;
2562 :
2563 5495 : combined_fn cfn = gimple_call_combined_fn (call);
2564 5495 : if (gimple_call_num_args (call) != 1
2565 5495 : && (gimple_call_num_args (call) != 2
2566 : || cfn == CFN_CLZ
2567 585 : || cfn == CFN_CTZ))
2568 : return false;
2569 :
2570 3989 : arg = gimple_call_arg (call, 0);
2571 :
2572 3989 : internal_fn ifn = IFN_LAST;
2573 3989 : int val = 0;
2574 3989 : bool any_val = false;
2575 3989 : switch (cfn)
2576 : {
2577 : case CFN_BUILT_IN_BSWAP16:
2578 : case CFN_BUILT_IN_BSWAP32:
2579 : case CFN_BUILT_IN_BSWAP64:
2580 : case CFN_BUILT_IN_BSWAP128:
2581 : CASE_CFN_FFS:
2582 : CASE_CFN_PARITY:
2583 : CASE_CFN_POPCOUNT:
2584 : break;
2585 694 : CASE_CFN_CLZ:
2586 694 : if (INTEGRAL_TYPE_P (TREE_TYPE (arg)))
2587 : {
2588 694 : tree type = TREE_TYPE (arg);
2589 694 : if (TREE_CODE (type) == BITINT_TYPE)
2590 : {
2591 4 : if (gimple_call_num_args (call) == 1)
2592 : {
2593 : any_val = true;
2594 : ifn = IFN_CLZ;
2595 : break;
2596 : }
2597 0 : if (!tree_fits_shwi_p (gimple_call_arg (call, 1)))
2598 : return false;
2599 0 : HOST_WIDE_INT at_zero = tree_to_shwi (gimple_call_arg (call, 1));
2600 0 : if ((int) at_zero != at_zero)
2601 : return false;
2602 0 : ifn = IFN_CLZ;
2603 0 : val = at_zero;
2604 0 : break;
2605 : }
2606 690 : if (direct_internal_fn_supported_p (IFN_CLZ, type, OPTIMIZE_FOR_BOTH)
2607 1355 : && CLZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (type),
2608 : val) == 2)
2609 : {
2610 : ifn = IFN_CLZ;
2611 : break;
2612 : }
2613 : }
2614 : return false;
2615 263 : CASE_CFN_CTZ:
2616 263 : if (INTEGRAL_TYPE_P (TREE_TYPE (arg)))
2617 : {
2618 263 : tree type = TREE_TYPE (arg);
2619 263 : if (TREE_CODE (type) == BITINT_TYPE)
2620 : {
2621 4 : if (gimple_call_num_args (call) == 1)
2622 : {
2623 : any_val = true;
2624 : ifn = IFN_CTZ;
2625 : break;
2626 : }
2627 0 : if (!tree_fits_shwi_p (gimple_call_arg (call, 1)))
2628 : return false;
2629 0 : HOST_WIDE_INT at_zero = tree_to_shwi (gimple_call_arg (call, 1));
2630 0 : if ((int) at_zero != at_zero)
2631 : return false;
2632 0 : ifn = IFN_CTZ;
2633 0 : val = at_zero;
2634 0 : break;
2635 : }
2636 259 : if (direct_internal_fn_supported_p (IFN_CTZ, type, OPTIMIZE_FOR_BOTH)
2637 497 : && CTZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (type),
2638 : val) == 2)
2639 : {
2640 : ifn = IFN_CTZ;
2641 : break;
2642 : }
2643 : }
2644 : return false;
2645 3 : case CFN_BUILT_IN_CLRSB:
2646 3 : val = TYPE_PRECISION (integer_type_node) - 1;
2647 3 : break;
2648 3 : case CFN_BUILT_IN_CLRSBL:
2649 3 : val = TYPE_PRECISION (long_integer_type_node) - 1;
2650 3 : break;
2651 3 : case CFN_BUILT_IN_CLRSBLL:
2652 3 : val = TYPE_PRECISION (long_long_integer_type_node) - 1;
2653 3 : break;
2654 : default:
2655 : return false;
2656 : }
2657 :
2658 142 : if (cast)
2659 : {
2660 : /* We have a cast stmt feeding popcount/clz/ctz builtin. */
2661 : /* Check that we have a cast prior to that. */
2662 54 : if (gimple_code (cast) != GIMPLE_ASSIGN
2663 54 : || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (cast)))
2664 : return false;
2665 : /* Result of the cast stmt is the argument to the builtin. */
2666 24 : if (arg != gimple_assign_lhs (cast))
2667 : return false;
2668 24 : arg = gimple_assign_rhs1 (cast);
2669 : }
2670 :
2671 224 : gcond *cond = dyn_cast <gcond *> (*gsi_last_bb (cond_bb));
2672 :
2673 : /* Cond_bb has a check for b_4 [!=|==] 0 before calling the popcount/clz/ctz
2674 : builtin. */
2675 112 : if (!cond
2676 112 : || (gimple_cond_code (cond) != NE_EXPR
2677 20 : && gimple_cond_code (cond) != EQ_EXPR)
2678 112 : || !integer_zerop (gimple_cond_rhs (cond))
2679 112 : || arg != gimple_cond_lhs (cond))
2680 78 : return false;
2681 :
2682 34 : edge true_edge, false_edge;
2683 : /* We need to know which is the true edge and which is the false
2684 : edge so that we know when to invert the condition below. */
2685 34 : extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
2686 :
2687 : /* Forward the edges over the middle basic block. */
2688 34 : if (true_edge->dest == middle_bb)
2689 34 : true_edge = EDGE_SUCC (true_edge->dest, 0);
2690 34 : if (false_edge->dest == middle_bb)
2691 0 : false_edge = EDGE_SUCC (false_edge->dest, 0);
2692 :
2693 : /* Canonicalize the args with respect to the edges,
2694 : arg0 is from the true edge and arg1 is from the
2695 : false edge.
2696 : That is `cond ? arg0 : arg1`.*/
2697 34 : if (true_edge == e1)
2698 34 : gcc_assert (false_edge == e2);
2699 : else
2700 : {
2701 0 : gcc_assert (false_edge == e1);
2702 0 : gcc_assert (true_edge == e2);
2703 : std::swap (arg0, arg1);
2704 : }
2705 :
2706 : /* Canonicalize the args such that we get:
2707 : `arg != 0 ? arg0 : arg1`. So swap arg0/arg1
2708 : around if cond was an equals. */
2709 34 : if (gimple_cond_code (cond) == EQ_EXPR)
2710 2 : std::swap (arg0, arg1);
2711 :
2712 : /* Check PHI arguments. */
2713 34 : if (lhs != arg0
2714 32 : || TREE_CODE (arg1) != INTEGER_CST)
2715 : return false;
2716 24 : if (any_val)
2717 : {
2718 0 : if (!tree_fits_shwi_p (arg1))
2719 : return false;
2720 0 : HOST_WIDE_INT at_zero = tree_to_shwi (arg1);
2721 0 : if ((int) at_zero != at_zero)
2722 : return false;
2723 0 : val = at_zero;
2724 : }
2725 24 : else if (wi::to_wide (arg1) != val)
2726 : return false;
2727 :
2728 : /* And insert the popcount/clz/ctz builtin and cast stmt before the
2729 : cond_bb. */
2730 13 : gsi = gsi_last_bb (cond_bb);
2731 13 : if (cast)
2732 : {
2733 13 : gsi_from = gsi_for_stmt (cast);
2734 13 : gsi_move_before (&gsi_from, &gsi);
2735 13 : reset_flow_sensitive_info (gimple_get_lhs (cast));
2736 : }
2737 13 : gsi_from = gsi_for_stmt (call);
2738 13 : if (ifn == IFN_LAST
2739 13 : || (gimple_call_internal_p (call) && gimple_call_num_args (call) == 2))
2740 8 : gsi_move_before (&gsi_from, &gsi);
2741 : else
2742 : {
2743 : /* For __builtin_c[lt]z* force .C[LT]Z ifn, because only
2744 : the latter is well defined at zero. */
2745 5 : call = gimple_build_call_internal (ifn, 2, gimple_call_arg (call, 0),
2746 5 : build_int_cst (integer_type_node, val));
2747 5 : gimple_call_set_lhs (call, lhs);
2748 5 : gsi_insert_before (&gsi, call, GSI_SAME_STMT);
2749 5 : gsi_remove (&gsi_from, true);
2750 : }
2751 13 : reset_flow_sensitive_info (lhs);
2752 :
2753 : /* Now update the PHI and remove unneeded bbs. */
2754 13 : replace_phi_edge_with_variable (cond_bb, e2, phi, lhs);
2755 13 : return true;
2756 : }
2757 :
2758 : /* Auxiliary functions to determine the set of memory accesses which
2759 : can't trap because they are preceded by accesses to the same memory
2760 : portion. We do that for MEM_REFs, so we only need to track
2761 : the SSA_NAME of the pointer indirectly referenced. The algorithm
2762 : simply is a walk over all instructions in dominator order. When
2763 : we see an MEM_REF we determine if we've already seen a same
2764 : ref anywhere up to the root of the dominator tree. If we do the
2765 : current access can't trap. If we don't see any dominating access
2766 : the current access might trap, but might also make later accesses
2767 : non-trapping, so we remember it. We need to be careful with loads
2768 : or stores, for instance a load might not trap, while a store would,
2769 : so if we see a dominating read access this doesn't mean that a later
2770 : write access would not trap. Hence we also need to differentiate the
2771 : type of access(es) seen.
2772 :
2773 : ??? We currently are very conservative and assume that a load might
2774 : trap even if a store doesn't (write-only memory). This probably is
2775 : overly conservative.
2776 :
2777 : We currently support a special case that for !TREE_ADDRESSABLE automatic
2778 : variables, it could ignore whether something is a load or store because the
2779 : local stack should be always writable. */
2780 :
2781 : /* A hash-table of references (MEM_REF/ARRAY_REF/COMPONENT_REF), and in which
2782 : basic block an *_REF through it was seen, which would constitute a
2783 : no-trap region for same accesses.
2784 :
2785 : Size is needed to support 2 MEM_REFs of different types, like
2786 : MEM<double>(s_1) and MEM<long>(s_1), which would compare equal with
2787 : OEP_ADDRESS_OF. */
2788 : struct ref_to_bb
2789 : {
2790 : tree exp;
2791 : HOST_WIDE_INT size;
2792 : unsigned int phase;
2793 : basic_block bb;
2794 : };
2795 :
2796 : /* Hashtable helpers. */
2797 :
2798 : struct refs_hasher : free_ptr_hash<ref_to_bb>
2799 : {
2800 : static inline hashval_t hash (const ref_to_bb *);
2801 : static inline bool equal (const ref_to_bb *, const ref_to_bb *);
2802 : };
2803 :
2804 : /* Used for quick clearing of the hash-table when we see calls.
2805 : Hash entries with phase < nt_call_phase are invalid. */
2806 : static unsigned int nt_call_phase;
2807 :
2808 : /* The hash function. */
2809 :
2810 : inline hashval_t
2811 19436820 : refs_hasher::hash (const ref_to_bb *n)
2812 : {
2813 19436820 : inchash::hash hstate;
2814 19436820 : inchash::add_expr (n->exp, hstate, OEP_ADDRESS_OF);
2815 19436820 : hstate.add_hwi (n->size);
2816 19436820 : return hstate.end ();
2817 : }
2818 :
2819 : /* The equality function of *P1 and *P2. */
2820 :
2821 : inline bool
2822 14167839 : refs_hasher::equal (const ref_to_bb *n1, const ref_to_bb *n2)
2823 : {
2824 14167839 : return operand_equal_p (n1->exp, n2->exp, OEP_ADDRESS_OF)
2825 14167839 : && n1->size == n2->size;
2826 : }
2827 :
2828 : class nontrapping_dom_walker : public dom_walker
2829 : {
2830 : public:
2831 1041396 : nontrapping_dom_walker (cdi_direction direction, hash_set<tree> *ps)
2832 1041396 : : dom_walker (direction), m_nontrapping (ps), m_seen_refs (128)
2833 1041396 : {}
2834 :
2835 : edge before_dom_children (basic_block) final override;
2836 : void after_dom_children (basic_block) final override;
2837 :
2838 : private:
2839 :
2840 : /* We see the expression EXP in basic block BB. If it's an interesting
2841 : expression (an MEM_REF through an SSA_NAME) possibly insert the
2842 : expression into the set NONTRAP or the hash table of seen expressions.
2843 : STORE is true if this expression is on the LHS, otherwise it's on
2844 : the RHS. */
2845 : void add_or_mark_expr (basic_block, tree, bool);
2846 :
2847 : hash_set<tree> *m_nontrapping;
2848 :
2849 : /* The hash table for remembering what we've seen. */
2850 : hash_table<refs_hasher> m_seen_refs;
2851 : };
2852 :
2853 : /* Called by walk_dominator_tree, when entering the block BB. */
2854 : edge
2855 11615164 : nontrapping_dom_walker::before_dom_children (basic_block bb)
2856 : {
2857 11615164 : edge e;
2858 11615164 : edge_iterator ei;
2859 11615164 : gimple_stmt_iterator gsi;
2860 :
2861 : /* If we haven't seen all our predecessors, clear the hash-table. */
2862 25516825 : FOR_EACH_EDGE (e, ei, bb->preds)
2863 14588718 : if ((((size_t)e->src->aux) & 2) == 0)
2864 : {
2865 687057 : nt_call_phase++;
2866 687057 : break;
2867 : }
2868 :
2869 : /* Mark this BB as being on the path to dominator root and as visited. */
2870 11615164 : bb->aux = (void*)(1 | 2);
2871 :
2872 : /* And walk the statements in order. */
2873 101813262 : for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2874 : {
2875 78582934 : gimple *stmt = gsi_stmt (gsi);
2876 :
2877 78582934 : if ((gimple_code (stmt) == GIMPLE_ASM && gimple_vdef (stmt))
2878 78626081 : || (is_gimple_call (stmt)
2879 5520275 : && (!nonfreeing_call_p (stmt) || !nonbarrier_call_p (stmt))))
2880 4936373 : nt_call_phase++;
2881 88510570 : else if (gimple_assign_single_p (stmt) && !gimple_has_volatile_ops (stmt))
2882 : {
2883 13029054 : add_or_mark_expr (bb, gimple_assign_lhs (stmt), true);
2884 13029054 : add_or_mark_expr (bb, gimple_assign_rhs1 (stmt), false);
2885 : }
2886 : }
2887 11615164 : return NULL;
2888 : }
2889 :
2890 : /* Called by walk_dominator_tree, when basic block BB is exited. */
2891 : void
2892 11615164 : nontrapping_dom_walker::after_dom_children (basic_block bb)
2893 : {
2894 : /* This BB isn't on the path to dominator root anymore. */
2895 11615164 : bb->aux = (void*)2;
2896 11615164 : }
2897 :
2898 : /* We see the expression EXP in basic block BB. If it's an interesting
2899 : expression of:
2900 : 1) MEM_REF
2901 : 2) ARRAY_REF
2902 : 3) COMPONENT_REF
2903 : possibly insert the expression into the set NONTRAP or the hash table
2904 : of seen expressions. STORE is true if this expression is on the LHS,
2905 : otherwise it's on the RHS. */
2906 : void
2907 26058108 : nontrapping_dom_walker::add_or_mark_expr (basic_block bb, tree exp, bool store)
2908 : {
2909 26058108 : HOST_WIDE_INT size;
2910 :
2911 26058108 : if ((TREE_CODE (exp) == MEM_REF || TREE_CODE (exp) == ARRAY_REF
2912 21839470 : || TREE_CODE (exp) == COMPONENT_REF)
2913 33149443 : && (size = int_size_in_bytes (TREE_TYPE (exp))) > 0)
2914 : {
2915 11309968 : struct ref_to_bb map;
2916 11309968 : ref_to_bb **slot;
2917 11309968 : struct ref_to_bb *r2bb;
2918 11309968 : basic_block found_bb = 0;
2919 :
2920 11309968 : if (!store)
2921 : {
2922 5218050 : tree base = get_base_address (exp);
2923 : /* Only record a LOAD of a local variable without address-taken, as
2924 : the local stack is always writable. This allows cselim on a STORE
2925 : with a dominating LOAD. */
2926 5218050 : if (!auto_var_p (base) || TREE_ADDRESSABLE (base))
2927 4251973 : return;
2928 : }
2929 :
2930 : /* Try to find the last seen *_REF, which can trap. */
2931 7057995 : map.exp = exp;
2932 7057995 : map.size = size;
2933 7057995 : slot = m_seen_refs.find_slot (&map, INSERT);
2934 7057995 : r2bb = *slot;
2935 7057995 : if (r2bb && r2bb->phase >= nt_call_phase)
2936 293961 : found_bb = r2bb->bb;
2937 :
2938 : /* If we've found a trapping *_REF, _and_ it dominates EXP
2939 : (it's in a basic block on the path from us to the dominator root)
2940 : then we can't trap. */
2941 293961 : if (found_bb && (((size_t)found_bb->aux) & 1) == 1)
2942 : {
2943 79895 : m_nontrapping->add (exp);
2944 : }
2945 : else
2946 : {
2947 : /* EXP might trap, so insert it into the hash table. */
2948 6978100 : if (r2bb)
2949 : {
2950 980989 : r2bb->phase = nt_call_phase;
2951 980989 : r2bb->bb = bb;
2952 : }
2953 : else
2954 : {
2955 5997111 : r2bb = XNEW (struct ref_to_bb);
2956 5997111 : r2bb->phase = nt_call_phase;
2957 5997111 : r2bb->bb = bb;
2958 5997111 : r2bb->exp = exp;
2959 5997111 : r2bb->size = size;
2960 5997111 : *slot = r2bb;
2961 : }
2962 : }
2963 : }
2964 : }
2965 :
2966 : /* This is the entry point of gathering non trapping memory accesses.
2967 : It will do a dominator walk over the whole function, and it will
2968 : make use of the bb->aux pointers. It returns a set of trees
2969 : (the MEM_REFs itself) which can't trap. */
2970 : static hash_set<tree> *
2971 1041396 : get_non_trapping (void)
2972 : {
2973 1041396 : nt_call_phase = 0;
2974 1041396 : hash_set<tree> *nontrap = new hash_set<tree>;
2975 :
2976 2082792 : nontrapping_dom_walker (CDI_DOMINATORS, nontrap)
2977 1041396 : .walk (cfun->cfg->x_entry_block_ptr);
2978 :
2979 1041396 : clear_aux_for_blocks ();
2980 1041396 : return nontrap;
2981 : }
2982 :
2983 : /* Do the main work of conditional store replacement. We already know
2984 : that the recognized pattern looks like so:
2985 :
2986 : split:
2987 : if (cond) goto MIDDLE_BB; else goto JOIN_BB (edge E1)
2988 : MIDDLE_BB:
2989 : something
2990 : fallthrough (edge E0)
2991 : JOIN_BB:
2992 : some more
2993 :
2994 : We check that MIDDLE_BB contains only one store, that that store
2995 : doesn't trap (not via NOTRAP, but via checking if an access to the same
2996 : memory location dominates us, or the store is to a local addressable
2997 : object) and that the store has a "simple" RHS. */
2998 :
2999 : static bool
3000 426992 : cond_store_replacement (basic_block middle_bb, basic_block join_bb,
3001 : edge e0, edge e1, hash_set<tree> *nontrap)
3002 : {
3003 426992 : gimple *assign = last_and_only_stmt (middle_bb);
3004 426992 : tree lhs, rhs, name, name2;
3005 426992 : gphi *newphi;
3006 426992 : gassign *new_stmt;
3007 426992 : gimple_stmt_iterator gsi;
3008 426992 : location_t locus;
3009 :
3010 : /* Check if middle_bb contains of only one store. */
3011 426992 : if (!assign
3012 173826 : || !gimple_assign_single_p (assign)
3013 458301 : || gimple_has_volatile_ops (assign))
3014 : return false;
3015 :
3016 : /* And no PHI nodes so all uses in the single stmt are also
3017 : available where we insert to. */
3018 31047 : if (!gimple_seq_empty_p (phi_nodes (middle_bb)))
3019 : return false;
3020 :
3021 30914 : locus = gimple_location (assign);
3022 30914 : lhs = gimple_assign_lhs (assign);
3023 30914 : rhs = gimple_assign_rhs1 (assign);
3024 30914 : if ((!REFERENCE_CLASS_P (lhs)
3025 30914 : && !DECL_P (lhs))
3026 30914 : || !is_gimple_reg_type (TREE_TYPE (lhs)))
3027 : return false;
3028 :
3029 : /* Prove that we can move the store down. We could also check
3030 : TREE_THIS_NOTRAP here, but in that case we also could move stores,
3031 : whose value is not available readily, which we want to avoid. */
3032 17605 : if (!nontrap->contains (lhs))
3033 : {
3034 : /* If LHS is an access to a local variable without address-taken
3035 : (or when we allow data races) and known not to trap, we could
3036 : always safely move down the store. */
3037 11945 : tree base;
3038 11945 : if (ref_can_have_store_data_races (lhs)
3039 333 : || tree_could_trap_p (lhs)
3040 : /* tree_could_trap_p is a predicate for rvalues, so check
3041 : for readonly memory explicitly. */
3042 12159 : || ((base = get_base_address (lhs))
3043 214 : && ((DECL_P (base)
3044 207 : && TREE_READONLY (base))
3045 209 : || TREE_CODE (base) == STRING_CST)))
3046 11742 : return false;
3047 : }
3048 :
3049 : /* Now we've checked the constraints, so do the transformation:
3050 : 1) Remove the single store. */
3051 5863 : gsi = gsi_for_stmt (assign);
3052 5863 : unlink_stmt_vdef (assign);
3053 5863 : gsi_remove (&gsi, true);
3054 5863 : release_defs (assign);
3055 :
3056 : /* Make both store and load use alias-set zero as we have to
3057 : deal with the case of the store being a conditional change
3058 : of the dynamic type. */
3059 5863 : lhs = unshare_expr (lhs);
3060 5863 : tree *basep = &lhs;
3061 11774 : while (handled_component_p (*basep))
3062 5911 : basep = &TREE_OPERAND (*basep, 0);
3063 5863 : if (TREE_CODE (*basep) == MEM_REF
3064 5863 : || TREE_CODE (*basep) == TARGET_MEM_REF)
3065 585 : TREE_OPERAND (*basep, 1)
3066 1170 : = fold_convert (ptr_type_node, TREE_OPERAND (*basep, 1));
3067 : else
3068 5278 : *basep = build2 (MEM_REF, TREE_TYPE (*basep),
3069 : build_fold_addr_expr (*basep),
3070 : build_zero_cst (ptr_type_node));
3071 :
3072 : /* 2) Insert a load from the memory of the store to the temporary
3073 : on the edge which did not contain the store. */
3074 5863 : name = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
3075 5863 : new_stmt = gimple_build_assign (name, lhs);
3076 5863 : gimple_set_location (new_stmt, locus);
3077 5863 : lhs = unshare_expr (lhs);
3078 5863 : {
3079 : /* Set the no-warning bit on the rhs of the load to avoid uninit
3080 : warnings. */
3081 5863 : tree rhs1 = gimple_assign_rhs1 (new_stmt);
3082 5863 : suppress_warning (rhs1, OPT_Wuninitialized);
3083 : }
3084 5863 : gsi_insert_on_edge (e1, new_stmt);
3085 :
3086 : /* 3) Create a PHI node at the join block, with one argument
3087 : holding the old RHS, and the other holding the temporary
3088 : where we stored the old memory contents. */
3089 5863 : name2 = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
3090 5863 : newphi = create_phi_node (name2, join_bb);
3091 5863 : add_phi_arg (newphi, rhs, e0, locus);
3092 5863 : add_phi_arg (newphi, name, e1, locus);
3093 :
3094 5863 : new_stmt = gimple_build_assign (lhs, gimple_phi_result (newphi));
3095 :
3096 : /* 4) Insert that PHI node. */
3097 5863 : gsi = gsi_after_labels (join_bb);
3098 5863 : if (gsi_end_p (gsi))
3099 : {
3100 25 : gsi = gsi_last_bb (join_bb);
3101 25 : gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
3102 : }
3103 : else
3104 5838 : gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
3105 :
3106 5863 : if (dump_file && (dump_flags & TDF_DETAILS))
3107 : {
3108 7 : fprintf (dump_file, "\nConditional store replacement happened!");
3109 7 : fprintf (dump_file, "\nReplaced the store with a load.");
3110 7 : fprintf (dump_file, "\nInserted a new PHI statement in joint block:\n");
3111 7 : print_gimple_stmt (dump_file, new_stmt, 0, TDF_VOPS|TDF_MEMSYMS);
3112 : }
3113 5863 : statistics_counter_event (cfun, "conditional store replacement", 1);
3114 :
3115 5863 : return true;
3116 : }
3117 :
3118 : /* Do the main work of conditional store replacement. */
3119 :
3120 : static bool
3121 824763 : cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb,
3122 : basic_block join_bb, gimple *then_assign,
3123 : gimple *else_assign,
3124 : gphi *vphi)
3125 : {
3126 824763 : tree lhs_base, lhs, then_rhs, else_rhs, name;
3127 824763 : location_t then_locus, else_locus;
3128 824763 : gimple_stmt_iterator gsi;
3129 824763 : gphi *newphi = nullptr;
3130 824763 : gassign *new_stmt;
3131 :
3132 824763 : if (then_assign == NULL
3133 824763 : || !gimple_assign_single_p (then_assign)
3134 756342 : || else_assign == NULL
3135 756342 : || !gimple_assign_single_p (else_assign)
3136 84286 : || stmt_references_abnormal_ssa_name (then_assign)
3137 909035 : || stmt_references_abnormal_ssa_name (else_assign))
3138 740491 : return false;
3139 :
3140 : /* Allow both being clobbers but no other volatile operations. */
3141 84272 : if (gimple_clobber_p (then_assign)
3142 84272 : && gimple_clobber_p (else_assign))
3143 : ;
3144 152144 : else if (gimple_has_volatile_ops (then_assign)
3145 152144 : || gimple_has_volatile_ops (else_assign))
3146 : return false;
3147 :
3148 81311 : lhs = gimple_assign_lhs (then_assign);
3149 81311 : if (!operand_equal_p (lhs, gimple_assign_lhs (else_assign), 0))
3150 : return false;
3151 :
3152 30392 : lhs_base = get_base_address (lhs);
3153 30392 : if (lhs_base == NULL_TREE
3154 30392 : || (!DECL_P (lhs_base) && TREE_CODE (lhs_base) != MEM_REF))
3155 : return false;
3156 :
3157 30345 : then_rhs = gimple_assign_rhs1 (then_assign);
3158 30345 : else_rhs = gimple_assign_rhs1 (else_assign);
3159 30345 : then_locus = gimple_location (then_assign);
3160 30345 : else_locus = gimple_location (else_assign);
3161 :
3162 30345 : if (!is_gimple_reg_type (TREE_TYPE (lhs)))
3163 : {
3164 : /* Handle clobbers seperately as operand_equal_p does not check
3165 : the kind of the clobbers being the same. */
3166 5218 : if (TREE_CLOBBER_P (then_rhs) && TREE_CLOBBER_P (else_rhs))
3167 : {
3168 1774 : if (CLOBBER_KIND (then_rhs) != CLOBBER_KIND (else_rhs))
3169 : return false;
3170 : }
3171 3444 : else if (!operand_equal_p (then_rhs, else_rhs))
3172 : return false;
3173 : /* Currently only handle commoning of `= {}`. */
3174 2229 : if (TREE_CODE (then_rhs) != CONSTRUCTOR)
3175 : return false;
3176 : }
3177 :
3178 26972 : if (dump_file && (dump_flags & TDF_DETAILS))
3179 : {
3180 7 : if (TREE_CLOBBER_P (then_rhs))
3181 3 : fprintf(dump_file, "factoring out clobber:\n\tthen:\n");
3182 : else
3183 4 : fprintf(dump_file, "factoring out stores:\n\tthen:\n");
3184 7 : print_gimple_stmt (dump_file, then_assign, 0,
3185 : TDF_VOPS|TDF_MEMSYMS);
3186 7 : fprintf(dump_file, "\telse:\n");
3187 7 : print_gimple_stmt (dump_file, else_assign, 0,
3188 : TDF_VOPS|TDF_MEMSYMS);
3189 7 : fprintf (dump_file, "\n");
3190 : }
3191 :
3192 : /* Now we've checked the constraints, so do the transformation:
3193 : 1) Remove the stores. */
3194 26972 : gsi = gsi_for_stmt (then_assign);
3195 26972 : unlink_stmt_vdef (then_assign);
3196 26972 : gsi_remove (&gsi, true);
3197 26972 : release_defs (then_assign);
3198 :
3199 26972 : gsi = gsi_for_stmt (else_assign);
3200 26972 : unlink_stmt_vdef (else_assign);
3201 26972 : gsi_remove (&gsi, true);
3202 26972 : release_defs (else_assign);
3203 :
3204 : /* 2) Create a PHI node at the join block, with one argument
3205 : holding the old RHS, and the other holding the temporary
3206 : where we stored the old memory contents. */
3207 26972 : if (operand_equal_p (then_rhs, else_rhs))
3208 : name = then_rhs;
3209 : else
3210 : {
3211 23365 : name = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
3212 23365 : newphi = create_phi_node (name, join_bb);
3213 23365 : add_phi_arg (newphi, then_rhs, EDGE_SUCC (then_bb, 0), then_locus);
3214 23365 : add_phi_arg (newphi, else_rhs, EDGE_SUCC (else_bb, 0), else_locus);
3215 : }
3216 :
3217 26972 : new_stmt = gimple_build_assign (lhs, name);
3218 : /* Update the vdef for the new store statement. */
3219 26972 : tree newvphilhs = make_ssa_name (gimple_vop (cfun));
3220 26972 : tree vdef = gimple_phi_result (vphi);
3221 26972 : gimple_set_vuse (new_stmt, newvphilhs);
3222 26972 : gimple_set_vdef (new_stmt, vdef);
3223 26972 : gimple_phi_set_result (vphi, newvphilhs);
3224 26972 : SSA_NAME_DEF_STMT (vdef) = new_stmt;
3225 26972 : update_stmt (vphi);
3226 26972 : if (dump_file && (dump_flags & TDF_DETAILS))
3227 : {
3228 7 : if (newphi)
3229 : {
3230 3 : fprintf(dump_file, "to use phi:\n");
3231 3 : print_gimple_stmt (dump_file, newphi, 0,
3232 : TDF_VOPS|TDF_MEMSYMS);
3233 3 : fprintf(dump_file, "\n");
3234 : }
3235 : else
3236 4 : fprintf(dump_file, "to:\n");
3237 7 : print_gimple_stmt (dump_file, new_stmt, 0,
3238 : TDF_VOPS|TDF_MEMSYMS);
3239 7 : fprintf(dump_file, "\n\n");
3240 : }
3241 :
3242 : /* 3) Insert that new store. */
3243 26972 : gsi = gsi_after_labels (join_bb);
3244 26972 : if (gsi_end_p (gsi))
3245 : {
3246 86 : gsi = gsi_last_bb (join_bb);
3247 86 : gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
3248 : }
3249 : else
3250 26886 : gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
3251 :
3252 26972 : statistics_counter_event (cfun, "if-then-else store replacement", 1);
3253 :
3254 26972 : return true;
3255 : }
3256 :
3257 : /* Return the last store in BB with VDEF or NULL if there are
3258 : loads following the store. VPHI is where the only use of the
3259 : vdef should be. If ONLYONESTORE is true, then the store is
3260 : the only store in the BB. */
3261 :
3262 : static gimple *
3263 1759808 : trailing_store_in_bb (basic_block bb, tree vdef, gphi *vphi, bool onlyonestore)
3264 : {
3265 1759808 : if (SSA_NAME_IS_DEFAULT_DEF (vdef))
3266 : return NULL;
3267 1736306 : gimple *store = SSA_NAME_DEF_STMT (vdef);
3268 1736306 : if (gimple_bb (store) != bb
3269 1736306 : || gimple_code (store) == GIMPLE_PHI)
3270 : return NULL;
3271 :
3272 : /* Verify there is no other store in this BB if requested. */
3273 1696601 : if (onlyonestore
3274 24831 : && !SSA_NAME_IS_DEFAULT_DEF (gimple_vuse (store))
3275 23559 : && gimple_bb (SSA_NAME_DEF_STMT (gimple_vuse (store))) == bb
3276 1704419 : && gimple_code (SSA_NAME_DEF_STMT (gimple_vuse (store))) != GIMPLE_PHI)
3277 : return NULL;
3278 :
3279 :
3280 : /* Verify there is no load or store after the store, the vdef of the store
3281 : should only be used by the vphi joining the 2 bbs. */
3282 1688789 : use_operand_p use_p;
3283 1688789 : gimple *use_stmt;
3284 3377578 : if (!single_imm_use (gimple_vdef (store), &use_p, &use_stmt))
3285 : return NULL;
3286 1667330 : if (use_stmt != vphi)
3287 : return NULL;
3288 :
3289 : return store;
3290 : }
3291 :
3292 : /* Limited Conditional store replacement. We already know
3293 : that the recognized pattern looks like so:
3294 :
3295 : split:
3296 : if (cond) goto THEN_BB; else goto ELSE_BB (edge E1)
3297 : THEN_BB:
3298 : ...
3299 : STORE = Y;
3300 : ...
3301 : goto JOIN_BB;
3302 : ELSE_BB:
3303 : ...
3304 : STORE = Z;
3305 : ...
3306 : fallthrough (edge E0)
3307 : JOIN_BB:
3308 : some more
3309 :
3310 : Handles only the case with store in THEN_BB and ELSE_BB. That is
3311 : cheap enough due to in phiopt and not worry about heurstics. Moving the store
3312 : out might provide an opportunity for a phiopt to happen.
3313 : At -O1 (!flag_expensive_optimizations), this only handles the only store in
3314 : the BBs. */
3315 :
3316 : static bool
3317 982803 : cond_if_else_store_replacement_limited (basic_block then_bb, basic_block else_bb,
3318 : basic_block join_bb)
3319 : {
3320 982803 : gphi *vphi = get_virtual_phi (join_bb);
3321 982803 : if (!vphi)
3322 : return false;
3323 :
3324 915582 : tree then_vdef = PHI_ARG_DEF_FROM_EDGE (vphi, single_succ_edge (then_bb));
3325 1831164 : gimple *then_assign = trailing_store_in_bb (then_bb, then_vdef, vphi,
3326 915582 : !flag_expensive_optimizations);
3327 915582 : if (!then_assign)
3328 : return false;
3329 :
3330 844226 : tree else_vdef = PHI_ARG_DEF_FROM_EDGE (vphi, single_succ_edge (else_bb));
3331 1688452 : gimple *else_assign = trailing_store_in_bb (else_bb, else_vdef, vphi,
3332 844226 : !flag_expensive_optimizations);
3333 844226 : if (!else_assign)
3334 : return false;
3335 :
3336 823104 : return cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb,
3337 823104 : then_assign, else_assign, vphi);
3338 : }
3339 :
3340 : /* Conditional store replacement. We already know
3341 : that the recognized pattern looks like so:
3342 :
3343 : split:
3344 : if (cond) goto THEN_BB; else goto ELSE_BB (edge E1)
3345 : THEN_BB:
3346 : ...
3347 : X = Y;
3348 : ...
3349 : goto JOIN_BB;
3350 : ELSE_BB:
3351 : ...
3352 : X = Z;
3353 : ...
3354 : fallthrough (edge E0)
3355 : JOIN_BB:
3356 : some more
3357 :
3358 : We check that it is safe to sink the store to JOIN_BB by verifying that
3359 : there are no read-after-write or write-after-write dependencies in
3360 : THEN_BB and ELSE_BB. */
3361 :
3362 : static bool
3363 229801 : cond_if_else_store_replacement (basic_block then_bb, basic_block else_bb,
3364 : basic_block join_bb)
3365 : {
3366 229801 : vec<data_reference_p> then_datarefs, else_datarefs;
3367 229801 : vec<ddr_p> then_ddrs, else_ddrs;
3368 229801 : gimple *then_store, *else_store;
3369 229801 : bool found, ok = false, res;
3370 229801 : tree then_lhs, else_lhs;
3371 229801 : basic_block blocks[3];
3372 229801 : gphi *vphi = get_virtual_phi (join_bb);
3373 229801 : if (!vphi)
3374 : return false;
3375 :
3376 : /* Handle the case with trailing stores in THEN_BB and ELSE_BB. That is
3377 : cheap enough to always handle as it allows us to elide dependence
3378 : checking. */
3379 226893 : while (cond_if_else_store_replacement_limited (then_bb, else_bb, join_bb))
3380 : ;
3381 :
3382 : /* If either vectorization or if-conversion is disabled then do
3383 : not sink any stores. */
3384 213918 : if (param_max_stores_to_sink == 0
3385 213917 : || (!flag_tree_loop_vectorize && !flag_tree_slp_vectorize)
3386 209137 : || !flag_tree_loop_if_convert)
3387 : return false;
3388 :
3389 : /* Find data references. */
3390 209134 : then_datarefs.create (1);
3391 209134 : else_datarefs.create (1);
3392 209134 : if ((find_data_references_in_bb (NULL, then_bb, &then_datarefs)
3393 209134 : == chrec_dont_know)
3394 186988 : || !then_datarefs.length ()
3395 181347 : || (find_data_references_in_bb (NULL, else_bb, &else_datarefs)
3396 181347 : == chrec_dont_know)
3397 225680 : || !else_datarefs.length ())
3398 : {
3399 194688 : free_data_refs (then_datarefs);
3400 194688 : free_data_refs (else_datarefs);
3401 194688 : return false;
3402 : }
3403 :
3404 : /* Clear visited on else stores, we want to make sure to pick each store
3405 : at most once to avoid quadratic behavior. */
3406 51192 : for (auto else_dr : else_datarefs)
3407 : {
3408 36746 : if (DR_IS_READ (else_dr))
3409 19027 : continue;
3410 17719 : gimple_set_visited (DR_STMT (else_dr), false);
3411 : }
3412 :
3413 : /* Find pairs of stores with equal LHS. Work from the end to avoid
3414 : re-ordering stores unnecessarily. */
3415 14446 : auto_vec<std::pair<gimple *, gimple *>, 1> stores_pairs;
3416 14446 : unsigned i;
3417 14446 : data_reference_p then_dr;
3418 61631 : FOR_EACH_VEC_ELT_REVERSE (then_datarefs, i, then_dr)
3419 : {
3420 32739 : if (DR_IS_READ (then_dr))
3421 45940 : continue;
3422 :
3423 19538 : then_store = DR_STMT (then_dr);
3424 19538 : then_lhs = gimple_get_lhs (then_store);
3425 19538 : if (then_lhs == NULL_TREE)
3426 0 : continue;
3427 19538 : found = false;
3428 :
3429 19538 : unsigned j;
3430 19538 : data_reference_p else_dr;
3431 90791 : FOR_EACH_VEC_ELT_REVERSE (else_datarefs, j, else_dr)
3432 : {
3433 55438 : if (DR_IS_READ (else_dr))
3434 19955 : continue;
3435 :
3436 35483 : else_store = DR_STMT (else_dr);
3437 35483 : if (gimple_visited_p (else_store))
3438 3535 : continue;
3439 31948 : else_lhs = gimple_get_lhs (else_store);
3440 31948 : if (else_lhs == NULL_TREE)
3441 0 : continue;
3442 :
3443 31948 : if (operand_equal_p (then_lhs, else_lhs, 0))
3444 : {
3445 : found = true;
3446 : break;
3447 : }
3448 : }
3449 :
3450 19538 : if (!found)
3451 15815 : continue;
3452 :
3453 3723 : gimple_set_visited (else_store, true);
3454 3723 : stores_pairs.safe_push (std::make_pair (then_store, else_store));
3455 : }
3456 :
3457 : /* No pairs of stores found. */
3458 14446 : if (!stores_pairs.length ()
3459 14446 : || stores_pairs.length () > (unsigned) param_max_stores_to_sink)
3460 : {
3461 12328 : free_data_refs (then_datarefs);
3462 12328 : free_data_refs (else_datarefs);
3463 12328 : return false;
3464 : }
3465 :
3466 : /* Compute and check data dependencies in both basic blocks. */
3467 2118 : then_ddrs.create (1);
3468 2118 : else_ddrs.create (1);
3469 2118 : if (!compute_all_dependences (then_datarefs, &then_ddrs,
3470 2118 : vNULL, false)
3471 4236 : || !compute_all_dependences (else_datarefs, &else_ddrs,
3472 2118 : vNULL, false))
3473 : {
3474 0 : free_dependence_relations (then_ddrs);
3475 0 : free_dependence_relations (else_ddrs);
3476 0 : free_data_refs (then_datarefs);
3477 0 : free_data_refs (else_datarefs);
3478 0 : return false;
3479 : }
3480 2118 : blocks[0] = then_bb;
3481 2118 : blocks[1] = else_bb;
3482 2118 : blocks[2] = join_bb;
3483 2118 : renumber_gimple_stmt_uids_in_blocks (blocks, 3);
3484 :
3485 : /* Check that there are no read-after-write or write-after-write dependencies
3486 : in THEN_BB. */
3487 13344 : for (auto ddr : then_ddrs)
3488 : {
3489 7715 : struct data_reference *dra = DDR_A (ddr);
3490 7715 : struct data_reference *drb = DDR_B (ddr);
3491 :
3492 7715 : if (DDR_ARE_DEPENDENT (ddr) != chrec_known
3493 7715 : && ((DR_IS_READ (dra) && DR_IS_WRITE (drb)
3494 872 : && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT (drb)))
3495 1597 : || (DR_IS_READ (drb) && DR_IS_WRITE (dra)
3496 466 : && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT (dra)))
3497 1131 : || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb))))
3498 : {
3499 725 : free_dependence_relations (then_ddrs);
3500 725 : free_dependence_relations (else_ddrs);
3501 725 : free_data_refs (then_datarefs);
3502 725 : free_data_refs (else_datarefs);
3503 725 : return false;
3504 : }
3505 : }
3506 :
3507 : /* Check that there are no read-after-write or write-after-write dependencies
3508 : in ELSE_BB. */
3509 8815 : for (auto ddr : else_ddrs)
3510 : {
3511 4800 : struct data_reference *dra = DDR_A (ddr);
3512 4800 : struct data_reference *drb = DDR_B (ddr);
3513 :
3514 4800 : if (DDR_ARE_DEPENDENT (ddr) != chrec_known
3515 4800 : && ((DR_IS_READ (dra) && DR_IS_WRITE (drb)
3516 401 : && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT (drb)))
3517 565 : || (DR_IS_READ (drb) && DR_IS_WRITE (dra)
3518 136 : && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT (dra)))
3519 429 : || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb))))
3520 : {
3521 164 : free_dependence_relations (then_ddrs);
3522 164 : free_dependence_relations (else_ddrs);
3523 164 : free_data_refs (then_datarefs);
3524 164 : free_data_refs (else_datarefs);
3525 164 : return false;
3526 : }
3527 : }
3528 :
3529 : /* Sink stores with same LHS. */
3530 5346 : for (auto &store_pair : stores_pairs)
3531 : {
3532 1659 : then_store = store_pair.first;
3533 1659 : else_store = store_pair.second;
3534 1659 : res = cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb,
3535 : then_store, else_store, vphi);
3536 1659 : ok = ok || res;
3537 : }
3538 :
3539 1229 : free_dependence_relations (then_ddrs);
3540 1229 : free_dependence_relations (else_ddrs);
3541 1229 : free_data_refs (then_datarefs);
3542 1229 : free_data_refs (else_datarefs);
3543 :
3544 1229 : return ok;
3545 14446 : }
3546 :
3547 : /* Return TRUE if STMT has a VUSE whose corresponding VDEF is in BB. */
3548 :
3549 : static bool
3550 11886 : local_mem_dependence (gimple *stmt, basic_block bb)
3551 : {
3552 23772 : tree vuse = gimple_vuse (stmt);
3553 11886 : gimple *def;
3554 :
3555 11886 : if (!vuse)
3556 : return false;
3557 :
3558 11886 : def = SSA_NAME_DEF_STMT (vuse);
3559 11886 : return (def && gimple_bb (def) == bb);
3560 : }
3561 :
3562 : /* Given a "diamond" control-flow pattern where BB0 tests a condition,
3563 : BB1 and BB2 are "then" and "else" blocks dependent on this test,
3564 : and BB3 rejoins control flow following BB1 and BB2, look for
3565 : opportunities to hoist loads as follows. If BB3 contains a PHI of
3566 : two loads, one each occurring in BB1 and BB2, and the loads are
3567 : provably of adjacent fields in the same structure, then move both
3568 : loads into BB0. Of course this can only be done if there are no
3569 : dependencies preventing such motion.
3570 :
3571 : One of the hoisted loads will always be speculative, so the
3572 : transformation is currently conservative:
3573 :
3574 : - The fields must be strictly adjacent.
3575 : - The two fields must occupy a single memory block that is
3576 : guaranteed to not cross a page boundary.
3577 :
3578 : The last is difficult to prove, as such memory blocks should be
3579 : aligned on the minimum of the stack alignment boundary and the
3580 : alignment guaranteed by heap allocation interfaces. Thus we rely
3581 : on a parameter for the alignment value.
3582 :
3583 : Provided a good value is used for the last case, the first
3584 : restriction could possibly be relaxed. */
3585 :
3586 : static void
3587 581742 : hoist_adjacent_loads (basic_block bb0, basic_block bb1,
3588 : basic_block bb2, basic_block bb3)
3589 : {
3590 581742 : unsigned HOST_WIDE_INT param_align = param_l1_cache_line_size;
3591 581742 : unsigned HOST_WIDE_INT param_align_bits = param_align * BITS_PER_UNIT;
3592 581742 : gphi_iterator gsi;
3593 :
3594 : /* Walk the phis in bb3 looking for an opportunity. We are looking
3595 : for phis of two SSA names, one each of which is defined in bb1 and
3596 : bb2. */
3597 1292687 : for (gsi = gsi_start_phis (bb3); !gsi_end_p (gsi); gsi_next (&gsi))
3598 : {
3599 710945 : gphi *phi_stmt = gsi.phi ();
3600 710945 : gimple *def1, *def2;
3601 710945 : tree arg1, arg2, ref1, ref2, field1, field2;
3602 710945 : tree tree_offset1, tree_offset2, tree_size2, next;
3603 710945 : unsigned HOST_WIDE_INT offset1, offset2, size2, align1;
3604 710945 : gimple_stmt_iterator gsi2;
3605 710945 : basic_block bb_for_def1, bb_for_def2;
3606 :
3607 710945 : if (gimple_phi_num_args (phi_stmt) != 2
3608 1421890 : || virtual_operand_p (gimple_phi_result (phi_stmt)))
3609 705002 : continue;
3610 :
3611 168839 : arg1 = gimple_phi_arg_def (phi_stmt, 0);
3612 168839 : arg2 = gimple_phi_arg_def (phi_stmt, 1);
3613 :
3614 197630 : if (TREE_CODE (arg1) != SSA_NAME
3615 152177 : || TREE_CODE (arg2) != SSA_NAME
3616 140487 : || SSA_NAME_IS_DEFAULT_DEF (arg1)
3617 309028 : || SSA_NAME_IS_DEFAULT_DEF (arg2))
3618 28791 : continue;
3619 :
3620 140048 : def1 = SSA_NAME_DEF_STMT (arg1);
3621 140048 : def2 = SSA_NAME_DEF_STMT (arg2);
3622 :
3623 140048 : if ((gimple_bb (def1) != bb1 || gimple_bb (def2) != bb2)
3624 150397 : && (gimple_bb (def2) != bb1 || gimple_bb (def1) != bb2))
3625 33172 : continue;
3626 :
3627 : /* Check the mode of the arguments to be sure a conditional move
3628 : can be generated for it. */
3629 213752 : if (optab_handler (movcc_optab, TYPE_MODE (TREE_TYPE (arg1)))
3630 : == CODE_FOR_nothing)
3631 5255 : continue;
3632 :
3633 : /* Both statements must be assignments whose RHS is a COMPONENT_REF. */
3634 101621 : if (!gimple_assign_single_p (def1)
3635 47550 : || !gimple_assign_single_p (def2)
3636 58712 : || gimple_has_volatile_ops (def1)
3637 160327 : || gimple_has_volatile_ops (def2))
3638 72268 : continue;
3639 :
3640 29353 : ref1 = gimple_assign_rhs1 (def1);
3641 29353 : ref2 = gimple_assign_rhs1 (def2);
3642 :
3643 29353 : if (TREE_CODE (ref1) != COMPONENT_REF
3644 16318 : || TREE_CODE (ref2) != COMPONENT_REF)
3645 13144 : continue;
3646 :
3647 : /* The zeroth operand of the two component references must be
3648 : identical. It is not sufficient to compare get_base_address of
3649 : the two references, because this could allow for different
3650 : elements of the same array in the two trees. It is not safe to
3651 : assume that the existence of one array element implies the
3652 : existence of a different one. */
3653 16209 : if (!operand_equal_p (TREE_OPERAND (ref1, 0), TREE_OPERAND (ref2, 0), 0))
3654 4924 : continue;
3655 :
3656 11285 : field1 = TREE_OPERAND (ref1, 1);
3657 11285 : field2 = TREE_OPERAND (ref2, 1);
3658 :
3659 : /* Check for field adjacency, and ensure field1 comes first. */
3660 11285 : for (next = DECL_CHAIN (field1);
3661 25322 : next && TREE_CODE (next) != FIELD_DECL;
3662 14037 : next = DECL_CHAIN (next))
3663 : ;
3664 :
3665 11285 : if (next != field2)
3666 : {
3667 7774 : for (next = DECL_CHAIN (field2);
3668 9847 : next && TREE_CODE (next) != FIELD_DECL;
3669 2073 : next = DECL_CHAIN (next))
3670 : ;
3671 :
3672 7774 : if (next != field1)
3673 5342 : continue;
3674 :
3675 : std::swap (field1, field2);
3676 : std::swap (def1, def2);
3677 : }
3678 :
3679 5943 : bb_for_def1 = gimple_bb (def1);
3680 5943 : bb_for_def2 = gimple_bb (def2);
3681 :
3682 : /* Check for proper alignment of the first field. */
3683 5943 : tree_offset1 = bit_position (field1);
3684 5943 : tree_offset2 = bit_position (field2);
3685 5943 : tree_size2 = DECL_SIZE (field2);
3686 :
3687 5943 : if (!tree_fits_uhwi_p (tree_offset1)
3688 5943 : || !tree_fits_uhwi_p (tree_offset2)
3689 5943 : || !tree_fits_uhwi_p (tree_size2))
3690 0 : continue;
3691 :
3692 5943 : offset1 = tree_to_uhwi (tree_offset1);
3693 5943 : offset2 = tree_to_uhwi (tree_offset2);
3694 5943 : size2 = tree_to_uhwi (tree_size2);
3695 5943 : align1 = DECL_ALIGN (field1) % param_align_bits;
3696 :
3697 5943 : if (offset1 % BITS_PER_UNIT != 0)
3698 0 : continue;
3699 :
3700 : /* For profitability, the two field references should fit within
3701 : a single cache line. */
3702 5943 : if (align1 + offset2 - offset1 + size2 > param_align_bits)
3703 0 : continue;
3704 :
3705 : /* The two expressions cannot be dependent upon vdefs defined
3706 : in bb1/bb2. */
3707 5943 : if (local_mem_dependence (def1, bb_for_def1)
3708 5943 : || local_mem_dependence (def2, bb_for_def2))
3709 0 : continue;
3710 :
3711 : /* The conditions are satisfied; hoist the loads from bb1 and bb2 into
3712 : bb0. We hoist the first one first so that a cache miss is handled
3713 : efficiently regardless of hardware cache-fill policy. */
3714 5943 : gsi2 = gsi_for_stmt (def1);
3715 5943 : gsi_move_to_bb_end (&gsi2, bb0);
3716 5943 : gsi2 = gsi_for_stmt (def2);
3717 5943 : gsi_move_to_bb_end (&gsi2, bb0);
3718 5943 : statistics_counter_event (cfun, "hoisted loads", 1);
3719 :
3720 5943 : if (dump_file && (dump_flags & TDF_DETAILS))
3721 : {
3722 0 : fprintf (dump_file,
3723 : "\nHoisting adjacent loads from %d and %d into %d: \n",
3724 : bb_for_def1->index, bb_for_def2->index, bb0->index);
3725 0 : print_gimple_stmt (dump_file, def1, 0, TDF_VOPS|TDF_MEMSYMS);
3726 0 : print_gimple_stmt (dump_file, def2, 0, TDF_VOPS|TDF_MEMSYMS);
3727 : }
3728 : }
3729 581742 : }
3730 :
3731 : /* Determine whether we should attempt to hoist adjacent loads out of
3732 : diamond patterns in pass_phiopt. Always hoist loads if
3733 : -fhoist-adjacent-loads is specified and the target machine has
3734 : both a conditional move instruction and a defined cache line size. */
3735 :
3736 : static bool
3737 3124091 : gate_hoist_loads (void)
3738 : {
3739 3124091 : return (flag_hoist_adjacent_loads == 1
3740 3124091 : && param_l1_cache_line_size
3741 0 : && HAVE_conditional_move);
3742 : }
3743 :
3744 : template <class func_type>
3745 : static void
3746 6574836 : execute_over_cond_phis (func_type func)
3747 : {
3748 : unsigned n, i;
3749 : basic_block *bb_order;
3750 : basic_block bb;
3751 : /* Search every basic block for COND_EXPR we may be able to optimize.
3752 :
3753 : We walk the blocks in order that guarantees that a block with
3754 : a single predecessor is processed before the predecessor.
3755 : This ensures that we collapse inner ifs before visiting the
3756 : outer ones, and also that we do not try to visit a removed
3757 : block. */
3758 6574836 : bb_order = single_pred_before_succ_order ();
3759 6574836 : n = n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS;
3760 :
3761 59096232 : for (i = 0; i < n; i++)
3762 : {
3763 : basic_block bb1, bb2;
3764 : edge e1, e2;
3765 52521396 : bool diamond_p = false;
3766 :
3767 52521396 : bb = bb_order[i];
3768 :
3769 : /* Check to see if the last statement is a GIMPLE_COND. */
3770 52521396 : gcond *cond_stmt = safe_dyn_cast <gcond *> (*gsi_last_bb (bb));
3771 31233116 : if (!cond_stmt)
3772 52521396 : continue;
3773 :
3774 21288280 : e1 = EDGE_SUCC (bb, 0);
3775 21288280 : bb1 = e1->dest;
3776 21288280 : e2 = EDGE_SUCC (bb, 1);
3777 21288280 : bb2 = e2->dest;
3778 :
3779 : /* We cannot do the optimization on abnormal edges. */
3780 21288280 : if ((e1->flags & EDGE_ABNORMAL) != 0
3781 21288280 : || (e2->flags & EDGE_ABNORMAL) != 0)
3782 0 : continue;
3783 :
3784 : /* If either bb1's succ or bb2 or bb2's succ is non NULL. */
3785 21288280 : if (EDGE_COUNT (bb1->succs) == 0
3786 19895845 : || EDGE_COUNT (bb2->succs) == 0)
3787 4881119 : continue;
3788 :
3789 : /* Find the bb which is the fall through to the other. */
3790 16407161 : if (EDGE_SUCC (bb1, 0)->dest == bb2)
3791 : ;
3792 13922661 : else if (EDGE_SUCC (bb2, 0)->dest == bb1)
3793 : {
3794 : std::swap (bb1, bb2);
3795 : std::swap (e1, e2);
3796 : }
3797 10576891 : else if (EDGE_SUCC (bb1, 0)->dest == EDGE_SUCC (bb2, 0)->dest
3798 12103871 : && single_succ_p (bb2))
3799 : {
3800 1526980 : diamond_p = true;
3801 1526980 : e2 = EDGE_SUCC (bb2, 0);
3802 : /* Make sure bb2 is just a fall through. */
3803 1526980 : if ((e2->flags & EDGE_FALLTHRU) == 0)
3804 52063 : continue;
3805 : }
3806 : else
3807 10576891 : continue;
3808 :
3809 5778207 : e1 = EDGE_SUCC (bb1, 0);
3810 :
3811 : /* Make sure that bb1 is just a fall through. */
3812 5778207 : if (!single_succ_p (bb1)
3813 5778207 : || (e1->flags & EDGE_FALLTHRU) == 0)
3814 1399800 : continue;
3815 :
3816 4378407 : func (bb, bb1, bb2, e1, e2, diamond_p, cond_stmt);
3817 : }
3818 6574836 : free (bb_order);
3819 6574836 : }
3820 :
3821 : /* This pass tries to replaces an if-then-else block with an
3822 : assignment. We have different kinds of transformations.
3823 : Some of these transformations are also performed by the ifcvt
3824 : RTL optimizer.
3825 :
3826 : PHI-OPT using Match-and-simplify infrastructure
3827 : -----------------------
3828 :
3829 : The PHI-OPT pass will try to use match-and-simplify infrastructure
3830 : (gimple_simplify) to do transformations. This is implemented in
3831 : match_simplify_replacement.
3832 :
3833 : The way it works is it replaces:
3834 : bb0:
3835 : if (cond) goto bb2; else goto bb1;
3836 : bb1:
3837 : bb2:
3838 : x = PHI <a (bb1), b (bb0), ...>;
3839 :
3840 : with a statement if it gets simplified from `cond ? b : a`.
3841 :
3842 : bb0:
3843 : x1 = cond ? b : a;
3844 : bb2:
3845 : x = PHI <a (bb1), x1 (bb0), ...>;
3846 : Bb1 might be removed as it becomes unreachable when doing the replacement.
3847 : Though bb1 does not have to be considered a forwarding basic block from bb0.
3848 :
3849 : Will try to see if `(!cond) ? a : b` gets simplified (iff !cond simplifies);
3850 : this is done not to have an explosion of patterns in match.pd.
3851 : Note bb1 does not need to be completely empty, it can contain
3852 : one statement which is known not to trap.
3853 :
3854 : It also can handle the case where we have two forwarding bbs (diamond):
3855 : bb0:
3856 : if (cond) goto bb2; else goto bb1;
3857 : bb1: goto bb3;
3858 : bb2: goto bb3;
3859 : bb3:
3860 : x = PHI <a (bb1), b (bb2), ...>;
3861 : And that is replaced with a statement if it is simplified
3862 : from `cond ? b : a`.
3863 : Again bb1 and bb2 does not have to be completely empty but
3864 : each can contain one statement which is known not to trap.
3865 : But in this case bb1/bb2 can only be forwarding basic blocks.
3866 :
3867 : This fully replaces the old "Conditional Replacement",
3868 : "ABS Replacement" and "MIN/MAX Replacement" transformations as they are now
3869 : implmeneted in match.pd.
3870 :
3871 : Value Replacement
3872 : -----------------
3873 :
3874 : This transformation, implemented in value_replacement, replaces
3875 :
3876 : bb0:
3877 : if (a != b) goto bb2; else goto bb1;
3878 : bb1:
3879 : bb2:
3880 : x = PHI <a (bb1), b (bb0), ...>;
3881 :
3882 : with
3883 :
3884 : bb0:
3885 : bb2:
3886 : x = PHI <b (bb0), ...>;
3887 :
3888 : This opportunity can sometimes occur as a result of other
3889 : optimizations.
3890 :
3891 :
3892 : Another case caught by value replacement looks like this:
3893 :
3894 : bb0:
3895 : t1 = a == CONST;
3896 : t2 = b > c;
3897 : t3 = t1 & t2;
3898 : if (t3 != 0) goto bb1; else goto bb2;
3899 : bb1:
3900 : bb2:
3901 : x = PHI (CONST, a)
3902 :
3903 : Gets replaced with:
3904 : bb0:
3905 : bb2:
3906 : t1 = a == CONST;
3907 : t2 = b > c;
3908 : t3 = t1 & t2;
3909 : x = a;
3910 :
3911 :
3912 : This pass also performs a fifth transformation of a slightly different
3913 : flavor.
3914 :
3915 : Factor operations in COND_EXPR
3916 : ------------------------------
3917 :
3918 : This transformation factors the unary operations out of COND_EXPR with
3919 : factor_out_conditional_operation.
3920 :
3921 : For example:
3922 : if (a <= CST) goto <bb 3>; else goto <bb 4>;
3923 : <bb 3>:
3924 : tmp = (int) a;
3925 : <bb 4>:
3926 : tmp = PHI <tmp, CST>
3927 :
3928 : Into:
3929 : if (a <= CST) goto <bb 3>; else goto <bb 4>;
3930 : <bb 3>:
3931 : <bb 4>:
3932 : a = PHI <a, CST>
3933 : tmp = (int) a;
3934 :
3935 : Adjacent Load Hoisting
3936 : ----------------------
3937 :
3938 : This transformation replaces
3939 :
3940 : bb0:
3941 : if (...) goto bb2; else goto bb1;
3942 : bb1:
3943 : x1 = (<expr>).field1;
3944 : goto bb3;
3945 : bb2:
3946 : x2 = (<expr>).field2;
3947 : bb3:
3948 : # x = PHI <x1, x2>;
3949 :
3950 : with
3951 :
3952 : bb0:
3953 : x1 = (<expr>).field1;
3954 : x2 = (<expr>).field2;
3955 : if (...) goto bb2; else goto bb1;
3956 : bb1:
3957 : goto bb3;
3958 : bb2:
3959 : bb3:
3960 : # x = PHI <x1, x2>;
3961 :
3962 : The purpose of this transformation is to enable generation of conditional
3963 : move instructions such as Intel CMOVE or PowerPC ISEL. Because one of
3964 : the loads is speculative, the transformation is restricted to very
3965 : specific cases to avoid introducing a page fault. We are looking for
3966 : the common idiom:
3967 :
3968 : if (...)
3969 : x = y->left;
3970 : else
3971 : x = y->right;
3972 :
3973 : where left and right are typically adjacent pointers in a tree structure. */
3974 :
3975 : namespace {
3976 :
3977 : const pass_data pass_data_phiopt =
3978 : {
3979 : GIMPLE_PASS, /* type */
3980 : "phiopt", /* name */
3981 : OPTGROUP_NONE, /* optinfo_flags */
3982 : TV_TREE_PHIOPT, /* tv_id */
3983 : ( PROP_cfg | PROP_ssa ), /* properties_required */
3984 : 0, /* properties_provided */
3985 : 0, /* properties_destroyed */
3986 : 0, /* todo_flags_start */
3987 : 0, /* todo_flags_finish */
3988 : };
3989 :
3990 : class pass_phiopt : public gimple_opt_pass
3991 : {
3992 : public:
3993 1142888 : pass_phiopt (gcc::context *ctxt)
3994 2285776 : : gimple_opt_pass (pass_data_phiopt, ctxt), early_p (false)
3995 : {}
3996 :
3997 : /* opt_pass methods: */
3998 857166 : opt_pass * clone () final override { return new pass_phiopt (m_ctxt); }
3999 1142888 : void set_pass_param (unsigned n, bool param) final override
4000 : {
4001 1142888 : gcc_assert (n == 0);
4002 1142888 : early_p = param;
4003 1142888 : }
4004 5536880 : bool gate (function *) final override { return flag_ssa_phiopt; }
4005 : unsigned int execute (function *) final override;
4006 :
4007 : private:
4008 : bool early_p;
4009 : }; // class pass_phiopt
4010 :
4011 : } // anon namespace
4012 :
4013 : gimple_opt_pass *
4014 285722 : make_pass_phiopt (gcc::context *ctxt)
4015 : {
4016 285722 : return new pass_phiopt (ctxt);
4017 : }
4018 :
4019 : unsigned int
4020 5533440 : pass_phiopt::execute (function *)
4021 : {
4022 5533440 : bool do_hoist_loads = !early_p ? gate_hoist_loads () : false;
4023 5533440 : bool cfgchanged = false;
4024 :
4025 5533440 : calculate_dominance_info (CDI_DOMINATORS);
4026 5533440 : mark_ssa_maybe_undefs ();
4027 :
4028 8995369 : auto phiopt_exec = [&] (basic_block bb, basic_block bb1,
4029 : basic_block bb2, edge e1, edge e2,
4030 : bool diamond_p, gcond *cond_stmt)
4031 : {
4032 3461929 : if (diamond_p)
4033 : {
4034 1081681 : basic_block bb3 = e1->dest;
4035 :
4036 1081681 : if (!single_pred_p (bb1)
4037 2107961 : || !single_pred_p (bb2))
4038 2641163 : return;
4039 :
4040 971441 : if (do_hoist_loads
4041 763500 : && !FLOAT_TYPE_P (TREE_TYPE (gimple_cond_lhs (cond_stmt)))
4042 756295 : && EDGE_COUNT (bb->succs) == 2
4043 756295 : && EDGE_COUNT (bb3->preds) == 2
4044 : /* If one edge or the other is dominant, a conditional move
4045 : is likely to perform worse than the well-predicted branch. */
4046 586073 : && !predictable_edge_p (EDGE_SUCC (bb, 0))
4047 1553183 : && !predictable_edge_p (EDGE_SUCC (bb, 1)))
4048 581742 : hoist_adjacent_loads (bb, bb1, bb2, bb3);
4049 :
4050 : /* Try to see if there are only store in each side of the if
4051 : and try to remove that; don't do this for -Og. */
4052 971441 : if (EDGE_COUNT (bb3->preds) == 2 && !optimize_debug)
4053 755910 : while (cond_if_else_store_replacement_limited (bb1, bb2, bb3))
4054 : ;
4055 : }
4056 :
4057 971441 : gimple_stmt_iterator gsi;
4058 :
4059 : /* Check that we're looking for nested phis. */
4060 971441 : basic_block merge = diamond_p ? EDGE_SUCC (bb2, 0)->dest : bb2;
4061 3351689 : gimple_seq phis = phi_nodes (merge);
4062 :
4063 3351689 : if (gimple_seq_empty_p (phis))
4064 : return;
4065 :
4066 : /* Factor out operations from the phi if possible. */
4067 3337508 : if (single_pred_p (bb1)
4068 5749660 : && EDGE_COUNT (merge->preds) == 2
4069 5749660 : && !optimize_debug)
4070 : {
4071 5409886 : for (gsi = gsi_start (phis); !gsi_end_p (gsi); )
4072 : {
4073 2997734 : gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
4074 :
4075 2997734 : if (factor_out_conditional_operation (e1, e2, merge, phi,
4076 : cond_stmt))
4077 : {
4078 : /* Start over if there was an operation that was factored out because the new phi might have another opportunity. */
4079 23156 : phis = phi_nodes (merge);
4080 5433042 : gsi = gsi_start (phis);
4081 : }
4082 : else
4083 2974578 : gsi_next (&gsi);
4084 : }
4085 : }
4086 :
4087 : /* Value replacement can work with more than one PHI
4088 : so try that first. */
4089 3337508 : if (!early_p && !diamond_p)
4090 4273099 : for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
4091 : {
4092 2506886 : gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
4093 2506886 : tree arg0 = gimple_phi_arg_def (phi, e1->dest_idx);
4094 2506886 : tree arg1 = gimple_phi_arg_def (phi, e2->dest_idx);
4095 2506886 : if (value_replacement (bb, bb1, e1, e2, phi, arg0, arg1) == 2)
4096 : {
4097 1943 : cfgchanged = true;
4098 1943 : return;
4099 : }
4100 : }
4101 :
4102 3335565 : gphi *phi = single_non_singleton_phi_for_edges (phis, e1, e2);
4103 3335565 : if (!phi)
4104 : return;
4105 :
4106 820766 : tree arg0 = gimple_phi_arg_def (phi, e1->dest_idx);
4107 820766 : tree arg1 = gimple_phi_arg_def (phi, e2->dest_idx);
4108 :
4109 : /* Something is wrong if we cannot find the arguments in the PHI
4110 : node. */
4111 820766 : gcc_assert (arg0 != NULL_TREE && arg1 != NULL_TREE);
4112 :
4113 :
4114 : /* Do the replacement of conditional if it can be done. */
4115 820766 : if (match_simplify_replacement (bb, bb1, bb2, e1, e2, phi,
4116 820766 : arg0, arg1, early_p, diamond_p))
4117 87377 : cfgchanged = true;
4118 733389 : else if (!early_p
4119 485390 : && !diamond_p
4120 452916 : && single_pred_p (bb1)
4121 1169326 : && cond_removal_in_builtin_zero_pattern (bb, bb1, e1, e2,
4122 : phi, arg0, arg1))
4123 13 : cfgchanged = true;
4124 1554142 : else if (single_pred_p (bb1)
4125 687784 : && !diamond_p
4126 1361894 : && spaceship_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
4127 2269 : cfgchanged = true;
4128 5533440 : };
4129 :
4130 5533440 : execute_over_cond_phis (phiopt_exec);
4131 :
4132 5533440 : if (cfgchanged)
4133 63411 : return TODO_cleanup_cfg;
4134 : return 0;
4135 : }
4136 :
4137 : /* This pass tries to transform conditional stores into unconditional
4138 : ones, enabling further simplifications with the simpler then and else
4139 : blocks. In particular it replaces this:
4140 :
4141 : bb0:
4142 : if (cond) goto bb2; else goto bb1;
4143 : bb1:
4144 : *p = RHS;
4145 : bb2:
4146 :
4147 : with
4148 :
4149 : bb0:
4150 : if (cond) goto bb1; else goto bb2;
4151 : bb1:
4152 : condtmp' = *p;
4153 : bb2:
4154 : condtmp = PHI <RHS, condtmp'>
4155 : *p = condtmp;
4156 :
4157 : This transformation can only be done under several constraints,
4158 : documented below. It also replaces:
4159 :
4160 : bb0:
4161 : if (cond) goto bb2; else goto bb1;
4162 : bb1:
4163 : *p = RHS1;
4164 : goto bb3;
4165 : bb2:
4166 : *p = RHS2;
4167 : bb3:
4168 :
4169 : with
4170 :
4171 : bb0:
4172 : if (cond) goto bb3; else goto bb1;
4173 : bb1:
4174 : bb3:
4175 : condtmp = PHI <RHS1, RHS2>
4176 : *p = condtmp; */
4177 :
4178 : namespace {
4179 :
4180 : const pass_data pass_data_cselim =
4181 : {
4182 : GIMPLE_PASS, /* type */
4183 : "cselim", /* name */
4184 : OPTGROUP_NONE, /* optinfo_flags */
4185 : TV_TREE_PHIOPT, /* tv_id */
4186 : ( PROP_cfg | PROP_ssa ), /* properties_required */
4187 : 0, /* properties_provided */
4188 : 0, /* properties_destroyed */
4189 : 0, /* todo_flags_start */
4190 : 0, /* todo_flags_finish */
4191 : };
4192 :
4193 : class pass_cselim : public gimple_opt_pass
4194 : {
4195 : public:
4196 285722 : pass_cselim (gcc::context *ctxt)
4197 571444 : : gimple_opt_pass (pass_data_cselim, ctxt)
4198 : {}
4199 :
4200 : /* opt_pass methods: */
4201 1041484 : bool gate (function *) final override { return flag_tree_cselim; }
4202 : unsigned int execute (function *) final override;
4203 :
4204 : }; // class pass_cselim
4205 :
4206 : } // anon namespace
4207 :
4208 : gimple_opt_pass *
4209 285722 : make_pass_cselim (gcc::context *ctxt)
4210 : {
4211 285722 : return new pass_cselim (ctxt);
4212 : }
4213 :
4214 : unsigned int
4215 1041396 : pass_cselim::execute (function *)
4216 : {
4217 1041396 : bool cfgchanged = false;
4218 1041396 : hash_set<tree> *nontrap = 0;
4219 1041396 : unsigned todo = 0;
4220 :
4221 : /* ??? We are not interested in loop related info, but the following
4222 : will create it, ICEing as we didn't init loops with pre-headers.
4223 : An interfacing issue of find_data_references_in_bb. */
4224 1041396 : loop_optimizer_init (LOOPS_NORMAL);
4225 1041396 : scev_initialize ();
4226 :
4227 1041396 : calculate_dominance_info (CDI_DOMINATORS);
4228 :
4229 : /* Calculate the set of non-trapping memory accesses. */
4230 1041396 : nontrap = get_non_trapping ();
4231 :
4232 1957874 : auto cselim_exec = [&] (basic_block bb, basic_block bb1,
4233 : basic_block bb2, edge e1, edge e2,
4234 : bool diamond_p, gcond *)
4235 : {
4236 916478 : if (diamond_p)
4237 : {
4238 312181 : basic_block bb3 = e1->dest;
4239 :
4240 : /* Only handle sinking of store from 2 bbs only,
4241 : The middle bbs don't need to come from the
4242 : if always since we are sinking rather than
4243 : hoisting. */
4244 312181 : if (EDGE_COUNT (bb3->preds) != 2)
4245 : return;
4246 229801 : if (cond_if_else_store_replacement (bb1, bb2, bb3))
4247 1045 : cfgchanged = true;
4248 229801 : return;
4249 : }
4250 :
4251 : /* Also make sure that bb1 only have one predecessor and that it
4252 : is bb. */
4253 604297 : if (!single_pred_p (bb1)
4254 1162300 : || single_pred (bb1) != bb)
4255 : return;
4256 :
4257 : /* bb1 is the middle block, bb2 the join block, bb the split block,
4258 : e1 the fallthrough edge from bb1 to bb2. We can't do the
4259 : optimization if the join block has more than two predecessors. */
4260 558003 : if (EDGE_COUNT (bb2->preds) > 2)
4261 : return;
4262 426992 : if (cond_store_replacement (bb1, bb2, e1, e2, nontrap))
4263 5863 : cfgchanged = true;
4264 1041396 : };
4265 :
4266 1041396 : execute_over_cond_phis (cselim_exec);
4267 :
4268 2082792 : delete nontrap;
4269 : /* If the CFG has changed, we should cleanup the CFG. */
4270 1041396 : if (cfgchanged)
4271 : {
4272 : /* In cond-store replacement we have added some loads on edges
4273 : and new VOPS (as we moved the store, and created a load). */
4274 3993 : gsi_commit_edge_inserts ();
4275 3993 : todo = TODO_cleanup_cfg | TODO_update_ssa_only_virtuals;
4276 : }
4277 1041396 : scev_finalize ();
4278 1041396 : loop_optimizer_finalize ();
4279 1041396 : return todo;
4280 : }
|