c++: Implement for namespace statics CWG 2867 - Order of initialization for structure...
[official-gcc.git] / gcc / tree-ssa-forwprop.cc
blob9474682152a6d89e20c8cd8b2c9b6a4012a1539d
1 /* Forward propagation of expressions for single use variables.
2 Copyright (C) 2004-2025 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
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/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "rtl.h"
25 #include "tree.h"
26 #include "gimple.h"
27 #include "cfghooks.h"
28 #include "tree-pass.h"
29 #include "ssa.h"
30 #include "expmed.h"
31 #include "optabs-query.h"
32 #include "gimple-pretty-print.h"
33 #include "fold-const.h"
34 #include "stor-layout.h"
35 #include "gimple-iterator.h"
36 #include "gimple-fold.h"
37 #include "tree-eh.h"
38 #include "gimplify.h"
39 #include "gimplify-me.h"
40 #include "tree-cfg.h"
41 #include "expr.h"
42 #include "tree-dfa.h"
43 #include "tree-ssa-propagate.h"
44 #include "tree-ssa-dom.h"
45 #include "tree-ssa-strlen.h"
46 #include "builtins.h"
47 #include "tree-cfgcleanup.h"
48 #include "cfganal.h"
49 #include "optabs-tree.h"
50 #include "insn-config.h"
51 #include "recog.h"
52 #include "cfgloop.h"
53 #include "tree-vectorizer.h"
54 #include "tree-vector-builder.h"
55 #include "vec-perm-indices.h"
56 #include "internal-fn.h"
57 #include "cgraph.h"
58 #include "tree-ssa.h"
59 #include "gimple-range.h"
60 #include "tree-ssa-dce.h"
62 /* This pass propagates the RHS of assignment statements into use
63 sites of the LHS of the assignment. It's basically a specialized
64 form of tree combination. It is hoped all of this can disappear
65 when we have a generalized tree combiner.
67 One class of common cases we handle is forward propagating a single use
68 variable into a COND_EXPR.
70 bb0:
71 x = a COND b;
72 if (x) goto ... else goto ...
74 Will be transformed into:
76 bb0:
77 if (a COND b) goto ... else goto ...
79 Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
81 Or (assuming c1 and c2 are constants):
83 bb0:
84 x = a + c1;
85 if (x EQ/NEQ c2) goto ... else goto ...
87 Will be transformed into:
89 bb0:
90 if (a EQ/NEQ (c2 - c1)) goto ... else goto ...
92 Similarly for x = a - c1.
96 bb0:
97 x = !a
98 if (x) goto ... else goto ...
100 Will be transformed into:
102 bb0:
103 if (a == 0) goto ... else goto ...
105 Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
106 For these cases, we propagate A into all, possibly more than one,
107 COND_EXPRs that use X.
111 bb0:
112 x = (typecast) a
113 if (x) goto ... else goto ...
115 Will be transformed into:
117 bb0:
118 if (a != 0) goto ... else goto ...
120 (Assuming a is an integral type and x is a boolean or x is an
121 integral and a is a boolean.)
123 Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
124 For these cases, we propagate A into all, possibly more than one,
125 COND_EXPRs that use X.
127 In addition to eliminating the variable and the statement which assigns
128 a value to the variable, we may be able to later thread the jump without
129 adding insane complexity in the dominator optimizer.
131 Also note these transformations can cascade. We handle this by having
132 a worklist of COND_EXPR statements to examine. As we make a change to
133 a statement, we put it back on the worklist to examine on the next
134 iteration of the main loop.
136 A second class of propagation opportunities arises for ADDR_EXPR
137 nodes.
139 ptr = &x->y->z;
140 res = *ptr;
142 Will get turned into
144 res = x->y->z;
147 ptr = (type1*)&type2var;
148 res = *ptr
150 Will get turned into (if type1 and type2 are the same size
151 and neither have volatile on them):
152 res = VIEW_CONVERT_EXPR<type1>(type2var)
156 ptr = &x[0];
157 ptr2 = ptr + <constant>;
159 Will get turned into
161 ptr2 = &x[constant/elementsize];
165 ptr = &x[0];
166 offset = index * element_size;
167 offset_p = (pointer) offset;
168 ptr2 = ptr + offset_p
170 Will get turned into:
172 ptr2 = &x[index];
175 ssa = (int) decl
176 res = ssa & 1
178 Provided that decl has known alignment >= 2, will get turned into
180 res = 0
182 We also propagate casts into SWITCH_EXPR and COND_EXPR conditions to
183 allow us to remove the cast and {NOT_EXPR,NEG_EXPR} into a subsequent
184 {NOT_EXPR,NEG_EXPR}.
186 This will (of course) be extended as other needs arise. */
188 /* Data structure that contains simplifiable vectorized permute sequences.
189 See recognise_vec_perm_simplify_seq () for a description of the sequence. */
191 struct _vec_perm_simplify_seq
193 /* Defining stmts of vectors in the sequence. */
194 gassign *v_1_stmt;
195 gassign *v_2_stmt;
196 gassign *v_x_stmt;
197 gassign *v_y_stmt;
198 /* Final permute statment. */
199 gassign *stmt;
200 /* New selector indices for stmt. */
201 tree new_sel;
202 /* Elements of each vector and selector. */
203 unsigned int nelts;
205 typedef struct _vec_perm_simplify_seq *vec_perm_simplify_seq;
207 static bool forward_propagate_addr_expr (tree, tree, bool);
209 /* Set to true if we delete dead edges during the optimization. */
210 static bool cfg_changed;
212 static tree rhs_to_tree (tree type, gimple *stmt);
214 static bitmap to_purge;
216 /* Const-and-copy lattice. */
217 static vec<tree> lattice;
219 /* Set the lattice entry for NAME to VAL. */
220 static void
221 fwprop_set_lattice_val (tree name, tree val)
223 if (TREE_CODE (name) == SSA_NAME)
225 if (SSA_NAME_VERSION (name) >= lattice.length ())
227 lattice.reserve (num_ssa_names - lattice.length ());
228 lattice.quick_grow_cleared (num_ssa_names);
230 lattice[SSA_NAME_VERSION (name)] = val;
231 /* As this now constitutes a copy duplicate points-to
232 and range info appropriately. */
233 if (TREE_CODE (val) == SSA_NAME)
234 maybe_duplicate_ssa_info_at_copy (name, val);
238 /* Invalidate the lattice entry for NAME, done when releasing SSA names. */
239 static void
240 fwprop_invalidate_lattice (tree name)
242 if (name
243 && TREE_CODE (name) == SSA_NAME
244 && SSA_NAME_VERSION (name) < lattice.length ())
245 lattice[SSA_NAME_VERSION (name)] = NULL_TREE;
248 /* Get the statement we can propagate from into NAME skipping
249 trivial copies. Returns the statement which defines the
250 propagation source or NULL_TREE if there is no such one.
251 If SINGLE_USE_ONLY is set considers only sources which have
252 a single use chain up to NAME. If SINGLE_USE_P is non-null,
253 it is set to whether the chain to NAME is a single use chain
254 or not. SINGLE_USE_P is not written to if SINGLE_USE_ONLY is set. */
256 static gimple *
257 get_prop_source_stmt (tree name, bool single_use_only, bool *single_use_p)
259 bool single_use = true;
261 do {
262 gimple *def_stmt = SSA_NAME_DEF_STMT (name);
264 if (!has_single_use (name))
266 single_use = false;
267 if (single_use_only)
268 return NULL;
271 /* If name is defined by a PHI node or is the default def, bail out. */
272 if (!is_gimple_assign (def_stmt))
273 return NULL;
275 /* If def_stmt is a simple copy, continue looking. */
276 if (gimple_assign_rhs_code (def_stmt) == SSA_NAME)
277 name = gimple_assign_rhs1 (def_stmt);
278 else
280 if (!single_use_only && single_use_p)
281 *single_use_p = single_use;
283 return def_stmt;
285 } while (1);
288 /* Checks if the destination ssa name in DEF_STMT can be used as
289 propagation source. Returns true if so, otherwise false. */
291 static bool
292 can_propagate_from (gimple *def_stmt)
294 gcc_assert (is_gimple_assign (def_stmt));
296 /* If the rhs has side-effects we cannot propagate from it. */
297 if (gimple_has_volatile_ops (def_stmt))
298 return false;
300 /* If the rhs is a load we cannot propagate from it. */
301 if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_reference
302 || TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_declaration)
303 return false;
305 /* Constants can be always propagated. */
306 if (gimple_assign_single_p (def_stmt)
307 && is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt)))
308 return true;
310 /* We cannot propagate ssa names that occur in abnormal phi nodes. */
311 if (stmt_references_abnormal_ssa_name (def_stmt))
312 return false;
314 /* If the definition is a conversion of a pointer to a function type,
315 then we cannot apply optimizations as some targets require
316 function pointers to be canonicalized and in this case this
317 optimization could eliminate a necessary canonicalization. */
318 if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
320 tree rhs = gimple_assign_rhs1 (def_stmt);
321 if (FUNCTION_POINTER_TYPE_P (TREE_TYPE (rhs)))
322 return false;
325 return true;
328 /* Remove a chain of dead statements starting at the definition of
329 NAME. The chain is linked via the first operand of the defining statements.
330 If NAME was replaced in its only use then this function can be used
331 to clean up dead stmts. The function handles already released SSA
332 names gracefully.
333 Returns true if cleanup-cfg has to run. */
335 static bool
336 remove_prop_source_from_use (tree name)
338 gimple_stmt_iterator gsi;
339 gimple *stmt;
340 bool cfg_changed = false;
342 do {
343 basic_block bb;
345 if (SSA_NAME_IN_FREE_LIST (name)
346 || SSA_NAME_IS_DEFAULT_DEF (name)
347 || !has_zero_uses (name))
348 return cfg_changed;
350 stmt = SSA_NAME_DEF_STMT (name);
351 if (gimple_code (stmt) == GIMPLE_PHI
352 || gimple_has_side_effects (stmt))
353 return cfg_changed;
355 bb = gimple_bb (stmt);
356 gsi = gsi_for_stmt (stmt);
357 unlink_stmt_vdef (stmt);
358 if (gsi_remove (&gsi, true))
359 bitmap_set_bit (to_purge, bb->index);
360 fwprop_invalidate_lattice (gimple_get_lhs (stmt));
361 release_defs (stmt);
363 name = is_gimple_assign (stmt) ? gimple_assign_rhs1 (stmt) : NULL_TREE;
364 } while (name && TREE_CODE (name) == SSA_NAME);
366 return cfg_changed;
369 /* Return the rhs of a gassign *STMT in a form of a single tree,
370 converted to type TYPE.
372 This should disappear, but is needed so we can combine expressions and use
373 the fold() interfaces. Long term, we need to develop folding and combine
374 routines that deal with gimple exclusively . */
376 static tree
377 rhs_to_tree (tree type, gimple *stmt)
379 location_t loc = gimple_location (stmt);
380 enum tree_code code = gimple_assign_rhs_code (stmt);
381 switch (get_gimple_rhs_class (code))
383 case GIMPLE_TERNARY_RHS:
384 return fold_build3_loc (loc, code, type, gimple_assign_rhs1 (stmt),
385 gimple_assign_rhs2 (stmt),
386 gimple_assign_rhs3 (stmt));
387 case GIMPLE_BINARY_RHS:
388 return fold_build2_loc (loc, code, type, gimple_assign_rhs1 (stmt),
389 gimple_assign_rhs2 (stmt));
390 case GIMPLE_UNARY_RHS:
391 return build1 (code, type, gimple_assign_rhs1 (stmt));
392 case GIMPLE_SINGLE_RHS:
393 return gimple_assign_rhs1 (stmt);
394 default:
395 gcc_unreachable ();
399 /* Combine OP0 CODE OP1 in the context of a COND_EXPR. Returns
400 the folded result in a form suitable for COND_EXPR_COND or
401 NULL_TREE, if there is no suitable simplified form. If
402 INVARIANT_ONLY is true only gimple_min_invariant results are
403 considered simplified. */
405 static tree
406 combine_cond_expr_cond (gimple *stmt, enum tree_code code, tree type,
407 tree op0, tree op1, bool invariant_only)
409 tree t;
411 gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
413 fold_defer_overflow_warnings ();
414 t = fold_binary_loc (gimple_location (stmt), code, type, op0, op1);
415 if (!t)
417 fold_undefer_overflow_warnings (false, NULL, 0);
418 return NULL_TREE;
421 /* Require that we got a boolean type out if we put one in. */
422 gcc_assert (TREE_CODE (TREE_TYPE (t)) == TREE_CODE (type));
424 /* Canonicalize the combined condition for use in a COND_EXPR. */
425 t = canonicalize_cond_expr_cond (t);
427 /* Bail out if we required an invariant but didn't get one. */
428 if (!t || (invariant_only && !is_gimple_min_invariant (t)))
430 fold_undefer_overflow_warnings (false, NULL, 0);
431 return NULL_TREE;
434 bool nowarn = warning_suppressed_p (stmt, OPT_Wstrict_overflow);
435 fold_undefer_overflow_warnings (!nowarn, stmt, 0);
437 return t;
440 /* Combine the comparison OP0 CODE OP1 at LOC with the defining statements
441 of its operand. Return a new comparison tree or NULL_TREE if there
442 were no simplifying combines. */
444 static tree
445 forward_propagate_into_comparison_1 (gimple *stmt,
446 enum tree_code code, tree type,
447 tree op0, tree op1)
449 tree tmp = NULL_TREE;
450 tree rhs0 = NULL_TREE, rhs1 = NULL_TREE;
451 bool single_use0_p = false, single_use1_p = false;
453 /* For comparisons use the first operand, that is likely to
454 simplify comparisons against constants. */
455 if (TREE_CODE (op0) == SSA_NAME)
457 gimple *def_stmt = get_prop_source_stmt (op0, false, &single_use0_p);
458 if (def_stmt && can_propagate_from (def_stmt))
460 enum tree_code def_code = gimple_assign_rhs_code (def_stmt);
461 bool invariant_only_p = !single_use0_p;
463 rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
465 /* Always combine comparisons or conversions from booleans. */
466 if (TREE_CODE (op1) == INTEGER_CST
467 && ((CONVERT_EXPR_CODE_P (def_code)
468 && TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs0, 0)))
469 == BOOLEAN_TYPE)
470 || TREE_CODE_CLASS (def_code) == tcc_comparison))
471 invariant_only_p = false;
473 tmp = combine_cond_expr_cond (stmt, code, type,
474 rhs0, op1, invariant_only_p);
475 if (tmp)
476 return tmp;
480 /* If that wasn't successful, try the second operand. */
481 if (TREE_CODE (op1) == SSA_NAME)
483 gimple *def_stmt = get_prop_source_stmt (op1, false, &single_use1_p);
484 if (def_stmt && can_propagate_from (def_stmt))
486 rhs1 = rhs_to_tree (TREE_TYPE (op0), def_stmt);
487 tmp = combine_cond_expr_cond (stmt, code, type,
488 op0, rhs1, !single_use1_p);
489 if (tmp)
490 return tmp;
494 /* If that wasn't successful either, try both operands. */
495 if (rhs0 != NULL_TREE
496 && rhs1 != NULL_TREE)
497 tmp = combine_cond_expr_cond (stmt, code, type,
498 rhs0, rhs1,
499 !(single_use0_p && single_use1_p));
501 return tmp;
504 /* Propagate from the ssa name definition statements of the assignment
505 from a comparison at *GSI into the conditional if that simplifies it.
506 Returns 1 if the stmt was modified and 2 if the CFG needs cleanup,
507 otherwise returns 0. */
509 static int
510 forward_propagate_into_comparison (gimple_stmt_iterator *gsi)
512 gimple *stmt = gsi_stmt (*gsi);
513 tree tmp;
514 bool cfg_changed = false;
515 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
516 tree rhs1 = gimple_assign_rhs1 (stmt);
517 tree rhs2 = gimple_assign_rhs2 (stmt);
519 /* Combine the comparison with defining statements. */
520 tmp = forward_propagate_into_comparison_1 (stmt,
521 gimple_assign_rhs_code (stmt),
522 type, rhs1, rhs2);
523 if (tmp && useless_type_conversion_p (type, TREE_TYPE (tmp)))
525 gimple_assign_set_rhs_from_tree (gsi, tmp);
526 fold_stmt (gsi);
527 update_stmt (gsi_stmt (*gsi));
529 if (TREE_CODE (rhs1) == SSA_NAME)
530 cfg_changed |= remove_prop_source_from_use (rhs1);
531 if (TREE_CODE (rhs2) == SSA_NAME)
532 cfg_changed |= remove_prop_source_from_use (rhs2);
533 return cfg_changed ? 2 : 1;
536 return 0;
539 /* Propagate from the ssa name definition statements of COND_EXPR
540 in GIMPLE_COND statement STMT into the conditional if that simplifies it.
541 Returns zero if no statement was changed, one if there were
542 changes and two if cfg_cleanup needs to run. */
544 static int
545 forward_propagate_into_gimple_cond (gcond *stmt)
547 tree tmp;
548 enum tree_code code = gimple_cond_code (stmt);
549 bool cfg_changed = false;
550 tree rhs1 = gimple_cond_lhs (stmt);
551 tree rhs2 = gimple_cond_rhs (stmt);
553 /* We can do tree combining on SSA_NAME and comparison expressions. */
554 if (TREE_CODE_CLASS (gimple_cond_code (stmt)) != tcc_comparison)
555 return 0;
557 tmp = forward_propagate_into_comparison_1 (stmt, code,
558 boolean_type_node,
559 rhs1, rhs2);
560 if (tmp
561 && is_gimple_condexpr_for_cond (tmp))
563 if (dump_file)
565 fprintf (dump_file, " Replaced '");
566 print_gimple_expr (dump_file, stmt, 0);
567 fprintf (dump_file, "' with '");
568 print_generic_expr (dump_file, tmp);
569 fprintf (dump_file, "'\n");
572 gimple_cond_set_condition_from_tree (stmt, unshare_expr (tmp));
573 update_stmt (stmt);
575 if (TREE_CODE (rhs1) == SSA_NAME)
576 cfg_changed |= remove_prop_source_from_use (rhs1);
577 if (TREE_CODE (rhs2) == SSA_NAME)
578 cfg_changed |= remove_prop_source_from_use (rhs2);
579 return (cfg_changed || is_gimple_min_invariant (tmp)) ? 2 : 1;
582 /* Canonicalize _Bool == 0 and _Bool != 1 to _Bool != 0 by swapping edges. */
583 if ((TREE_CODE (TREE_TYPE (rhs1)) == BOOLEAN_TYPE
584 || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
585 && TYPE_PRECISION (TREE_TYPE (rhs1)) == 1))
586 && ((code == EQ_EXPR
587 && integer_zerop (rhs2))
588 || (code == NE_EXPR
589 && integer_onep (rhs2))))
591 basic_block bb = gimple_bb (stmt);
592 gimple_cond_set_code (stmt, NE_EXPR);
593 gimple_cond_set_rhs (stmt, build_zero_cst (TREE_TYPE (rhs1)));
594 EDGE_SUCC (bb, 0)->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE);
595 EDGE_SUCC (bb, 1)->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE);
596 return 1;
599 return 0;
602 /* We've just substituted an ADDR_EXPR into stmt. Update all the
603 relevant data structures to match. */
605 static void
606 tidy_after_forward_propagate_addr (gimple *stmt)
608 /* We may have turned a trapping insn into a non-trapping insn. */
609 if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
610 bitmap_set_bit (to_purge, gimple_bb (stmt)->index);
612 if (TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR)
613 recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));
616 /* NAME is a SSA_NAME representing DEF_RHS which is of the form
617 ADDR_EXPR <whatever>.
619 Try to forward propagate the ADDR_EXPR into the use USE_STMT.
620 Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF
621 node or for recovery of array indexing from pointer arithmetic.
623 Return true if the propagation was successful (the propagation can
624 be not totally successful, yet things may have been changed). */
626 static bool
627 forward_propagate_addr_expr_1 (tree name, tree def_rhs,
628 gimple_stmt_iterator *use_stmt_gsi,
629 bool single_use_p)
631 tree lhs, rhs, rhs2, array_ref;
632 gimple *use_stmt = gsi_stmt (*use_stmt_gsi);
633 enum tree_code rhs_code;
634 bool res = true;
636 gcc_assert (TREE_CODE (def_rhs) == ADDR_EXPR);
638 lhs = gimple_assign_lhs (use_stmt);
639 rhs_code = gimple_assign_rhs_code (use_stmt);
640 rhs = gimple_assign_rhs1 (use_stmt);
642 /* Do not perform copy-propagation but recurse through copy chains. */
643 if (TREE_CODE (lhs) == SSA_NAME
644 && rhs_code == SSA_NAME)
645 return forward_propagate_addr_expr (lhs, def_rhs, single_use_p);
647 /* The use statement could be a conversion. Recurse to the uses of the
648 lhs as copyprop does not copy through pointer to integer to pointer
649 conversions and FRE does not catch all cases either.
650 Treat the case of a single-use name and
651 a conversion to def_rhs type separate, though. */
652 if (TREE_CODE (lhs) == SSA_NAME
653 && CONVERT_EXPR_CODE_P (rhs_code))
655 /* If there is a point in a conversion chain where the types match
656 so we can remove a conversion re-materialize the address here
657 and stop. */
658 if (single_use_p
659 && useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs)))
661 gimple_assign_set_rhs1 (use_stmt, unshare_expr (def_rhs));
662 gimple_assign_set_rhs_code (use_stmt, TREE_CODE (def_rhs));
663 return true;
666 /* Else recurse if the conversion preserves the address value. */
667 if ((INTEGRAL_TYPE_P (TREE_TYPE (lhs))
668 || POINTER_TYPE_P (TREE_TYPE (lhs)))
669 && (TYPE_PRECISION (TREE_TYPE (lhs))
670 >= TYPE_PRECISION (TREE_TYPE (def_rhs))))
671 return forward_propagate_addr_expr (lhs, def_rhs, single_use_p);
673 return false;
676 /* If this isn't a conversion chain from this on we only can propagate
677 into compatible pointer contexts. */
678 if (!types_compatible_p (TREE_TYPE (name), TREE_TYPE (def_rhs)))
679 return false;
681 /* Propagate through constant pointer adjustments. */
682 if (TREE_CODE (lhs) == SSA_NAME
683 && rhs_code == POINTER_PLUS_EXPR
684 && rhs == name
685 && TREE_CODE (gimple_assign_rhs2 (use_stmt)) == INTEGER_CST)
687 tree new_def_rhs;
688 /* As we come here with non-invariant addresses in def_rhs we need
689 to make sure we can build a valid constant offsetted address
690 for further propagation. Simply rely on fold building that
691 and check after the fact. */
692 new_def_rhs = fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (rhs)),
693 def_rhs,
694 fold_convert (ptr_type_node,
695 gimple_assign_rhs2 (use_stmt)));
696 if (TREE_CODE (new_def_rhs) == MEM_REF
697 && !is_gimple_mem_ref_addr (TREE_OPERAND (new_def_rhs, 0)))
698 return false;
699 new_def_rhs = build1 (ADDR_EXPR, TREE_TYPE (rhs), new_def_rhs);
701 /* Recurse. If we could propagate into all uses of lhs do not
702 bother to replace into the current use but just pretend we did. */
703 if (forward_propagate_addr_expr (lhs, new_def_rhs, single_use_p))
704 return true;
706 if (useless_type_conversion_p (TREE_TYPE (lhs),
707 TREE_TYPE (new_def_rhs)))
708 gimple_assign_set_rhs_with_ops (use_stmt_gsi, TREE_CODE (new_def_rhs),
709 new_def_rhs);
710 else if (is_gimple_min_invariant (new_def_rhs))
711 gimple_assign_set_rhs_with_ops (use_stmt_gsi, NOP_EXPR, new_def_rhs);
712 else
713 return false;
714 gcc_assert (gsi_stmt (*use_stmt_gsi) == use_stmt);
715 update_stmt (use_stmt);
716 return true;
719 /* Now strip away any outer COMPONENT_REF/ARRAY_REF nodes from the LHS.
720 ADDR_EXPR will not appear on the LHS. */
721 tree *lhsp = gimple_assign_lhs_ptr (use_stmt);
722 while (handled_component_p (*lhsp))
723 lhsp = &TREE_OPERAND (*lhsp, 0);
724 lhs = *lhsp;
726 /* Now see if the LHS node is a MEM_REF using NAME. If so,
727 propagate the ADDR_EXPR into the use of NAME and fold the result. */
728 if (TREE_CODE (lhs) == MEM_REF
729 && TREE_OPERAND (lhs, 0) == name)
731 tree def_rhs_base;
732 poly_int64 def_rhs_offset;
733 /* If the address is invariant we can always fold it. */
734 if ((def_rhs_base = get_addr_base_and_unit_offset (TREE_OPERAND (def_rhs, 0),
735 &def_rhs_offset)))
737 poly_offset_int off = mem_ref_offset (lhs);
738 tree new_ptr;
739 off += def_rhs_offset;
740 if (TREE_CODE (def_rhs_base) == MEM_REF)
742 off += mem_ref_offset (def_rhs_base);
743 new_ptr = TREE_OPERAND (def_rhs_base, 0);
745 else
746 new_ptr = build_fold_addr_expr (def_rhs_base);
747 TREE_OPERAND (lhs, 0) = new_ptr;
748 TREE_OPERAND (lhs, 1)
749 = wide_int_to_tree (TREE_TYPE (TREE_OPERAND (lhs, 1)), off);
750 tidy_after_forward_propagate_addr (use_stmt);
751 /* Continue propagating into the RHS if this was not the only use. */
752 if (single_use_p)
753 return true;
755 /* If the LHS is a plain dereference and the value type is the same as
756 that of the pointed-to type of the address we can put the
757 dereferenced address on the LHS preserving the original alias-type. */
758 else if (integer_zerop (TREE_OPERAND (lhs, 1))
759 && ((gimple_assign_lhs (use_stmt) == lhs
760 && useless_type_conversion_p
761 (TREE_TYPE (TREE_OPERAND (def_rhs, 0)),
762 TREE_TYPE (gimple_assign_rhs1 (use_stmt))))
763 || types_compatible_p (TREE_TYPE (lhs),
764 TREE_TYPE (TREE_OPERAND (def_rhs, 0))))
765 /* Don't forward anything into clobber stmts if it would result
766 in the lhs no longer being a MEM_REF. */
767 && (!gimple_clobber_p (use_stmt)
768 || TREE_CODE (TREE_OPERAND (def_rhs, 0)) == MEM_REF))
770 tree *def_rhs_basep = &TREE_OPERAND (def_rhs, 0);
771 tree new_offset, new_base, saved, new_lhs;
772 while (handled_component_p (*def_rhs_basep))
773 def_rhs_basep = &TREE_OPERAND (*def_rhs_basep, 0);
774 saved = *def_rhs_basep;
775 if (TREE_CODE (*def_rhs_basep) == MEM_REF)
777 new_base = TREE_OPERAND (*def_rhs_basep, 0);
778 new_offset = fold_convert (TREE_TYPE (TREE_OPERAND (lhs, 1)),
779 TREE_OPERAND (*def_rhs_basep, 1));
781 else
783 new_base = build_fold_addr_expr (*def_rhs_basep);
784 new_offset = TREE_OPERAND (lhs, 1);
786 *def_rhs_basep = build2 (MEM_REF, TREE_TYPE (*def_rhs_basep),
787 new_base, new_offset);
788 TREE_THIS_VOLATILE (*def_rhs_basep) = TREE_THIS_VOLATILE (lhs);
789 TREE_SIDE_EFFECTS (*def_rhs_basep) = TREE_SIDE_EFFECTS (lhs);
790 TREE_THIS_NOTRAP (*def_rhs_basep) = TREE_THIS_NOTRAP (lhs);
791 new_lhs = unshare_expr (TREE_OPERAND (def_rhs, 0));
792 *lhsp = new_lhs;
793 TREE_THIS_VOLATILE (new_lhs) = TREE_THIS_VOLATILE (lhs);
794 TREE_SIDE_EFFECTS (new_lhs) = TREE_SIDE_EFFECTS (lhs);
795 *def_rhs_basep = saved;
796 tidy_after_forward_propagate_addr (use_stmt);
797 /* Continue propagating into the RHS if this was not the
798 only use. */
799 if (single_use_p)
800 return true;
802 else
803 /* We can have a struct assignment dereferencing our name twice.
804 Note that we didn't propagate into the lhs to not falsely
805 claim we did when propagating into the rhs. */
806 res = false;
809 /* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR
810 nodes from the RHS. */
811 tree *rhsp = gimple_assign_rhs1_ptr (use_stmt);
812 if (TREE_CODE (*rhsp) == ADDR_EXPR)
813 rhsp = &TREE_OPERAND (*rhsp, 0);
814 while (handled_component_p (*rhsp))
815 rhsp = &TREE_OPERAND (*rhsp, 0);
816 rhs = *rhsp;
818 /* Now see if the RHS node is a MEM_REF using NAME. If so,
819 propagate the ADDR_EXPR into the use of NAME and fold the result. */
820 if (TREE_CODE (rhs) == MEM_REF
821 && TREE_OPERAND (rhs, 0) == name)
823 tree def_rhs_base;
824 poly_int64 def_rhs_offset;
825 if ((def_rhs_base = get_addr_base_and_unit_offset (TREE_OPERAND (def_rhs, 0),
826 &def_rhs_offset)))
828 poly_offset_int off = mem_ref_offset (rhs);
829 tree new_ptr;
830 off += def_rhs_offset;
831 if (TREE_CODE (def_rhs_base) == MEM_REF)
833 off += mem_ref_offset (def_rhs_base);
834 new_ptr = TREE_OPERAND (def_rhs_base, 0);
836 else
837 new_ptr = build_fold_addr_expr (def_rhs_base);
838 TREE_OPERAND (rhs, 0) = new_ptr;
839 TREE_OPERAND (rhs, 1)
840 = wide_int_to_tree (TREE_TYPE (TREE_OPERAND (rhs, 1)), off);
841 fold_stmt_inplace (use_stmt_gsi);
842 tidy_after_forward_propagate_addr (use_stmt);
843 return res;
845 /* If the RHS is a plain dereference and the value type is the same as
846 that of the pointed-to type of the address we can put the
847 dereferenced address on the RHS preserving the original alias-type. */
848 else if (integer_zerop (TREE_OPERAND (rhs, 1))
849 && ((gimple_assign_rhs1 (use_stmt) == rhs
850 && useless_type_conversion_p
851 (TREE_TYPE (gimple_assign_lhs (use_stmt)),
852 TREE_TYPE (TREE_OPERAND (def_rhs, 0))))
853 || types_compatible_p (TREE_TYPE (rhs),
854 TREE_TYPE (TREE_OPERAND (def_rhs, 0)))))
856 tree *def_rhs_basep = &TREE_OPERAND (def_rhs, 0);
857 tree new_offset, new_base, saved, new_rhs;
858 while (handled_component_p (*def_rhs_basep))
859 def_rhs_basep = &TREE_OPERAND (*def_rhs_basep, 0);
860 saved = *def_rhs_basep;
861 if (TREE_CODE (*def_rhs_basep) == MEM_REF)
863 new_base = TREE_OPERAND (*def_rhs_basep, 0);
864 new_offset = fold_convert (TREE_TYPE (TREE_OPERAND (rhs, 1)),
865 TREE_OPERAND (*def_rhs_basep, 1));
867 else
869 new_base = build_fold_addr_expr (*def_rhs_basep);
870 new_offset = TREE_OPERAND (rhs, 1);
872 *def_rhs_basep = build2 (MEM_REF, TREE_TYPE (*def_rhs_basep),
873 new_base, new_offset);
874 TREE_THIS_VOLATILE (*def_rhs_basep) = TREE_THIS_VOLATILE (rhs);
875 TREE_SIDE_EFFECTS (*def_rhs_basep) = TREE_SIDE_EFFECTS (rhs);
876 TREE_THIS_NOTRAP (*def_rhs_basep) = TREE_THIS_NOTRAP (rhs);
877 new_rhs = unshare_expr (TREE_OPERAND (def_rhs, 0));
878 *rhsp = new_rhs;
879 TREE_THIS_VOLATILE (new_rhs) = TREE_THIS_VOLATILE (rhs);
880 TREE_SIDE_EFFECTS (new_rhs) = TREE_SIDE_EFFECTS (rhs);
881 *def_rhs_basep = saved;
882 fold_stmt_inplace (use_stmt_gsi);
883 tidy_after_forward_propagate_addr (use_stmt);
884 return res;
888 /* If the use of the ADDR_EXPR is not a POINTER_PLUS_EXPR, there
889 is nothing to do. */
890 if (gimple_assign_rhs_code (use_stmt) != POINTER_PLUS_EXPR
891 || gimple_assign_rhs1 (use_stmt) != name)
892 return false;
894 /* The remaining cases are all for turning pointer arithmetic into
895 array indexing. They only apply when we have the address of
896 element zero in an array. If that is not the case then there
897 is nothing to do. */
898 array_ref = TREE_OPERAND (def_rhs, 0);
899 if ((TREE_CODE (array_ref) != ARRAY_REF
900 || TREE_CODE (TREE_TYPE (TREE_OPERAND (array_ref, 0))) != ARRAY_TYPE
901 || TREE_CODE (TREE_OPERAND (array_ref, 1)) != INTEGER_CST)
902 && TREE_CODE (TREE_TYPE (array_ref)) != ARRAY_TYPE)
903 return false;
905 rhs2 = gimple_assign_rhs2 (use_stmt);
906 /* Optimize &x[C1] p+ C2 to &x p+ C3 with C3 = C1 * element_size + C2. */
907 if (TREE_CODE (rhs2) == INTEGER_CST)
909 tree new_rhs = build1_loc (gimple_location (use_stmt),
910 ADDR_EXPR, TREE_TYPE (def_rhs),
911 fold_build2 (MEM_REF,
912 TREE_TYPE (TREE_TYPE (def_rhs)),
913 unshare_expr (def_rhs),
914 fold_convert (ptr_type_node,
915 rhs2)));
916 gimple_assign_set_rhs_from_tree (use_stmt_gsi, new_rhs);
917 use_stmt = gsi_stmt (*use_stmt_gsi);
918 update_stmt (use_stmt);
919 tidy_after_forward_propagate_addr (use_stmt);
920 return true;
923 return false;
926 /* STMT is a statement of the form SSA_NAME = ADDR_EXPR <whatever>.
928 Try to forward propagate the ADDR_EXPR into all uses of the SSA_NAME.
929 Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF
930 node or for recovery of array indexing from pointer arithmetic.
932 PARENT_SINGLE_USE_P tells if, when in a recursive invocation, NAME was
933 the single use in the previous invocation. Pass true when calling
934 this as toplevel.
936 Returns true, if all uses have been propagated into. */
938 static bool
939 forward_propagate_addr_expr (tree name, tree rhs, bool parent_single_use_p)
941 imm_use_iterator iter;
942 gimple *use_stmt;
943 bool all = true;
944 bool single_use_p = parent_single_use_p && has_single_use (name);
946 FOR_EACH_IMM_USE_STMT (use_stmt, iter, name)
948 bool result;
949 tree use_rhs;
951 /* If the use is not in a simple assignment statement, then
952 there is nothing we can do. */
953 if (!is_gimple_assign (use_stmt))
955 if (!is_gimple_debug (use_stmt))
956 all = false;
957 continue;
960 gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
961 result = forward_propagate_addr_expr_1 (name, rhs, &gsi,
962 single_use_p);
963 /* If the use has moved to a different statement adjust
964 the update machinery for the old statement too. */
965 if (use_stmt != gsi_stmt (gsi))
967 update_stmt (use_stmt);
968 use_stmt = gsi_stmt (gsi);
970 update_stmt (use_stmt);
971 all &= result;
973 /* Remove intermediate now unused copy and conversion chains. */
974 use_rhs = gimple_assign_rhs1 (use_stmt);
975 if (result
976 && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
977 && TREE_CODE (use_rhs) == SSA_NAME
978 && has_zero_uses (gimple_assign_lhs (use_stmt)))
980 gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
981 fwprop_invalidate_lattice (gimple_get_lhs (use_stmt));
982 release_defs (use_stmt);
983 gsi_remove (&gsi, true);
987 return all && has_zero_uses (name);
991 /* Helper function for simplify_gimple_switch. Remove case labels that
992 have values outside the range of the new type. */
994 static void
995 simplify_gimple_switch_label_vec (gswitch *stmt, tree index_type,
996 vec<std::pair<int, int> > &edges_to_remove)
998 unsigned int branch_num = gimple_switch_num_labels (stmt);
999 auto_vec<tree> labels (branch_num);
1000 unsigned int i, len;
1002 /* Collect the existing case labels in a VEC, and preprocess it as if
1003 we are gimplifying a GENERIC SWITCH_EXPR. */
1004 for (i = 1; i < branch_num; i++)
1005 labels.quick_push (gimple_switch_label (stmt, i));
1006 preprocess_case_label_vec_for_gimple (labels, index_type, NULL);
1008 /* If any labels were removed, replace the existing case labels
1009 in the GIMPLE_SWITCH statement with the correct ones.
1010 Note that the type updates were done in-place on the case labels,
1011 so we only have to replace the case labels in the GIMPLE_SWITCH
1012 if the number of labels changed. */
1013 len = labels.length ();
1014 if (len < branch_num - 1)
1016 bitmap target_blocks;
1017 edge_iterator ei;
1018 edge e;
1020 /* Corner case: *all* case labels have been removed as being
1021 out-of-range for INDEX_TYPE. Push one label and let the
1022 CFG cleanups deal with this further. */
1023 if (len == 0)
1025 tree label, elt;
1027 label = CASE_LABEL (gimple_switch_default_label (stmt));
1028 elt = build_case_label (build_int_cst (index_type, 0), NULL, label);
1029 labels.quick_push (elt);
1030 len = 1;
1033 for (i = 0; i < labels.length (); i++)
1034 gimple_switch_set_label (stmt, i + 1, labels[i]);
1035 for (i++ ; i < branch_num; i++)
1036 gimple_switch_set_label (stmt, i, NULL_TREE);
1037 gimple_switch_set_num_labels (stmt, len + 1);
1039 /* Cleanup any edges that are now dead. */
1040 target_blocks = BITMAP_ALLOC (NULL);
1041 for (i = 0; i < gimple_switch_num_labels (stmt); i++)
1043 tree elt = gimple_switch_label (stmt, i);
1044 basic_block target = label_to_block (cfun, CASE_LABEL (elt));
1045 bitmap_set_bit (target_blocks, target->index);
1047 for (ei = ei_start (gimple_bb (stmt)->succs); (e = ei_safe_edge (ei)); )
1049 if (! bitmap_bit_p (target_blocks, e->dest->index))
1050 edges_to_remove.safe_push (std::make_pair (e->src->index,
1051 e->dest->index));
1052 else
1053 ei_next (&ei);
1055 BITMAP_FREE (target_blocks);
1059 /* STMT is a SWITCH_EXPR for which we attempt to find equivalent forms of
1060 the condition which we may be able to optimize better. */
1062 static bool
1063 simplify_gimple_switch (gswitch *stmt,
1064 vec<std::pair<int, int> > &edges_to_remove)
1066 /* The optimization that we really care about is removing unnecessary
1067 casts. That will let us do much better in propagating the inferred
1068 constant at the switch target. */
1069 tree cond = gimple_switch_index (stmt);
1070 if (TREE_CODE (cond) == SSA_NAME)
1072 gimple *def_stmt = SSA_NAME_DEF_STMT (cond);
1073 if (gimple_assign_cast_p (def_stmt))
1075 tree def = gimple_assign_rhs1 (def_stmt);
1076 if (TREE_CODE (def) != SSA_NAME)
1077 return false;
1079 /* If we have an extension or sign-change that preserves the
1080 values we check against then we can copy the source value into
1081 the switch. */
1082 tree ti = TREE_TYPE (def);
1083 if (INTEGRAL_TYPE_P (ti)
1084 && TYPE_PRECISION (ti) <= TYPE_PRECISION (TREE_TYPE (cond)))
1086 size_t n = gimple_switch_num_labels (stmt);
1087 tree min = NULL_TREE, max = NULL_TREE;
1088 if (n > 1)
1090 min = CASE_LOW (gimple_switch_label (stmt, 1));
1091 if (CASE_HIGH (gimple_switch_label (stmt, n - 1)))
1092 max = CASE_HIGH (gimple_switch_label (stmt, n - 1));
1093 else
1094 max = CASE_LOW (gimple_switch_label (stmt, n - 1));
1096 if ((!min || int_fits_type_p (min, ti))
1097 && (!max || int_fits_type_p (max, ti)))
1099 gimple_switch_set_index (stmt, def);
1100 simplify_gimple_switch_label_vec (stmt, ti,
1101 edges_to_remove);
1102 update_stmt (stmt);
1103 return true;
1109 return false;
1112 /* For pointers p2 and p1 return p2 - p1 if the
1113 difference is known and constant, otherwise return NULL. */
1115 static tree
1116 constant_pointer_difference (tree p1, tree p2)
1118 int i, j;
1119 #define CPD_ITERATIONS 5
1120 tree exps[2][CPD_ITERATIONS];
1121 tree offs[2][CPD_ITERATIONS];
1122 int cnt[2];
1124 for (i = 0; i < 2; i++)
1126 tree p = i ? p1 : p2;
1127 tree off = size_zero_node;
1128 gimple *stmt;
1129 enum tree_code code;
1131 /* For each of p1 and p2 we need to iterate at least
1132 twice, to handle ADDR_EXPR directly in p1/p2,
1133 SSA_NAME with ADDR_EXPR or POINTER_PLUS_EXPR etc.
1134 on definition's stmt RHS. Iterate a few extra times. */
1135 j = 0;
1138 if (!POINTER_TYPE_P (TREE_TYPE (p)))
1139 break;
1140 if (TREE_CODE (p) == ADDR_EXPR)
1142 tree q = TREE_OPERAND (p, 0);
1143 poly_int64 offset;
1144 tree base = get_addr_base_and_unit_offset (q, &offset);
1145 if (base)
1147 q = base;
1148 if (maybe_ne (offset, 0))
1149 off = size_binop (PLUS_EXPR, off, size_int (offset));
1151 if (TREE_CODE (q) == MEM_REF
1152 && TREE_CODE (TREE_OPERAND (q, 0)) == SSA_NAME)
1154 p = TREE_OPERAND (q, 0);
1155 off = size_binop (PLUS_EXPR, off,
1156 wide_int_to_tree (sizetype,
1157 mem_ref_offset (q)));
1159 else
1161 exps[i][j] = q;
1162 offs[i][j++] = off;
1163 break;
1166 if (TREE_CODE (p) != SSA_NAME)
1167 break;
1168 exps[i][j] = p;
1169 offs[i][j++] = off;
1170 if (j == CPD_ITERATIONS)
1171 break;
1172 stmt = SSA_NAME_DEF_STMT (p);
1173 if (!is_gimple_assign (stmt) || gimple_assign_lhs (stmt) != p)
1174 break;
1175 code = gimple_assign_rhs_code (stmt);
1176 if (code == POINTER_PLUS_EXPR)
1178 if (TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST)
1179 break;
1180 off = size_binop (PLUS_EXPR, off, gimple_assign_rhs2 (stmt));
1181 p = gimple_assign_rhs1 (stmt);
1183 else if (code == ADDR_EXPR || CONVERT_EXPR_CODE_P (code))
1184 p = gimple_assign_rhs1 (stmt);
1185 else
1186 break;
1188 while (1);
1189 cnt[i] = j;
1192 for (i = 0; i < cnt[0]; i++)
1193 for (j = 0; j < cnt[1]; j++)
1194 if (exps[0][i] == exps[1][j])
1195 return size_binop (MINUS_EXPR, offs[0][i], offs[1][j]);
1197 return NULL_TREE;
1200 /* *GSI_P is a GIMPLE_CALL to a builtin function.
1201 Optimize
1202 memcpy (p, "abcd", 4);
1203 memset (p + 4, ' ', 3);
1204 into
1205 memcpy (p, "abcd ", 7);
1206 call if the latter can be stored by pieces during expansion.
1208 Optimize
1209 memchr ("abcd", a, 4) == 0;
1211 memchr ("abcd", a, 4) != 0;
1213 (a == 'a' || a == 'b' || a == 'c' || a == 'd') == 0
1215 (a == 'a' || a == 'b' || a == 'c' || a == 'd') != 0
1217 Also canonicalize __atomic_fetch_op (p, x, y) op x
1218 to __atomic_op_fetch (p, x, y) or
1219 __atomic_op_fetch (p, x, y) iop x
1220 to __atomic_fetch_op (p, x, y) when possible (also __sync). */
1222 static bool
1223 simplify_builtin_call (gimple_stmt_iterator *gsi_p, tree callee2)
1225 gimple *stmt1, *stmt2 = gsi_stmt (*gsi_p);
1226 enum built_in_function other_atomic = END_BUILTINS;
1227 enum tree_code atomic_op = ERROR_MARK;
1228 tree vuse = gimple_vuse (stmt2);
1229 if (vuse == NULL)
1230 return false;
1231 stmt1 = SSA_NAME_DEF_STMT (vuse);
1233 tree res;
1235 switch (DECL_FUNCTION_CODE (callee2))
1237 case BUILT_IN_MEMCHR:
1238 if (gimple_call_num_args (stmt2) == 3
1239 && (res = gimple_call_lhs (stmt2)) != nullptr
1240 && use_in_zero_equality (res) != nullptr
1241 && CHAR_BIT == 8
1242 && BITS_PER_UNIT == 8)
1244 tree ptr = gimple_call_arg (stmt2, 0);
1245 if (TREE_CODE (ptr) != ADDR_EXPR
1246 || TREE_CODE (TREE_OPERAND (ptr, 0)) != STRING_CST)
1247 break;
1248 unsigned HOST_WIDE_INT slen
1249 = TREE_STRING_LENGTH (TREE_OPERAND (ptr, 0));
1250 /* It must be a non-empty string constant. */
1251 if (slen < 2)
1252 break;
1253 /* For -Os, only simplify strings with a single character. */
1254 if (!optimize_bb_for_speed_p (gimple_bb (stmt2))
1255 && slen > 2)
1256 break;
1257 tree size = gimple_call_arg (stmt2, 2);
1258 /* Size must be a constant which is <= UNITS_PER_WORD and
1259 <= the string length. */
1260 if (TREE_CODE (size) != INTEGER_CST)
1261 break;
1263 if (!tree_fits_uhwi_p (size))
1264 break;
1266 unsigned HOST_WIDE_INT sz = tree_to_uhwi (size);
1267 if (sz == 0 || sz > UNITS_PER_WORD || sz >= slen)
1268 break;
1270 tree ch = gimple_call_arg (stmt2, 1);
1271 location_t loc = gimple_location (stmt2);
1272 if (!useless_type_conversion_p (char_type_node,
1273 TREE_TYPE (ch)))
1274 ch = fold_convert_loc (loc, char_type_node, ch);
1275 const char *p = TREE_STRING_POINTER (TREE_OPERAND (ptr, 0));
1276 unsigned int isize = sz;
1277 tree *op = XALLOCAVEC (tree, isize);
1278 for (unsigned int i = 0; i < isize; i++)
1280 op[i] = build_int_cst (char_type_node, p[i]);
1281 op[i] = fold_build2_loc (loc, EQ_EXPR, boolean_type_node,
1282 op[i], ch);
1284 for (unsigned int i = isize - 1; i >= 1; i--)
1285 op[i - 1] = fold_convert_loc (loc, boolean_type_node,
1286 fold_build2_loc (loc,
1287 BIT_IOR_EXPR,
1288 boolean_type_node,
1289 op[i - 1],
1290 op[i]));
1291 res = fold_convert_loc (loc, TREE_TYPE (res), op[0]);
1292 gimplify_and_update_call_from_tree (gsi_p, res);
1293 return true;
1295 break;
1297 case BUILT_IN_MEMSET:
1298 if (gimple_call_num_args (stmt2) != 3
1299 || gimple_call_lhs (stmt2)
1300 || CHAR_BIT != 8
1301 || BITS_PER_UNIT != 8)
1302 break;
1303 else
1305 tree callee1;
1306 tree ptr1, src1, str1, off1, len1, lhs1;
1307 tree ptr2 = gimple_call_arg (stmt2, 0);
1308 tree val2 = gimple_call_arg (stmt2, 1);
1309 tree len2 = gimple_call_arg (stmt2, 2);
1310 tree diff, vdef, new_str_cst;
1311 gimple *use_stmt;
1312 unsigned int ptr1_align;
1313 unsigned HOST_WIDE_INT src_len;
1314 char *src_buf;
1315 use_operand_p use_p;
1317 if (!tree_fits_shwi_p (val2)
1318 || !tree_fits_uhwi_p (len2)
1319 || compare_tree_int (len2, 1024) == 1)
1320 break;
1321 if (is_gimple_call (stmt1))
1323 /* If first stmt is a call, it needs to be memcpy
1324 or mempcpy, with string literal as second argument and
1325 constant length. */
1326 callee1 = gimple_call_fndecl (stmt1);
1327 if (callee1 == NULL_TREE
1328 || !fndecl_built_in_p (callee1, BUILT_IN_NORMAL)
1329 || gimple_call_num_args (stmt1) != 3)
1330 break;
1331 if (DECL_FUNCTION_CODE (callee1) != BUILT_IN_MEMCPY
1332 && DECL_FUNCTION_CODE (callee1) != BUILT_IN_MEMPCPY)
1333 break;
1334 ptr1 = gimple_call_arg (stmt1, 0);
1335 src1 = gimple_call_arg (stmt1, 1);
1336 len1 = gimple_call_arg (stmt1, 2);
1337 lhs1 = gimple_call_lhs (stmt1);
1338 if (!tree_fits_uhwi_p (len1))
1339 break;
1340 str1 = string_constant (src1, &off1, NULL, NULL);
1341 if (str1 == NULL_TREE)
1342 break;
1343 if (!tree_fits_uhwi_p (off1)
1344 || compare_tree_int (off1, TREE_STRING_LENGTH (str1) - 1) > 0
1345 || compare_tree_int (len1, TREE_STRING_LENGTH (str1)
1346 - tree_to_uhwi (off1)) > 0
1347 || TREE_CODE (TREE_TYPE (str1)) != ARRAY_TYPE
1348 || TYPE_MODE (TREE_TYPE (TREE_TYPE (str1)))
1349 != TYPE_MODE (char_type_node))
1350 break;
1352 else if (gimple_assign_single_p (stmt1))
1354 /* Otherwise look for length 1 memcpy optimized into
1355 assignment. */
1356 ptr1 = gimple_assign_lhs (stmt1);
1357 src1 = gimple_assign_rhs1 (stmt1);
1358 if (TREE_CODE (ptr1) != MEM_REF
1359 || TYPE_MODE (TREE_TYPE (ptr1)) != TYPE_MODE (char_type_node)
1360 || !tree_fits_shwi_p (src1))
1361 break;
1362 ptr1 = build_fold_addr_expr (ptr1);
1363 STRIP_USELESS_TYPE_CONVERSION (ptr1);
1364 callee1 = NULL_TREE;
1365 len1 = size_one_node;
1366 lhs1 = NULL_TREE;
1367 off1 = size_zero_node;
1368 str1 = NULL_TREE;
1370 else
1371 break;
1373 diff = constant_pointer_difference (ptr1, ptr2);
1374 if (diff == NULL && lhs1 != NULL)
1376 diff = constant_pointer_difference (lhs1, ptr2);
1377 if (DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY
1378 && diff != NULL)
1379 diff = size_binop (PLUS_EXPR, diff,
1380 fold_convert (sizetype, len1));
1382 /* If the difference between the second and first destination pointer
1383 is not constant, or is bigger than memcpy length, bail out. */
1384 if (diff == NULL
1385 || !tree_fits_uhwi_p (diff)
1386 || tree_int_cst_lt (len1, diff)
1387 || compare_tree_int (diff, 1024) == 1)
1388 break;
1390 /* Use maximum of difference plus memset length and memcpy length
1391 as the new memcpy length, if it is too big, bail out. */
1392 src_len = tree_to_uhwi (diff);
1393 src_len += tree_to_uhwi (len2);
1394 if (src_len < tree_to_uhwi (len1))
1395 src_len = tree_to_uhwi (len1);
1396 if (src_len > 1024)
1397 break;
1399 /* If mempcpy value is used elsewhere, bail out, as mempcpy
1400 with bigger length will return different result. */
1401 if (lhs1 != NULL_TREE
1402 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY
1403 && (TREE_CODE (lhs1) != SSA_NAME
1404 || !single_imm_use (lhs1, &use_p, &use_stmt)
1405 || use_stmt != stmt2))
1406 break;
1408 /* If anything reads memory in between memcpy and memset
1409 call, the modified memcpy call might change it. */
1410 vdef = gimple_vdef (stmt1);
1411 if (vdef != NULL
1412 && (!single_imm_use (vdef, &use_p, &use_stmt)
1413 || use_stmt != stmt2))
1414 break;
1416 ptr1_align = get_pointer_alignment (ptr1);
1417 /* Construct the new source string literal. */
1418 src_buf = XALLOCAVEC (char, src_len + 1);
1419 if (callee1)
1420 memcpy (src_buf,
1421 TREE_STRING_POINTER (str1) + tree_to_uhwi (off1),
1422 tree_to_uhwi (len1));
1423 else
1424 src_buf[0] = tree_to_shwi (src1);
1425 memset (src_buf + tree_to_uhwi (diff),
1426 tree_to_shwi (val2), tree_to_uhwi (len2));
1427 src_buf[src_len] = '\0';
1428 /* Neither builtin_strncpy_read_str nor builtin_memcpy_read_str
1429 handle embedded '\0's. */
1430 if (strlen (src_buf) != src_len)
1431 break;
1432 rtl_profile_for_bb (gimple_bb (stmt2));
1433 /* If the new memcpy wouldn't be emitted by storing the literal
1434 by pieces, this optimization might enlarge .rodata too much,
1435 as commonly used string literals couldn't be shared any
1436 longer. */
1437 if (!can_store_by_pieces (src_len,
1438 builtin_strncpy_read_str,
1439 src_buf, ptr1_align, false))
1440 break;
1442 new_str_cst = build_string_literal (src_len, src_buf);
1443 if (callee1)
1445 /* If STMT1 is a mem{,p}cpy call, adjust it and remove
1446 memset call. */
1447 if (lhs1 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY)
1448 gimple_call_set_lhs (stmt1, NULL_TREE);
1449 gimple_call_set_arg (stmt1, 1, new_str_cst);
1450 gimple_call_set_arg (stmt1, 2,
1451 build_int_cst (TREE_TYPE (len1), src_len));
1452 update_stmt (stmt1);
1453 unlink_stmt_vdef (stmt2);
1454 gsi_replace (gsi_p, gimple_build_nop (), false);
1455 fwprop_invalidate_lattice (gimple_get_lhs (stmt2));
1456 release_defs (stmt2);
1457 if (lhs1 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY)
1459 fwprop_invalidate_lattice (lhs1);
1460 release_ssa_name (lhs1);
1462 return true;
1464 else
1466 /* Otherwise, if STMT1 is length 1 memcpy optimized into
1467 assignment, remove STMT1 and change memset call into
1468 memcpy call. */
1469 gimple_stmt_iterator gsi = gsi_for_stmt (stmt1);
1471 if (!is_gimple_val (ptr1))
1472 ptr1 = force_gimple_operand_gsi (gsi_p, ptr1, true, NULL_TREE,
1473 true, GSI_SAME_STMT);
1474 tree fndecl = builtin_decl_explicit (BUILT_IN_MEMCPY);
1475 gimple_call_set_fndecl (stmt2, fndecl);
1476 gimple_call_set_fntype (as_a <gcall *> (stmt2),
1477 TREE_TYPE (fndecl));
1478 gimple_call_set_arg (stmt2, 0, ptr1);
1479 gimple_call_set_arg (stmt2, 1, new_str_cst);
1480 gimple_call_set_arg (stmt2, 2,
1481 build_int_cst (TREE_TYPE (len2), src_len));
1482 unlink_stmt_vdef (stmt1);
1483 gsi_remove (&gsi, true);
1484 fwprop_invalidate_lattice (gimple_get_lhs (stmt1));
1485 release_defs (stmt1);
1486 update_stmt (stmt2);
1487 return false;
1490 break;
1492 #define CASE_ATOMIC(NAME, OTHER, OP) \
1493 case BUILT_IN_##NAME##_1: \
1494 case BUILT_IN_##NAME##_2: \
1495 case BUILT_IN_##NAME##_4: \
1496 case BUILT_IN_##NAME##_8: \
1497 case BUILT_IN_##NAME##_16: \
1498 atomic_op = OP; \
1499 other_atomic \
1500 = (enum built_in_function) (BUILT_IN_##OTHER##_1 \
1501 + (DECL_FUNCTION_CODE (callee2) \
1502 - BUILT_IN_##NAME##_1)); \
1503 goto handle_atomic_fetch_op;
1505 CASE_ATOMIC (ATOMIC_FETCH_ADD, ATOMIC_ADD_FETCH, PLUS_EXPR)
1506 CASE_ATOMIC (ATOMIC_FETCH_SUB, ATOMIC_SUB_FETCH, MINUS_EXPR)
1507 CASE_ATOMIC (ATOMIC_FETCH_AND, ATOMIC_AND_FETCH, BIT_AND_EXPR)
1508 CASE_ATOMIC (ATOMIC_FETCH_XOR, ATOMIC_XOR_FETCH, BIT_XOR_EXPR)
1509 CASE_ATOMIC (ATOMIC_FETCH_OR, ATOMIC_OR_FETCH, BIT_IOR_EXPR)
1511 CASE_ATOMIC (SYNC_FETCH_AND_ADD, SYNC_ADD_AND_FETCH, PLUS_EXPR)
1512 CASE_ATOMIC (SYNC_FETCH_AND_SUB, SYNC_SUB_AND_FETCH, MINUS_EXPR)
1513 CASE_ATOMIC (SYNC_FETCH_AND_AND, SYNC_AND_AND_FETCH, BIT_AND_EXPR)
1514 CASE_ATOMIC (SYNC_FETCH_AND_XOR, SYNC_XOR_AND_FETCH, BIT_XOR_EXPR)
1515 CASE_ATOMIC (SYNC_FETCH_AND_OR, SYNC_OR_AND_FETCH, BIT_IOR_EXPR)
1517 CASE_ATOMIC (ATOMIC_ADD_FETCH, ATOMIC_FETCH_ADD, MINUS_EXPR)
1518 CASE_ATOMIC (ATOMIC_SUB_FETCH, ATOMIC_FETCH_SUB, PLUS_EXPR)
1519 CASE_ATOMIC (ATOMIC_XOR_FETCH, ATOMIC_FETCH_XOR, BIT_XOR_EXPR)
1521 CASE_ATOMIC (SYNC_ADD_AND_FETCH, SYNC_FETCH_AND_ADD, MINUS_EXPR)
1522 CASE_ATOMIC (SYNC_SUB_AND_FETCH, SYNC_FETCH_AND_SUB, PLUS_EXPR)
1523 CASE_ATOMIC (SYNC_XOR_AND_FETCH, SYNC_FETCH_AND_XOR, BIT_XOR_EXPR)
1525 #undef CASE_ATOMIC
1527 handle_atomic_fetch_op:
1528 if (gimple_call_num_args (stmt2) >= 2 && gimple_call_lhs (stmt2))
1530 tree lhs2 = gimple_call_lhs (stmt2), lhsc = lhs2;
1531 tree arg = gimple_call_arg (stmt2, 1);
1532 gimple *use_stmt, *cast_stmt = NULL;
1533 use_operand_p use_p;
1534 tree ndecl = builtin_decl_explicit (other_atomic);
1536 if (ndecl == NULL_TREE || !single_imm_use (lhs2, &use_p, &use_stmt))
1537 break;
1539 if (gimple_assign_cast_p (use_stmt))
1541 cast_stmt = use_stmt;
1542 lhsc = gimple_assign_lhs (cast_stmt);
1543 if (lhsc == NULL_TREE
1544 || !INTEGRAL_TYPE_P (TREE_TYPE (lhsc))
1545 || (TYPE_PRECISION (TREE_TYPE (lhsc))
1546 != TYPE_PRECISION (TREE_TYPE (lhs2)))
1547 || !single_imm_use (lhsc, &use_p, &use_stmt))
1549 use_stmt = cast_stmt;
1550 cast_stmt = NULL;
1551 lhsc = lhs2;
1555 bool ok = false;
1556 tree oarg = NULL_TREE;
1557 enum tree_code ccode = ERROR_MARK;
1558 tree crhs1 = NULL_TREE, crhs2 = NULL_TREE;
1559 if (is_gimple_assign (use_stmt)
1560 && gimple_assign_rhs_code (use_stmt) == atomic_op)
1562 if (gimple_assign_rhs1 (use_stmt) == lhsc)
1563 oarg = gimple_assign_rhs2 (use_stmt);
1564 else if (atomic_op != MINUS_EXPR)
1565 oarg = gimple_assign_rhs1 (use_stmt);
1567 else if (atomic_op == MINUS_EXPR
1568 && is_gimple_assign (use_stmt)
1569 && gimple_assign_rhs_code (use_stmt) == PLUS_EXPR
1570 && TREE_CODE (arg) == INTEGER_CST
1571 && (TREE_CODE (gimple_assign_rhs2 (use_stmt))
1572 == INTEGER_CST))
1574 tree a = fold_convert (TREE_TYPE (lhs2), arg);
1575 tree o = fold_convert (TREE_TYPE (lhs2),
1576 gimple_assign_rhs2 (use_stmt));
1577 if (wi::to_wide (a) == wi::neg (wi::to_wide (o)))
1578 ok = true;
1580 else if (atomic_op == BIT_AND_EXPR || atomic_op == BIT_IOR_EXPR)
1582 else if (gimple_code (use_stmt) == GIMPLE_COND)
1584 ccode = gimple_cond_code (use_stmt);
1585 crhs1 = gimple_cond_lhs (use_stmt);
1586 crhs2 = gimple_cond_rhs (use_stmt);
1588 else if (is_gimple_assign (use_stmt))
1590 if (gimple_assign_rhs_class (use_stmt) == GIMPLE_BINARY_RHS)
1592 ccode = gimple_assign_rhs_code (use_stmt);
1593 crhs1 = gimple_assign_rhs1 (use_stmt);
1594 crhs2 = gimple_assign_rhs2 (use_stmt);
1596 else if (gimple_assign_rhs_code (use_stmt) == COND_EXPR)
1598 tree cond = gimple_assign_rhs1 (use_stmt);
1599 if (COMPARISON_CLASS_P (cond))
1601 ccode = TREE_CODE (cond);
1602 crhs1 = TREE_OPERAND (cond, 0);
1603 crhs2 = TREE_OPERAND (cond, 1);
1607 if (ccode == EQ_EXPR || ccode == NE_EXPR)
1609 /* Deal with x - y == 0 or x ^ y == 0
1610 being optimized into x == y and x + cst == 0
1611 into x == -cst. */
1612 tree o = NULL_TREE;
1613 if (crhs1 == lhsc)
1614 o = crhs2;
1615 else if (crhs2 == lhsc)
1616 o = crhs1;
1617 if (o && atomic_op != PLUS_EXPR)
1618 oarg = o;
1619 else if (o
1620 && TREE_CODE (o) == INTEGER_CST
1621 && TREE_CODE (arg) == INTEGER_CST)
1623 tree a = fold_convert (TREE_TYPE (lhs2), arg);
1624 o = fold_convert (TREE_TYPE (lhs2), o);
1625 if (wi::to_wide (a) == wi::neg (wi::to_wide (o)))
1626 ok = true;
1629 if (oarg && !ok)
1631 if (operand_equal_p (arg, oarg, 0))
1632 ok = true;
1633 else if (TREE_CODE (arg) == SSA_NAME
1634 && TREE_CODE (oarg) == SSA_NAME)
1636 tree oarg2 = oarg;
1637 if (gimple_assign_cast_p (SSA_NAME_DEF_STMT (oarg)))
1639 gimple *g = SSA_NAME_DEF_STMT (oarg);
1640 oarg2 = gimple_assign_rhs1 (g);
1641 if (TREE_CODE (oarg2) != SSA_NAME
1642 || !INTEGRAL_TYPE_P (TREE_TYPE (oarg2))
1643 || (TYPE_PRECISION (TREE_TYPE (oarg2))
1644 != TYPE_PRECISION (TREE_TYPE (oarg))))
1645 oarg2 = oarg;
1647 if (gimple_assign_cast_p (SSA_NAME_DEF_STMT (arg)))
1649 gimple *g = SSA_NAME_DEF_STMT (arg);
1650 tree rhs1 = gimple_assign_rhs1 (g);
1651 /* Handle e.g.
1652 x.0_1 = (long unsigned int) x_4(D);
1653 _2 = __atomic_fetch_add_8 (&vlong, x.0_1, 0);
1654 _3 = (long int) _2;
1655 _7 = x_4(D) + _3; */
1656 if (rhs1 == oarg || rhs1 == oarg2)
1657 ok = true;
1658 /* Handle e.g.
1659 x.18_1 = (short unsigned int) x_5(D);
1660 _2 = (int) x.18_1;
1661 _3 = __atomic_fetch_xor_2 (&vshort, _2, 0);
1662 _4 = (short int) _3;
1663 _8 = x_5(D) ^ _4;
1664 This happens only for char/short. */
1665 else if (TREE_CODE (rhs1) == SSA_NAME
1666 && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
1667 && (TYPE_PRECISION (TREE_TYPE (rhs1))
1668 == TYPE_PRECISION (TREE_TYPE (lhs2))))
1670 g = SSA_NAME_DEF_STMT (rhs1);
1671 if (gimple_assign_cast_p (g)
1672 && (gimple_assign_rhs1 (g) == oarg
1673 || gimple_assign_rhs1 (g) == oarg2))
1674 ok = true;
1677 if (!ok && arg == oarg2)
1678 /* Handle e.g.
1679 _1 = __sync_fetch_and_add_4 (&v, x_5(D));
1680 _2 = (int) _1;
1681 x.0_3 = (int) x_5(D);
1682 _7 = _2 + x.0_3; */
1683 ok = true;
1687 if (ok)
1689 tree new_lhs = make_ssa_name (TREE_TYPE (lhs2));
1690 gimple_call_set_lhs (stmt2, new_lhs);
1691 gimple_call_set_fndecl (stmt2, ndecl);
1692 gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
1693 if (ccode == ERROR_MARK)
1694 gimple_assign_set_rhs_with_ops (&gsi, cast_stmt
1695 ? NOP_EXPR : SSA_NAME,
1696 new_lhs);
1697 else
1699 crhs1 = new_lhs;
1700 crhs2 = build_zero_cst (TREE_TYPE (lhs2));
1701 if (gimple_code (use_stmt) == GIMPLE_COND)
1703 gcond *cond_stmt = as_a <gcond *> (use_stmt);
1704 gimple_cond_set_lhs (cond_stmt, crhs1);
1705 gimple_cond_set_rhs (cond_stmt, crhs2);
1707 else if (gimple_assign_rhs_class (use_stmt)
1708 == GIMPLE_BINARY_RHS)
1710 gimple_assign_set_rhs1 (use_stmt, crhs1);
1711 gimple_assign_set_rhs2 (use_stmt, crhs2);
1713 else
1715 gcc_checking_assert (gimple_assign_rhs_code (use_stmt)
1716 == COND_EXPR);
1717 tree cond = build2 (ccode, boolean_type_node,
1718 crhs1, crhs2);
1719 gimple_assign_set_rhs1 (use_stmt, cond);
1722 update_stmt (use_stmt);
1723 if (atomic_op != BIT_AND_EXPR
1724 && atomic_op != BIT_IOR_EXPR
1725 && !stmt_ends_bb_p (stmt2))
1727 /* For the benefit of debug stmts, emit stmt(s) to set
1728 lhs2 to the value it had from the new builtin.
1729 E.g. if it was previously:
1730 lhs2 = __atomic_fetch_add_8 (ptr, arg, 0);
1731 emit:
1732 new_lhs = __atomic_add_fetch_8 (ptr, arg, 0);
1733 lhs2 = new_lhs - arg;
1734 We also keep cast_stmt if any in the IL for
1735 the same reasons.
1736 These stmts will be DCEd later and proper debug info
1737 will be emitted.
1738 This is only possible for reversible operations
1739 (+/-/^) and without -fnon-call-exceptions. */
1740 gsi = gsi_for_stmt (stmt2);
1741 tree type = TREE_TYPE (lhs2);
1742 if (TREE_CODE (arg) == INTEGER_CST)
1743 arg = fold_convert (type, arg);
1744 else if (!useless_type_conversion_p (type, TREE_TYPE (arg)))
1746 tree narg = make_ssa_name (type);
1747 gimple *g = gimple_build_assign (narg, NOP_EXPR, arg);
1748 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
1749 arg = narg;
1751 enum tree_code rcode;
1752 switch (atomic_op)
1754 case PLUS_EXPR: rcode = MINUS_EXPR; break;
1755 case MINUS_EXPR: rcode = PLUS_EXPR; break;
1756 case BIT_XOR_EXPR: rcode = atomic_op; break;
1757 default: gcc_unreachable ();
1759 gimple *g = gimple_build_assign (lhs2, rcode, new_lhs, arg);
1760 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
1761 update_stmt (stmt2);
1763 else
1765 /* For e.g.
1766 lhs2 = __atomic_fetch_or_8 (ptr, arg, 0);
1767 after we change it to
1768 new_lhs = __atomic_or_fetch_8 (ptr, arg, 0);
1769 there is no way to find out the lhs2 value (i.e.
1770 what the atomic memory contained before the operation),
1771 values of some bits are lost. We have checked earlier
1772 that we don't have any non-debug users except for what
1773 we are already changing, so we need to reset the
1774 debug stmts and remove the cast_stmt if any. */
1775 imm_use_iterator iter;
1776 FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs2)
1777 if (use_stmt != cast_stmt)
1779 gcc_assert (is_gimple_debug (use_stmt));
1780 gimple_debug_bind_reset_value (use_stmt);
1781 update_stmt (use_stmt);
1783 if (cast_stmt)
1785 gsi = gsi_for_stmt (cast_stmt);
1786 gsi_remove (&gsi, true);
1788 update_stmt (stmt2);
1789 release_ssa_name (lhs2);
1793 break;
1795 default:
1796 break;
1798 return false;
1801 /* Given a ssa_name in NAME see if it was defined by an assignment and
1802 set CODE to be the code and ARG1 to the first operand on the rhs and ARG2
1803 to the second operand on the rhs. */
1805 static inline void
1806 defcodefor_name (tree name, enum tree_code *code, tree *arg1, tree *arg2)
1808 gimple *def;
1809 enum tree_code code1;
1810 tree arg11;
1811 tree arg21;
1812 tree arg31;
1813 enum gimple_rhs_class grhs_class;
1815 code1 = TREE_CODE (name);
1816 arg11 = name;
1817 arg21 = NULL_TREE;
1818 arg31 = NULL_TREE;
1819 grhs_class = get_gimple_rhs_class (code1);
1821 if (code1 == SSA_NAME)
1823 def = SSA_NAME_DEF_STMT (name);
1825 if (def && is_gimple_assign (def)
1826 && can_propagate_from (def))
1828 code1 = gimple_assign_rhs_code (def);
1829 arg11 = gimple_assign_rhs1 (def);
1830 arg21 = gimple_assign_rhs2 (def);
1831 arg31 = gimple_assign_rhs3 (def);
1834 else if (grhs_class != GIMPLE_SINGLE_RHS)
1835 code1 = ERROR_MARK;
1837 *code = code1;
1838 *arg1 = arg11;
1839 if (arg2)
1840 *arg2 = arg21;
1841 if (arg31)
1842 *code = ERROR_MARK;
1846 /* Recognize rotation patterns. Return true if a transformation
1847 applied, otherwise return false.
1849 We are looking for X with unsigned type T with bitsize B, OP being
1850 +, | or ^, some type T2 wider than T. For:
1851 (X << CNT1) OP (X >> CNT2) iff CNT1 + CNT2 == B
1852 ((T) ((T2) X << CNT1)) OP ((T) ((T2) X >> CNT2)) iff CNT1 + CNT2 == B
1854 transform these into:
1855 X r<< CNT1
1857 Or for:
1858 (X << Y) OP (X >> (B - Y))
1859 (X << (int) Y) OP (X >> (int) (B - Y))
1860 ((T) ((T2) X << Y)) OP ((T) ((T2) X >> (B - Y)))
1861 ((T) ((T2) X << (int) Y)) OP ((T) ((T2) X >> (int) (B - Y)))
1862 (X << Y) | (X >> ((-Y) & (B - 1)))
1863 (X << (int) Y) | (X >> (int) ((-Y) & (B - 1)))
1864 ((T) ((T2) X << Y)) | ((T) ((T2) X >> ((-Y) & (B - 1))))
1865 ((T) ((T2) X << (int) Y)) | ((T) ((T2) X >> (int) ((-Y) & (B - 1))))
1867 transform these into (last 2 only if ranger can prove Y < B
1868 or Y = N * B):
1869 X r<< Y
1871 X r<< (& & (B - 1))
1872 The latter for the forms with T2 wider than T if ranger can't prove Y < B.
1874 Or for:
1875 (X << (Y & (B - 1))) | (X >> ((-Y) & (B - 1)))
1876 (X << (int) (Y & (B - 1))) | (X >> (int) ((-Y) & (B - 1)))
1877 ((T) ((T2) X << (Y & (B - 1)))) | ((T) ((T2) X >> ((-Y) & (B - 1))))
1878 ((T) ((T2) X << (int) (Y & (B - 1)))) \
1879 | ((T) ((T2) X >> (int) ((-Y) & (B - 1))))
1881 transform these into:
1882 X r<< (Y & (B - 1))
1884 Note, in the patterns with T2 type, the type of OP operands
1885 might be even a signed type, but should have precision B.
1886 Expressions with & (B - 1) should be recognized only if B is
1887 a power of 2. */
1889 static bool
1890 simplify_rotate (gimple_stmt_iterator *gsi)
1892 gimple *stmt = gsi_stmt (*gsi);
1893 tree arg[2], rtype, rotcnt = NULL_TREE;
1894 tree def_arg1[2], def_arg2[2];
1895 enum tree_code def_code[2];
1896 tree lhs;
1897 int i;
1898 bool swapped_p = false;
1899 gimple *g;
1900 gimple *def_arg_stmt[2] = { NULL, NULL };
1901 int wider_prec = 0;
1902 bool add_masking = false;
1904 arg[0] = gimple_assign_rhs1 (stmt);
1905 arg[1] = gimple_assign_rhs2 (stmt);
1906 rtype = TREE_TYPE (arg[0]);
1908 /* Only create rotates in complete modes. Other cases are not
1909 expanded properly. */
1910 if (!INTEGRAL_TYPE_P (rtype)
1911 || !type_has_mode_precision_p (rtype))
1912 return false;
1914 for (i = 0; i < 2; i++)
1916 defcodefor_name (arg[i], &def_code[i], &def_arg1[i], &def_arg2[i]);
1917 if (TREE_CODE (arg[i]) == SSA_NAME)
1918 def_arg_stmt[i] = SSA_NAME_DEF_STMT (arg[i]);
1921 /* Look through narrowing (or same precision) conversions. */
1922 if (CONVERT_EXPR_CODE_P (def_code[0])
1923 && CONVERT_EXPR_CODE_P (def_code[1])
1924 && INTEGRAL_TYPE_P (TREE_TYPE (def_arg1[0]))
1925 && INTEGRAL_TYPE_P (TREE_TYPE (def_arg1[1]))
1926 && TYPE_PRECISION (TREE_TYPE (def_arg1[0]))
1927 == TYPE_PRECISION (TREE_TYPE (def_arg1[1]))
1928 && TYPE_PRECISION (TREE_TYPE (def_arg1[0])) >= TYPE_PRECISION (rtype)
1929 && has_single_use (arg[0])
1930 && has_single_use (arg[1]))
1932 wider_prec = TYPE_PRECISION (TREE_TYPE (def_arg1[0]));
1933 for (i = 0; i < 2; i++)
1935 arg[i] = def_arg1[i];
1936 defcodefor_name (arg[i], &def_code[i], &def_arg1[i], &def_arg2[i]);
1937 if (TREE_CODE (arg[i]) == SSA_NAME)
1938 def_arg_stmt[i] = SSA_NAME_DEF_STMT (arg[i]);
1941 else
1943 /* Handle signed rotate; the RSHIFT_EXPR has to be done
1944 in unsigned type but LSHIFT_EXPR could be signed. */
1945 i = (def_code[0] == LSHIFT_EXPR || def_code[0] == RSHIFT_EXPR);
1946 if (CONVERT_EXPR_CODE_P (def_code[i])
1947 && (def_code[1 - i] == LSHIFT_EXPR || def_code[1 - i] == RSHIFT_EXPR)
1948 && INTEGRAL_TYPE_P (TREE_TYPE (def_arg1[i]))
1949 && TYPE_PRECISION (rtype) == TYPE_PRECISION (TREE_TYPE (def_arg1[i]))
1950 && has_single_use (arg[i]))
1952 arg[i] = def_arg1[i];
1953 defcodefor_name (arg[i], &def_code[i], &def_arg1[i], &def_arg2[i]);
1954 if (TREE_CODE (arg[i]) == SSA_NAME)
1955 def_arg_stmt[i] = SSA_NAME_DEF_STMT (arg[i]);
1959 /* One operand has to be LSHIFT_EXPR and one RSHIFT_EXPR. */
1960 for (i = 0; i < 2; i++)
1961 if (def_code[i] != LSHIFT_EXPR && def_code[i] != RSHIFT_EXPR)
1962 return false;
1963 else if (!has_single_use (arg[i]))
1964 return false;
1965 if (def_code[0] == def_code[1])
1966 return false;
1968 /* If we've looked through narrowing conversions before, look through
1969 widening conversions from unsigned type with the same precision
1970 as rtype here. */
1971 if (TYPE_PRECISION (TREE_TYPE (def_arg1[0])) != TYPE_PRECISION (rtype))
1972 for (i = 0; i < 2; i++)
1974 tree tem;
1975 enum tree_code code;
1976 defcodefor_name (def_arg1[i], &code, &tem, NULL);
1977 if (!CONVERT_EXPR_CODE_P (code)
1978 || !INTEGRAL_TYPE_P (TREE_TYPE (tem))
1979 || TYPE_PRECISION (TREE_TYPE (tem)) != TYPE_PRECISION (rtype))
1980 return false;
1981 def_arg1[i] = tem;
1983 /* Both shifts have to use the same first operand. */
1984 if (!operand_equal_for_phi_arg_p (def_arg1[0], def_arg1[1])
1985 || !types_compatible_p (TREE_TYPE (def_arg1[0]),
1986 TREE_TYPE (def_arg1[1])))
1988 if ((TYPE_PRECISION (TREE_TYPE (def_arg1[0]))
1989 != TYPE_PRECISION (TREE_TYPE (def_arg1[1])))
1990 || (TYPE_UNSIGNED (TREE_TYPE (def_arg1[0]))
1991 == TYPE_UNSIGNED (TREE_TYPE (def_arg1[1]))))
1992 return false;
1994 /* Handle signed rotate; the RSHIFT_EXPR has to be done
1995 in unsigned type but LSHIFT_EXPR could be signed. */
1996 i = def_code[0] != RSHIFT_EXPR;
1997 if (!TYPE_UNSIGNED (TREE_TYPE (def_arg1[i])))
1998 return false;
2000 tree tem;
2001 enum tree_code code;
2002 defcodefor_name (def_arg1[i], &code, &tem, NULL);
2003 if (!CONVERT_EXPR_CODE_P (code)
2004 || !INTEGRAL_TYPE_P (TREE_TYPE (tem))
2005 || TYPE_PRECISION (TREE_TYPE (tem)) != TYPE_PRECISION (rtype))
2006 return false;
2007 def_arg1[i] = tem;
2008 if (!operand_equal_for_phi_arg_p (def_arg1[0], def_arg1[1])
2009 || !types_compatible_p (TREE_TYPE (def_arg1[0]),
2010 TREE_TYPE (def_arg1[1])))
2011 return false;
2013 else if (!TYPE_UNSIGNED (TREE_TYPE (def_arg1[0])))
2014 return false;
2016 /* CNT1 + CNT2 == B case above. */
2017 if (tree_fits_uhwi_p (def_arg2[0])
2018 && tree_fits_uhwi_p (def_arg2[1])
2019 && tree_to_uhwi (def_arg2[0])
2020 + tree_to_uhwi (def_arg2[1]) == TYPE_PRECISION (rtype))
2021 rotcnt = def_arg2[0];
2022 else if (TREE_CODE (def_arg2[0]) != SSA_NAME
2023 || TREE_CODE (def_arg2[1]) != SSA_NAME)
2024 return false;
2025 else
2027 tree cdef_arg1[2], cdef_arg2[2], def_arg2_alt[2];
2028 enum tree_code cdef_code[2];
2029 gimple *def_arg_alt_stmt[2] = { NULL, NULL };
2030 int check_range = 0;
2031 gimple *check_range_stmt = NULL;
2032 /* Look through conversion of the shift count argument.
2033 The C/C++ FE cast any shift count argument to integer_type_node.
2034 The only problem might be if the shift count type maximum value
2035 is equal or smaller than number of bits in rtype. */
2036 for (i = 0; i < 2; i++)
2038 def_arg2_alt[i] = def_arg2[i];
2039 defcodefor_name (def_arg2[i], &cdef_code[i],
2040 &cdef_arg1[i], &cdef_arg2[i]);
2041 if (CONVERT_EXPR_CODE_P (cdef_code[i])
2042 && INTEGRAL_TYPE_P (TREE_TYPE (cdef_arg1[i]))
2043 && TYPE_PRECISION (TREE_TYPE (cdef_arg1[i]))
2044 > floor_log2 (TYPE_PRECISION (rtype))
2045 && type_has_mode_precision_p (TREE_TYPE (cdef_arg1[i])))
2047 def_arg2_alt[i] = cdef_arg1[i];
2048 if (TREE_CODE (def_arg2[i]) == SSA_NAME)
2049 def_arg_alt_stmt[i] = SSA_NAME_DEF_STMT (def_arg2[i]);
2050 defcodefor_name (def_arg2_alt[i], &cdef_code[i],
2051 &cdef_arg1[i], &cdef_arg2[i]);
2053 else
2054 def_arg_alt_stmt[i] = def_arg_stmt[i];
2056 for (i = 0; i < 2; i++)
2057 /* Check for one shift count being Y and the other B - Y,
2058 with optional casts. */
2059 if (cdef_code[i] == MINUS_EXPR
2060 && tree_fits_shwi_p (cdef_arg1[i])
2061 && tree_to_shwi (cdef_arg1[i]) == TYPE_PRECISION (rtype)
2062 && TREE_CODE (cdef_arg2[i]) == SSA_NAME)
2064 tree tem;
2065 enum tree_code code;
2067 if (cdef_arg2[i] == def_arg2[1 - i]
2068 || cdef_arg2[i] == def_arg2_alt[1 - i])
2070 rotcnt = cdef_arg2[i];
2071 check_range = -1;
2072 if (cdef_arg2[i] == def_arg2[1 - i])
2073 check_range_stmt = def_arg_stmt[1 - i];
2074 else
2075 check_range_stmt = def_arg_alt_stmt[1 - i];
2076 break;
2078 defcodefor_name (cdef_arg2[i], &code, &tem, NULL);
2079 if (CONVERT_EXPR_CODE_P (code)
2080 && INTEGRAL_TYPE_P (TREE_TYPE (tem))
2081 && TYPE_PRECISION (TREE_TYPE (tem))
2082 > floor_log2 (TYPE_PRECISION (rtype))
2083 && type_has_mode_precision_p (TREE_TYPE (tem))
2084 && (tem == def_arg2[1 - i]
2085 || tem == def_arg2_alt[1 - i]))
2087 rotcnt = tem;
2088 check_range = -1;
2089 if (tem == def_arg2[1 - i])
2090 check_range_stmt = def_arg_stmt[1 - i];
2091 else
2092 check_range_stmt = def_arg_alt_stmt[1 - i];
2093 break;
2096 /* The above sequence isn't safe for Y being 0,
2097 because then one of the shifts triggers undefined behavior.
2098 This alternative is safe even for rotation count of 0.
2099 One shift count is Y and the other (-Y) & (B - 1).
2100 Or one shift count is Y & (B - 1) and the other (-Y) & (B - 1). */
2101 else if (cdef_code[i] == BIT_AND_EXPR
2102 && pow2p_hwi (TYPE_PRECISION (rtype))
2103 && tree_fits_shwi_p (cdef_arg2[i])
2104 && tree_to_shwi (cdef_arg2[i])
2105 == TYPE_PRECISION (rtype) - 1
2106 && TREE_CODE (cdef_arg1[i]) == SSA_NAME
2107 && gimple_assign_rhs_code (stmt) == BIT_IOR_EXPR)
2109 tree tem;
2110 enum tree_code code;
2112 defcodefor_name (cdef_arg1[i], &code, &tem, NULL);
2113 if (CONVERT_EXPR_CODE_P (code)
2114 && INTEGRAL_TYPE_P (TREE_TYPE (tem))
2115 && TYPE_PRECISION (TREE_TYPE (tem))
2116 > floor_log2 (TYPE_PRECISION (rtype))
2117 && type_has_mode_precision_p (TREE_TYPE (tem)))
2118 defcodefor_name (tem, &code, &tem, NULL);
2120 if (code == NEGATE_EXPR)
2122 if (tem == def_arg2[1 - i] || tem == def_arg2_alt[1 - i])
2124 rotcnt = tem;
2125 check_range = 1;
2126 if (tem == def_arg2[1 - i])
2127 check_range_stmt = def_arg_stmt[1 - i];
2128 else
2129 check_range_stmt = def_arg_alt_stmt[1 - i];
2130 break;
2132 tree tem2;
2133 defcodefor_name (tem, &code, &tem2, NULL);
2134 if (CONVERT_EXPR_CODE_P (code)
2135 && INTEGRAL_TYPE_P (TREE_TYPE (tem2))
2136 && TYPE_PRECISION (TREE_TYPE (tem2))
2137 > floor_log2 (TYPE_PRECISION (rtype))
2138 && type_has_mode_precision_p (TREE_TYPE (tem2)))
2140 if (tem2 == def_arg2[1 - i]
2141 || tem2 == def_arg2_alt[1 - i])
2143 rotcnt = tem2;
2144 check_range = 1;
2145 if (tem2 == def_arg2[1 - i])
2146 check_range_stmt = def_arg_stmt[1 - i];
2147 else
2148 check_range_stmt = def_arg_alt_stmt[1 - i];
2149 break;
2152 else
2153 tem2 = NULL_TREE;
2155 if (cdef_code[1 - i] == BIT_AND_EXPR
2156 && tree_fits_shwi_p (cdef_arg2[1 - i])
2157 && tree_to_shwi (cdef_arg2[1 - i])
2158 == TYPE_PRECISION (rtype) - 1
2159 && TREE_CODE (cdef_arg1[1 - i]) == SSA_NAME)
2161 if (tem == cdef_arg1[1 - i]
2162 || tem2 == cdef_arg1[1 - i])
2164 rotcnt = def_arg2[1 - i];
2165 break;
2167 tree tem3;
2168 defcodefor_name (cdef_arg1[1 - i], &code, &tem3, NULL);
2169 if (CONVERT_EXPR_CODE_P (code)
2170 && INTEGRAL_TYPE_P (TREE_TYPE (tem3))
2171 && TYPE_PRECISION (TREE_TYPE (tem3))
2172 > floor_log2 (TYPE_PRECISION (rtype))
2173 && type_has_mode_precision_p (TREE_TYPE (tem3)))
2175 if (tem == tem3 || tem2 == tem3)
2177 rotcnt = def_arg2[1 - i];
2178 break;
2184 if (check_range && wider_prec > TYPE_PRECISION (rtype))
2186 if (TREE_CODE (rotcnt) != SSA_NAME)
2187 return false;
2188 int_range_max r;
2189 range_query *q = get_range_query (cfun);
2190 if (q == get_global_range_query ())
2191 q = enable_ranger (cfun);
2192 if (!q->range_of_expr (r, rotcnt, check_range_stmt))
2194 if (check_range > 0)
2195 return false;
2196 r.set_varying (TREE_TYPE (rotcnt));
2198 int prec = TYPE_PRECISION (TREE_TYPE (rotcnt));
2199 signop sign = TYPE_SIGN (TREE_TYPE (rotcnt));
2200 wide_int min = wide_int::from (TYPE_PRECISION (rtype), prec, sign);
2201 wide_int max = wide_int::from (wider_prec - 1, prec, sign);
2202 if (check_range < 0)
2203 max = min;
2204 int_range<1> r2 (TREE_TYPE (rotcnt), min, max);
2205 r.intersect (r2);
2206 if (!r.undefined_p ())
2208 if (check_range > 0)
2210 int_range_max r3;
2211 for (int i = TYPE_PRECISION (rtype) + 1; i < wider_prec;
2212 i += TYPE_PRECISION (rtype))
2214 int j = i + TYPE_PRECISION (rtype) - 2;
2215 min = wide_int::from (i, prec, sign);
2216 max = wide_int::from (MIN (j, wider_prec - 1),
2217 prec, sign);
2218 int_range<1> r4 (TREE_TYPE (rotcnt), min, max);
2219 r3.union_ (r4);
2221 r.intersect (r3);
2222 if (!r.undefined_p ())
2223 return false;
2225 add_masking = true;
2228 if (rotcnt == NULL_TREE)
2229 return false;
2230 swapped_p = i != 1;
2233 if (!useless_type_conversion_p (TREE_TYPE (def_arg2[0]),
2234 TREE_TYPE (rotcnt)))
2236 g = gimple_build_assign (make_ssa_name (TREE_TYPE (def_arg2[0])),
2237 NOP_EXPR, rotcnt);
2238 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2239 rotcnt = gimple_assign_lhs (g);
2241 if (add_masking)
2243 g = gimple_build_assign (make_ssa_name (TREE_TYPE (rotcnt)),
2244 BIT_AND_EXPR, rotcnt,
2245 build_int_cst (TREE_TYPE (rotcnt),
2246 TYPE_PRECISION (rtype) - 1));
2247 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2248 rotcnt = gimple_assign_lhs (g);
2250 lhs = gimple_assign_lhs (stmt);
2251 if (!useless_type_conversion_p (rtype, TREE_TYPE (def_arg1[0])))
2252 lhs = make_ssa_name (TREE_TYPE (def_arg1[0]));
2253 g = gimple_build_assign (lhs,
2254 ((def_code[0] == LSHIFT_EXPR) ^ swapped_p)
2255 ? LROTATE_EXPR : RROTATE_EXPR, def_arg1[0], rotcnt);
2256 if (!useless_type_conversion_p (rtype, TREE_TYPE (def_arg1[0])))
2258 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2259 g = gimple_build_assign (gimple_assign_lhs (stmt), NOP_EXPR, lhs);
2261 gsi_replace (gsi, g, false);
2262 return true;
2266 /* Check whether an array contains a valid ctz table. */
2267 static bool
2268 check_ctz_array (tree ctor, unsigned HOST_WIDE_INT mulc,
2269 HOST_WIDE_INT &zero_val, unsigned shift, unsigned bits)
2271 tree elt, idx;
2272 unsigned HOST_WIDE_INT i, mask, raw_idx = 0;
2273 unsigned matched = 0;
2275 mask = ((HOST_WIDE_INT_1U << (bits - shift)) - 1) << shift;
2277 zero_val = 0;
2279 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), i, idx, elt)
2281 if (!tree_fits_shwi_p (idx))
2282 return false;
2283 if (!tree_fits_shwi_p (elt) && TREE_CODE (elt) != RAW_DATA_CST)
2284 return false;
2286 unsigned HOST_WIDE_INT index = tree_to_shwi (idx);
2287 HOST_WIDE_INT val;
2289 if (TREE_CODE (elt) == INTEGER_CST)
2290 val = tree_to_shwi (elt);
2291 else
2293 if (raw_idx == (unsigned) RAW_DATA_LENGTH (elt))
2295 raw_idx = 0;
2296 continue;
2298 if (TYPE_UNSIGNED (TREE_TYPE (elt)))
2299 val = RAW_DATA_UCHAR_ELT (elt, raw_idx);
2300 else
2301 val = RAW_DATA_SCHAR_ELT (elt, raw_idx);
2302 index += raw_idx;
2303 raw_idx++;
2304 i--;
2307 if (index > bits * 2)
2308 return false;
2310 if (index == 0)
2312 zero_val = val;
2313 matched++;
2316 if (val >= 0 && val < bits && (((mulc << val) & mask) >> shift) == index)
2317 matched++;
2319 if (matched > bits)
2320 return true;
2323 return false;
2326 /* Check whether a string contains a valid ctz table. */
2327 static bool
2328 check_ctz_string (tree string, unsigned HOST_WIDE_INT mulc,
2329 HOST_WIDE_INT &zero_val, unsigned shift, unsigned bits)
2331 unsigned HOST_WIDE_INT len = TREE_STRING_LENGTH (string);
2332 unsigned HOST_WIDE_INT mask;
2333 unsigned matched = 0;
2334 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (string);
2336 if (len < bits || len > bits * 2)
2337 return false;
2339 mask = ((HOST_WIDE_INT_1U << (bits - shift)) - 1) << shift;
2341 zero_val = p[0];
2343 for (unsigned i = 0; i < len; i++)
2344 if (p[i] < bits && (((mulc << p[i]) & mask) >> shift) == i)
2345 matched++;
2347 return matched == bits;
2350 /* Recognize count trailing zeroes idiom.
2351 The canonical form is array[((x & -x) * C) >> SHIFT] where C is a magic
2352 constant which when multiplied by a power of 2 creates a unique value
2353 in the top 5 or 6 bits. This is then indexed into a table which maps it
2354 to the number of trailing zeroes. Array[0] is returned so the caller can
2355 emit an appropriate sequence depending on whether ctz (0) is defined on
2356 the target. */
2357 static bool
2358 optimize_count_trailing_zeroes (tree array_ref, tree x, tree mulc,
2359 tree tshift, HOST_WIDE_INT &zero_val)
2361 tree type = TREE_TYPE (array_ref);
2362 tree array = TREE_OPERAND (array_ref, 0);
2364 gcc_assert (TREE_CODE (mulc) == INTEGER_CST);
2365 gcc_assert (TREE_CODE (tshift) == INTEGER_CST);
2367 tree input_type = TREE_TYPE (x);
2368 unsigned input_bits = tree_to_shwi (TYPE_SIZE (input_type));
2370 /* Check the array element type is not wider than 32 bits and the input is
2371 an unsigned 32-bit or 64-bit type. */
2372 if (TYPE_PRECISION (type) > 32 || !TYPE_UNSIGNED (input_type))
2373 return false;
2374 if (input_bits != 32 && input_bits != 64)
2375 return false;
2377 if (!direct_internal_fn_supported_p (IFN_CTZ, input_type, OPTIMIZE_FOR_BOTH))
2378 return false;
2380 /* Check the lower bound of the array is zero. */
2381 tree low = array_ref_low_bound (array_ref);
2382 if (!low || !integer_zerop (low))
2383 return false;
2385 unsigned shiftval = tree_to_shwi (tshift);
2387 /* Check the shift extracts the top 5..7 bits. */
2388 if (shiftval < input_bits - 7 || shiftval > input_bits - 5)
2389 return false;
2391 tree ctor = ctor_for_folding (array);
2392 if (!ctor)
2393 return false;
2395 unsigned HOST_WIDE_INT val = tree_to_uhwi (mulc);
2397 if (TREE_CODE (ctor) == CONSTRUCTOR)
2398 return check_ctz_array (ctor, val, zero_val, shiftval, input_bits);
2400 if (TREE_CODE (ctor) == STRING_CST
2401 && TYPE_PRECISION (type) == CHAR_TYPE_SIZE)
2402 return check_ctz_string (ctor, val, zero_val, shiftval, input_bits);
2404 return false;
2407 /* Match.pd function to match the ctz expression. */
2408 extern bool gimple_ctz_table_index (tree, tree *, tree (*)(tree));
2410 static bool
2411 simplify_count_trailing_zeroes (gimple_stmt_iterator *gsi)
2413 gimple *stmt = gsi_stmt (*gsi);
2414 tree array_ref = gimple_assign_rhs1 (stmt);
2415 tree res_ops[3];
2416 HOST_WIDE_INT zero_val;
2418 gcc_checking_assert (TREE_CODE (array_ref) == ARRAY_REF);
2420 if (!gimple_ctz_table_index (TREE_OPERAND (array_ref, 1), &res_ops[0], NULL))
2421 return false;
2423 if (optimize_count_trailing_zeroes (array_ref, res_ops[0],
2424 res_ops[1], res_ops[2], zero_val))
2426 tree type = TREE_TYPE (res_ops[0]);
2427 HOST_WIDE_INT ctz_val = 0;
2428 HOST_WIDE_INT type_size = tree_to_shwi (TYPE_SIZE (type));
2429 bool zero_ok
2430 = CTZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (type), ctz_val) == 2;
2431 int nargs = 2;
2433 /* If the input value can't be zero, don't special case ctz (0). */
2434 if (tree_expr_nonzero_p (res_ops[0]))
2436 zero_ok = true;
2437 zero_val = 0;
2438 ctz_val = 0;
2439 nargs = 1;
2442 /* Skip if there is no value defined at zero, or if we can't easily
2443 return the correct value for zero. */
2444 if (!zero_ok)
2445 return false;
2446 if (zero_val != ctz_val && !(zero_val == 0 && ctz_val == type_size))
2447 return false;
2449 gimple_seq seq = NULL;
2450 gimple *g;
2451 gcall *call
2452 = gimple_build_call_internal (IFN_CTZ, nargs, res_ops[0],
2453 nargs == 1 ? NULL_TREE
2454 : build_int_cst (integer_type_node,
2455 ctz_val));
2456 gimple_set_location (call, gimple_location (stmt));
2457 gimple_set_lhs (call, make_ssa_name (integer_type_node));
2458 gimple_seq_add_stmt (&seq, call);
2460 tree prev_lhs = gimple_call_lhs (call);
2462 /* Emit ctz (x) & 31 if ctz (0) is 32 but we need to return 0. */
2463 if (zero_val == 0 && ctz_val == type_size)
2465 g = gimple_build_assign (make_ssa_name (integer_type_node),
2466 BIT_AND_EXPR, prev_lhs,
2467 build_int_cst (integer_type_node,
2468 type_size - 1));
2469 gimple_set_location (g, gimple_location (stmt));
2470 gimple_seq_add_stmt (&seq, g);
2471 prev_lhs = gimple_assign_lhs (g);
2474 g = gimple_build_assign (gimple_assign_lhs (stmt), NOP_EXPR, prev_lhs);
2475 gimple_seq_add_stmt (&seq, g);
2476 gsi_replace_with_seq (gsi, seq, true);
2477 return true;
2480 return false;
2484 /* Combine an element access with a shuffle. Returns true if there were
2485 any changes made, else it returns false. */
2487 static bool
2488 simplify_bitfield_ref (gimple_stmt_iterator *gsi)
2490 gimple *stmt = gsi_stmt (*gsi);
2491 gimple *def_stmt;
2492 tree op, op0, op1;
2493 tree elem_type, type;
2494 tree p, m, tem;
2495 unsigned HOST_WIDE_INT nelts, idx;
2496 poly_uint64 size, elem_size;
2497 enum tree_code code;
2499 op = gimple_assign_rhs1 (stmt);
2500 gcc_checking_assert (TREE_CODE (op) == BIT_FIELD_REF);
2502 op0 = TREE_OPERAND (op, 0);
2503 if (TREE_CODE (op0) != SSA_NAME
2504 || TREE_CODE (TREE_TYPE (op0)) != VECTOR_TYPE)
2505 return false;
2507 def_stmt = get_prop_source_stmt (op0, false, NULL);
2508 if (!def_stmt || !can_propagate_from (def_stmt))
2509 return false;
2511 op1 = TREE_OPERAND (op, 1);
2512 code = gimple_assign_rhs_code (def_stmt);
2513 elem_type = TREE_TYPE (TREE_TYPE (op0));
2514 type = TREE_TYPE (op);
2515 /* Also handle vector type.
2516 .i.e.
2517 _7 = VEC_PERM_EXPR <_1, _1, { 2, 3, 2, 3 }>;
2518 _11 = BIT_FIELD_REF <_7, 64, 0>;
2522 _11 = BIT_FIELD_REF <_1, 64, 64>. */
2524 size = tree_to_poly_uint64 (TYPE_SIZE (type));
2525 if (maybe_ne (bit_field_size (op), size))
2526 return false;
2528 elem_size = tree_to_poly_uint64 (TYPE_SIZE (elem_type));
2529 if (code != VEC_PERM_EXPR
2530 || !constant_multiple_p (bit_field_offset (op), elem_size, &idx))
2531 return false;
2533 m = gimple_assign_rhs3 (def_stmt);
2534 if (TREE_CODE (m) != VECTOR_CST
2535 || !VECTOR_CST_NELTS (m).is_constant (&nelts))
2536 return false;
2538 /* One element. */
2539 if (known_eq (size, elem_size))
2540 idx = TREE_INT_CST_LOW (VECTOR_CST_ELT (m, idx)) % (2 * nelts);
2541 else
2543 unsigned HOST_WIDE_INT nelts_op;
2544 if (!constant_multiple_p (size, elem_size, &nelts_op)
2545 || !pow2p_hwi (nelts_op))
2546 return false;
2547 /* Clamp vec_perm_expr index. */
2548 unsigned start = TREE_INT_CST_LOW (vector_cst_elt (m, idx)) % (2 * nelts);
2549 unsigned end = TREE_INT_CST_LOW (vector_cst_elt (m, idx + nelts_op - 1))
2550 % (2 * nelts);
2551 /* Be in the same vector. */
2552 if ((start < nelts) != (end < nelts))
2553 return false;
2554 for (unsigned HOST_WIDE_INT i = 1; i != nelts_op; i++)
2556 /* Continuous area. */
2557 if (TREE_INT_CST_LOW (vector_cst_elt (m, idx + i)) % (2 * nelts) - 1
2558 != TREE_INT_CST_LOW (vector_cst_elt (m, idx + i - 1))
2559 % (2 * nelts))
2560 return false;
2562 /* Alignment not worse than before. */
2563 if (start % nelts_op)
2564 return false;
2565 idx = start;
2568 if (idx < nelts)
2569 p = gimple_assign_rhs1 (def_stmt);
2570 else
2572 p = gimple_assign_rhs2 (def_stmt);
2573 idx -= nelts;
2576 tem = build3 (BIT_FIELD_REF, TREE_TYPE (op),
2577 p, op1, bitsize_int (idx * elem_size));
2578 gimple_assign_set_rhs1 (stmt, tem);
2579 fold_stmt (gsi);
2580 update_stmt (gsi_stmt (*gsi));
2581 return true;
2584 /* Determine whether applying the 2 permutations (mask1 then mask2)
2585 gives back one of the input. */
2587 static int
2588 is_combined_permutation_identity (tree mask1, tree mask2)
2590 tree mask;
2591 unsigned HOST_WIDE_INT nelts, i, j;
2592 bool maybe_identity1 = true;
2593 bool maybe_identity2 = true;
2595 gcc_checking_assert (TREE_CODE (mask1) == VECTOR_CST
2596 && TREE_CODE (mask2) == VECTOR_CST);
2598 /* For VLA masks, check for the following pattern:
2599 v1 = VEC_PERM_EXPR (v0, ..., mask1)
2600 v2 = VEC_PERM_EXPR (v1, ..., mask2)
2602 v2 = v0
2603 if mask1 == mask2 == {nelts - 1, nelts - 2, ...}. */
2605 if (operand_equal_p (mask1, mask2, 0)
2606 && !VECTOR_CST_NELTS (mask1).is_constant ())
2608 vec_perm_builder builder;
2609 if (tree_to_vec_perm_builder (&builder, mask1))
2611 poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (mask1));
2612 vec_perm_indices sel (builder, 1, nelts);
2613 if (sel.series_p (0, 1, nelts - 1, -1))
2614 return 1;
2618 mask = fold_ternary (VEC_PERM_EXPR, TREE_TYPE (mask1), mask1, mask1, mask2);
2619 if (mask == NULL_TREE || TREE_CODE (mask) != VECTOR_CST)
2620 return 0;
2622 if (!VECTOR_CST_NELTS (mask).is_constant (&nelts))
2623 return 0;
2624 for (i = 0; i < nelts; i++)
2626 tree val = VECTOR_CST_ELT (mask, i);
2627 gcc_assert (TREE_CODE (val) == INTEGER_CST);
2628 j = TREE_INT_CST_LOW (val) & (2 * nelts - 1);
2629 if (j == i)
2630 maybe_identity2 = false;
2631 else if (j == i + nelts)
2632 maybe_identity1 = false;
2633 else
2634 return 0;
2636 return maybe_identity1 ? 1 : maybe_identity2 ? 2 : 0;
2639 /* Combine a shuffle with its arguments. Returns 1 if there were any
2640 changes made, 2 if cfg-cleanup needs to run. Else it returns 0. */
2642 static int
2643 simplify_permutation (gimple_stmt_iterator *gsi)
2645 gimple *stmt = gsi_stmt (*gsi);
2646 gimple *def_stmt = NULL;
2647 tree op0, op1, op2, op3, arg0, arg1;
2648 enum tree_code code, code2 = ERROR_MARK;
2649 bool single_use_op0 = false;
2651 gcc_checking_assert (gimple_assign_rhs_code (stmt) == VEC_PERM_EXPR);
2653 op0 = gimple_assign_rhs1 (stmt);
2654 op1 = gimple_assign_rhs2 (stmt);
2655 op2 = gimple_assign_rhs3 (stmt);
2657 if (TREE_CODE (op2) != VECTOR_CST)
2658 return 0;
2660 if (TREE_CODE (op0) == VECTOR_CST)
2662 code = VECTOR_CST;
2663 arg0 = op0;
2665 else if (TREE_CODE (op0) == SSA_NAME)
2667 def_stmt = get_prop_source_stmt (op0, false, &single_use_op0);
2668 if (!def_stmt)
2669 return 0;
2670 code = gimple_assign_rhs_code (def_stmt);
2671 if (code == VIEW_CONVERT_EXPR)
2673 tree rhs = gimple_assign_rhs1 (def_stmt);
2674 tree name = TREE_OPERAND (rhs, 0);
2675 if (TREE_CODE (name) != SSA_NAME)
2676 return 0;
2677 if (!has_single_use (name))
2678 single_use_op0 = false;
2679 /* Here we update the def_stmt through this VIEW_CONVERT_EXPR,
2680 but still keep the code to indicate it comes from
2681 VIEW_CONVERT_EXPR. */
2682 def_stmt = SSA_NAME_DEF_STMT (name);
2683 if (!def_stmt || !is_gimple_assign (def_stmt))
2684 return 0;
2685 if (gimple_assign_rhs_code (def_stmt) != CONSTRUCTOR)
2686 return 0;
2688 if (!can_propagate_from (def_stmt))
2689 return 0;
2690 arg0 = gimple_assign_rhs1 (def_stmt);
2692 else
2693 return 0;
2695 /* Two consecutive shuffles. */
2696 if (code == VEC_PERM_EXPR)
2698 tree orig;
2699 int ident;
2701 if (op0 != op1)
2702 return 0;
2703 op3 = gimple_assign_rhs3 (def_stmt);
2704 if (TREE_CODE (op3) != VECTOR_CST)
2705 return 0;
2706 ident = is_combined_permutation_identity (op3, op2);
2707 if (!ident)
2708 return 0;
2709 orig = (ident == 1) ? gimple_assign_rhs1 (def_stmt)
2710 : gimple_assign_rhs2 (def_stmt);
2711 gimple_assign_set_rhs1 (stmt, unshare_expr (orig));
2712 gimple_assign_set_rhs_code (stmt, TREE_CODE (orig));
2713 gimple_set_num_ops (stmt, 2);
2714 update_stmt (stmt);
2715 return remove_prop_source_from_use (op0) ? 2 : 1;
2717 else if (code == CONSTRUCTOR
2718 || code == VECTOR_CST
2719 || code == VIEW_CONVERT_EXPR)
2721 if (op0 != op1)
2723 if (TREE_CODE (op0) == SSA_NAME && !single_use_op0)
2724 return 0;
2726 if (TREE_CODE (op1) == VECTOR_CST)
2727 arg1 = op1;
2728 else if (TREE_CODE (op1) == SSA_NAME)
2730 gimple *def_stmt2 = get_prop_source_stmt (op1, true, NULL);
2731 if (!def_stmt2)
2732 return 0;
2733 code2 = gimple_assign_rhs_code (def_stmt2);
2734 if (code2 == VIEW_CONVERT_EXPR)
2736 tree rhs = gimple_assign_rhs1 (def_stmt2);
2737 tree name = TREE_OPERAND (rhs, 0);
2738 if (TREE_CODE (name) != SSA_NAME)
2739 return 0;
2740 if (!has_single_use (name))
2741 return 0;
2742 def_stmt2 = SSA_NAME_DEF_STMT (name);
2743 if (!def_stmt2 || !is_gimple_assign (def_stmt2))
2744 return 0;
2745 if (gimple_assign_rhs_code (def_stmt2) != CONSTRUCTOR)
2746 return 0;
2748 else if (code2 != CONSTRUCTOR && code2 != VECTOR_CST)
2749 return 0;
2750 if (!can_propagate_from (def_stmt2))
2751 return 0;
2752 arg1 = gimple_assign_rhs1 (def_stmt2);
2754 else
2755 return 0;
2757 else
2759 /* Already used twice in this statement. */
2760 if (TREE_CODE (op0) == SSA_NAME && num_imm_uses (op0) > 2)
2761 return 0;
2762 arg1 = arg0;
2765 /* If there are any VIEW_CONVERT_EXPRs found when finding permutation
2766 operands source, check whether it's valid to transform and prepare
2767 the required new operands. */
2768 if (code == VIEW_CONVERT_EXPR || code2 == VIEW_CONVERT_EXPR)
2770 /* Figure out the target vector type to which operands should be
2771 converted. If both are CONSTRUCTOR, the types should be the
2772 same, otherwise, use the one of CONSTRUCTOR. */
2773 tree tgt_type = NULL_TREE;
2774 if (code == VIEW_CONVERT_EXPR)
2776 gcc_assert (gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR);
2777 code = CONSTRUCTOR;
2778 tgt_type = TREE_TYPE (arg0);
2780 if (code2 == VIEW_CONVERT_EXPR)
2782 tree arg1_type = TREE_TYPE (arg1);
2783 if (tgt_type == NULL_TREE)
2784 tgt_type = arg1_type;
2785 else if (tgt_type != arg1_type)
2786 return 0;
2789 if (!VECTOR_TYPE_P (tgt_type))
2790 return 0;
2791 tree op2_type = TREE_TYPE (op2);
2793 /* Figure out the shrunk factor. */
2794 poly_uint64 tgt_units = TYPE_VECTOR_SUBPARTS (tgt_type);
2795 poly_uint64 op2_units = TYPE_VECTOR_SUBPARTS (op2_type);
2796 if (maybe_gt (tgt_units, op2_units))
2797 return 0;
2798 unsigned int factor;
2799 if (!constant_multiple_p (op2_units, tgt_units, &factor))
2800 return 0;
2802 /* Build the new permutation control vector as target vector. */
2803 vec_perm_builder builder;
2804 if (!tree_to_vec_perm_builder (&builder, op2))
2805 return 0;
2806 vec_perm_indices indices (builder, 2, op2_units);
2807 vec_perm_indices new_indices;
2808 if (new_indices.new_shrunk_vector (indices, factor))
2810 tree mask_type = tgt_type;
2811 if (!VECTOR_INTEGER_TYPE_P (mask_type))
2813 tree elem_type = TREE_TYPE (mask_type);
2814 unsigned elem_size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type));
2815 tree int_type = build_nonstandard_integer_type (elem_size, 0);
2816 mask_type = build_vector_type (int_type, tgt_units);
2818 op2 = vec_perm_indices_to_tree (mask_type, new_indices);
2820 else
2821 return 0;
2823 /* Convert the VECTOR_CST to the appropriate vector type. */
2824 if (tgt_type != TREE_TYPE (arg0))
2825 arg0 = fold_build1 (VIEW_CONVERT_EXPR, tgt_type, arg0);
2826 else if (tgt_type != TREE_TYPE (arg1))
2827 arg1 = fold_build1 (VIEW_CONVERT_EXPR, tgt_type, arg1);
2830 /* VIEW_CONVERT_EXPR should be updated to CONSTRUCTOR before. */
2831 gcc_assert (code == CONSTRUCTOR || code == VECTOR_CST);
2833 /* Shuffle of a constructor. */
2834 bool ret = false;
2835 tree res_type
2836 = build_vector_type (TREE_TYPE (TREE_TYPE (arg0)),
2837 TYPE_VECTOR_SUBPARTS (TREE_TYPE (op2)));
2838 tree opt = fold_ternary (VEC_PERM_EXPR, res_type, arg0, arg1, op2);
2839 if (!opt
2840 || (TREE_CODE (opt) != CONSTRUCTOR && TREE_CODE (opt) != VECTOR_CST))
2841 return 0;
2842 /* Found VIEW_CONVERT_EXPR before, need one explicit conversion. */
2843 if (res_type != TREE_TYPE (op0))
2845 tree name = make_ssa_name (TREE_TYPE (opt));
2846 gimple *ass_stmt = gimple_build_assign (name, opt);
2847 gsi_insert_before (gsi, ass_stmt, GSI_SAME_STMT);
2848 opt = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (op0), name);
2850 gimple_assign_set_rhs_from_tree (gsi, opt);
2851 update_stmt (gsi_stmt (*gsi));
2852 if (TREE_CODE (op0) == SSA_NAME)
2853 ret = remove_prop_source_from_use (op0);
2854 if (op0 != op1 && TREE_CODE (op1) == SSA_NAME)
2855 ret |= remove_prop_source_from_use (op1);
2856 return ret ? 2 : 1;
2859 return 0;
2862 /* Get the BIT_FIELD_REF definition of VAL, if any, looking through
2863 conversions with code CONV_CODE or update it if still ERROR_MARK.
2864 Return NULL_TREE if no such matching def was found. */
2866 static tree
2867 get_bit_field_ref_def (tree val, enum tree_code &conv_code)
2869 if (TREE_CODE (val) != SSA_NAME)
2870 return NULL_TREE ;
2871 gimple *def_stmt = get_prop_source_stmt (val, false, NULL);
2872 if (!def_stmt)
2873 return NULL_TREE;
2874 enum tree_code code = gimple_assign_rhs_code (def_stmt);
2875 if (code == FLOAT_EXPR
2876 || code == FIX_TRUNC_EXPR
2877 || CONVERT_EXPR_CODE_P (code))
2879 tree op1 = gimple_assign_rhs1 (def_stmt);
2880 if (conv_code == ERROR_MARK)
2881 conv_code = code;
2882 else if (conv_code != code)
2883 return NULL_TREE;
2884 if (TREE_CODE (op1) != SSA_NAME)
2885 return NULL_TREE;
2886 def_stmt = SSA_NAME_DEF_STMT (op1);
2887 if (! is_gimple_assign (def_stmt))
2888 return NULL_TREE;
2889 code = gimple_assign_rhs_code (def_stmt);
2891 if (code != BIT_FIELD_REF)
2892 return NULL_TREE;
2893 return gimple_assign_rhs1 (def_stmt);
2896 /* Recognize a VEC_PERM_EXPR. Returns true if there were any changes. */
2898 static bool
2899 simplify_vector_constructor (gimple_stmt_iterator *gsi)
2901 gimple *stmt = gsi_stmt (*gsi);
2902 tree op, orig[2], type, elem_type;
2903 unsigned elem_size, i;
2904 unsigned HOST_WIDE_INT nelts;
2905 unsigned HOST_WIDE_INT refnelts;
2906 enum tree_code conv_code;
2907 constructor_elt *elt;
2909 op = gimple_assign_rhs1 (stmt);
2910 type = TREE_TYPE (op);
2911 gcc_checking_assert (TREE_CODE (op) == CONSTRUCTOR
2912 && TREE_CODE (type) == VECTOR_TYPE);
2914 if (!TYPE_VECTOR_SUBPARTS (type).is_constant (&nelts))
2915 return false;
2916 elem_type = TREE_TYPE (type);
2917 elem_size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type));
2919 orig[0] = NULL;
2920 orig[1] = NULL;
2921 conv_code = ERROR_MARK;
2922 bool maybe_ident = true;
2923 bool maybe_blend[2] = { true, true };
2924 tree one_constant = NULL_TREE;
2925 tree one_nonconstant = NULL_TREE;
2926 auto_vec<tree> constants;
2927 constants.safe_grow_cleared (nelts, true);
2928 auto_vec<std::pair<unsigned, unsigned>, 64> elts;
2929 FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (op), i, elt)
2931 tree ref, op1;
2932 unsigned int elem;
2934 if (i >= nelts)
2935 return false;
2937 /* Look for elements extracted and possibly converted from
2938 another vector. */
2939 op1 = get_bit_field_ref_def (elt->value, conv_code);
2940 if (op1
2941 && TREE_CODE ((ref = TREE_OPERAND (op1, 0))) == SSA_NAME
2942 && VECTOR_TYPE_P (TREE_TYPE (ref))
2943 && useless_type_conversion_p (TREE_TYPE (op1),
2944 TREE_TYPE (TREE_TYPE (ref)))
2945 && constant_multiple_p (bit_field_offset (op1),
2946 bit_field_size (op1), &elem)
2947 && TYPE_VECTOR_SUBPARTS (TREE_TYPE (ref)).is_constant (&refnelts))
2949 unsigned int j;
2950 for (j = 0; j < 2; ++j)
2952 if (!orig[j])
2954 if (j == 0
2955 || useless_type_conversion_p (TREE_TYPE (orig[0]),
2956 TREE_TYPE (ref)))
2957 break;
2959 else if (ref == orig[j])
2960 break;
2962 /* Found a suitable vector element. */
2963 if (j < 2)
2965 orig[j] = ref;
2966 if (elem != i || j != 0)
2967 maybe_ident = false;
2968 if (elem != i)
2969 maybe_blend[j] = false;
2970 elts.safe_push (std::make_pair (j, elem));
2971 continue;
2973 /* Else fallthru. */
2975 /* Handle elements not extracted from a vector.
2976 1. constants by permuting with constant vector
2977 2. a unique non-constant element by permuting with a splat vector */
2978 if (orig[1]
2979 && orig[1] != error_mark_node)
2980 return false;
2981 orig[1] = error_mark_node;
2982 if (CONSTANT_CLASS_P (elt->value))
2984 if (one_nonconstant)
2985 return false;
2986 if (!one_constant)
2987 one_constant = elt->value;
2988 constants[i] = elt->value;
2990 else
2992 if (one_constant)
2993 return false;
2994 if (!one_nonconstant)
2995 one_nonconstant = elt->value;
2996 else if (!operand_equal_p (one_nonconstant, elt->value, 0))
2997 return false;
2999 elts.safe_push (std::make_pair (1, i));
3000 maybe_ident = false;
3002 if (i < nelts)
3003 return false;
3005 if (! orig[0]
3006 || ! VECTOR_TYPE_P (TREE_TYPE (orig[0])))
3007 return false;
3008 refnelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (orig[0])).to_constant ();
3009 /* We currently do not handle larger destination vectors. */
3010 if (refnelts < nelts)
3011 return false;
3013 if (maybe_ident)
3015 tree conv_src_type
3016 = (nelts != refnelts
3017 ? (conv_code != ERROR_MARK
3018 ? build_vector_type (TREE_TYPE (TREE_TYPE (orig[0])), nelts)
3019 : type)
3020 : TREE_TYPE (orig[0]));
3021 if (conv_code != ERROR_MARK
3022 && !supportable_convert_operation (conv_code, type, conv_src_type,
3023 &conv_code))
3025 /* Only few targets implement direct conversion patterns so try
3026 some simple special cases via VEC_[UN]PACK[_FLOAT]_LO_EXPR. */
3027 optab optab;
3028 insn_code icode;
3029 tree halfvectype, dblvectype;
3030 enum tree_code unpack_op;
3032 if (!BYTES_BIG_ENDIAN)
3033 unpack_op = (FLOAT_TYPE_P (TREE_TYPE (type))
3034 ? VEC_UNPACK_FLOAT_LO_EXPR
3035 : VEC_UNPACK_LO_EXPR);
3036 else
3037 unpack_op = (FLOAT_TYPE_P (TREE_TYPE (type))
3038 ? VEC_UNPACK_FLOAT_HI_EXPR
3039 : VEC_UNPACK_HI_EXPR);
3041 /* Conversions between DFP and FP have no special tree code
3042 but we cannot handle those since all relevant vector conversion
3043 optabs only have a single mode. */
3044 if (CONVERT_EXPR_CODE_P (conv_code)
3045 && FLOAT_TYPE_P (TREE_TYPE (type))
3046 && (DECIMAL_FLOAT_TYPE_P (TREE_TYPE (type))
3047 != DECIMAL_FLOAT_TYPE_P (TREE_TYPE (conv_src_type))))
3048 return false;
3050 if (CONVERT_EXPR_CODE_P (conv_code)
3051 && (2 * TYPE_PRECISION (TREE_TYPE (TREE_TYPE (orig[0])))
3052 == TYPE_PRECISION (TREE_TYPE (type)))
3053 && mode_for_vector (as_a <scalar_mode>
3054 (TYPE_MODE (TREE_TYPE (TREE_TYPE (orig[0])))),
3055 nelts * 2).exists ()
3056 && (dblvectype
3057 = build_vector_type (TREE_TYPE (TREE_TYPE (orig[0])),
3058 nelts * 2))
3059 /* Only use it for vector modes or for vector booleans
3060 represented as scalar bitmasks. See PR95528. */
3061 && (VECTOR_MODE_P (TYPE_MODE (dblvectype))
3062 || VECTOR_BOOLEAN_TYPE_P (dblvectype))
3063 && (optab = optab_for_tree_code (unpack_op,
3064 dblvectype,
3065 optab_default))
3066 && ((icode = optab_handler (optab, TYPE_MODE (dblvectype)))
3067 != CODE_FOR_nothing)
3068 && (insn_data[icode].operand[0].mode == TYPE_MODE (type)))
3070 gimple_seq stmts = NULL;
3071 tree dbl;
3072 if (refnelts == nelts)
3074 /* ??? Paradoxical subregs don't exist, so insert into
3075 the lower half of a wider zero vector. */
3076 dbl = gimple_build (&stmts, BIT_INSERT_EXPR, dblvectype,
3077 build_zero_cst (dblvectype), orig[0],
3078 bitsize_zero_node);
3080 else if (refnelts == 2 * nelts)
3081 dbl = orig[0];
3082 else
3083 dbl = gimple_build (&stmts, BIT_FIELD_REF, dblvectype,
3084 orig[0], TYPE_SIZE (dblvectype),
3085 bitsize_zero_node);
3086 gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
3087 gimple_assign_set_rhs_with_ops (gsi, unpack_op, dbl);
3089 else if (CONVERT_EXPR_CODE_P (conv_code)
3090 && (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (orig[0])))
3091 == 2 * TYPE_PRECISION (TREE_TYPE (type)))
3092 && mode_for_vector (as_a <scalar_mode>
3093 (TYPE_MODE
3094 (TREE_TYPE (TREE_TYPE (orig[0])))),
3095 nelts / 2).exists ()
3096 && (halfvectype
3097 = build_vector_type (TREE_TYPE (TREE_TYPE (orig[0])),
3098 nelts / 2))
3099 /* Only use it for vector modes or for vector booleans
3100 represented as scalar bitmasks. See PR95528. */
3101 && (VECTOR_MODE_P (TYPE_MODE (halfvectype))
3102 || VECTOR_BOOLEAN_TYPE_P (halfvectype))
3103 && (optab = optab_for_tree_code (VEC_PACK_TRUNC_EXPR,
3104 halfvectype,
3105 optab_default))
3106 && ((icode = optab_handler (optab, TYPE_MODE (halfvectype)))
3107 != CODE_FOR_nothing)
3108 && (insn_data[icode].operand[0].mode == TYPE_MODE (type)))
3110 gimple_seq stmts = NULL;
3111 tree low = gimple_build (&stmts, BIT_FIELD_REF, halfvectype,
3112 orig[0], TYPE_SIZE (halfvectype),
3113 bitsize_zero_node);
3114 tree hig = gimple_build (&stmts, BIT_FIELD_REF, halfvectype,
3115 orig[0], TYPE_SIZE (halfvectype),
3116 TYPE_SIZE (halfvectype));
3117 gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
3118 gimple_assign_set_rhs_with_ops (gsi, VEC_PACK_TRUNC_EXPR,
3119 low, hig);
3121 else
3122 return false;
3123 update_stmt (gsi_stmt (*gsi));
3124 return true;
3126 if (nelts != refnelts)
3128 gassign *lowpart
3129 = gimple_build_assign (make_ssa_name (conv_src_type),
3130 build3 (BIT_FIELD_REF, conv_src_type,
3131 orig[0], TYPE_SIZE (conv_src_type),
3132 bitsize_zero_node));
3133 gsi_insert_before (gsi, lowpart, GSI_SAME_STMT);
3134 orig[0] = gimple_assign_lhs (lowpart);
3136 if (conv_code == ERROR_MARK)
3138 tree src_type = TREE_TYPE (orig[0]);
3139 if (!useless_type_conversion_p (type, src_type))
3141 gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (type),
3142 TYPE_VECTOR_SUBPARTS (src_type))
3143 && useless_type_conversion_p (TREE_TYPE (type),
3144 TREE_TYPE (src_type)));
3145 tree rhs = build1 (VIEW_CONVERT_EXPR, type, orig[0]);
3146 orig[0] = make_ssa_name (type);
3147 gassign *assign = gimple_build_assign (orig[0], rhs);
3148 gsi_insert_before (gsi, assign, GSI_SAME_STMT);
3150 gimple_assign_set_rhs_from_tree (gsi, orig[0]);
3152 else
3153 gimple_assign_set_rhs_with_ops (gsi, conv_code, orig[0],
3154 NULL_TREE, NULL_TREE);
3156 else
3158 /* If we combine a vector with a non-vector avoid cases where
3159 we'll obviously end up with more GIMPLE stmts which is when
3160 we'll later not fold this to a single insert into the vector
3161 and we had a single extract originally. See PR92819. */
3162 if (nelts == 2
3163 && refnelts > 2
3164 && orig[1] == error_mark_node
3165 && !maybe_blend[0])
3166 return false;
3167 tree mask_type, perm_type, conv_src_type;
3168 perm_type = TREE_TYPE (orig[0]);
3169 conv_src_type = (nelts == refnelts
3170 ? perm_type
3171 : build_vector_type (TREE_TYPE (perm_type), nelts));
3172 if (conv_code != ERROR_MARK
3173 && !supportable_convert_operation (conv_code, type, conv_src_type,
3174 &conv_code))
3175 return false;
3177 /* Now that we know the number of elements of the source build the
3178 permute vector.
3179 ??? When the second vector has constant values we can shuffle
3180 it and its source indexes to make the permutation supported.
3181 For now it mimics a blend. */
3182 vec_perm_builder sel (refnelts, refnelts, 1);
3183 bool all_same_p = true;
3184 for (i = 0; i < elts.length (); ++i)
3186 sel.quick_push (elts[i].second + elts[i].first * refnelts);
3187 all_same_p &= known_eq (sel[i], sel[0]);
3189 /* And fill the tail with "something". It's really don't care,
3190 and ideally we'd allow VEC_PERM to have a smaller destination
3191 vector. As a heuristic:
3193 (a) if what we have so far duplicates a single element, make the
3194 tail do the same
3196 (b) otherwise preserve a uniform orig[0]. This facilitates
3197 later pattern-matching of VEC_PERM_EXPR to a BIT_INSERT_EXPR. */
3198 for (; i < refnelts; ++i)
3199 sel.quick_push (all_same_p
3200 ? sel[0]
3201 : (elts[0].second == 0 && elts[0].first == 0
3202 ? 0 : refnelts) + i);
3203 vec_perm_indices indices (sel, orig[1] ? 2 : 1, refnelts);
3204 machine_mode vmode = TYPE_MODE (perm_type);
3205 if (!can_vec_perm_const_p (vmode, vmode, indices))
3206 return false;
3207 mask_type
3208 = build_vector_type (build_nonstandard_integer_type (elem_size, 1),
3209 refnelts);
3210 if (GET_MODE_CLASS (TYPE_MODE (mask_type)) != MODE_VECTOR_INT
3211 || maybe_ne (GET_MODE_SIZE (TYPE_MODE (mask_type)),
3212 GET_MODE_SIZE (TYPE_MODE (perm_type))))
3213 return false;
3214 tree op2 = vec_perm_indices_to_tree (mask_type, indices);
3215 bool converted_orig1 = false;
3216 gimple_seq stmts = NULL;
3217 if (!orig[1])
3218 orig[1] = orig[0];
3219 else if (orig[1] == error_mark_node
3220 && one_nonconstant)
3222 /* ??? We can see if we can safely convert to the original
3223 element type. */
3224 converted_orig1 = conv_code != ERROR_MARK;
3225 orig[1] = gimple_build_vector_from_val (&stmts, UNKNOWN_LOCATION,
3226 converted_orig1
3227 ? type : perm_type,
3228 one_nonconstant);
3230 else if (orig[1] == error_mark_node)
3232 /* ??? See if we can convert the vector to the original type. */
3233 converted_orig1 = conv_code != ERROR_MARK;
3234 unsigned n = converted_orig1 ? nelts : refnelts;
3235 tree_vector_builder vec (converted_orig1
3236 ? type : perm_type, n, 1);
3237 for (unsigned i = 0; i < n; ++i)
3238 if (i < nelts && constants[i])
3239 vec.quick_push (constants[i]);
3240 else
3241 /* ??? Push a don't-care value. */
3242 vec.quick_push (one_constant);
3243 orig[1] = vec.build ();
3245 tree blend_op2 = NULL_TREE;
3246 if (converted_orig1)
3248 /* Make sure we can do a blend in the target type. */
3249 vec_perm_builder sel (nelts, nelts, 1);
3250 for (i = 0; i < elts.length (); ++i)
3251 sel.quick_push (elts[i].first
3252 ? elts[i].second + nelts : i);
3253 vec_perm_indices indices (sel, 2, nelts);
3254 machine_mode vmode = TYPE_MODE (type);
3255 if (!can_vec_perm_const_p (vmode, vmode, indices))
3256 return false;
3257 mask_type
3258 = build_vector_type (build_nonstandard_integer_type (elem_size, 1),
3259 nelts);
3260 if (GET_MODE_CLASS (TYPE_MODE (mask_type)) != MODE_VECTOR_INT
3261 || maybe_ne (GET_MODE_SIZE (TYPE_MODE (mask_type)),
3262 GET_MODE_SIZE (TYPE_MODE (type))))
3263 return false;
3264 blend_op2 = vec_perm_indices_to_tree (mask_type, indices);
3266 tree orig1_for_perm
3267 = converted_orig1 ? build_zero_cst (perm_type) : orig[1];
3268 tree res = gimple_build (&stmts, VEC_PERM_EXPR, perm_type,
3269 orig[0], orig1_for_perm, op2);
3270 if (nelts != refnelts)
3271 res = gimple_build (&stmts, BIT_FIELD_REF,
3272 conv_code != ERROR_MARK ? conv_src_type : type,
3273 res, TYPE_SIZE (type), bitsize_zero_node);
3274 if (conv_code != ERROR_MARK)
3275 res = gimple_build (&stmts, conv_code, type, res);
3276 else if (!useless_type_conversion_p (type, TREE_TYPE (res)))
3278 gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (type),
3279 TYPE_VECTOR_SUBPARTS (perm_type))
3280 && useless_type_conversion_p (TREE_TYPE (type),
3281 TREE_TYPE (perm_type)));
3282 res = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, res);
3284 /* Blend in the actual constant. */
3285 if (converted_orig1)
3286 res = gimple_build (&stmts, VEC_PERM_EXPR, type,
3287 res, orig[1], blend_op2);
3288 gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
3289 gimple_assign_set_rhs_with_ops (gsi, SSA_NAME, res);
3291 update_stmt (gsi_stmt (*gsi));
3292 return true;
3295 /* Prepare a TARGET_MEM_REF ref so that it can be subsetted as
3296 lvalue. This splits out an address computation stmt before *GSI
3297 and returns a MEM_REF wrapping the address. */
3299 static tree
3300 prepare_target_mem_ref_lvalue (tree ref, gimple_stmt_iterator *gsi)
3302 if (TREE_CODE (TREE_OPERAND (ref, 0)) == ADDR_EXPR)
3303 mark_addressable (TREE_OPERAND (TREE_OPERAND (ref, 0), 0));
3304 tree ptrtype = build_pointer_type (TREE_TYPE (ref));
3305 tree tem = make_ssa_name (ptrtype);
3306 gimple *new_stmt
3307 = gimple_build_assign (tem, build1 (ADDR_EXPR, TREE_TYPE (tem),
3308 unshare_expr (ref)));
3309 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
3310 ref = build2_loc (EXPR_LOCATION (ref),
3311 MEM_REF, TREE_TYPE (ref), tem,
3312 build_int_cst (TREE_TYPE (TREE_OPERAND (ref, 1)), 0));
3313 return ref;
3316 /* Rewrite the vector load at *GSI to component-wise loads if the load
3317 is only used in BIT_FIELD_REF extractions with eventual intermediate
3318 widening. */
3320 static void
3321 optimize_vector_load (gimple_stmt_iterator *gsi)
3323 gimple *stmt = gsi_stmt (*gsi);
3324 tree lhs = gimple_assign_lhs (stmt);
3325 tree rhs = gimple_assign_rhs1 (stmt);
3327 /* Gather BIT_FIELD_REFs to rewrite, looking through
3328 VEC_UNPACK_{LO,HI}_EXPR. */
3329 use_operand_p use_p;
3330 imm_use_iterator iter;
3331 bool rewrite = true;
3332 auto_vec<gimple *, 8> bf_stmts;
3333 auto_vec<tree, 8> worklist;
3334 worklist.quick_push (lhs);
3337 tree def = worklist.pop ();
3338 unsigned HOST_WIDE_INT def_eltsize
3339 = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (TREE_TYPE (def))));
3340 FOR_EACH_IMM_USE_FAST (use_p, iter, def)
3342 gimple *use_stmt = USE_STMT (use_p);
3343 if (is_gimple_debug (use_stmt))
3344 continue;
3345 if (!is_gimple_assign (use_stmt))
3347 rewrite = false;
3348 break;
3350 enum tree_code use_code = gimple_assign_rhs_code (use_stmt);
3351 tree use_rhs = gimple_assign_rhs1 (use_stmt);
3352 if (use_code == BIT_FIELD_REF
3353 && TREE_OPERAND (use_rhs, 0) == def
3354 /* If its on the VEC_UNPACK_{HI,LO}_EXPR
3355 def need to verify it is element aligned. */
3356 && (def == lhs
3357 || (known_eq (bit_field_size (use_rhs), def_eltsize)
3358 && constant_multiple_p (bit_field_offset (use_rhs),
3359 def_eltsize)
3360 /* We can simulate the VEC_UNPACK_{HI,LO}_EXPR
3361 via a NOP_EXPR only for integral types.
3362 ??? Support VEC_UNPACK_FLOAT_{HI,LO}_EXPR. */
3363 && INTEGRAL_TYPE_P (TREE_TYPE (use_rhs)))))
3365 bf_stmts.safe_push (use_stmt);
3366 continue;
3368 /* Walk through one level of VEC_UNPACK_{LO,HI}_EXPR. */
3369 if (def == lhs
3370 && (use_code == VEC_UNPACK_HI_EXPR
3371 || use_code == VEC_UNPACK_LO_EXPR)
3372 && use_rhs == lhs)
3374 worklist.safe_push (gimple_assign_lhs (use_stmt));
3375 continue;
3377 rewrite = false;
3378 break;
3380 if (!rewrite)
3381 break;
3383 while (!worklist.is_empty ());
3385 if (!rewrite)
3387 gsi_next (gsi);
3388 return;
3390 /* We now have all ultimate uses of the load to rewrite in bf_stmts. */
3392 /* Prepare the original ref to be wrapped in adjusted BIT_FIELD_REFs.
3393 For TARGET_MEM_REFs we have to separate the LEA from the reference. */
3394 tree load_rhs = rhs;
3395 if (TREE_CODE (load_rhs) == TARGET_MEM_REF)
3396 load_rhs = prepare_target_mem_ref_lvalue (load_rhs, gsi);
3398 /* Rewrite the BIT_FIELD_REFs to be actual loads, re-emitting them at
3399 the place of the original load. */
3400 for (gimple *use_stmt : bf_stmts)
3402 tree bfr = gimple_assign_rhs1 (use_stmt);
3403 tree new_rhs = unshare_expr (load_rhs);
3404 if (TREE_OPERAND (bfr, 0) != lhs)
3406 /* When the BIT_FIELD_REF is on the promoted vector we have to
3407 adjust it and emit a conversion afterwards. */
3408 gimple *def_stmt
3409 = SSA_NAME_DEF_STMT (TREE_OPERAND (bfr, 0));
3410 enum tree_code def_code
3411 = gimple_assign_rhs_code (def_stmt);
3413 /* The adjusted BIT_FIELD_REF is of the promotion source
3414 vector size and at half of the offset... */
3415 new_rhs = fold_build3 (BIT_FIELD_REF,
3416 TREE_TYPE (TREE_TYPE (lhs)),
3417 new_rhs,
3418 TYPE_SIZE (TREE_TYPE (TREE_TYPE (lhs))),
3419 size_binop (EXACT_DIV_EXPR,
3420 TREE_OPERAND (bfr, 2),
3421 bitsize_int (2)));
3422 /* ... and offsetted by half of the vector if VEC_UNPACK_HI_EXPR. */
3423 if (def_code == (!BYTES_BIG_ENDIAN
3424 ? VEC_UNPACK_HI_EXPR : VEC_UNPACK_LO_EXPR))
3425 TREE_OPERAND (new_rhs, 2)
3426 = size_binop (PLUS_EXPR, TREE_OPERAND (new_rhs, 2),
3427 size_binop (EXACT_DIV_EXPR,
3428 TYPE_SIZE (TREE_TYPE (lhs)),
3429 bitsize_int (2)));
3430 tree tem = make_ssa_name (TREE_TYPE (TREE_TYPE (lhs)));
3431 gimple *new_stmt = gimple_build_assign (tem, new_rhs);
3432 location_t loc = gimple_location (use_stmt);
3433 gimple_set_location (new_stmt, loc);
3434 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
3435 /* Perform scalar promotion. */
3436 new_stmt = gimple_build_assign (gimple_assign_lhs (use_stmt),
3437 NOP_EXPR, tem);
3438 gimple_set_location (new_stmt, loc);
3439 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
3441 else
3443 /* When the BIT_FIELD_REF is on the original load result
3444 we can just wrap that. */
3445 tree new_rhs = fold_build3 (BIT_FIELD_REF, TREE_TYPE (bfr),
3446 unshare_expr (load_rhs),
3447 TREE_OPERAND (bfr, 1),
3448 TREE_OPERAND (bfr, 2));
3449 gimple *new_stmt = gimple_build_assign (gimple_assign_lhs (use_stmt),
3450 new_rhs);
3451 location_t loc = gimple_location (use_stmt);
3452 gimple_set_location (new_stmt, loc);
3453 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
3455 gimple_stmt_iterator gsi2 = gsi_for_stmt (use_stmt);
3456 unlink_stmt_vdef (use_stmt);
3457 gsi_remove (&gsi2, true);
3460 /* Finally get rid of the intermediate stmts. */
3461 gimple *use_stmt;
3462 FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
3464 if (is_gimple_debug (use_stmt))
3466 if (gimple_debug_bind_p (use_stmt))
3468 gimple_debug_bind_reset_value (use_stmt);
3469 update_stmt (use_stmt);
3471 continue;
3473 gimple_stmt_iterator gsi2 = gsi_for_stmt (use_stmt);
3474 unlink_stmt_vdef (use_stmt);
3475 release_defs (use_stmt);
3476 gsi_remove (&gsi2, true);
3478 /* And the original load. */
3479 release_defs (stmt);
3480 gsi_remove (gsi, true);
3484 /* Primitive "lattice" function for gimple_simplify. */
3486 static tree
3487 fwprop_ssa_val (tree name)
3489 /* First valueize NAME. */
3490 if (TREE_CODE (name) == SSA_NAME
3491 && SSA_NAME_VERSION (name) < lattice.length ())
3493 tree val = lattice[SSA_NAME_VERSION (name)];
3494 if (val)
3495 name = val;
3497 /* We continue matching along SSA use-def edges for SSA names
3498 that are not single-use. Currently there are no patterns
3499 that would cause any issues with that. */
3500 return name;
3503 /* Search for opportunities to free half of the lanes in the following pattern:
3505 v_in = {e0, e1, e2, e3}
3506 v_1 = VEC_PERM <v_in, v_in, {0, 2, 0, 2}>
3507 // v_1 = {e0, e2, e0, e2}
3508 v_2 = VEC_PERM <v_in, v_in, {1, 3, 1, 3}>
3509 // v_2 = {e1, e3, e1, e3}
3511 v_x = v_1 + v_2
3512 // v_x = {e0+e1, e2+e3, e0+e1, e2+e3}
3513 v_y = v_1 - v_2
3514 // v_y = {e0-e1, e2-e3, e0-e1, e2-e3}
3516 v_out = VEC_PERM <v_x, v_y, {0, 1, 6, 7}>
3517 // v_out = {e0+e1, e2+e3, e0-e1, e2-e3}
3519 The last statement could be simplified to:
3520 v_out' = VEC_PERM <v_x, v_y, {0, 1, 4, 5}>
3521 // v_out' = {e0+e1, e2+e3, e0-e1, e2-e3}
3523 Characteristic properties:
3524 - v_1 and v_2 are created from the same input vector v_in and introduce the
3525 lane duplication (in the selection operand) that we can eliminate.
3526 - v_x and v_y are results from lane-preserving operations that use v_1 and
3527 v_2 as inputs.
3528 - v_out is created by selecting from duplicated lanes. */
3530 static bool
3531 recognise_vec_perm_simplify_seq (gassign *stmt, vec_perm_simplify_seq *seq)
3533 unsigned HOST_WIDE_INT nelts;
3535 gcc_checking_assert (stmt);
3536 gcc_checking_assert (gimple_assign_rhs_code (stmt) == VEC_PERM_EXPR);
3537 basic_block bb = gimple_bb (stmt);
3539 /* Decompose the final vec permute statement. */
3540 tree v_x = gimple_assign_rhs1 (stmt);
3541 tree v_y = gimple_assign_rhs2 (stmt);
3542 tree sel = gimple_assign_rhs3 (stmt);
3544 if (TREE_CODE (sel) != VECTOR_CST
3545 || !VECTOR_CST_NELTS (sel).is_constant (&nelts)
3546 || TREE_CODE (v_x) != SSA_NAME
3547 || TREE_CODE (v_y) != SSA_NAME
3548 || !has_single_use (v_x)
3549 || !has_single_use (v_y))
3550 return false;
3552 /* Don't analyse sequences with many lanes. */
3553 if (nelts > 4)
3554 return false;
3556 /* Lookup the definition of v_x and v_y. */
3557 gassign *v_x_stmt = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (v_x));
3558 gassign *v_y_stmt = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (v_y));
3559 if (!v_x_stmt || gimple_bb (v_x_stmt) != bb
3560 || !v_y_stmt || gimple_bb (v_y_stmt) != bb)
3561 return false;
3563 /* Check the operations that define v_x and v_y. */
3564 if (TREE_CODE_CLASS (gimple_assign_rhs_code (v_x_stmt)) != tcc_binary
3565 || TREE_CODE_CLASS (gimple_assign_rhs_code (v_y_stmt)) != tcc_binary)
3566 return false;
3568 tree v_x_1 = gimple_assign_rhs1 (v_x_stmt);
3569 tree v_x_2 = gimple_assign_rhs2 (v_x_stmt);
3570 tree v_y_1 = gimple_assign_rhs1 (v_y_stmt);
3571 tree v_y_2 = gimple_assign_rhs2 (v_y_stmt);
3573 if (v_x_stmt == v_y_stmt
3574 || TREE_CODE (v_x_1) != SSA_NAME
3575 || TREE_CODE (v_x_2) != SSA_NAME
3576 || num_imm_uses (v_x_1) != 2
3577 || num_imm_uses (v_x_2) != 2)
3578 return false;
3580 if (v_x_1 != v_y_1 || v_x_2 != v_y_2)
3582 /* Allow operands of commutative operators to swap. */
3583 if (commutative_tree_code (gimple_assign_rhs_code (v_x_stmt)))
3585 /* Keep v_x_1 the first operand for non-commutative operators. */
3586 v_x_1 = gimple_assign_rhs2 (v_x_stmt);
3587 v_x_2 = gimple_assign_rhs1 (v_x_stmt);
3588 if (v_x_1 != v_y_1 || v_x_2 != v_y_2)
3589 return false;
3591 else if (commutative_tree_code (gimple_assign_rhs_code (v_y_stmt)))
3593 if (v_x_1 != v_y_2 || v_x_2 != v_y_1)
3594 return false;
3596 else
3597 return false;
3599 gassign *v_1_stmt = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (v_x_1));
3600 gassign *v_2_stmt = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (v_x_2));
3601 if (!v_1_stmt || gimple_bb (v_1_stmt) != bb
3602 || !v_2_stmt || gimple_bb (v_2_stmt) != bb)
3603 return false;
3605 if (gimple_assign_rhs_code (v_1_stmt) != VEC_PERM_EXPR
3606 || gimple_assign_rhs_code (v_2_stmt) != VEC_PERM_EXPR)
3607 return false;
3609 /* Decompose initial VEC_PERM_EXPRs. */
3610 tree v_in = gimple_assign_rhs1 (v_1_stmt);
3611 tree v_1_sel = gimple_assign_rhs3 (v_1_stmt);
3612 tree v_2_sel = gimple_assign_rhs3 (v_2_stmt);
3613 if (v_in != gimple_assign_rhs2 (v_1_stmt)
3614 || v_in != gimple_assign_rhs1 (v_2_stmt)
3615 || v_in != gimple_assign_rhs2 (v_2_stmt))
3616 return false;
3618 unsigned HOST_WIDE_INT v_1_nelts, v_2_nelts;
3619 if (TREE_CODE (v_1_sel) != VECTOR_CST
3620 || !VECTOR_CST_NELTS (v_1_sel).is_constant (&v_1_nelts)
3621 || TREE_CODE (v_2_sel) != VECTOR_CST
3622 || !VECTOR_CST_NELTS (v_2_sel).is_constant (&v_2_nelts))
3623 return false;
3625 if (nelts != v_1_nelts || nelts != v_2_nelts)
3626 return false;
3628 /* Create the new selector. */
3629 vec_perm_builder new_sel_perm (nelts, nelts, 1);
3630 auto_vec<unsigned int> lanes (nelts);
3631 lanes.quick_grow_cleared (nelts);
3632 for (unsigned int i = 0; i < nelts; i++)
3634 /* Extract the i-th value from the selector. */
3635 unsigned int sel_cst = TREE_INT_CST_LOW (VECTOR_CST_ELT (sel, i));
3636 unsigned int lane = sel_cst % nelts;
3637 unsigned int offs = sel_cst / nelts;
3639 /* Check what's in the lane. */
3640 unsigned int e_1 = TREE_INT_CST_LOW (VECTOR_CST_ELT (v_1_sel, lane));
3641 unsigned int e_2 = TREE_INT_CST_LOW (VECTOR_CST_ELT (v_2_sel, lane));
3643 /* Reuse previous lane (if any). */
3644 unsigned int l = 0;
3645 for (; l < lane; l++)
3647 if ((TREE_INT_CST_LOW (VECTOR_CST_ELT (v_1_sel, l)) == e_1)
3648 && (TREE_INT_CST_LOW (VECTOR_CST_ELT (v_2_sel, l)) == e_2))
3649 break;
3652 /* Add to narrowed selector. */
3653 new_sel_perm.quick_push (l + offs * nelts);
3655 /* Mark lane as used. */
3656 lanes[l] = 1;
3659 /* Count how many lanes are need. */
3660 unsigned int cnt = 0;
3661 for (unsigned int i = 0; i < nelts; i++)
3662 cnt += lanes[i];
3664 /* If more than (nelts/2) lanes are needed, skip the sequence. */
3665 if (cnt > nelts / 2)
3666 return false;
3668 /* Check if the resulting permuation is cheap. */
3669 vec_perm_indices new_indices (new_sel_perm, 2, nelts);
3670 tree vectype = TREE_TYPE (gimple_assign_lhs (stmt));
3671 machine_mode vmode = TYPE_MODE (vectype);
3672 if (!can_vec_perm_const_p (vmode, vmode, new_indices, false))
3673 return false;
3675 *seq = XNEW (struct _vec_perm_simplify_seq);
3676 (*seq)->stmt = stmt;
3677 (*seq)->v_1_stmt = v_1_stmt;
3678 (*seq)->v_2_stmt = v_2_stmt;
3679 (*seq)->v_x_stmt = v_x_stmt;
3680 (*seq)->v_y_stmt = v_y_stmt;
3681 (*seq)->nelts = nelts;
3682 (*seq)->new_sel = vect_gen_perm_mask_checked (vectype, new_indices);
3684 if (dump_file)
3686 fprintf (dump_file, "Found vec perm simplify sequence ending with:\n\t");
3687 print_gimple_stmt (dump_file, stmt, 0);
3689 if (dump_flags & TDF_DETAILS)
3691 fprintf (dump_file, "\tNarrowed vec_perm selector: ");
3692 print_generic_expr (dump_file, (*seq)->new_sel);
3693 fprintf (dump_file, "\n");
3697 return true;
3700 /* Reduce the lane consumption of a simplifiable vec perm sequence. */
3702 static void
3703 narrow_vec_perm_simplify_seq (const vec_perm_simplify_seq &seq)
3705 gassign *stmt = seq->stmt;
3706 if (dump_file && (dump_flags & TDF_DETAILS))
3708 fprintf (dump_file, "Updating VEC_PERM statment:\n");
3709 fprintf (dump_file, "Old stmt: ");
3710 print_gimple_stmt (dump_file, stmt, 0);
3713 /* Update the last VEC_PERM statement. */
3714 gimple_assign_set_rhs3 (stmt, seq->new_sel);
3715 update_stmt (stmt);
3717 if (dump_file && (dump_flags & TDF_DETAILS))
3719 fprintf (dump_file, "New stmt: ");
3720 print_gimple_stmt (dump_file, stmt, 0);
3724 /* Test if we can blend two simplifiable vec permute sequences.
3725 NEED_SWAP will be set, if sequences must be swapped for blending. */
3727 static bool
3728 can_blend_vec_perm_simplify_seqs_p (vec_perm_simplify_seq seq1,
3729 vec_perm_simplify_seq seq2,
3730 bool *need_swap)
3732 unsigned int nelts = seq1->nelts;
3733 basic_block bb = gimple_bb (seq1->stmt);
3735 gcc_assert (gimple_bb (seq2->stmt) == bb);
3737 /* BBs and number of elements must be equal. */
3738 if (gimple_bb (seq2->stmt) != bb || seq2->nelts != nelts)
3739 return false;
3741 /* We need vectors of the same type. */
3742 if (TREE_TYPE (gimple_assign_lhs (seq1->stmt))
3743 != TREE_TYPE (gimple_assign_lhs (seq2->stmt)))
3744 return false;
3746 /* We require isomorphic operators. */
3747 if (((gimple_assign_rhs_code (seq1->v_x_stmt)
3748 != gimple_assign_rhs_code (seq2->v_x_stmt))
3749 || (gimple_assign_rhs_code (seq1->v_y_stmt)
3750 != gimple_assign_rhs_code (seq2->v_y_stmt))))
3751 return false;
3753 /* We cannot have any dependencies between the sequences.
3755 For merging, we will reuse seq1->v_1_stmt and seq1->v_2_stmt.
3756 seq1's v_in is defined before these statements, but we need
3757 to check if seq2's v_in is defined before them as well.
3759 Further, we will reuse seq2->stmt. We need to ensure that
3760 seq1->v_x_stmt and seq1->v_y_stmt are before it.
3762 Note, that we don't need to check the BBs here, because all
3763 statements of both sequences have to be in the same BB.
3766 tree seq2_v_in = gimple_assign_rhs1 (seq2->v_1_stmt);
3767 if (TREE_CODE (seq2_v_in) != SSA_NAME)
3768 return false;
3770 gassign *seq2_v_in_stmt = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (seq2_v_in));
3771 if (!seq2_v_in_stmt || gimple_bb (seq2_v_in_stmt) != bb
3772 || (gimple_uid (seq2_v_in_stmt) > gimple_uid (seq1->v_1_stmt))
3773 || (gimple_uid (seq1->v_x_stmt) > gimple_uid (seq2->stmt))
3774 || (gimple_uid (seq1->v_y_stmt) > gimple_uid (seq2->stmt)))
3776 tree seq1_v_in = gimple_assign_rhs1 (seq1->v_1_stmt);
3777 if (TREE_CODE (seq1_v_in) != SSA_NAME)
3778 return false;
3780 gassign *seq1_v_in_stmt
3781 = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (seq1_v_in));
3782 /* Let's try to see if we succeed when swapping the sequences. */
3783 if (!seq1_v_in_stmt || gimple_bb (seq1_v_in_stmt)
3784 || (gimple_uid (seq1_v_in_stmt) > gimple_uid (seq2->v_1_stmt))
3785 || (gimple_uid (seq2->v_x_stmt) > gimple_uid (seq1->stmt))
3786 || (gimple_uid (seq2->v_y_stmt) > gimple_uid (seq1->stmt)))
3787 return false;
3788 *need_swap = true;
3790 else
3791 *need_swap = false;
3793 if (dump_file && (dump_flags & TDF_DETAILS))
3794 fprintf (dump_file, "Found vec perm simplify sequence pair.\n");
3796 return true;
3799 /* Calculate the permutations for blending the two given vec permute
3800 sequences. This may fail if the resulting permutation is not
3801 supported. */
3803 static bool
3804 calc_perm_vec_perm_simplify_seqs (vec_perm_simplify_seq seq1,
3805 vec_perm_simplify_seq seq2,
3806 vec_perm_indices *seq2_stmt_indices,
3807 vec_perm_indices *seq1_v_1_stmt_indices,
3808 vec_perm_indices *seq1_v_2_stmt_indices)
3810 unsigned int i;
3811 unsigned int nelts = seq1->nelts;
3812 auto_vec<int> lane_assignment;
3813 lane_assignment.create (nelts);
3815 /* Mark all lanes as free. */
3816 lane_assignment.quick_grow_cleared (nelts);
3818 /* Allocate lanes for seq1. */
3819 for (i = 0; i < nelts; i++)
3821 unsigned int l = TREE_INT_CST_LOW (VECTOR_CST_ELT (seq1->new_sel, i));
3822 l %= nelts;
3823 lane_assignment[l] = 1;
3826 /* Allocate lanes for seq2 and calculate selector for seq2->stmt. */
3827 vec_perm_builder seq2_stmt_sel_perm (nelts, nelts, 1);
3828 for (i = 0; i < nelts; i++)
3830 unsigned int sel = TREE_INT_CST_LOW (VECTOR_CST_ELT (seq2->new_sel, i));
3831 unsigned int lane = sel % nelts;
3832 unsigned int offs = sel / nelts;
3833 unsigned int new_sel;
3835 /* Check if we already allocated the lane for seq2. */
3836 unsigned int j = 0;
3837 for (; j < i; j++)
3839 unsigned int sel_old;
3840 sel_old = TREE_INT_CST_LOW (VECTOR_CST_ELT (seq2->new_sel, j));
3841 unsigned int lane_old = sel_old % nelts;
3842 if (lane == lane_old)
3844 new_sel = seq2_stmt_sel_perm[j].to_constant ();
3845 new_sel = (new_sel % nelts) + offs * nelts;
3846 break;
3850 /* If the lane is not allocated, we need to do that now. */
3851 if (j == i)
3853 unsigned int l_orig = lane;
3854 while (lane_assignment[lane] != 0)
3856 lane = (lane + 1) % nelts;
3858 /* This should not happen if both sequences utilize no more than
3859 half of the lanes. Test anyway to guarantee termination. */
3860 if (lane == l_orig)
3861 return false;
3864 /* Allocate lane. */
3865 lane_assignment[lane] = 2;
3866 new_sel = lane + offs * nelts;
3869 seq2_stmt_sel_perm.quick_push (new_sel);
3872 /* Check if the resulting permuation is cheap. */
3873 seq2_stmt_indices->new_vector (seq2_stmt_sel_perm, 2, nelts);
3874 tree vectype = TREE_TYPE (gimple_assign_lhs (seq2->stmt));
3875 machine_mode vmode = TYPE_MODE (vectype);
3876 if (!can_vec_perm_const_p (vmode, vmode, *seq2_stmt_indices, false))
3877 return false;
3879 /* Calculate selectors for seq1->v_1_stmt and seq1->v_2_stmt. */
3880 vec_perm_builder seq1_v_1_stmt_sel_perm (nelts, nelts, 1);
3881 vec_perm_builder seq1_v_2_stmt_sel_perm (nelts, nelts, 1);
3882 for (i = 0; i < nelts; i++)
3884 bool use_seq1 = lane_assignment[i] != 2;
3885 unsigned int l1, l2;
3887 if (use_seq1)
3889 /* Just reuse the selector indices. */
3890 tree s1 = gimple_assign_rhs3 (seq1->v_1_stmt);
3891 tree s2 = gimple_assign_rhs3 (seq1->v_2_stmt);
3892 l1 = TREE_INT_CST_LOW (VECTOR_CST_ELT (s1, i));
3893 l2 = TREE_INT_CST_LOW (VECTOR_CST_ELT (s2, i));
3895 else
3897 /* We moved the lanes for seq2, so we need to adjust for that. */
3898 tree s1 = gimple_assign_rhs3 (seq2->v_1_stmt);
3899 tree s2 = gimple_assign_rhs3 (seq2->v_2_stmt);
3901 unsigned int j = 0;
3902 for (; j < i; j++)
3904 unsigned int sel_new;
3905 sel_new = seq2_stmt_sel_perm[j].to_constant ();
3906 sel_new %= nelts;
3907 if (sel_new == i)
3908 break;
3911 /* This should not happen. Test anyway to guarantee correctness. */
3912 if (j == i)
3913 return false;
3915 l1 = TREE_INT_CST_LOW (VECTOR_CST_ELT (s1, j));
3916 l2 = TREE_INT_CST_LOW (VECTOR_CST_ELT (s2, j));
3919 seq1_v_1_stmt_sel_perm.quick_push (l1 + (use_seq1 ? 0 : nelts));
3920 seq1_v_2_stmt_sel_perm.quick_push (l2 + (use_seq1 ? 0 : nelts));
3923 seq1_v_1_stmt_indices->new_vector (seq1_v_1_stmt_sel_perm, 2, nelts);
3924 vectype = TREE_TYPE (gimple_assign_lhs (seq1->v_1_stmt));
3925 vmode = TYPE_MODE (vectype);
3926 if (!can_vec_perm_const_p (vmode, vmode, *seq1_v_1_stmt_indices, false))
3927 return false;
3929 seq1_v_2_stmt_indices->new_vector (seq1_v_2_stmt_sel_perm, 2, nelts);
3930 vectype = TREE_TYPE (gimple_assign_lhs (seq1->v_2_stmt));
3931 vmode = TYPE_MODE (vectype);
3932 if (!can_vec_perm_const_p (vmode, vmode, *seq1_v_2_stmt_indices, false))
3933 return false;
3935 return true;
3938 /* Blend the two given simplifiable vec permute sequences using the
3939 given permutations. */
3941 static void
3942 blend_vec_perm_simplify_seqs (vec_perm_simplify_seq seq1,
3943 vec_perm_simplify_seq seq2,
3944 const vec_perm_indices &seq2_stmt_indices,
3945 const vec_perm_indices &seq1_v_1_stmt_indices,
3946 const vec_perm_indices &seq1_v_2_stmt_indices)
3948 /* We don't need to adjust seq1->stmt because its lanes consumption
3949 was already narrowed before entering this function. */
3951 /* Adjust seq2->stmt: copy RHS1/RHS2 from seq1->stmt and set new sel. */
3952 if (dump_file && (dump_flags & TDF_DETAILS))
3954 fprintf (dump_file, "Updating VEC_PERM statment:\n");
3955 fprintf (dump_file, "Old stmt: ");
3956 print_gimple_stmt (dump_file, seq2->stmt, 0);
3959 gimple_assign_set_rhs1 (seq2->stmt, gimple_assign_rhs1 (seq1->stmt));
3960 gimple_assign_set_rhs2 (seq2->stmt, gimple_assign_rhs2 (seq1->stmt));
3961 tree vectype = TREE_TYPE (gimple_assign_lhs (seq2->stmt));
3962 tree sel = vect_gen_perm_mask_checked (vectype, seq2_stmt_indices);
3963 gimple_assign_set_rhs3 (seq2->stmt, sel);
3964 update_stmt (seq2->stmt);
3966 if (dump_file && (dump_flags & TDF_DETAILS))
3968 fprintf (dump_file, "New stmt: ");
3969 print_gimple_stmt (dump_file, seq2->stmt, 0);
3972 /* Adjust seq1->v_1_stmt: copy RHS2 from seq2->v_1_stmt and set new sel. */
3973 if (dump_file && (dump_flags & TDF_DETAILS))
3975 fprintf (dump_file, "Updating VEC_PERM statment:\n");
3976 fprintf (dump_file, "Old stmt: ");
3977 print_gimple_stmt (dump_file, seq1->v_1_stmt, 0);
3980 gimple_assign_set_rhs2 (seq1->v_1_stmt, gimple_assign_rhs1 (seq2->v_1_stmt));
3981 vectype = TREE_TYPE (gimple_assign_lhs (seq1->v_1_stmt));
3982 sel = vect_gen_perm_mask_checked (vectype, seq1_v_1_stmt_indices);
3983 gimple_assign_set_rhs3 (seq1->v_1_stmt, sel);
3984 update_stmt (seq1->v_1_stmt);
3986 if (dump_file && (dump_flags & TDF_DETAILS))
3988 fprintf (dump_file, "New stmt: ");
3989 print_gimple_stmt (dump_file, seq1->v_1_stmt, 0);
3992 /* Adjust seq1->v_2_stmt: copy RHS2 from seq2->v_2_stmt and set new sel. */
3993 if (dump_file && (dump_flags & TDF_DETAILS))
3995 fprintf (dump_file, "Updating VEC_PERM statment:\n");
3996 fprintf (dump_file, "Old stmt: ");
3997 print_gimple_stmt (dump_file, seq1->v_2_stmt, 0);
4000 gimple_assign_set_rhs2 (seq1->v_2_stmt, gimple_assign_rhs1 (seq2->v_2_stmt));
4001 vectype = TREE_TYPE (gimple_assign_lhs (seq1->v_2_stmt));
4002 sel = vect_gen_perm_mask_checked (vectype, seq1_v_2_stmt_indices);
4003 gimple_assign_set_rhs3 (seq1->v_2_stmt, sel);
4004 update_stmt (seq1->v_2_stmt);
4006 if (dump_file && (dump_flags & TDF_DETAILS))
4008 fprintf (dump_file, "New stmt: ");
4009 print_gimple_stmt (dump_file, seq1->v_2_stmt, 0);
4012 /* At this point, we have four unmodified seq2 stmts, which will be
4013 eliminated by DCE. */
4015 if (dump_file)
4016 fprintf (dump_file, "Vec perm simplify sequences have been blended.\n\n");
4019 /* Try to blend narrowed vec_perm_simplify_seqs pairwise.
4020 The provided list will be empty after this call. */
4022 static void
4023 process_vec_perm_simplify_seq_list (vec<vec_perm_simplify_seq> *l)
4025 unsigned int i, j;
4026 vec_perm_simplify_seq seq1, seq2;
4028 if (l->is_empty ())
4029 return;
4031 if (dump_file && (dump_flags & TDF_DETAILS))
4032 fprintf (dump_file, "\nProcessing %u vec perm simplify sequences.\n",
4033 l->length ());
4035 FOR_EACH_VEC_ELT (*l, i, seq1)
4037 if (i + 1 < l->length ())
4039 FOR_EACH_VEC_ELT_FROM (*l, j, seq2, i + 1)
4041 bool swap = false;
4042 if (can_blend_vec_perm_simplify_seqs_p (seq1, seq2, &swap))
4044 vec_perm_indices seq2_stmt_indices;
4045 vec_perm_indices seq1_v_1_stmt_indices;
4046 vec_perm_indices seq1_v_2_stmt_indices;
4047 if (calc_perm_vec_perm_simplify_seqs (swap ? seq2 : seq1,
4048 swap ? seq1 : seq2,
4049 &seq2_stmt_indices,
4050 &seq1_v_1_stmt_indices,
4051 &seq1_v_2_stmt_indices))
4053 /* Narrow lane usage. */
4054 narrow_vec_perm_simplify_seq (seq1);
4055 narrow_vec_perm_simplify_seq (seq2);
4057 /* Blend sequences. */
4058 blend_vec_perm_simplify_seqs (swap ? seq2 : seq1,
4059 swap ? seq1 : seq2,
4060 seq2_stmt_indices,
4061 seq1_v_1_stmt_indices,
4062 seq1_v_2_stmt_indices);
4064 /* We can use unordered_remove as we break the loop. */
4065 l->unordered_remove (j);
4066 XDELETE (seq2);
4067 break;
4073 /* We don't need to call l->remove for seq1. */
4074 XDELETE (seq1);
4077 l->truncate (0);
4080 static void
4081 append_vec_perm_simplify_seq_list (vec<vec_perm_simplify_seq> *l,
4082 const vec_perm_simplify_seq &seq)
4084 /* If no space on list left, then process the list. */
4085 if (!l->space (1))
4086 process_vec_perm_simplify_seq_list (l);
4088 l->quick_push (seq);
4091 /* Main entry point for the forward propagation and statement combine
4092 optimizer. */
4094 namespace {
4096 const pass_data pass_data_forwprop =
4098 GIMPLE_PASS, /* type */
4099 "forwprop", /* name */
4100 OPTGROUP_NONE, /* optinfo_flags */
4101 TV_TREE_FORWPROP, /* tv_id */
4102 ( PROP_cfg | PROP_ssa ), /* properties_required */
4103 0, /* properties_provided */
4104 0, /* properties_destroyed */
4105 0, /* todo_flags_start */
4106 TODO_update_ssa, /* todo_flags_finish */
4109 class pass_forwprop : public gimple_opt_pass
4111 public:
4112 pass_forwprop (gcc::context *ctxt)
4113 : gimple_opt_pass (pass_data_forwprop, ctxt), last_p (false)
4116 /* opt_pass methods: */
4117 opt_pass * clone () final override { return new pass_forwprop (m_ctxt); }
4118 void set_pass_param (unsigned int n, bool param) final override
4120 gcc_assert (n == 0);
4121 last_p = param;
4123 bool gate (function *) final override { return flag_tree_forwprop; }
4124 unsigned int execute (function *) final override;
4126 private:
4127 /* Determines whether the pass instance should set PROP_last_full_fold. */
4128 bool last_p;
4129 }; // class pass_forwprop
4131 unsigned int
4132 pass_forwprop::execute (function *fun)
4134 unsigned int todoflags = 0;
4136 cfg_changed = false;
4137 if (last_p)
4138 fun->curr_properties |= PROP_last_full_fold;
4140 calculate_dominance_info (CDI_DOMINATORS);
4142 /* Combine stmts with the stmts defining their operands. Do that
4143 in an order that guarantees visiting SSA defs before SSA uses. */
4144 lattice.create (num_ssa_names);
4145 lattice.quick_grow_cleared (num_ssa_names);
4146 int *postorder = XNEWVEC (int, n_basic_blocks_for_fn (fun));
4147 int postorder_num = pre_and_rev_post_order_compute_fn (fun, NULL,
4148 postorder, false);
4149 int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fun));
4150 for (int i = 0; i < postorder_num; ++i)
4152 bb_to_rpo[postorder[i]] = i;
4153 edge_iterator ei;
4154 edge e;
4155 FOR_EACH_EDGE (e, ei, BASIC_BLOCK_FOR_FN (fun, postorder[i])->succs)
4156 e->flags &= ~EDGE_EXECUTABLE;
4158 single_succ_edge (BASIC_BLOCK_FOR_FN (fun, ENTRY_BLOCK))->flags
4159 |= EDGE_EXECUTABLE;
4160 auto_vec<gimple *, 4> to_fixup;
4161 auto_vec<gimple *, 32> to_remove;
4162 auto_vec<unsigned, 32> to_remove_defs;
4163 auto_vec<std::pair<int, int>, 10> edges_to_remove;
4164 auto_bitmap simple_dce_worklist;
4165 auto_bitmap need_ab_cleanup;
4166 to_purge = BITMAP_ALLOC (NULL);
4167 auto_vec<vec_perm_simplify_seq, 8> vec_perm_simplify_seq_list;
4168 for (int i = 0; i < postorder_num; ++i)
4170 gimple_stmt_iterator gsi;
4171 basic_block bb = BASIC_BLOCK_FOR_FN (fun, postorder[i]);
4172 edge_iterator ei;
4173 edge e;
4175 /* Skip processing not executable blocks. We could improve
4176 single_use tracking by at least unlinking uses from unreachable
4177 blocks but since blocks with uses are not processed in a
4178 meaningful order this is probably not worth it. */
4179 bool any = false;
4180 FOR_EACH_EDGE (e, ei, bb->preds)
4182 if ((e->flags & EDGE_EXECUTABLE)
4183 /* We can handle backedges in natural loops correctly but
4184 for irreducible regions we have to take all backedges
4185 conservatively when we did not visit the source yet. */
4186 || (bb_to_rpo[e->src->index] > i
4187 && !dominated_by_p (CDI_DOMINATORS, e->src, e->dest)))
4189 any = true;
4190 break;
4193 if (!any)
4194 continue;
4196 /* Record degenerate PHIs in the lattice. */
4197 for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
4198 gsi_next (&si))
4200 gphi *phi = si.phi ();
4201 tree res = gimple_phi_result (phi);
4202 if (virtual_operand_p (res))
4203 continue;
4205 tree first = NULL_TREE;
4206 bool all_same = true;
4207 edge_iterator ei;
4208 edge e;
4209 FOR_EACH_EDGE (e, ei, bb->preds)
4211 /* Ignore not executable forward edges. */
4212 if (!(e->flags & EDGE_EXECUTABLE))
4214 if (bb_to_rpo[e->src->index] < i)
4215 continue;
4216 /* Avoid equivalences from backedges - while we might
4217 be able to make irreducible regions reducible and
4218 thus turning a back into a forward edge we do not
4219 want to deal with the intermediate SSA issues that
4220 exposes. */
4221 all_same = false;
4223 tree use = PHI_ARG_DEF_FROM_EDGE (phi, e);
4224 if (use == res)
4225 /* The PHI result can also appear on a backedge, if so
4226 we can ignore this case for the purpose of determining
4227 the singular value. */
4229 else if (! first)
4230 first = use;
4231 else if (! operand_equal_p (first, use, 0))
4233 all_same = false;
4234 break;
4237 if (all_same)
4239 if (may_propagate_copy (res, first))
4240 to_remove_defs.safe_push (SSA_NAME_VERSION (res));
4241 fwprop_set_lattice_val (res, first);
4245 /* Apply forward propagation to all stmts in the basic-block.
4246 Note we update GSI within the loop as necessary. */
4247 unsigned int uid = 1;
4248 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
4250 gimple *stmt = gsi_stmt (gsi);
4251 tree lhs, rhs;
4252 enum tree_code code;
4254 gimple_set_uid (stmt, uid++);
4256 if (!is_gimple_assign (stmt))
4258 process_vec_perm_simplify_seq_list (&vec_perm_simplify_seq_list);
4259 gsi_next (&gsi);
4260 continue;
4263 lhs = gimple_assign_lhs (stmt);
4264 rhs = gimple_assign_rhs1 (stmt);
4265 code = gimple_assign_rhs_code (stmt);
4267 if (TREE_CODE (lhs) != SSA_NAME
4268 || has_zero_uses (lhs))
4270 process_vec_perm_simplify_seq_list (&vec_perm_simplify_seq_list);
4271 gsi_next (&gsi);
4272 continue;
4275 /* If this statement sets an SSA_NAME to an address,
4276 try to propagate the address into the uses of the SSA_NAME. */
4277 if ((code == ADDR_EXPR
4278 /* Handle pointer conversions on invariant addresses
4279 as well, as this is valid gimple. */
4280 || (CONVERT_EXPR_CODE_P (code)
4281 && TREE_CODE (rhs) == ADDR_EXPR
4282 && POINTER_TYPE_P (TREE_TYPE (lhs))))
4283 && TREE_CODE (TREE_OPERAND (rhs, 0)) != TARGET_MEM_REF)
4285 tree base = get_base_address (TREE_OPERAND (rhs, 0));
4286 if ((!base
4287 || !DECL_P (base)
4288 || decl_address_invariant_p (base))
4289 && !stmt_references_abnormal_ssa_name (stmt)
4290 && forward_propagate_addr_expr (lhs, rhs, true))
4292 fwprop_invalidate_lattice (gimple_get_lhs (stmt));
4293 release_defs (stmt);
4294 gsi_remove (&gsi, true);
4296 else
4297 gsi_next (&gsi);
4299 else if (code == POINTER_PLUS_EXPR)
4301 tree off = gimple_assign_rhs2 (stmt);
4302 if (TREE_CODE (off) == INTEGER_CST
4303 && can_propagate_from (stmt)
4304 && !simple_iv_increment_p (stmt)
4305 /* ??? Better adjust the interface to that function
4306 instead of building new trees here. */
4307 && forward_propagate_addr_expr
4308 (lhs,
4309 build1_loc (gimple_location (stmt),
4310 ADDR_EXPR, TREE_TYPE (rhs),
4311 fold_build2 (MEM_REF,
4312 TREE_TYPE (TREE_TYPE (rhs)),
4313 rhs,
4314 fold_convert (ptr_type_node,
4315 off))), true))
4317 fwprop_invalidate_lattice (gimple_get_lhs (stmt));
4318 release_defs (stmt);
4319 gsi_remove (&gsi, true);
4321 else if (is_gimple_min_invariant (rhs))
4323 /* Make sure to fold &a[0] + off_1 here. */
4324 fold_stmt_inplace (&gsi);
4325 update_stmt (stmt);
4326 if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
4327 gsi_next (&gsi);
4329 else
4330 gsi_next (&gsi);
4332 else if (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE
4333 && gimple_assign_load_p (stmt)
4334 && !gimple_has_volatile_ops (stmt)
4335 && TREE_CODE (rhs) != TARGET_MEM_REF
4336 && TREE_CODE (rhs) != BIT_FIELD_REF
4337 && !stmt_can_throw_internal (fun, stmt))
4339 /* Rewrite loads used only in real/imagpart extractions to
4340 component-wise loads. */
4341 use_operand_p use_p;
4342 imm_use_iterator iter;
4343 bool rewrite = true;
4344 FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
4346 gimple *use_stmt = USE_STMT (use_p);
4347 if (is_gimple_debug (use_stmt))
4348 continue;
4349 if (!is_gimple_assign (use_stmt)
4350 || (gimple_assign_rhs_code (use_stmt) != REALPART_EXPR
4351 && gimple_assign_rhs_code (use_stmt) != IMAGPART_EXPR)
4352 || TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) != lhs)
4354 rewrite = false;
4355 break;
4358 if (rewrite)
4360 gimple *use_stmt;
4361 FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
4363 if (is_gimple_debug (use_stmt))
4365 if (gimple_debug_bind_p (use_stmt))
4367 gimple_debug_bind_reset_value (use_stmt);
4368 update_stmt (use_stmt);
4370 continue;
4373 tree new_rhs = build1 (gimple_assign_rhs_code (use_stmt),
4374 TREE_TYPE (TREE_TYPE (rhs)),
4375 unshare_expr (rhs));
4376 gimple *new_stmt
4377 = gimple_build_assign (gimple_assign_lhs (use_stmt),
4378 new_rhs);
4380 location_t loc = gimple_location (use_stmt);
4381 gimple_set_location (new_stmt, loc);
4382 gimple_stmt_iterator gsi2 = gsi_for_stmt (use_stmt);
4383 unlink_stmt_vdef (use_stmt);
4384 gsi_remove (&gsi2, true);
4386 gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
4389 release_defs (stmt);
4390 gsi_remove (&gsi, true);
4392 else
4393 gsi_next (&gsi);
4395 else if (TREE_CODE (TREE_TYPE (lhs)) == VECTOR_TYPE
4396 && (TYPE_MODE (TREE_TYPE (lhs)) == BLKmode
4397 /* After vector lowering rewrite all loads, but
4398 initially do not since this conflicts with
4399 vector CONSTRUCTOR to shuffle optimization. */
4400 || (fun->curr_properties & PROP_gimple_lvec))
4401 && gimple_assign_load_p (stmt)
4402 && !gimple_has_volatile_ops (stmt)
4403 && !stmt_can_throw_internal (fun, stmt)
4404 && (!VAR_P (rhs) || !DECL_HARD_REGISTER (rhs)))
4405 optimize_vector_load (&gsi);
4407 else if (code == COMPLEX_EXPR)
4409 /* Rewrite stores of a single-use complex build expression
4410 to component-wise stores. */
4411 use_operand_p use_p;
4412 gimple *use_stmt, *def1, *def2;
4413 tree rhs2;
4414 if (single_imm_use (lhs, &use_p, &use_stmt)
4415 && gimple_store_p (use_stmt)
4416 && !gimple_has_volatile_ops (use_stmt)
4417 && is_gimple_assign (use_stmt)
4418 && (TREE_CODE (TREE_TYPE (gimple_assign_lhs (use_stmt)))
4419 == COMPLEX_TYPE)
4420 && (TREE_CODE (gimple_assign_lhs (use_stmt))
4421 != TARGET_MEM_REF))
4423 tree use_lhs = gimple_assign_lhs (use_stmt);
4424 if (auto_var_p (use_lhs))
4425 DECL_NOT_GIMPLE_REG_P (use_lhs) = 1;
4426 tree new_lhs = build1 (REALPART_EXPR,
4427 TREE_TYPE (TREE_TYPE (use_lhs)),
4428 unshare_expr (use_lhs));
4429 gimple *new_stmt = gimple_build_assign (new_lhs, rhs);
4430 location_t loc = gimple_location (use_stmt);
4431 gimple_set_location (new_stmt, loc);
4432 gimple_set_vuse (new_stmt, gimple_vuse (use_stmt));
4433 gimple_set_vdef (new_stmt, make_ssa_name (gimple_vop (fun)));
4434 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
4435 gimple_set_vuse (use_stmt, gimple_vdef (new_stmt));
4436 gimple_stmt_iterator gsi2 = gsi_for_stmt (use_stmt);
4437 gsi_insert_before (&gsi2, new_stmt, GSI_SAME_STMT);
4439 new_lhs = build1 (IMAGPART_EXPR,
4440 TREE_TYPE (TREE_TYPE (use_lhs)),
4441 unshare_expr (use_lhs));
4442 gimple_assign_set_lhs (use_stmt, new_lhs);
4443 gimple_assign_set_rhs1 (use_stmt, gimple_assign_rhs2 (stmt));
4444 update_stmt (use_stmt);
4446 release_defs (stmt);
4447 gsi_remove (&gsi, true);
4449 /* Rewrite a component-wise load of a complex to a complex
4450 load if the components are not used separately. */
4451 else if (TREE_CODE (rhs) == SSA_NAME
4452 && has_single_use (rhs)
4453 && ((rhs2 = gimple_assign_rhs2 (stmt)), true)
4454 && TREE_CODE (rhs2) == SSA_NAME
4455 && has_single_use (rhs2)
4456 && (def1 = SSA_NAME_DEF_STMT (rhs),
4457 gimple_assign_load_p (def1))
4458 && (def2 = SSA_NAME_DEF_STMT (rhs2),
4459 gimple_assign_load_p (def2))
4460 && (gimple_vuse (def1) == gimple_vuse (def2))
4461 && !gimple_has_volatile_ops (def1)
4462 && !gimple_has_volatile_ops (def2)
4463 && !stmt_can_throw_internal (fun, def1)
4464 && !stmt_can_throw_internal (fun, def2)
4465 && gimple_assign_rhs_code (def1) == REALPART_EXPR
4466 && gimple_assign_rhs_code (def2) == IMAGPART_EXPR
4467 && operand_equal_p (TREE_OPERAND (gimple_assign_rhs1
4468 (def1), 0),
4469 TREE_OPERAND (gimple_assign_rhs1
4470 (def2), 0)))
4472 tree cl = TREE_OPERAND (gimple_assign_rhs1 (def1), 0);
4473 gimple_assign_set_rhs_from_tree (&gsi, unshare_expr (cl));
4474 gcc_assert (gsi_stmt (gsi) == stmt);
4475 gimple_set_vuse (stmt, gimple_vuse (def1));
4476 gimple_set_modified (stmt, true);
4477 gimple_stmt_iterator gsi2 = gsi_for_stmt (def1);
4478 gsi_remove (&gsi, false);
4479 gsi_insert_after (&gsi2, stmt, GSI_SAME_STMT);
4481 else
4482 gsi_next (&gsi);
4484 else if (code == CONSTRUCTOR
4485 && VECTOR_TYPE_P (TREE_TYPE (rhs))
4486 && TYPE_MODE (TREE_TYPE (rhs)) == BLKmode
4487 && CONSTRUCTOR_NELTS (rhs) > 0
4488 && (!VECTOR_TYPE_P (TREE_TYPE (CONSTRUCTOR_ELT (rhs, 0)->value))
4489 || (TYPE_MODE (TREE_TYPE (CONSTRUCTOR_ELT (rhs, 0)->value))
4490 != BLKmode)))
4492 /* Rewrite stores of a single-use vector constructors
4493 to component-wise stores if the mode isn't supported. */
4494 use_operand_p use_p;
4495 gimple *use_stmt;
4496 if (single_imm_use (lhs, &use_p, &use_stmt)
4497 && gimple_store_p (use_stmt)
4498 && !gimple_has_volatile_ops (use_stmt)
4499 && !stmt_can_throw_internal (fun, use_stmt)
4500 && is_gimple_assign (use_stmt))
4502 tree elt_t = TREE_TYPE (CONSTRUCTOR_ELT (rhs, 0)->value);
4503 unsigned HOST_WIDE_INT elt_w
4504 = tree_to_uhwi (TYPE_SIZE (elt_t));
4505 unsigned HOST_WIDE_INT n
4506 = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (rhs)));
4507 tree use_lhs = gimple_assign_lhs (use_stmt);
4508 if (auto_var_p (use_lhs))
4509 DECL_NOT_GIMPLE_REG_P (use_lhs) = 1;
4510 else if (TREE_CODE (use_lhs) == TARGET_MEM_REF)
4512 gimple_stmt_iterator gsi2 = gsi_for_stmt (use_stmt);
4513 use_lhs = prepare_target_mem_ref_lvalue (use_lhs, &gsi2);
4515 for (unsigned HOST_WIDE_INT bi = 0; bi < n; bi += elt_w)
4517 unsigned HOST_WIDE_INT ci = bi / elt_w;
4518 tree new_rhs;
4519 if (ci < CONSTRUCTOR_NELTS (rhs))
4520 new_rhs = CONSTRUCTOR_ELT (rhs, ci)->value;
4521 else
4522 new_rhs = build_zero_cst (elt_t);
4523 tree new_lhs = build3 (BIT_FIELD_REF,
4524 elt_t,
4525 unshare_expr (use_lhs),
4526 bitsize_int (elt_w),
4527 bitsize_int (bi));
4528 gimple *new_stmt = gimple_build_assign (new_lhs, new_rhs);
4529 location_t loc = gimple_location (use_stmt);
4530 gimple_set_location (new_stmt, loc);
4531 gimple_set_vuse (new_stmt, gimple_vuse (use_stmt));
4532 gimple_set_vdef (new_stmt,
4533 make_ssa_name (gimple_vop (fun)));
4534 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
4535 gimple_set_vuse (use_stmt, gimple_vdef (new_stmt));
4536 gimple_stmt_iterator gsi2 = gsi_for_stmt (use_stmt);
4537 gsi_insert_before (&gsi2, new_stmt, GSI_SAME_STMT);
4539 gimple_stmt_iterator gsi2 = gsi_for_stmt (use_stmt);
4540 unlink_stmt_vdef (use_stmt);
4541 release_defs (use_stmt);
4542 gsi_remove (&gsi2, true);
4543 release_defs (stmt);
4544 gsi_remove (&gsi, true);
4546 else
4547 gsi_next (&gsi);
4549 else if (code == VEC_PERM_EXPR)
4551 /* Find vectorized sequences, where we can reduce the lane
4552 utilization. The narrowing will be donw later and only
4553 if we find a pair of sequences that can be blended. */
4554 gassign *assign = dyn_cast <gassign *> (stmt);
4555 vec_perm_simplify_seq seq;
4556 if (recognise_vec_perm_simplify_seq (assign, &seq))
4557 append_vec_perm_simplify_seq_list (&vec_perm_simplify_seq_list,
4558 seq);
4560 gsi_next (&gsi);
4562 else
4563 gsi_next (&gsi);
4566 process_vec_perm_simplify_seq_list (&vec_perm_simplify_seq_list);
4568 /* Combine stmts with the stmts defining their operands.
4569 Note we update GSI within the loop as necessary. */
4570 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4572 gimple *stmt = gsi_stmt (gsi);
4574 /* Mark stmt as potentially needing revisiting. */
4575 gimple_set_plf (stmt, GF_PLF_1, false);
4577 bool can_make_abnormal_goto = (is_gimple_call (stmt)
4578 && stmt_can_make_abnormal_goto (stmt));
4580 /* Substitute from our lattice. We need to do so only once. */
4581 bool substituted_p = false;
4582 use_operand_p usep;
4583 ssa_op_iter iter;
4584 FOR_EACH_SSA_USE_OPERAND (usep, stmt, iter, SSA_OP_USE)
4586 tree use = USE_FROM_PTR (usep);
4587 tree val = fwprop_ssa_val (use);
4588 if (val && val != use)
4590 if (!is_gimple_debug (stmt))
4591 bitmap_set_bit (simple_dce_worklist, SSA_NAME_VERSION (use));
4592 if (may_propagate_copy (use, val))
4594 propagate_value (usep, val);
4595 substituted_p = true;
4599 if (substituted_p
4600 && is_gimple_assign (stmt)
4601 && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
4602 recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));
4603 if (substituted_p
4604 && can_make_abnormal_goto
4605 && !stmt_can_make_abnormal_goto (stmt))
4606 bitmap_set_bit (need_ab_cleanup, bb->index);
4608 bool changed;
4611 gimple *orig_stmt = stmt = gsi_stmt (gsi);
4612 bool was_noreturn = (is_gimple_call (stmt)
4613 && gimple_call_noreturn_p (stmt));
4614 changed = false;
4616 auto_vec<tree, 8> uses;
4617 FOR_EACH_SSA_USE_OPERAND (usep, stmt, iter, SSA_OP_USE)
4618 if (uses.space (1))
4619 uses.quick_push (USE_FROM_PTR (usep));
4621 if (fold_stmt (&gsi, fwprop_ssa_val, simple_dce_worklist))
4623 changed = true;
4624 stmt = gsi_stmt (gsi);
4625 /* Cleanup the CFG if we simplified a condition to
4626 true or false. */
4627 if (gcond *cond = dyn_cast <gcond *> (stmt))
4628 if (gimple_cond_true_p (cond)
4629 || gimple_cond_false_p (cond))
4630 cfg_changed = true;
4631 /* Queue old uses for simple DCE if not debug statement. */
4632 if (!is_gimple_debug (stmt))
4633 for (tree use : uses)
4634 if (TREE_CODE (use) == SSA_NAME
4635 && !SSA_NAME_IS_DEFAULT_DEF (use))
4636 bitmap_set_bit (simple_dce_worklist,
4637 SSA_NAME_VERSION (use));
4640 if (changed || substituted_p)
4642 if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
4643 bitmap_set_bit (to_purge, bb->index);
4644 if (!was_noreturn
4645 && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt))
4646 to_fixup.safe_push (stmt);
4647 update_stmt (stmt);
4648 substituted_p = false;
4651 switch (gimple_code (stmt))
4653 case GIMPLE_ASSIGN:
4655 tree rhs1 = gimple_assign_rhs1 (stmt);
4656 enum tree_code code = gimple_assign_rhs_code (stmt);
4658 if (TREE_CODE_CLASS (code) == tcc_comparison)
4660 int did_something;
4661 did_something = forward_propagate_into_comparison (&gsi);
4662 if (maybe_clean_or_replace_eh_stmt (stmt, gsi_stmt (gsi)))
4663 bitmap_set_bit (to_purge, bb->index);
4664 if (did_something == 2)
4665 cfg_changed = true;
4666 changed = did_something != 0;
4668 else if ((code == PLUS_EXPR
4669 || code == BIT_IOR_EXPR
4670 || code == BIT_XOR_EXPR)
4671 && simplify_rotate (&gsi))
4672 changed = true;
4673 else if (code == VEC_PERM_EXPR)
4675 int did_something = simplify_permutation (&gsi);
4676 if (did_something == 2)
4677 cfg_changed = true;
4678 changed = did_something != 0;
4680 else if (code == BIT_FIELD_REF)
4681 changed = simplify_bitfield_ref (&gsi);
4682 else if (code == CONSTRUCTOR
4683 && TREE_CODE (TREE_TYPE (rhs1)) == VECTOR_TYPE)
4684 changed = simplify_vector_constructor (&gsi);
4685 else if (code == ARRAY_REF)
4686 changed = simplify_count_trailing_zeroes (&gsi);
4687 break;
4690 case GIMPLE_SWITCH:
4691 changed = simplify_gimple_switch (as_a <gswitch *> (stmt),
4692 edges_to_remove);
4693 break;
4695 case GIMPLE_COND:
4697 int did_something = forward_propagate_into_gimple_cond
4698 (as_a <gcond *> (stmt));
4699 if (did_something == 2)
4700 cfg_changed = true;
4701 changed = did_something != 0;
4702 break;
4705 case GIMPLE_CALL:
4707 tree callee = gimple_call_fndecl (stmt);
4708 if (callee != NULL_TREE
4709 && fndecl_built_in_p (callee, BUILT_IN_NORMAL))
4710 changed = simplify_builtin_call (&gsi, callee);
4711 break;
4714 default:;
4717 if (changed)
4719 /* If the stmt changed then re-visit it and the statements
4720 inserted before it. */
4721 for (; !gsi_end_p (gsi); gsi_prev (&gsi))
4722 if (gimple_plf (gsi_stmt (gsi), GF_PLF_1))
4723 break;
4724 if (gsi_end_p (gsi))
4725 gsi = gsi_start_bb (bb);
4726 else
4727 gsi_next (&gsi);
4730 while (changed);
4732 /* Stmt no longer needs to be revisited. */
4733 stmt = gsi_stmt (gsi);
4734 gcc_checking_assert (!gimple_plf (stmt, GF_PLF_1));
4735 gimple_set_plf (stmt, GF_PLF_1, true);
4737 /* Fill up the lattice. */
4738 if (gimple_assign_single_p (stmt))
4740 tree lhs = gimple_assign_lhs (stmt);
4741 tree rhs = gimple_assign_rhs1 (stmt);
4742 if (TREE_CODE (lhs) == SSA_NAME)
4744 tree val = lhs;
4745 if (TREE_CODE (rhs) == SSA_NAME)
4746 val = fwprop_ssa_val (rhs);
4747 else if (is_gimple_min_invariant (rhs))
4748 val = rhs;
4749 /* If we can propagate the lattice-value mark the
4750 stmt for removal. */
4751 if (val != lhs
4752 && may_propagate_copy (lhs, val))
4753 to_remove_defs.safe_push (SSA_NAME_VERSION (lhs));
4754 fwprop_set_lattice_val (lhs, val);
4757 else if (gimple_nop_p (stmt))
4758 to_remove.safe_push (stmt);
4761 /* Substitute in destination PHI arguments. */
4762 FOR_EACH_EDGE (e, ei, bb->succs)
4763 for (gphi_iterator gsi = gsi_start_phis (e->dest);
4764 !gsi_end_p (gsi); gsi_next (&gsi))
4766 gphi *phi = gsi.phi ();
4767 use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
4768 tree arg = USE_FROM_PTR (use_p);
4769 if (TREE_CODE (arg) != SSA_NAME
4770 || virtual_operand_p (arg))
4771 continue;
4772 tree val = fwprop_ssa_val (arg);
4773 if (val != arg
4774 && may_propagate_copy (arg, val, !(e->flags & EDGE_ABNORMAL)))
4775 propagate_value (use_p, val);
4778 /* Mark outgoing exectuable edges. */
4779 if (edge e = find_taken_edge (bb, NULL))
4781 e->flags |= EDGE_EXECUTABLE;
4782 if (EDGE_COUNT (bb->succs) > 1)
4783 cfg_changed = true;
4785 else
4787 FOR_EACH_EDGE (e, ei, bb->succs)
4788 e->flags |= EDGE_EXECUTABLE;
4791 free (postorder);
4792 free (bb_to_rpo);
4793 lattice.release ();
4795 /* First remove chains of stmts where we check no uses remain. */
4796 simple_dce_from_worklist (simple_dce_worklist, to_purge);
4798 auto remove = [](gimple *stmt)
4800 if (dump_file && (dump_flags & TDF_DETAILS))
4802 fprintf (dump_file, "Removing dead stmt ");
4803 print_gimple_stmt (dump_file, stmt, 0);
4804 fprintf (dump_file, "\n");
4806 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
4807 if (gimple_code (stmt) == GIMPLE_PHI)
4808 remove_phi_node (&gsi, true);
4809 else
4811 unlink_stmt_vdef (stmt);
4812 gsi_remove (&gsi, true);
4813 release_defs (stmt);
4817 /* Then remove stmts we know we can remove even though we did not
4818 substitute in dead code regions, so uses can remain. Do so in reverse
4819 order to make debug stmt creation possible. */
4820 while (!to_remove_defs.is_empty())
4822 tree def = ssa_name (to_remove_defs.pop ());
4823 /* For example remove_prop_source_from_use can remove stmts queued
4824 for removal. Deal with this gracefully. */
4825 if (!def)
4826 continue;
4827 gimple *stmt = SSA_NAME_DEF_STMT (def);
4828 remove (stmt);
4831 /* Wipe other queued stmts that do not have SSA defs. */
4832 while (!to_remove.is_empty())
4834 gimple *stmt = to_remove.pop ();
4835 remove (stmt);
4838 /* Fixup stmts that became noreturn calls. This may require splitting
4839 blocks and thus isn't possible during the walk. Do this
4840 in reverse order so we don't inadvertedly remove a stmt we want to
4841 fixup by visiting a dominating now noreturn call first. */
4842 while (!to_fixup.is_empty ())
4844 gimple *stmt = to_fixup.pop ();
4845 if (dump_file && dump_flags & TDF_DETAILS)
4847 fprintf (dump_file, "Fixing up noreturn call ");
4848 print_gimple_stmt (dump_file, stmt, 0);
4849 fprintf (dump_file, "\n");
4851 cfg_changed |= fixup_noreturn_call (stmt);
4854 cfg_changed |= gimple_purge_all_dead_eh_edges (to_purge);
4855 cfg_changed |= gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup);
4856 BITMAP_FREE (to_purge);
4858 /* Remove edges queued from switch stmt simplification. */
4859 for (auto ep : edges_to_remove)
4861 basic_block src = BASIC_BLOCK_FOR_FN (fun, ep.first);
4862 basic_block dest = BASIC_BLOCK_FOR_FN (fun, ep.second);
4863 edge e;
4864 if (src && dest && (e = find_edge (src, dest)))
4866 free_dominance_info (CDI_DOMINATORS);
4867 remove_edge (e);
4868 cfg_changed = true;
4872 if (get_range_query (fun) != get_global_range_query ())
4873 disable_ranger (fun);
4875 if (cfg_changed)
4876 todoflags |= TODO_cleanup_cfg;
4878 return todoflags;
4881 } // anon namespace
4883 gimple_opt_pass *
4884 make_pass_forwprop (gcc::context *ctxt)
4886 return new pass_forwprop (ctxt);