1 /* Helpers for the autogenerated gimple-match.cc file.
2 Copyright (C) 2023-2024 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
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"
30 #include "vec-perm-indices.h"
31 #include "fold-const.h"
32 #include "fold-const-call.h"
33 #include "stor-layout.h"
34 #include "gimple-iterator.h"
35 #include "gimple-fold.h"
39 #include "gimple-match.h"
40 #include "tree-pass.h"
41 #include "internal-fn.h"
42 #include "case-cfn-macros.h"
44 #include "optabs-tree.h"
48 #include "gimple-range.h"
49 #include "langhooks.h"
51 tree (*mprts_hook
) (gimple_match_op
*);
53 extern bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
54 code_helper
, tree
, tree
);
55 extern bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
56 code_helper
, tree
, tree
, tree
);
57 extern bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
58 code_helper
, tree
, tree
, tree
, tree
);
59 extern bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
60 code_helper
, tree
, tree
, tree
, tree
, tree
);
61 extern bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
62 code_helper
, tree
, tree
, tree
, tree
, tree
, tree
);
63 extern bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
64 code_helper
, tree
, tree
, tree
, tree
, tree
, tree
,
66 extern bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
67 code_helper
, tree
, tree
, tree
, tree
, tree
, tree
,
70 /* Functions that are needed by gimple-match but that are exported and used in
71 other places in the compiler. */
73 tree
gimple_simplify (enum tree_code
, tree
, tree
, gimple_seq
*,
75 tree
gimple_simplify (enum tree_code
, tree
, tree
, tree
, gimple_seq
*,
77 tree
gimple_simplify (enum tree_code
, tree
, tree
, tree
, tree
, gimple_seq
*,
79 tree
gimple_simplify (combined_fn
, tree
, tree
, gimple_seq
*,
81 tree
gimple_simplify (combined_fn
, tree
, tree
, tree
, gimple_seq
*,
83 tree
gimple_simplify (combined_fn
, tree
, tree
, tree
, tree
, gimple_seq
*,
86 tree
do_valueize (tree
, tree (*)(tree
), bool &);
87 tree
do_valueize (tree (*)(tree
), tree
);
89 /* Forward declarations of the private auto-generated matchers.
90 They expect valueized operands in canonical order and do not
91 perform simplification of all-constant operands. */
93 static bool gimple_resimplify1 (gimple_seq
*, gimple_match_op
*, tree (*)(tree
));
94 static bool gimple_resimplify2 (gimple_seq
*, gimple_match_op
*, tree (*)(tree
));
95 static bool gimple_resimplify3 (gimple_seq
*, gimple_match_op
*, tree (*)(tree
));
96 static bool gimple_resimplify4 (gimple_seq
*, gimple_match_op
*, tree (*)(tree
));
97 static bool gimple_resimplify5 (gimple_seq
*, gimple_match_op
*, tree (*)(tree
));
98 static bool gimple_resimplify6 (gimple_seq
*, gimple_match_op
*, tree (*)(tree
));
99 static bool gimple_resimplify7 (gimple_seq
*, gimple_match_op
*, tree (*)(tree
));
101 /* Match and simplify the toplevel valueized operation THIS.
102 Replaces THIS with a simplified and/or canonicalized result and
103 returns whether any change was made. */
106 gimple_match_op::resimplify (gimple_seq
*seq
, tree (*valueize
)(tree
))
111 return gimple_resimplify1 (seq
, this, valueize
);
113 return gimple_resimplify2 (seq
, this, valueize
);
115 return gimple_resimplify3 (seq
, this, valueize
);
117 return gimple_resimplify4 (seq
, this, valueize
);
119 return gimple_resimplify5 (seq
, this, valueize
);
121 return gimple_resimplify6 (seq
, this, valueize
);
123 return gimple_resimplify7 (seq
, this, valueize
);
129 /* Return whether T is a constant that we'll dispatch to fold to
130 evaluate fully constant expressions. */
133 constant_for_folding (tree t
)
135 return (CONSTANT_CLASS_P (t
)
136 /* The following is only interesting to string builtins. */
137 || (TREE_CODE (t
) == ADDR_EXPR
138 && TREE_CODE (TREE_OPERAND (t
, 0)) == STRING_CST
));
141 /* Try to convert conditional operation ORIG_OP into an IFN_COND_*
142 operation. Return true on success, storing the new operation in NEW_OP. */
145 convert_conditional_op (gimple_match_op
*orig_op
,
146 gimple_match_op
*new_op
)
149 if (orig_op
->code
.is_tree_code ())
150 ifn
= get_conditional_internal_fn ((tree_code
) orig_op
->code
);
153 auto cfn
= combined_fn (orig_op
->code
);
154 if (!internal_fn_p (cfn
))
156 ifn
= get_conditional_internal_fn (as_internal_fn (cfn
));
160 unsigned int num_ops
= orig_op
->num_ops
;
161 unsigned int num_cond_ops
= 2;
162 if (orig_op
->cond
.len
)
164 /* Add the length and bias parameters. */
165 ifn
= get_len_internal_fn (ifn
);
168 new_op
->set_op (as_combined_fn (ifn
), orig_op
->type
, num_ops
+ num_cond_ops
);
169 new_op
->ops
[0] = orig_op
->cond
.cond
;
170 for (unsigned int i
= 0; i
< num_ops
; ++i
)
171 new_op
->ops
[i
+ 1] = orig_op
->ops
[i
];
172 tree else_value
= orig_op
->cond
.else_value
;
174 else_value
= targetm
.preferred_else_value (ifn
, orig_op
->type
,
175 num_ops
, orig_op
->ops
);
176 new_op
->ops
[num_ops
+ 1] = else_value
;
177 if (orig_op
->cond
.len
)
179 new_op
->ops
[num_ops
+ 2] = orig_op
->cond
.len
;
180 new_op
->ops
[num_ops
+ 3] = orig_op
->cond
.bias
;
184 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
185 VALUEIZED to true if valueization changed OP. */
188 do_valueize (tree op
, tree (*valueize
)(tree
), bool &valueized
)
190 if (valueize
&& TREE_CODE (op
) == SSA_NAME
)
192 tree tem
= valueize (op
);
193 if (tem
&& tem
!= op
)
202 /* If in GIMPLE the operation described by RES_OP should be single-rhs,
203 build a GENERIC tree for that expression and update RES_OP accordingly. */
206 maybe_build_generic_op (gimple_match_op
*res_op
)
208 tree_code code
= (tree_code
) res_op
->code
;
214 case VIEW_CONVERT_EXPR
:
215 val
= build1 (code
, res_op
->type
, res_op
->ops
[0]);
216 res_op
->set_value (val
);
219 val
= build3 (code
, res_op
->type
, res_op
->ops
[0], res_op
->ops
[1],
221 REF_REVERSE_STORAGE_ORDER (val
) = res_op
->reverse
;
222 res_op
->set_value (val
);
228 /* Try to build RES_OP, which is known to be a call to FN. Return null
229 if the target doesn't support the function. */
232 build_call_internal (internal_fn fn
, gimple_match_op
*res_op
)
234 if (direct_internal_fn_p (fn
))
236 tree_pair types
= direct_internal_fn_types (fn
, res_op
->type
,
238 if (!direct_internal_fn_supported_p (fn
, types
, OPTIMIZE_FOR_BOTH
))
248 /* For these 6 builtins large/huge _BitInt operand is ok
249 before bitint lowering pass. */
250 if (res_op
->num_ops
>= 1
251 && TREE_CODE (TREE_TYPE (res_op
->ops
[0])) == BITINT_TYPE
252 && (TYPE_PRECISION (TREE_TYPE (res_op
->ops
[0]))
253 > MAX_FIXED_MODE_SIZE
)
255 && (cfun
->curr_properties
& PROP_gimple_lbitint
) == 0)
264 return gimple_build_call_internal (fn
, res_op
->num_ops
,
265 res_op
->op_or_null (0),
266 res_op
->op_or_null (1),
267 res_op
->op_or_null (2),
268 res_op
->op_or_null (3),
269 res_op
->op_or_null (4),
270 res_op
->op_or_null (5),
271 res_op
->op_or_null (6));
274 /* RES_OP is the result of a simplification. If it is conditional,
275 try to replace it with the equivalent UNCOND form, such as an
276 IFN_COND_* call or a VEC_COND_EXPR. Also try to resimplify the
277 result of the replacement if appropriate, adding any new statements to
278 SEQ and using VALUEIZE as the valueization function. Return true if
279 this resimplification occurred and resulted in at least one change. */
282 maybe_resimplify_conditional_op (gimple_seq
*seq
, gimple_match_op
*res_op
,
283 tree (*valueize
) (tree
))
285 if (!res_op
->cond
.cond
)
288 if (!res_op
->cond
.else_value
289 && res_op
->code
.is_tree_code ())
291 /* The "else" value doesn't matter. If the "then" value is a
292 gimple value, just use it unconditionally. This isn't a
293 simplification in itself, since there was no operation to
294 build in the first place. */
295 if (gimple_simplified_result_is_gimple_val (res_op
))
297 res_op
->cond
.cond
= NULL_TREE
;
301 /* Likewise if the operation would not trap. */
302 bool honor_trapv
= (INTEGRAL_TYPE_P (res_op
->type
)
303 && TYPE_OVERFLOW_TRAPS (res_op
->type
));
304 tree_code op_code
= (tree_code
) res_op
->code
;
307 /* COND_EXPR will trap if, and only if, the condition
308 traps and hence we have to check this. For all other operations, we
309 don't need to consider the operands. */
310 if (op_code
== COND_EXPR
)
311 op_could_trap
= generic_expr_could_trap_p (res_op
->ops
[0]);
313 op_could_trap
= operation_could_trap_p ((tree_code
) res_op
->code
,
314 FLOAT_TYPE_P (res_op
->type
),
316 res_op
->op_or_null (1));
320 res_op
->cond
.cond
= NULL_TREE
;
325 /* If the "then" value is a gimple value and the "else" value matters,
326 create a VEC_COND_EXPR between them, then see if it can be further
328 gimple_match_op new_op
;
329 if (res_op
->cond
.else_value
330 && VECTOR_TYPE_P (res_op
->type
)
331 && gimple_simplified_result_is_gimple_val (res_op
))
333 tree len
= res_op
->cond
.len
;
335 new_op
.set_op (VEC_COND_EXPR
, res_op
->type
,
336 res_op
->cond
.cond
, res_op
->ops
[0],
337 res_op
->cond
.else_value
);
339 new_op
.set_op (IFN_VCOND_MASK_LEN
, res_op
->type
,
340 res_op
->cond
.cond
, res_op
->ops
[0],
341 res_op
->cond
.else_value
,
342 res_op
->cond
.len
, res_op
->cond
.bias
);
344 return gimple_resimplify3 (seq
, res_op
, valueize
);
347 /* Otherwise try rewriting the operation as an IFN_COND_* call.
348 Again, this isn't a simplification in itself, since it's what
349 RES_OP already described. */
350 if (convert_conditional_op (res_op
, &new_op
))
356 /* If RES_OP is a call to a conditional internal function, try simplifying
357 the associated unconditional operation and using the result to build
358 a new conditional operation. For example, if RES_OP is:
360 IFN_COND_ADD (COND, A, B, ELSE)
362 try simplifying (plus A B) and using the result to build a replacement
363 for the whole IFN_COND_ADD.
365 Return true if this approach led to a simplification, otherwise leave
366 RES_OP unchanged (and so suitable for other simplifications). When
367 returning true, add any new statements to SEQ and use VALUEIZE as the
368 valueization function.
370 RES_OP is known to be a call to IFN. */
373 try_conditional_simplification (internal_fn ifn
, gimple_match_op
*res_op
,
374 gimple_seq
*seq
, tree (*valueize
) (tree
))
377 tree_code code
= conditional_internal_fn_code (ifn
);
378 int len_index
= internal_fn_len_index (ifn
);
379 if (code
!= ERROR_MARK
)
383 ifn
= get_unconditional_internal_fn (ifn
);
386 op
= as_combined_fn (ifn
);
389 unsigned int num_ops
= res_op
->num_ops
;
390 /* num_cond_ops = 2 for COND_ADD (MASK and ELSE)
391 wheras num_cond_ops = 4 for COND_LEN_ADD (MASK, ELSE, LEN and BIAS). */
392 unsigned int num_cond_ops
= len_index
< 0 ? 2 : 4;
394 = len_index
< 0 ? res_op
->ops
[num_ops
- 1] : res_op
->ops
[num_ops
- 3];
395 tree len
= len_index
< 0 ? NULL_TREE
: res_op
->ops
[num_ops
- 2];
396 tree bias
= len_index
< 0 ? NULL_TREE
: res_op
->ops
[num_ops
- 1];
397 gimple_match_op
cond_op (gimple_match_cond (res_op
->ops
[0],
398 else_value
, len
, bias
),
399 op
, res_op
->type
, num_ops
- num_cond_ops
);
401 memcpy (cond_op
.ops
, res_op
->ops
+ 1, (num_ops
- 1) * sizeof *cond_op
.ops
);
402 switch (num_ops
- num_cond_ops
)
405 if (!gimple_resimplify1 (seq
, &cond_op
, valueize
))
409 if (!gimple_resimplify2 (seq
, &cond_op
, valueize
))
413 if (!gimple_resimplify3 (seq
, &cond_op
, valueize
))
420 maybe_resimplify_conditional_op (seq
, res_op
, valueize
);
424 /* Helper for the autogenerated code, valueize OP. */
427 do_valueize (tree (*valueize
)(tree
), tree op
)
429 if (valueize
&& TREE_CODE (op
) == SSA_NAME
)
431 tree tem
= valueize (op
);
438 /* Push the exploded expression described by RES_OP as a statement to
439 SEQ if necessary and return a gimple value denoting the value of the
440 expression. If RES is not NULL then the result will be always RES
441 and even gimple values are pushed to SEQ. */
444 maybe_push_res_to_seq (gimple_match_op
*res_op
, gimple_seq
*seq
, tree res
)
446 tree
*ops
= res_op
->ops
;
447 unsigned num_ops
= res_op
->num_ops
;
449 /* The caller should have converted conditional operations into an UNCOND
450 form and resimplified as appropriate. The conditional form only
451 survives this far if that conversion failed. */
452 if (res_op
->cond
.cond
)
455 if (res_op
->code
.is_tree_code ())
458 && gimple_simplified_result_is_gimple_val (res_op
))
462 tree tem
= mprts_hook (res_op
);
471 /* Play safe and do not allow abnormals to be mentioned in
472 newly created statements. */
473 for (unsigned int i
= 0; i
< num_ops
; ++i
)
474 if (TREE_CODE (ops
[i
]) == SSA_NAME
475 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[i
]))
478 if (num_ops
> 0 && COMPARISON_CLASS_P (ops
[0]))
479 for (unsigned int i
= 0; i
< 2; ++i
)
480 if (TREE_CODE (TREE_OPERAND (ops
[0], i
)) == SSA_NAME
481 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops
[0], i
)))
484 if (res_op
->code
.is_tree_code ())
486 auto code
= tree_code (res_op
->code
);
489 if (gimple_in_ssa_p (cfun
))
490 res
= make_ssa_name (res_op
->type
);
492 res
= create_tmp_reg (res_op
->type
);
494 maybe_build_generic_op (res_op
);
495 gimple
*new_stmt
= gimple_build_assign (res
, code
,
496 res_op
->op_or_null (0),
497 res_op
->op_or_null (1),
498 res_op
->op_or_null (2));
499 gimple_seq_add_stmt_without_update (seq
, new_stmt
);
504 gcc_assert (num_ops
!= 0);
505 auto fn
= combined_fn (res_op
->code
);
506 gcall
*new_stmt
= NULL
;
507 if (internal_fn_p (fn
))
509 /* Generate the given function if we can. */
510 internal_fn ifn
= as_internal_fn (fn
);
511 new_stmt
= build_call_internal (ifn
, res_op
);
517 /* Find the function we want to call. */
518 tree decl
= builtin_decl_implicit (as_builtin_fn (fn
));
522 /* We can't and should not emit calls to non-const functions. */
523 if (!(flags_from_decl_or_type (decl
) & ECF_CONST
))
526 new_stmt
= gimple_build_call (decl
, num_ops
,
527 res_op
->op_or_null (0),
528 res_op
->op_or_null (1),
529 res_op
->op_or_null (2),
530 res_op
->op_or_null (3),
531 res_op
->op_or_null (4));
535 if (gimple_in_ssa_p (cfun
))
536 res
= make_ssa_name (res_op
->type
);
538 res
= create_tmp_reg (res_op
->type
);
540 gimple_call_set_lhs (new_stmt
, res
);
541 gimple_seq_add_stmt_without_update (seq
, new_stmt
);
547 /* Public API overloads follow for operation being tree_code or
548 built_in_function and for one to three operands or arguments.
549 They return NULL_TREE if nothing could be simplified or
550 the resulting simplified value with parts pushed to SEQ.
551 If SEQ is NULL then if the simplification needs to create
552 new stmts it will fail. If VALUEIZE is non-NULL then all
553 SSA names will be valueized using that hook prior to
554 applying simplifications. */
559 gimple_simplify (enum tree_code code
, tree type
,
561 gimple_seq
*seq
, tree (*valueize
)(tree
))
563 if (constant_for_folding (op0
))
565 tree res
= const_unop (code
, type
, op0
);
567 && CONSTANT_CLASS_P (res
))
571 gimple_match_op res_op
;
572 if (!gimple_simplify (&res_op
, seq
, valueize
, code
, type
, op0
))
574 return maybe_push_res_to_seq (&res_op
, seq
);
580 gimple_simplify (enum tree_code code
, tree type
,
582 gimple_seq
*seq
, tree (*valueize
)(tree
))
584 if (constant_for_folding (op0
) && constant_for_folding (op1
))
586 tree res
= const_binop (code
, type
, op0
, op1
);
588 && CONSTANT_CLASS_P (res
))
592 /* Canonicalize operand order both for matching and fallback stmt
594 if ((commutative_tree_code (code
)
595 || TREE_CODE_CLASS (code
) == tcc_comparison
)
596 && tree_swap_operands_p (op0
, op1
))
598 std::swap (op0
, op1
);
599 if (TREE_CODE_CLASS (code
) == tcc_comparison
)
600 code
= swap_tree_comparison (code
);
603 gimple_match_op res_op
;
604 if (!gimple_simplify (&res_op
, seq
, valueize
, code
, type
, op0
, op1
))
606 return maybe_push_res_to_seq (&res_op
, seq
);
612 gimple_simplify (enum tree_code code
, tree type
,
613 tree op0
, tree op1
, tree op2
,
614 gimple_seq
*seq
, tree (*valueize
)(tree
))
616 if (constant_for_folding (op0
) && constant_for_folding (op1
)
617 && constant_for_folding (op2
))
619 tree res
= fold_ternary
/*_to_constant */ (code
, type
, op0
, op1
, op2
);
621 && CONSTANT_CLASS_P (res
))
625 /* Canonicalize operand order both for matching and fallback stmt
627 if (commutative_ternary_tree_code (code
)
628 && tree_swap_operands_p (op0
, op1
))
629 std::swap (op0
, op1
);
631 gimple_match_op res_op
;
632 if (!gimple_simplify (&res_op
, seq
, valueize
, code
, type
, op0
, op1
, op2
))
634 return maybe_push_res_to_seq (&res_op
, seq
);
637 /* Builtin or internal function with one argument. */
640 gimple_simplify (combined_fn fn
, tree type
,
642 gimple_seq
*seq
, tree (*valueize
)(tree
))
644 if (constant_for_folding (arg0
))
646 tree res
= fold_const_call (fn
, type
, arg0
);
647 if (res
&& CONSTANT_CLASS_P (res
))
651 gimple_match_op res_op
;
652 if (!gimple_simplify (&res_op
, seq
, valueize
, fn
, type
, arg0
))
654 return maybe_push_res_to_seq (&res_op
, seq
);
657 /* Builtin or internal function with two arguments. */
660 gimple_simplify (combined_fn fn
, tree type
,
661 tree arg0
, tree arg1
,
662 gimple_seq
*seq
, tree (*valueize
)(tree
))
664 if (constant_for_folding (arg0
)
665 && constant_for_folding (arg1
))
667 tree res
= fold_const_call (fn
, type
, arg0
, arg1
);
668 if (res
&& CONSTANT_CLASS_P (res
))
672 gimple_match_op res_op
;
673 if (!gimple_simplify (&res_op
, seq
, valueize
, fn
, type
, arg0
, arg1
))
675 return maybe_push_res_to_seq (&res_op
, seq
);
678 /* Builtin or internal function with three arguments. */
681 gimple_simplify (combined_fn fn
, tree type
,
682 tree arg0
, tree arg1
, tree arg2
,
683 gimple_seq
*seq
, tree (*valueize
)(tree
))
685 if (constant_for_folding (arg0
)
686 && constant_for_folding (arg1
)
687 && constant_for_folding (arg2
))
689 tree res
= fold_const_call (fn
, type
, arg0
, arg1
, arg2
);
690 if (res
&& CONSTANT_CLASS_P (res
))
694 gimple_match_op res_op
;
695 if (!gimple_simplify (&res_op
, seq
, valueize
, fn
, type
, arg0
, arg1
, arg2
))
697 return maybe_push_res_to_seq (&res_op
, seq
);
700 /* Common subroutine of gimple_extract_op and gimple_simplify. Try to
701 describe STMT in RES_OP, returning true on success. Before recording
704 - VALUEIZE_CONDITION for a COND_EXPR condition
705 - VALUEIZE_OP for every other top-level operand
707 Both routines take a tree argument and returns a tree. */
709 template<typename ValueizeOp
, typename ValueizeCondition
>
711 gimple_extract (gimple
*stmt
, gimple_match_op
*res_op
,
712 ValueizeOp valueize_op
,
713 ValueizeCondition valueize_condition
)
715 switch (gimple_code (stmt
))
719 enum tree_code code
= gimple_assign_rhs_code (stmt
);
720 tree type
= TREE_TYPE (gimple_assign_lhs (stmt
));
721 switch (gimple_assign_rhs_class (stmt
))
723 case GIMPLE_SINGLE_RHS
:
724 if (code
== REALPART_EXPR
725 || code
== IMAGPART_EXPR
726 || code
== VIEW_CONVERT_EXPR
)
728 tree op0
= TREE_OPERAND (gimple_assign_rhs1 (stmt
), 0);
729 res_op
->set_op (code
, type
, valueize_op (op0
));
732 else if (code
== BIT_FIELD_REF
)
734 tree rhs1
= gimple_assign_rhs1 (stmt
);
735 tree op0
= valueize_op (TREE_OPERAND (rhs1
, 0));
736 res_op
->set_op (code
, type
, op0
,
737 TREE_OPERAND (rhs1
, 1),
738 TREE_OPERAND (rhs1
, 2),
739 REF_REVERSE_STORAGE_ORDER (rhs1
));
742 else if (code
== SSA_NAME
)
744 tree op0
= gimple_assign_rhs1 (stmt
);
745 res_op
->set_op (TREE_CODE (op0
), type
, valueize_op (op0
));
749 case GIMPLE_UNARY_RHS
:
751 tree rhs1
= gimple_assign_rhs1 (stmt
);
752 res_op
->set_op (code
, type
, valueize_op (rhs1
));
755 case GIMPLE_BINARY_RHS
:
757 tree rhs1
= valueize_op (gimple_assign_rhs1 (stmt
));
758 tree rhs2
= valueize_op (gimple_assign_rhs2 (stmt
));
759 res_op
->set_op (code
, type
, rhs1
, rhs2
);
762 case GIMPLE_TERNARY_RHS
:
764 tree rhs1
= gimple_assign_rhs1 (stmt
);
765 if (code
== COND_EXPR
&& COMPARISON_CLASS_P (rhs1
))
766 rhs1
= valueize_condition (rhs1
);
768 rhs1
= valueize_op (rhs1
);
769 tree rhs2
= valueize_op (gimple_assign_rhs2 (stmt
));
770 tree rhs3
= valueize_op (gimple_assign_rhs3 (stmt
));
771 res_op
->set_op (code
, type
, rhs1
, rhs2
, rhs3
);
781 /* ??? This way we can't simplify calls with side-effects. */
782 if (gimple_call_lhs (stmt
) != NULL_TREE
783 && gimple_call_num_args (stmt
) >= 1
784 && gimple_call_num_args (stmt
) <= 7)
787 if (gimple_call_internal_p (stmt
))
788 cfn
= as_combined_fn (gimple_call_internal_fn (stmt
));
791 tree fn
= gimple_call_fn (stmt
);
795 fn
= valueize_op (fn
);
796 if (TREE_CODE (fn
) != ADDR_EXPR
797 || TREE_CODE (TREE_OPERAND (fn
, 0)) != FUNCTION_DECL
)
800 tree decl
= TREE_OPERAND (fn
, 0);
801 if (DECL_BUILT_IN_CLASS (decl
) != BUILT_IN_NORMAL
802 || !gimple_builtin_call_types_compatible_p (stmt
, decl
))
805 cfn
= as_combined_fn (DECL_FUNCTION_CODE (decl
));
808 unsigned int num_args
= gimple_call_num_args (stmt
);
809 res_op
->set_op (cfn
, TREE_TYPE (gimple_call_lhs (stmt
)), num_args
);
810 for (unsigned i
= 0; i
< num_args
; ++i
)
811 res_op
->ops
[i
] = valueize_op (gimple_call_arg (stmt
, i
));
818 tree lhs
= valueize_op (gimple_cond_lhs (stmt
));
819 tree rhs
= valueize_op (gimple_cond_rhs (stmt
));
820 res_op
->set_op (gimple_cond_code (stmt
), boolean_type_node
, lhs
, rhs
);
831 /* Try to describe STMT in RES_OP, returning true on success.
832 For GIMPLE_CONDs, describe the condition that is being tested.
833 For GIMPLE_ASSIGNs, describe the rhs of the assignment.
834 For GIMPLE_CALLs, describe the call. */
837 gimple_extract_op (gimple
*stmt
, gimple_match_op
*res_op
)
839 auto nop
= [](tree op
) { return op
; };
840 return gimple_extract (stmt
, res_op
, nop
, nop
);
843 /* The main STMT based simplification entry. It is used by the fold_stmt
844 and the fold_stmt_to_constant APIs. */
847 gimple_simplify (gimple
*stmt
, gimple_match_op
*res_op
, gimple_seq
*seq
,
848 tree (*valueize
)(tree
), tree (*top_valueize
)(tree
))
850 bool valueized
= false;
851 auto valueize_op
= [&](tree op
)
853 return do_valueize (op
, top_valueize
, valueized
);
855 auto valueize_condition
= [&](tree op
) -> tree
857 bool cond_valueized
= false;
858 tree lhs
= do_valueize (TREE_OPERAND (op
, 0), top_valueize
,
860 tree rhs
= do_valueize (TREE_OPERAND (op
, 1), top_valueize
,
862 gimple_match_op
res_op2 (res_op
->cond
, TREE_CODE (op
),
863 TREE_TYPE (op
), lhs
, rhs
);
864 if ((gimple_resimplify2 (seq
, &res_op2
, valueize
)
866 && res_op2
.code
.is_tree_code ())
868 auto code
= tree_code (res_op2
.code
);
869 if (TREE_CODE_CLASS (code
) == tcc_comparison
)
872 return build2 (code
, TREE_TYPE (op
),
873 res_op2
.ops
[0], res_op2
.ops
[1]);
875 else if (code
== SSA_NAME
876 || code
== INTEGER_CST
877 || code
== VECTOR_CST
)
880 return res_op2
.ops
[0];
883 return valueize_op (op
);
886 if (!gimple_extract (stmt
, res_op
, valueize_op
, valueize_condition
))
889 if (res_op
->code
.is_internal_fn ())
891 internal_fn ifn
= internal_fn (res_op
->code
);
892 if (try_conditional_simplification (ifn
, res_op
, seq
, valueize
))
898 && res_op
->resimplify (seq
, valueize
))
904 /* Helper that matches and simplifies the toplevel result from
905 a gimple_simplify run (where we don't want to build
906 a stmt in case it's used in in-place folding). Replaces
907 RES_OP with a simplified and/or canonicalized result and
908 returns whether any change was made. */
911 gimple_resimplify1 (gimple_seq
*seq
, gimple_match_op
*res_op
,
912 tree (*valueize
)(tree
))
914 if (constant_for_folding (res_op
->ops
[0]))
916 tree tem
= NULL_TREE
;
917 if (res_op
->code
.is_tree_code ())
919 auto code
= tree_code (res_op
->code
);
920 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code
))
921 && TREE_CODE_LENGTH (code
) == 1)
922 tem
= const_unop (code
, res_op
->type
, res_op
->ops
[0]);
925 tem
= fold_const_call (combined_fn (res_op
->code
), res_op
->type
,
928 && CONSTANT_CLASS_P (tem
))
930 if (TREE_OVERFLOW_P (tem
))
931 tem
= drop_tree_overflow (tem
);
932 res_op
->set_value (tem
);
933 maybe_resimplify_conditional_op (seq
, res_op
, valueize
);
938 /* Limit recursion, there are cases like PR80887 and others, for
939 example when value-numbering presents us with unfolded expressions
940 that we are really not prepared to handle without eventual
941 oscillation like ((_50 + 0) + 8) where _50 gets mapped to _50
942 itself as available expression. */
943 static unsigned depth
;
946 if (dump_file
&& (dump_flags
& TDF_FOLDING
))
947 fprintf (dump_file
, "Aborting expression simplification due to "
953 gimple_match_op
res_op2 (*res_op
);
954 if (gimple_simplify (&res_op2
, seq
, valueize
,
955 res_op
->code
, res_op
->type
, res_op
->ops
[0]))
963 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
969 /* Helper that matches and simplifies the toplevel result from
970 a gimple_simplify run (where we don't want to build
971 a stmt in case it's used in in-place folding). Replaces
972 RES_OP with a simplified and/or canonicalized result and
973 returns whether any change was made. */
976 gimple_resimplify2 (gimple_seq
*seq
, gimple_match_op
*res_op
,
977 tree (*valueize
)(tree
))
979 if (constant_for_folding (res_op
->ops
[0])
980 && constant_for_folding (res_op
->ops
[1]))
982 tree tem
= NULL_TREE
;
983 if (res_op
->code
.is_tree_code ())
985 auto code
= tree_code (res_op
->code
);
986 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code
))
987 && TREE_CODE_LENGTH (code
) == 2)
988 tem
= const_binop (code
, res_op
->type
,
989 res_op
->ops
[0], res_op
->ops
[1]);
992 tem
= fold_const_call (combined_fn (res_op
->code
), res_op
->type
,
993 res_op
->ops
[0], res_op
->ops
[1]);
995 && CONSTANT_CLASS_P (tem
))
997 if (TREE_OVERFLOW_P (tem
))
998 tem
= drop_tree_overflow (tem
);
999 res_op
->set_value (tem
);
1000 maybe_resimplify_conditional_op (seq
, res_op
, valueize
);
1005 /* Canonicalize operand order. */
1006 bool canonicalized
= false;
1008 = (res_op
->code
.is_tree_code ()
1009 && TREE_CODE_CLASS (tree_code (res_op
->code
)) == tcc_comparison
);
1010 if ((is_comparison
|| commutative_binary_op_p (res_op
->code
, res_op
->type
))
1011 && tree_swap_operands_p (res_op
->ops
[0], res_op
->ops
[1]))
1013 std::swap (res_op
->ops
[0], res_op
->ops
[1]);
1015 res_op
->code
= swap_tree_comparison (tree_code (res_op
->code
));
1016 canonicalized
= true;
1019 /* Limit recursion, see gimple_resimplify1. */
1020 static unsigned depth
;
1023 if (dump_file
&& (dump_flags
& TDF_FOLDING
))
1024 fprintf (dump_file
, "Aborting expression simplification due to "
1025 "deep recursion\n");
1030 gimple_match_op
res_op2 (*res_op
);
1031 if (gimple_simplify (&res_op2
, seq
, valueize
,
1032 res_op
->code
, res_op
->type
,
1033 res_op
->ops
[0], res_op
->ops
[1]))
1041 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1044 return canonicalized
;
1047 /* Helper that matches and simplifies the toplevel result from
1048 a gimple_simplify run (where we don't want to build
1049 a stmt in case it's used in in-place folding). Replaces
1050 RES_OP with a simplified and/or canonicalized result and
1051 returns whether any change was made. */
1054 gimple_resimplify3 (gimple_seq
*seq
, gimple_match_op
*res_op
,
1055 tree (*valueize
)(tree
))
1057 if (constant_for_folding (res_op
->ops
[0])
1058 && constant_for_folding (res_op
->ops
[1])
1059 && constant_for_folding (res_op
->ops
[2]))
1061 tree tem
= NULL_TREE
;
1062 if (res_op
->code
.is_tree_code ())
1064 auto code
= tree_code (res_op
->code
);
1065 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code
))
1066 && TREE_CODE_LENGTH (code
) == 3)
1067 tem
= fold_ternary
/*_to_constant*/ (code
, res_op
->type
,
1068 res_op
->ops
[0], res_op
->ops
[1],
1072 tem
= fold_const_call (combined_fn (res_op
->code
), res_op
->type
,
1073 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2]);
1074 if (tem
!= NULL_TREE
1075 && CONSTANT_CLASS_P (tem
))
1077 if (TREE_OVERFLOW_P (tem
))
1078 tem
= drop_tree_overflow (tem
);
1079 res_op
->set_value (tem
);
1080 maybe_resimplify_conditional_op (seq
, res_op
, valueize
);
1085 /* Canonicalize operand order. */
1086 bool canonicalized
= false;
1087 int argno
= first_commutative_argument (res_op
->code
, res_op
->type
);
1089 && tree_swap_operands_p (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]))
1091 std::swap (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]);
1092 canonicalized
= true;
1095 /* Limit recursion, see gimple_resimplify1. */
1096 static unsigned depth
;
1099 if (dump_file
&& (dump_flags
& TDF_FOLDING
))
1100 fprintf (dump_file
, "Aborting expression simplification due to "
1101 "deep recursion\n");
1106 gimple_match_op
res_op2 (*res_op
);
1107 if (gimple_simplify (&res_op2
, seq
, valueize
,
1108 res_op
->code
, res_op
->type
,
1109 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2]))
1117 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1120 return canonicalized
;
1123 /* Helper that matches and simplifies the toplevel result from
1124 a gimple_simplify run (where we don't want to build
1125 a stmt in case it's used in in-place folding). Replaces
1126 RES_OP with a simplified and/or canonicalized result and
1127 returns whether any change was made. */
1130 gimple_resimplify4 (gimple_seq
*seq
, gimple_match_op
*res_op
,
1131 tree (*valueize
)(tree
))
1133 /* No constant folding is defined for four-operand functions. */
1135 /* Canonicalize operand order. */
1136 bool canonicalized
= false;
1137 int argno
= first_commutative_argument (res_op
->code
, res_op
->type
);
1139 && tree_swap_operands_p (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]))
1141 std::swap (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]);
1142 canonicalized
= true;
1145 /* Limit recursion, see gimple_resimplify1. */
1146 static unsigned depth
;
1149 if (dump_file
&& (dump_flags
& TDF_FOLDING
))
1150 fprintf (dump_file
, "Aborting expression simplification due to "
1151 "deep recursion\n");
1156 gimple_match_op
res_op2 (*res_op
);
1157 if (gimple_simplify (&res_op2
, seq
, valueize
,
1158 res_op
->code
, res_op
->type
,
1159 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2],
1168 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1171 return canonicalized
;
1174 /* Helper that matches and simplifies the toplevel result from
1175 a gimple_simplify run (where we don't want to build
1176 a stmt in case it's used in in-place folding). Replaces
1177 RES_OP with a simplified and/or canonicalized result and
1178 returns whether any change was made. */
1181 gimple_resimplify5 (gimple_seq
*seq
, gimple_match_op
*res_op
,
1182 tree (*valueize
)(tree
))
1184 /* No constant folding is defined for five-operand functions. */
1186 /* Canonicalize operand order. */
1187 bool canonicalized
= false;
1188 int argno
= first_commutative_argument (res_op
->code
, res_op
->type
);
1190 && tree_swap_operands_p (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]))
1192 std::swap (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]);
1193 canonicalized
= true;
1196 gimple_match_op
res_op2 (*res_op
);
1197 if (gimple_simplify (&res_op2
, seq
, valueize
,
1198 res_op
->code
, res_op
->type
,
1199 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2],
1200 res_op
->ops
[3], res_op
->ops
[4]))
1206 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1209 return canonicalized
;
1212 /* Helper that matches and simplifies the toplevel result from
1213 a gimple_simplify run (where we don't want to build
1214 a stmt in case it's used in in-place folding). Replaces
1215 RES_OP with a simplified and/or canonicalized result and
1216 returns whether any change was made. */
1219 gimple_resimplify6 (gimple_seq
*seq
, gimple_match_op
*res_op
,
1220 tree (*valueize
)(tree
))
1222 /* No constant folding is defined for six-operand functions. */
1224 /* Canonicalize operand order. */
1225 bool canonicalized
= false;
1226 int argno
= first_commutative_argument (res_op
->code
, res_op
->type
);
1228 && tree_swap_operands_p (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]))
1230 std::swap (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]);
1231 canonicalized
= true;
1234 gimple_match_op
res_op2 (*res_op
);
1235 if (gimple_simplify (&res_op2
, seq
, valueize
,
1236 res_op
->code
, res_op
->type
,
1237 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2],
1238 res_op
->ops
[3], res_op
->ops
[4], res_op
->ops
[5]))
1244 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1247 return canonicalized
;
1250 /* Helper that matches and simplifies the toplevel result from
1251 a gimple_simplify run (where we don't want to build
1252 a stmt in case it's used in in-place folding). Replaces
1253 RES_OP with a simplified and/or canonicalized result and
1254 returns whether any change was made. */
1257 gimple_resimplify7 (gimple_seq
*seq
, gimple_match_op
*res_op
,
1258 tree (*valueize
)(tree
))
1260 /* No constant folding is defined for seven-operand functions. */
1262 /* Canonicalize operand order. */
1263 bool canonicalized
= false;
1264 int argno
= first_commutative_argument (res_op
->code
, res_op
->type
);
1266 && tree_swap_operands_p (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]))
1268 std::swap (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]);
1269 canonicalized
= true;
1272 gimple_match_op
res_op2 (*res_op
);
1273 if (gimple_simplify (&res_op2
, seq
, valueize
,
1274 res_op
->code
, res_op
->type
,
1275 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2],
1276 res_op
->ops
[3], res_op
->ops
[4], res_op
->ops
[5],
1283 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1286 return canonicalized
;
1289 /* Return a canonical form for CODE when operating on TYPE. The idea
1290 is to remove redundant ways of representing the same operation so
1291 that code_helpers can be hashed and compared for equality.
1293 The only current canonicalization is to replace built-in functions
1294 with internal functions, in cases where internal-fn.def defines
1295 such an internal function.
1297 Note that the new code_helper cannot necessarily be used in place of
1298 the original code_helper. For example, the new code_helper might be
1299 an internal function that the target does not support. */
1302 canonicalize_code (code_helper code
, tree type
)
1304 if (code
.is_fn_code ())
1305 return associated_internal_fn (combined_fn (code
), type
);
1309 /* Return true if CODE is a binary operation and if CODE is commutative when
1310 operating on type TYPE. */
1313 commutative_binary_op_p (code_helper code
, tree type
)
1315 if (code
.is_tree_code ())
1316 return commutative_tree_code (tree_code (code
));
1317 auto cfn
= combined_fn (code
);
1318 return commutative_binary_fn_p (associated_internal_fn (cfn
, type
));
1321 /* Return true if CODE represents a ternary operation and if the first two
1322 operands are commutative when CODE is operating on TYPE. */
1325 commutative_ternary_op_p (code_helper code
, tree type
)
1327 if (code
.is_tree_code ())
1328 return commutative_ternary_tree_code (tree_code (code
));
1329 auto cfn
= combined_fn (code
);
1330 return commutative_ternary_fn_p (associated_internal_fn (cfn
, type
));
1333 /* If CODE is commutative in two consecutive operands, return the
1334 index of the first, otherwise return -1. */
1337 first_commutative_argument (code_helper code
, tree type
)
1339 if (code
.is_tree_code ())
1341 auto tcode
= tree_code (code
);
1342 if (commutative_tree_code (tcode
)
1343 || commutative_ternary_tree_code (tcode
))
1347 auto cfn
= combined_fn (code
);
1348 return first_commutative_argument (associated_internal_fn (cfn
, type
));
1351 /* Return true if CODE is a binary operation that is associative when
1352 operating on type TYPE. */
1355 associative_binary_op_p (code_helper code
, tree type
)
1357 if (code
.is_tree_code ())
1358 return associative_tree_code (tree_code (code
));
1359 auto cfn
= combined_fn (code
);
1360 return associative_binary_fn_p (associated_internal_fn (cfn
, type
));
1363 /* Return true if the target directly supports operation CODE on type TYPE.
1364 QUERY_TYPE acts as for optab_for_tree_code. */
1367 directly_supported_p (code_helper code
, tree type
, optab_subtype query_type
)
1369 if (code
.is_tree_code ())
1371 direct_optab optab
= optab_for_tree_code (tree_code (code
), type
,
1373 return (optab
!= unknown_optab
1374 && optab_handler (optab
, TYPE_MODE (type
)) != CODE_FOR_nothing
);
1376 gcc_assert (query_type
== optab_default
1377 || (query_type
== optab_vector
&& VECTOR_TYPE_P (type
))
1378 || (query_type
== optab_scalar
&& !VECTOR_TYPE_P (type
)));
1379 internal_fn ifn
= associated_internal_fn (combined_fn (code
), type
);
1380 return (direct_internal_fn_p (ifn
)
1381 && direct_internal_fn_supported_p (ifn
, type
, OPTIMIZE_FOR_SPEED
));
1384 /* A wrapper around the internal-fn.cc versions of get_conditional_internal_fn
1385 for a code_helper CODE operating on type TYPE. */
1388 get_conditional_internal_fn (code_helper code
, tree type
)
1390 if (code
.is_tree_code ())
1391 return get_conditional_internal_fn (tree_code (code
));
1392 auto cfn
= combined_fn (code
);
1393 return get_conditional_internal_fn (associated_internal_fn (cfn
, type
));