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)
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/>. */
22 #include "coretypes.h"
28 #include "tree-pass.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"
39 #include "gimplify-me.h"
43 #include "tree-ssa-propagate.h"
44 #include "tree-ssa-dom.h"
45 #include "tree-ssa-strlen.h"
47 #include "tree-cfgcleanup.h"
49 #include "optabs-tree.h"
50 #include "insn-config.h"
53 #include "tree-vectorizer.h"
54 #include "tree-vector-builder.h"
55 #include "vec-perm-indices.h"
56 #include "internal-fn.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.
72 if (x) goto ... else goto ...
74 Will be transformed into:
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):
85 if (x EQ/NEQ c2) goto ... else goto ...
87 Will be transformed into:
90 if (a EQ/NEQ (c2 - c1)) goto ... else goto ...
92 Similarly for x = a - c1.
98 if (x) goto ... else goto ...
100 Will be transformed into:
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.
113 if (x) goto ... else goto ...
115 Will be transformed into:
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
147 ptr = (type1*)&type2var;
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)
157 ptr2 = ptr + <constant>;
161 ptr2 = &x[constant/elementsize];
166 offset = index * element_size;
167 offset_p = (pointer) offset;
168 ptr2 = ptr + offset_p
170 Will get turned into:
178 Provided that decl has known alignment >= 2, will get turned into
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
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. */
198 /* Final permute statment. */
200 /* New selector indices for stmt. */
202 /* Elements of each vector and selector. */
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. */
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. */
240 fwprop_invalidate_lattice (tree 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. */
257 get_prop_source_stmt (tree name
, bool single_use_only
, bool *single_use_p
)
259 bool single_use
= true;
262 gimple
*def_stmt
= SSA_NAME_DEF_STMT (name
);
264 if (!has_single_use (name
))
271 /* If name is defined by a PHI node or is the default def, bail out. */
272 if (!is_gimple_assign (def_stmt
))
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
);
280 if (!single_use_only
&& single_use_p
)
281 *single_use_p
= single_use
;
288 /* Checks if the destination ssa name in DEF_STMT can be used as
289 propagation source. Returns true if so, otherwise false. */
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
))
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
)
305 /* Constants can be always propagated. */
306 if (gimple_assign_single_p (def_stmt
)
307 && is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt
)))
310 /* We cannot propagate ssa names that occur in abnormal phi nodes. */
311 if (stmt_references_abnormal_ssa_name (def_stmt
))
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
)))
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
333 Returns true if cleanup-cfg has to run. */
336 remove_prop_source_from_use (tree name
)
338 gimple_stmt_iterator gsi
;
340 bool cfg_changed
= false;
345 if (SSA_NAME_IN_FREE_LIST (name
)
346 || SSA_NAME_IS_DEFAULT_DEF (name
)
347 || !has_zero_uses (name
))
350 stmt
= SSA_NAME_DEF_STMT (name
);
351 if (gimple_code (stmt
) == GIMPLE_PHI
352 || gimple_has_side_effects (stmt
))
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
));
363 name
= is_gimple_assign (stmt
) ? gimple_assign_rhs1 (stmt
) : NULL_TREE
;
364 } while (name
&& TREE_CODE (name
) == SSA_NAME
);
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 . */
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
);
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. */
406 combine_cond_expr_cond (gimple
*stmt
, enum tree_code code
, tree type
,
407 tree op0
, tree op1
, bool invariant_only
)
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
);
417 fold_undefer_overflow_warnings (false, NULL
, 0);
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);
434 bool nowarn
= warning_suppressed_p (stmt
, OPT_Wstrict_overflow
);
435 fold_undefer_overflow_warnings (!nowarn
, stmt
, 0);
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. */
445 forward_propagate_into_comparison_1 (gimple
*stmt
,
446 enum tree_code code
, tree type
,
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)))
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
);
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
);
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
,
499 !(single_use0_p
&& single_use1_p
));
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. */
510 forward_propagate_into_comparison (gimple_stmt_iterator
*gsi
)
512 gimple
*stmt
= gsi_stmt (*gsi
);
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
),
523 if (tmp
&& useless_type_conversion_p (type
, TREE_TYPE (tmp
)))
525 gimple_assign_set_rhs_from_tree (gsi
, tmp
);
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;
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. */
545 forward_propagate_into_gimple_cond (gcond
*stmt
)
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
)
557 tmp
= forward_propagate_into_comparison_1 (stmt
, code
,
561 && is_gimple_condexpr_for_cond (tmp
))
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
));
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))
587 && integer_zerop (rhs2
))
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
);
602 /* We've just substituted an ADDR_EXPR into stmt. Update all the
603 relevant data structures to match. */
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). */
627 forward_propagate_addr_expr_1 (tree name
, tree def_rhs
,
628 gimple_stmt_iterator
*use_stmt_gsi
,
631 tree lhs
, rhs
, rhs2
, array_ref
;
632 gimple
*use_stmt
= gsi_stmt (*use_stmt_gsi
);
633 enum tree_code rhs_code
;
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
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
));
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
);
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
)))
681 /* Propagate through constant pointer adjustments. */
682 if (TREE_CODE (lhs
) == SSA_NAME
683 && rhs_code
== POINTER_PLUS_EXPR
685 && TREE_CODE (gimple_assign_rhs2 (use_stmt
)) == INTEGER_CST
)
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
)),
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)))
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
))
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
),
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
);
714 gcc_assert (gsi_stmt (*use_stmt_gsi
) == use_stmt
);
715 update_stmt (use_stmt
);
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);
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
)
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),
737 poly_offset_int off
= mem_ref_offset (lhs
);
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);
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. */
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));
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));
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
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. */
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);
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
)
824 poly_int64 def_rhs_offset
;
825 if ((def_rhs_base
= get_addr_base_and_unit_offset (TREE_OPERAND (def_rhs
, 0),
828 poly_offset_int off
= mem_ref_offset (rhs
);
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);
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
);
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));
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));
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
);
888 /* If the use of the ADDR_EXPR is not a POINTER_PLUS_EXPR, there
890 if (gimple_assign_rhs_code (use_stmt
) != POINTER_PLUS_EXPR
891 || gimple_assign_rhs1 (use_stmt
) != name
)
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
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
)
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
,
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
);
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
936 Returns true, if all uses have been propagated into. */
939 forward_propagate_addr_expr (tree name
, tree rhs
, bool parent_single_use_p
)
941 imm_use_iterator iter
;
944 bool single_use_p
= parent_single_use_p
&& has_single_use (name
);
946 FOR_EACH_IMM_USE_STMT (use_stmt
, iter
, name
)
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
))
960 gimple_stmt_iterator gsi
= gsi_for_stmt (use_stmt
);
961 result
= forward_propagate_addr_expr_1 (name
, rhs
, &gsi
,
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
);
973 /* Remove intermediate now unused copy and conversion chains. */
974 use_rhs
= gimple_assign_rhs1 (use_stmt
);
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. */
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
;
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. */
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
);
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
,
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. */
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
)
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
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
;
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));
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
,
1112 /* For pointers p2 and p1 return p2 - p1 if the
1113 difference is known and constant, otherwise return NULL. */
1116 constant_pointer_difference (tree p1
, tree p2
)
1119 #define CPD_ITERATIONS 5
1120 tree exps
[2][CPD_ITERATIONS
];
1121 tree offs
[2][CPD_ITERATIONS
];
1124 for (i
= 0; i
< 2; i
++)
1126 tree p
= i
? p1
: p2
;
1127 tree off
= size_zero_node
;
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. */
1138 if (!POINTER_TYPE_P (TREE_TYPE (p
)))
1140 if (TREE_CODE (p
) == ADDR_EXPR
)
1142 tree q
= TREE_OPERAND (p
, 0);
1144 tree base
= get_addr_base_and_unit_offset (q
, &offset
);
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
)));
1166 if (TREE_CODE (p
) != SSA_NAME
)
1170 if (j
== CPD_ITERATIONS
)
1172 stmt
= SSA_NAME_DEF_STMT (p
);
1173 if (!is_gimple_assign (stmt
) || gimple_assign_lhs (stmt
) != p
)
1175 code
= gimple_assign_rhs_code (stmt
);
1176 if (code
== POINTER_PLUS_EXPR
)
1178 if (TREE_CODE (gimple_assign_rhs2 (stmt
)) != INTEGER_CST
)
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
);
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
]);
1200 /* *GSI_P is a GIMPLE_CALL to a builtin function.
1202 memcpy (p, "abcd", 4);
1203 memset (p + 4, ' ', 3);
1205 memcpy (p, "abcd ", 7);
1206 call if the latter can be stored by pieces during expansion.
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). */
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
);
1231 stmt1
= SSA_NAME_DEF_STMT (vuse
);
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
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
)
1248 unsigned HOST_WIDE_INT slen
1249 = TREE_STRING_LENGTH (TREE_OPERAND (ptr
, 0));
1250 /* It must be a non-empty string constant. */
1253 /* For -Os, only simplify strings with a single character. */
1254 if (!optimize_bb_for_speed_p (gimple_bb (stmt2
))
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
)
1263 if (!tree_fits_uhwi_p (size
))
1266 unsigned HOST_WIDE_INT sz
= tree_to_uhwi (size
);
1267 if (sz
== 0 || sz
> UNITS_PER_WORD
|| sz
>= slen
)
1270 tree ch
= gimple_call_arg (stmt2
, 1);
1271 location_t loc
= gimple_location (stmt2
);
1272 if (!useless_type_conversion_p (char_type_node
,
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
,
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
,
1291 res
= fold_convert_loc (loc
, TREE_TYPE (res
), op
[0]);
1292 gimplify_and_update_call_from_tree (gsi_p
, res
);
1297 case BUILT_IN_MEMSET
:
1298 if (gimple_call_num_args (stmt2
) != 3
1299 || gimple_call_lhs (stmt2
)
1301 || BITS_PER_UNIT
!= 8)
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
;
1312 unsigned int ptr1_align
;
1313 unsigned HOST_WIDE_INT src_len
;
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)
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
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)
1331 if (DECL_FUNCTION_CODE (callee1
) != BUILT_IN_MEMCPY
1332 && DECL_FUNCTION_CODE (callee1
) != BUILT_IN_MEMPCPY
)
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
))
1340 str1
= string_constant (src1
, &off1
, NULL
, NULL
);
1341 if (str1
== NULL_TREE
)
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
))
1352 else if (gimple_assign_single_p (stmt1
))
1354 /* Otherwise look for length 1 memcpy optimized into
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
))
1362 ptr1
= build_fold_addr_expr (ptr1
);
1363 STRIP_USELESS_TYPE_CONVERSION (ptr1
);
1364 callee1
= NULL_TREE
;
1365 len1
= size_one_node
;
1367 off1
= size_zero_node
;
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
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. */
1385 || !tree_fits_uhwi_p (diff
)
1386 || tree_int_cst_lt (len1
, diff
)
1387 || compare_tree_int (diff
, 1024) == 1)
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
);
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
))
1408 /* If anything reads memory in between memcpy and memset
1409 call, the modified memcpy call might change it. */
1410 vdef
= gimple_vdef (stmt1
);
1412 && (!single_imm_use (vdef
, &use_p
, &use_stmt
)
1413 || use_stmt
!= stmt2
))
1416 ptr1_align
= get_pointer_alignment (ptr1
);
1417 /* Construct the new source string literal. */
1418 src_buf
= XALLOCAVEC (char, src_len
+ 1);
1421 TREE_STRING_POINTER (str1
) + tree_to_uhwi (off1
),
1422 tree_to_uhwi (len1
));
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
)
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
1437 if (!can_store_by_pieces (src_len
,
1438 builtin_strncpy_read_str
,
1439 src_buf
, ptr1_align
, false))
1442 new_str_cst
= build_string_literal (src_len
, src_buf
);
1445 /* If STMT1 is a mem{,p}cpy call, adjust it and remove
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
);
1466 /* Otherwise, if STMT1 is length 1 memcpy optimized into
1467 assignment, remove STMT1 and change memset call into
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
);
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: \
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
)
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
))
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
;
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
))
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
)))
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
1615 else if (crhs2
== lhsc
)
1617 if (o
&& atomic_op
!= PLUS_EXPR
)
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
)))
1631 if (operand_equal_p (arg
, oarg
, 0))
1633 else if (TREE_CODE (arg
) == SSA_NAME
1634 && TREE_CODE (oarg
) == SSA_NAME
)
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
))))
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
);
1652 x.0_1 = (long unsigned int) x_4(D);
1653 _2 = __atomic_fetch_add_8 (&vlong, x.0_1, 0);
1655 _7 = x_4(D) + _3; */
1656 if (rhs1
== oarg
|| rhs1
== oarg2
)
1659 x.18_1 = (short unsigned int) x_5(D);
1661 _3 = __atomic_fetch_xor_2 (&vshort, _2, 0);
1662 _4 = (short int) _3;
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
))
1677 if (!ok
&& arg
== oarg2
)
1679 _1 = __sync_fetch_and_add_4 (&v, x_5(D));
1681 x.0_3 = (int) x_5(D);
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
,
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
);
1715 gcc_checking_assert (gimple_assign_rhs_code (use_stmt
)
1717 tree cond
= build2 (ccode
, boolean_type_node
,
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);
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
1736 These stmts will be DCEd later and proper debug info
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
);
1751 enum tree_code rcode
;
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
);
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
);
1785 gsi
= gsi_for_stmt (cast_stmt
);
1786 gsi_remove (&gsi
, true);
1788 update_stmt (stmt2
);
1789 release_ssa_name (lhs2
);
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. */
1806 defcodefor_name (tree name
, enum tree_code
*code
, tree
*arg1
, tree
*arg2
)
1809 enum tree_code code1
;
1813 enum gimple_rhs_class grhs_class
;
1815 code1
= TREE_CODE (name
);
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
)
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:
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
1872 The latter for the forms with T2 wider than T if ranger can't prove Y < B.
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:
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
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];
1898 bool swapped_p
= false;
1900 gimple
*def_arg_stmt
[2] = { NULL
, NULL
};
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
))
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
]);
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
)
1963 else if (!has_single_use (arg
[i
]))
1965 if (def_code
[0] == def_code
[1])
1968 /* If we've looked through narrowing conversions before, look through
1969 widening conversions from unsigned type with the same precision
1971 if (TYPE_PRECISION (TREE_TYPE (def_arg1
[0])) != TYPE_PRECISION (rtype
))
1972 for (i
= 0; i
< 2; i
++)
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
))
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]))))
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
])))
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
))
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])))
2013 else if (!TYPE_UNSIGNED (TREE_TYPE (def_arg1
[0])))
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
)
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
]);
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
)
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
];
2072 if (cdef_arg2
[i
] == def_arg2
[1 - i
])
2073 check_range_stmt
= def_arg_stmt
[1 - i
];
2075 check_range_stmt
= def_arg_alt_stmt
[1 - i
];
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
]))
2089 if (tem
== def_arg2
[1 - i
])
2090 check_range_stmt
= def_arg_stmt
[1 - i
];
2092 check_range_stmt
= def_arg_alt_stmt
[1 - i
];
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
)
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
])
2126 if (tem
== def_arg2
[1 - i
])
2127 check_range_stmt
= def_arg_stmt
[1 - i
];
2129 check_range_stmt
= def_arg_alt_stmt
[1 - i
];
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
])
2145 if (tem2
== def_arg2
[1 - i
])
2146 check_range_stmt
= def_arg_stmt
[1 - i
];
2148 check_range_stmt
= def_arg_alt_stmt
[1 - i
];
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
];
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
];
2184 if (check_range
&& wider_prec
> TYPE_PRECISION (rtype
))
2186 if (TREE_CODE (rotcnt
) != SSA_NAME
)
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)
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)
2204 int_range
<1> r2 (TREE_TYPE (rotcnt
), min
, max
);
2206 if (!r
.undefined_p ())
2208 if (check_range
> 0)
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),
2218 int_range
<1> r4 (TREE_TYPE (rotcnt
), min
, max
);
2222 if (!r
.undefined_p ())
2228 if (rotcnt
== NULL_TREE
)
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])),
2238 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
2239 rotcnt
= gimple_assign_lhs (g
);
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);
2266 /* Check whether an array contains a valid ctz table. */
2268 check_ctz_array (tree ctor
, unsigned HOST_WIDE_INT mulc
,
2269 HOST_WIDE_INT
&zero_val
, unsigned shift
, unsigned bits
)
2272 unsigned HOST_WIDE_INT i
, mask
, raw_idx
= 0;
2273 unsigned matched
= 0;
2275 mask
= ((HOST_WIDE_INT_1U
<< (bits
- shift
)) - 1) << shift
;
2279 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor
), i
, idx
, elt
)
2281 if (!tree_fits_shwi_p (idx
))
2283 if (!tree_fits_shwi_p (elt
) && TREE_CODE (elt
) != RAW_DATA_CST
)
2286 unsigned HOST_WIDE_INT index
= tree_to_shwi (idx
);
2289 if (TREE_CODE (elt
) == INTEGER_CST
)
2290 val
= tree_to_shwi (elt
);
2293 if (raw_idx
== (unsigned) RAW_DATA_LENGTH (elt
))
2298 if (TYPE_UNSIGNED (TREE_TYPE (elt
)))
2299 val
= RAW_DATA_UCHAR_ELT (elt
, raw_idx
);
2301 val
= RAW_DATA_SCHAR_ELT (elt
, raw_idx
);
2307 if (index
> bits
* 2)
2316 if (val
>= 0 && val
< bits
&& (((mulc
<< val
) & mask
) >> shift
) == index
)
2326 /* Check whether a string contains a valid ctz table. */
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)
2339 mask
= ((HOST_WIDE_INT_1U
<< (bits
- shift
)) - 1) << shift
;
2343 for (unsigned i
= 0; i
< len
; i
++)
2344 if (p
[i
] < bits
&& (((mulc
<< p
[i
]) & mask
) >> shift
) == i
)
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
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
))
2374 if (input_bits
!= 32 && input_bits
!= 64)
2377 if (!direct_internal_fn_supported_p (IFN_CTZ
, input_type
, OPTIMIZE_FOR_BOTH
))
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
))
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)
2391 tree ctor
= ctor_for_folding (array
);
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
);
2407 /* Match.pd function to match the ctz expression. */
2408 extern bool gimple_ctz_table_index (tree
, tree
*, tree (*)(tree
));
2411 simplify_count_trailing_zeroes (gimple_stmt_iterator
*gsi
)
2413 gimple
*stmt
= gsi_stmt (*gsi
);
2414 tree array_ref
= gimple_assign_rhs1 (stmt
);
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
))
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
));
2430 = CTZ_DEFINED_VALUE_AT_ZERO (SCALAR_INT_TYPE_MODE (type
), ctz_val
) == 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]))
2442 /* Skip if there is no value defined at zero, or if we can't easily
2443 return the correct value for zero. */
2446 if (zero_val
!= ctz_val
&& !(zero_val
== 0 && ctz_val
== type_size
))
2449 gimple_seq seq
= NULL
;
2452 = gimple_build_call_internal (IFN_CTZ
, nargs
, res_ops
[0],
2453 nargs
== 1 ? NULL_TREE
2454 : build_int_cst (integer_type_node
,
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
,
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);
2484 /* Combine an element access with a shuffle. Returns true if there were
2485 any changes made, else it returns false. */
2488 simplify_bitfield_ref (gimple_stmt_iterator
*gsi
)
2490 gimple
*stmt
= gsi_stmt (*gsi
);
2493 tree elem_type
, type
;
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
)
2507 def_stmt
= get_prop_source_stmt (op0
, false, NULL
);
2508 if (!def_stmt
|| !can_propagate_from (def_stmt
))
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.
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
))
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
))
2533 m
= gimple_assign_rhs3 (def_stmt
);
2534 if (TREE_CODE (m
) != VECTOR_CST
2535 || !VECTOR_CST_NELTS (m
).is_constant (&nelts
))
2539 if (known_eq (size
, elem_size
))
2540 idx
= TREE_INT_CST_LOW (VECTOR_CST_ELT (m
, idx
)) % (2 * nelts
);
2543 unsigned HOST_WIDE_INT nelts_op
;
2544 if (!constant_multiple_p (size
, elem_size
, &nelts_op
)
2545 || !pow2p_hwi (nelts_op
))
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))
2551 /* Be in the same vector. */
2552 if ((start
< nelts
) != (end
< nelts
))
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))
2562 /* Alignment not worse than before. */
2563 if (start
% nelts_op
)
2569 p
= gimple_assign_rhs1 (def_stmt
);
2572 p
= gimple_assign_rhs2 (def_stmt
);
2576 tem
= build3 (BIT_FIELD_REF
, TREE_TYPE (op
),
2577 p
, op1
, bitsize_int (idx
* elem_size
));
2578 gimple_assign_set_rhs1 (stmt
, tem
);
2580 update_stmt (gsi_stmt (*gsi
));
2584 /* Determine whether applying the 2 permutations (mask1 then mask2)
2585 gives back one of the input. */
2588 is_combined_permutation_identity (tree mask1
, tree mask2
)
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)
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))
2618 mask
= fold_ternary (VEC_PERM_EXPR
, TREE_TYPE (mask1
), mask1
, mask1
, mask2
);
2619 if (mask
== NULL_TREE
|| TREE_CODE (mask
) != VECTOR_CST
)
2622 if (!VECTOR_CST_NELTS (mask
).is_constant (&nelts
))
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);
2630 maybe_identity2
= false;
2631 else if (j
== i
+ nelts
)
2632 maybe_identity1
= false;
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. */
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
)
2660 if (TREE_CODE (op0
) == VECTOR_CST
)
2665 else if (TREE_CODE (op0
) == SSA_NAME
)
2667 def_stmt
= get_prop_source_stmt (op0
, false, &single_use_op0
);
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
)
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
))
2685 if (gimple_assign_rhs_code (def_stmt
) != CONSTRUCTOR
)
2688 if (!can_propagate_from (def_stmt
))
2690 arg0
= gimple_assign_rhs1 (def_stmt
);
2695 /* Two consecutive shuffles. */
2696 if (code
== VEC_PERM_EXPR
)
2703 op3
= gimple_assign_rhs3 (def_stmt
);
2704 if (TREE_CODE (op3
) != VECTOR_CST
)
2706 ident
= is_combined_permutation_identity (op3
, op2
);
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);
2715 return remove_prop_source_from_use (op0
) ? 2 : 1;
2717 else if (code
== CONSTRUCTOR
2718 || code
== VECTOR_CST
2719 || code
== VIEW_CONVERT_EXPR
)
2723 if (TREE_CODE (op0
) == SSA_NAME
&& !single_use_op0
)
2726 if (TREE_CODE (op1
) == VECTOR_CST
)
2728 else if (TREE_CODE (op1
) == SSA_NAME
)
2730 gimple
*def_stmt2
= get_prop_source_stmt (op1
, true, NULL
);
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
)
2740 if (!has_single_use (name
))
2742 def_stmt2
= SSA_NAME_DEF_STMT (name
);
2743 if (!def_stmt2
|| !is_gimple_assign (def_stmt2
))
2745 if (gimple_assign_rhs_code (def_stmt2
) != CONSTRUCTOR
)
2748 else if (code2
!= CONSTRUCTOR
&& code2
!= VECTOR_CST
)
2750 if (!can_propagate_from (def_stmt2
))
2752 arg1
= gimple_assign_rhs1 (def_stmt2
);
2759 /* Already used twice in this statement. */
2760 if (TREE_CODE (op0
) == SSA_NAME
&& num_imm_uses (op0
) > 2)
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
);
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
)
2789 if (!VECTOR_TYPE_P (tgt_type
))
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
))
2798 unsigned int factor
;
2799 if (!constant_multiple_p (op2_units
, tgt_units
, &factor
))
2802 /* Build the new permutation control vector as target vector. */
2803 vec_perm_builder builder
;
2804 if (!tree_to_vec_perm_builder (&builder
, op2
))
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
);
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. */
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
);
2840 || (TREE_CODE (opt
) != CONSTRUCTOR
&& TREE_CODE (opt
) != VECTOR_CST
))
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
);
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. */
2867 get_bit_field_ref_def (tree val
, enum tree_code
&conv_code
)
2869 if (TREE_CODE (val
) != SSA_NAME
)
2871 gimple
*def_stmt
= get_prop_source_stmt (val
, false, NULL
);
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
)
2882 else if (conv_code
!= code
)
2884 if (TREE_CODE (op1
) != SSA_NAME
)
2886 def_stmt
= SSA_NAME_DEF_STMT (op1
);
2887 if (! is_gimple_assign (def_stmt
))
2889 code
= gimple_assign_rhs_code (def_stmt
);
2891 if (code
!= BIT_FIELD_REF
)
2893 return gimple_assign_rhs1 (def_stmt
);
2896 /* Recognize a VEC_PERM_EXPR. Returns true if there were any changes. */
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
))
2916 elem_type
= TREE_TYPE (type
);
2917 elem_size
= TREE_INT_CST_LOW (TYPE_SIZE (elem_type
));
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
)
2937 /* Look for elements extracted and possibly converted from
2939 op1
= get_bit_field_ref_def (elt
->value
, conv_code
);
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
))
2950 for (j
= 0; j
< 2; ++j
)
2955 || useless_type_conversion_p (TREE_TYPE (orig
[0]),
2959 else if (ref
== orig
[j
])
2962 /* Found a suitable vector element. */
2966 if (elem
!= i
|| j
!= 0)
2967 maybe_ident
= false;
2969 maybe_blend
[j
] = false;
2970 elts
.safe_push (std::make_pair (j
, elem
));
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 */
2979 && orig
[1] != error_mark_node
)
2981 orig
[1] = error_mark_node
;
2982 if (CONSTANT_CLASS_P (elt
->value
))
2984 if (one_nonconstant
)
2987 one_constant
= elt
->value
;
2988 constants
[i
] = elt
->value
;
2994 if (!one_nonconstant
)
2995 one_nonconstant
= elt
->value
;
2996 else if (!operand_equal_p (one_nonconstant
, elt
->value
, 0))
2999 elts
.safe_push (std::make_pair (1, i
));
3000 maybe_ident
= false;
3006 || ! VECTOR_TYPE_P (TREE_TYPE (orig
[0])))
3008 refnelts
= TYPE_VECTOR_SUBPARTS (TREE_TYPE (orig
[0])).to_constant ();
3009 /* We currently do not handle larger destination vectors. */
3010 if (refnelts
< nelts
)
3016 = (nelts
!= refnelts
3017 ? (conv_code
!= ERROR_MARK
3018 ? build_vector_type (TREE_TYPE (TREE_TYPE (orig
[0])), nelts
)
3020 : TREE_TYPE (orig
[0]));
3021 if (conv_code
!= ERROR_MARK
3022 && !supportable_convert_operation (conv_code
, type
, conv_src_type
,
3025 /* Only few targets implement direct conversion patterns so try
3026 some simple special cases via VEC_[UN]PACK[_FLOAT]_LO_EXPR. */
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
);
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
))))
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 ()
3057 = build_vector_type (TREE_TYPE (TREE_TYPE (orig
[0])),
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
,
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
;
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],
3080 else if (refnelts
== 2 * nelts
)
3083 dbl
= gimple_build (&stmts
, BIT_FIELD_REF
, dblvectype
,
3084 orig
[0], TYPE_SIZE (dblvectype
),
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
>
3094 (TREE_TYPE (TREE_TYPE (orig
[0])))),
3095 nelts
/ 2).exists ()
3097 = build_vector_type (TREE_TYPE (TREE_TYPE (orig
[0])),
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
,
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
),
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
,
3123 update_stmt (gsi_stmt (*gsi
));
3126 if (nelts
!= refnelts
)
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]);
3153 gimple_assign_set_rhs_with_ops (gsi
, conv_code
, orig
[0],
3154 NULL_TREE
, NULL_TREE
);
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. */
3164 && orig
[1] == error_mark_node
3167 tree mask_type
, perm_type
, conv_src_type
;
3168 perm_type
= TREE_TYPE (orig
[0]);
3169 conv_src_type
= (nelts
== refnelts
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
,
3177 /* Now that we know the number of elements of the source build the
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
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
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
))
3208 = build_vector_type (build_nonstandard_integer_type (elem_size
, 1),
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
))))
3214 tree op2
= vec_perm_indices_to_tree (mask_type
, indices
);
3215 bool converted_orig1
= false;
3216 gimple_seq stmts
= NULL
;
3219 else if (orig
[1] == error_mark_node
3222 /* ??? We can see if we can safely convert to the original
3224 converted_orig1
= conv_code
!= ERROR_MARK
;
3225 orig
[1] = gimple_build_vector_from_val (&stmts
, UNKNOWN_LOCATION
,
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
]);
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
))
3258 = build_vector_type (build_nonstandard_integer_type (elem_size
, 1),
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
))))
3264 blend_op2
= vec_perm_indices_to_tree (mask_type
, indices
);
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
));
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. */
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
);
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));
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
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
))
3345 if (!is_gimple_assign (use_stmt
))
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. */
3357 || (known_eq (bit_field_size (use_rhs
), def_eltsize
)
3358 && constant_multiple_p (bit_field_offset (use_rhs
),
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
);
3368 /* Walk through one level of VEC_UNPACK_{LO,HI}_EXPR. */
3370 && (use_code
== VEC_UNPACK_HI_EXPR
3371 || use_code
== VEC_UNPACK_LO_EXPR
)
3374 worklist
.safe_push (gimple_assign_lhs (use_stmt
));
3383 while (!worklist
.is_empty ());
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. */
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
)),
3418 TYPE_SIZE (TREE_TYPE (TREE_TYPE (lhs
))),
3419 size_binop (EXACT_DIV_EXPR
,
3420 TREE_OPERAND (bfr
, 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
)),
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
),
3438 gimple_set_location (new_stmt
, loc
);
3439 gsi_insert_before (gsi
, new_stmt
, GSI_SAME_STMT
);
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
),
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. */
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
);
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. */
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
)];
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. */
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}
3512 // v_x = {e0+e1, e2+e3, e0+e1, e2+e3}
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
3528 - v_out is created by selecting from duplicated lanes. */
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
))
3552 /* Don't analyse sequences with many lanes. */
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
)
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
)
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)
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
)
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
)
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
)
3605 if (gimple_assign_rhs_code (v_1_stmt
) != VEC_PERM_EXPR
3606 || gimple_assign_rhs_code (v_2_stmt
) != VEC_PERM_EXPR
)
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
))
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
))
3625 if (nelts
!= v_1_nelts
|| nelts
!= v_2_nelts
)
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). */
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
))
3652 /* Add to narrowed selector. */
3653 new_sel_perm
.quick_push (l
+ offs
* nelts
);
3655 /* Mark lane as used. */
3659 /* Count how many lanes are need. */
3660 unsigned int cnt
= 0;
3661 for (unsigned int i
= 0; i
< nelts
; i
++)
3664 /* If more than (nelts/2) lanes are needed, skip the sequence. */
3665 if (cnt
> nelts
/ 2)
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))
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
);
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");
3700 /* Reduce the lane consumption of a simplifiable vec perm sequence. */
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
);
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. */
3728 can_blend_vec_perm_simplify_seqs_p (vec_perm_simplify_seq seq1
,
3729 vec_perm_simplify_seq seq2
,
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
)
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
)))
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
))))
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
)
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
)
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
)))
3793 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3794 fprintf (dump_file
, "Found vec perm simplify sequence pair.\n");
3799 /* Calculate the permutations for blending the two given vec permute
3800 sequences. This may fail if the resulting permutation is not
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
)
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
));
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. */
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
;
3850 /* If the lane is not allocated, we need to do that now. */
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. */
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))
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
;
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
));
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
);
3904 unsigned int sel_new
;
3905 sel_new
= seq2_stmt_sel_perm
[j
].to_constant ();
3911 /* This should not happen. Test anyway to guarantee correctness. */
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))
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))
3938 /* Blend the two given simplifiable vec permute sequences using the
3939 given permutations. */
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. */
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. */
4023 process_vec_perm_simplify_seq_list (vec
<vec_perm_simplify_seq
> *l
)
4026 vec_perm_simplify_seq seq1
, seq2
;
4031 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4032 fprintf (dump_file
, "\nProcessing %u vec perm simplify sequences.\n",
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)
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
,
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
,
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
);
4073 /* We don't need to call l->remove for seq1. */
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. */
4086 process_vec_perm_simplify_seq_list (l
);
4088 l
->quick_push (seq
);
4091 /* Main entry point for the forward propagation and statement combine
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
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);
4123 bool gate (function
*) final override
{ return flag_tree_forwprop
; }
4124 unsigned int execute (function
*) final override
;
4127 /* Determines whether the pass instance should set PROP_last_full_fold. */
4129 }; // class pass_forwprop
4132 pass_forwprop::execute (function
*fun
)
4134 unsigned int todoflags
= 0;
4136 cfg_changed
= false;
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
,
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
;
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
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
]);
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. */
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
)))
4196 /* Record degenerate PHIs in the lattice. */
4197 for (gphi_iterator si
= gsi_start_phis (bb
); !gsi_end_p (si
);
4200 gphi
*phi
= si
.phi ();
4201 tree res
= gimple_phi_result (phi
);
4202 if (virtual_operand_p (res
))
4205 tree first
= NULL_TREE
;
4206 bool all_same
= true;
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
)
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
4223 tree use
= PHI_ARG_DEF_FROM_EDGE (phi
, e
);
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. */
4231 else if (! operand_equal_p (first
, use
, 0))
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
);
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
);
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
);
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));
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);
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
4309 build1_loc (gimple_location (stmt
),
4310 ADDR_EXPR
, TREE_TYPE (rhs
),
4311 fold_build2 (MEM_REF
,
4312 TREE_TYPE (TREE_TYPE (rhs
)),
4314 fold_convert (ptr_type_node
,
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
);
4326 if (gimple_assign_rhs_code (stmt
) == POINTER_PLUS_EXPR
)
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
))
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
)
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
);
4373 tree new_rhs
= build1 (gimple_assign_rhs_code (use_stmt
),
4374 TREE_TYPE (TREE_TYPE (rhs
)),
4375 unshare_expr (rhs
));
4377 = gimple_build_assign (gimple_assign_lhs (use_stmt
),
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);
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
;
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
)))
4420 && (TREE_CODE (gimple_assign_lhs (use_stmt
))
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
4469 TREE_OPERAND (gimple_assign_rhs1
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
);
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
))
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
;
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
;
4519 if (ci
< CONSTRUCTOR_NELTS (rhs
))
4520 new_rhs
= CONSTRUCTOR_ELT (rhs
, ci
)->value
;
4522 new_rhs
= build_zero_cst (elt_t
);
4523 tree new_lhs
= build3 (BIT_FIELD_REF
,
4525 unshare_expr (use_lhs
),
4526 bitsize_int (elt_w
),
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);
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
,
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;
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;
4600 && is_gimple_assign (stmt
)
4601 && gimple_assign_rhs_code (stmt
) == ADDR_EXPR
)
4602 recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt
));
4604 && can_make_abnormal_goto
4605 && !stmt_can_make_abnormal_goto (stmt
))
4606 bitmap_set_bit (need_ab_cleanup
, bb
->index
);
4611 gimple
*orig_stmt
= stmt
= gsi_stmt (gsi
);
4612 bool was_noreturn
= (is_gimple_call (stmt
)
4613 && gimple_call_noreturn_p (stmt
));
4616 auto_vec
<tree
, 8> uses
;
4617 FOR_EACH_SSA_USE_OPERAND (usep
, stmt
, iter
, SSA_OP_USE
)
4619 uses
.quick_push (USE_FROM_PTR (usep
));
4621 if (fold_stmt (&gsi
, fwprop_ssa_val
, simple_dce_worklist
))
4624 stmt
= gsi_stmt (gsi
);
4625 /* Cleanup the CFG if we simplified a condition to
4627 if (gcond
*cond
= dyn_cast
<gcond
*> (stmt
))
4628 if (gimple_cond_true_p (cond
)
4629 || gimple_cond_false_p (cond
))
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
);
4645 && is_gimple_call (stmt
) && gimple_call_noreturn_p (stmt
))
4646 to_fixup
.safe_push (stmt
);
4648 substituted_p
= false;
4651 switch (gimple_code (stmt
))
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
)
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)
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
))
4673 else if (code
== VEC_PERM_EXPR
)
4675 int did_something
= simplify_permutation (&gsi
);
4676 if (did_something
== 2)
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
);
4691 changed
= simplify_gimple_switch (as_a
<gswitch
*> (stmt
),
4697 int did_something
= forward_propagate_into_gimple_cond
4698 (as_a
<gcond
*> (stmt
));
4699 if (did_something
== 2)
4701 changed
= did_something
!= 0;
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
);
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
))
4724 if (gsi_end_p (gsi
))
4725 gsi
= gsi_start_bb (bb
);
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
)
4745 if (TREE_CODE (rhs
) == SSA_NAME
)
4746 val
= fwprop_ssa_val (rhs
);
4747 else if (is_gimple_min_invariant (rhs
))
4749 /* If we can propagate the lattice-value mark the
4750 stmt for removal. */
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
))
4772 tree val
= fwprop_ssa_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)
4787 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
4788 e
->flags
|= EDGE_EXECUTABLE
;
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);
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. */
4827 gimple
*stmt
= SSA_NAME_DEF_STMT (def
);
4831 /* Wipe other queued stmts that do not have SSA defs. */
4832 while (!to_remove
.is_empty())
4834 gimple
*stmt
= to_remove
.pop ();
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
);
4864 if (src
&& dest
&& (e
= find_edge (src
, dest
)))
4866 free_dominance_info (CDI_DOMINATORS
);
4872 if (get_range_query (fun
) != get_global_range_query ())
4873 disable_ranger (fun
);
4876 todoflags
|= TODO_cleanup_cfg
;
4884 make_pass_forwprop (gcc::context
*ctxt
)
4886 return new pass_forwprop (ctxt
);