1 /* Helpers for the autogenerated gimple-match.cc file.
2 Copyright (C) 2023 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
))
241 return gimple_build_call_internal (fn
, res_op
->num_ops
,
242 res_op
->op_or_null (0),
243 res_op
->op_or_null (1),
244 res_op
->op_or_null (2),
245 res_op
->op_or_null (3),
246 res_op
->op_or_null (4),
247 res_op
->op_or_null (5),
248 res_op
->op_or_null (6));
251 /* RES_OP is the result of a simplification. If it is conditional,
252 try to replace it with the equivalent UNCOND form, such as an
253 IFN_COND_* call or a VEC_COND_EXPR. Also try to resimplify the
254 result of the replacement if appropriate, adding any new statements to
255 SEQ and using VALUEIZE as the valueization function. Return true if
256 this resimplification occurred and resulted in at least one change. */
259 maybe_resimplify_conditional_op (gimple_seq
*seq
, gimple_match_op
*res_op
,
260 tree (*valueize
) (tree
))
262 if (!res_op
->cond
.cond
)
265 if (!res_op
->cond
.else_value
266 && res_op
->code
.is_tree_code ())
268 /* The "else" value doesn't matter. If the "then" value is a
269 gimple value, just use it unconditionally. This isn't a
270 simplification in itself, since there was no operation to
271 build in the first place. */
272 if (gimple_simplified_result_is_gimple_val (res_op
))
274 res_op
->cond
.cond
= NULL_TREE
;
278 /* Likewise if the operation would not trap. */
279 bool honor_trapv
= (INTEGRAL_TYPE_P (res_op
->type
)
280 && TYPE_OVERFLOW_TRAPS (res_op
->type
));
281 tree_code op_code
= (tree_code
) res_op
->code
;
284 /* COND_EXPR will trap if, and only if, the condition
285 traps and hence we have to check this. For all other operations, we
286 don't need to consider the operands. */
287 if (op_code
== COND_EXPR
)
288 op_could_trap
= generic_expr_could_trap_p (res_op
->ops
[0]);
290 op_could_trap
= operation_could_trap_p ((tree_code
) res_op
->code
,
291 FLOAT_TYPE_P (res_op
->type
),
293 res_op
->op_or_null (1));
297 res_op
->cond
.cond
= NULL_TREE
;
302 /* If the "then" value is a gimple value and the "else" value matters,
303 create a VEC_COND_EXPR between them, then see if it can be further
305 gimple_match_op new_op
;
306 if (res_op
->cond
.else_value
307 && VECTOR_TYPE_P (res_op
->type
)
308 && gimple_simplified_result_is_gimple_val (res_op
))
310 new_op
.set_op (VEC_COND_EXPR
, res_op
->type
,
311 res_op
->cond
.cond
, res_op
->ops
[0],
312 res_op
->cond
.else_value
);
314 return gimple_resimplify3 (seq
, res_op
, valueize
);
317 /* Otherwise try rewriting the operation as an IFN_COND_* call.
318 Again, this isn't a simplification in itself, since it's what
319 RES_OP already described. */
320 if (convert_conditional_op (res_op
, &new_op
))
326 /* If RES_OP is a call to a conditional internal function, try simplifying
327 the associated unconditional operation and using the result to build
328 a new conditional operation. For example, if RES_OP is:
330 IFN_COND_ADD (COND, A, B, ELSE)
332 try simplifying (plus A B) and using the result to build a replacement
333 for the whole IFN_COND_ADD.
335 Return true if this approach led to a simplification, otherwise leave
336 RES_OP unchanged (and so suitable for other simplifications). When
337 returning true, add any new statements to SEQ and use VALUEIZE as the
338 valueization function.
340 RES_OP is known to be a call to IFN. */
343 try_conditional_simplification (internal_fn ifn
, gimple_match_op
*res_op
,
344 gimple_seq
*seq
, tree (*valueize
) (tree
))
347 tree_code code
= conditional_internal_fn_code (ifn
);
348 int len_index
= internal_fn_len_index (ifn
);
349 if (code
!= ERROR_MARK
)
353 ifn
= get_unconditional_internal_fn (ifn
);
356 op
= as_combined_fn (ifn
);
359 unsigned int num_ops
= res_op
->num_ops
;
360 /* num_cond_ops = 2 for COND_ADD (MASK and ELSE)
361 wheras num_cond_ops = 4 for COND_LEN_ADD (MASK, ELSE, LEN and BIAS). */
362 unsigned int num_cond_ops
= len_index
< 0 ? 2 : 4;
364 = len_index
< 0 ? res_op
->ops
[num_ops
- 1] : res_op
->ops
[num_ops
- 3];
365 tree len
= len_index
< 0 ? NULL_TREE
: res_op
->ops
[num_ops
- 2];
366 tree bias
= len_index
< 0 ? NULL_TREE
: res_op
->ops
[num_ops
- 1];
367 gimple_match_op
cond_op (gimple_match_cond (res_op
->ops
[0],
368 else_value
, len
, bias
),
369 op
, res_op
->type
, num_ops
- num_cond_ops
);
371 memcpy (cond_op
.ops
, res_op
->ops
+ 1, (num_ops
- 1) * sizeof *cond_op
.ops
);
372 switch (num_ops
- num_cond_ops
)
375 if (!gimple_resimplify1 (seq
, &cond_op
, valueize
))
379 if (!gimple_resimplify2 (seq
, &cond_op
, valueize
))
383 if (!gimple_resimplify3 (seq
, &cond_op
, valueize
))
390 maybe_resimplify_conditional_op (seq
, res_op
, valueize
);
394 /* Helper for the autogenerated code, valueize OP. */
397 do_valueize (tree (*valueize
)(tree
), tree op
)
399 if (valueize
&& TREE_CODE (op
) == SSA_NAME
)
401 tree tem
= valueize (op
);
408 /* Push the exploded expression described by RES_OP as a statement to
409 SEQ if necessary and return a gimple value denoting the value of the
410 expression. If RES is not NULL then the result will be always RES
411 and even gimple values are pushed to SEQ. */
414 maybe_push_res_to_seq (gimple_match_op
*res_op
, gimple_seq
*seq
, tree res
)
416 tree
*ops
= res_op
->ops
;
417 unsigned num_ops
= res_op
->num_ops
;
419 /* The caller should have converted conditional operations into an UNCOND
420 form and resimplified as appropriate. The conditional form only
421 survives this far if that conversion failed. */
422 if (res_op
->cond
.cond
)
425 if (res_op
->code
.is_tree_code ())
428 && gimple_simplified_result_is_gimple_val (res_op
))
432 tree tem
= mprts_hook (res_op
);
441 /* Play safe and do not allow abnormals to be mentioned in
442 newly created statements. */
443 for (unsigned int i
= 0; i
< num_ops
; ++i
)
444 if (TREE_CODE (ops
[i
]) == SSA_NAME
445 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[i
]))
448 if (num_ops
> 0 && COMPARISON_CLASS_P (ops
[0]))
449 for (unsigned int i
= 0; i
< 2; ++i
)
450 if (TREE_CODE (TREE_OPERAND (ops
[0], i
)) == SSA_NAME
451 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops
[0], i
)))
454 if (res_op
->code
.is_tree_code ())
456 auto code
= tree_code (res_op
->code
);
459 if (gimple_in_ssa_p (cfun
))
460 res
= make_ssa_name (res_op
->type
);
462 res
= create_tmp_reg (res_op
->type
);
464 maybe_build_generic_op (res_op
);
465 gimple
*new_stmt
= gimple_build_assign (res
, code
,
466 res_op
->op_or_null (0),
467 res_op
->op_or_null (1),
468 res_op
->op_or_null (2));
469 gimple_seq_add_stmt_without_update (seq
, new_stmt
);
474 gcc_assert (num_ops
!= 0);
475 auto fn
= combined_fn (res_op
->code
);
476 gcall
*new_stmt
= NULL
;
477 if (internal_fn_p (fn
))
479 /* Generate the given function if we can. */
480 internal_fn ifn
= as_internal_fn (fn
);
481 new_stmt
= build_call_internal (ifn
, res_op
);
487 /* Find the function we want to call. */
488 tree decl
= builtin_decl_implicit (as_builtin_fn (fn
));
492 /* We can't and should not emit calls to non-const functions. */
493 if (!(flags_from_decl_or_type (decl
) & ECF_CONST
))
496 new_stmt
= gimple_build_call (decl
, num_ops
,
497 res_op
->op_or_null (0),
498 res_op
->op_or_null (1),
499 res_op
->op_or_null (2),
500 res_op
->op_or_null (3),
501 res_op
->op_or_null (4));
505 if (gimple_in_ssa_p (cfun
))
506 res
= make_ssa_name (res_op
->type
);
508 res
= create_tmp_reg (res_op
->type
);
510 gimple_call_set_lhs (new_stmt
, res
);
511 gimple_seq_add_stmt_without_update (seq
, new_stmt
);
517 /* Public API overloads follow for operation being tree_code or
518 built_in_function and for one to three operands or arguments.
519 They return NULL_TREE if nothing could be simplified or
520 the resulting simplified value with parts pushed to SEQ.
521 If SEQ is NULL then if the simplification needs to create
522 new stmts it will fail. If VALUEIZE is non-NULL then all
523 SSA names will be valueized using that hook prior to
524 applying simplifications. */
529 gimple_simplify (enum tree_code code
, tree type
,
531 gimple_seq
*seq
, tree (*valueize
)(tree
))
533 if (constant_for_folding (op0
))
535 tree res
= const_unop (code
, type
, op0
);
537 && CONSTANT_CLASS_P (res
))
541 gimple_match_op res_op
;
542 if (!gimple_simplify (&res_op
, seq
, valueize
, code
, type
, op0
))
544 return maybe_push_res_to_seq (&res_op
, seq
);
550 gimple_simplify (enum tree_code code
, tree type
,
552 gimple_seq
*seq
, tree (*valueize
)(tree
))
554 if (constant_for_folding (op0
) && constant_for_folding (op1
))
556 tree res
= const_binop (code
, type
, op0
, op1
);
558 && CONSTANT_CLASS_P (res
))
562 /* Canonicalize operand order both for matching and fallback stmt
564 if ((commutative_tree_code (code
)
565 || TREE_CODE_CLASS (code
) == tcc_comparison
)
566 && tree_swap_operands_p (op0
, op1
))
568 std::swap (op0
, op1
);
569 if (TREE_CODE_CLASS (code
) == tcc_comparison
)
570 code
= swap_tree_comparison (code
);
573 gimple_match_op res_op
;
574 if (!gimple_simplify (&res_op
, seq
, valueize
, code
, type
, op0
, op1
))
576 return maybe_push_res_to_seq (&res_op
, seq
);
582 gimple_simplify (enum tree_code code
, tree type
,
583 tree op0
, tree op1
, tree op2
,
584 gimple_seq
*seq
, tree (*valueize
)(tree
))
586 if (constant_for_folding (op0
) && constant_for_folding (op1
)
587 && constant_for_folding (op2
))
589 tree res
= fold_ternary
/*_to_constant */ (code
, type
, op0
, op1
, op2
);
591 && CONSTANT_CLASS_P (res
))
595 /* Canonicalize operand order both for matching and fallback stmt
597 if (commutative_ternary_tree_code (code
)
598 && tree_swap_operands_p (op0
, op1
))
599 std::swap (op0
, op1
);
601 gimple_match_op res_op
;
602 if (!gimple_simplify (&res_op
, seq
, valueize
, code
, type
, op0
, op1
, op2
))
604 return maybe_push_res_to_seq (&res_op
, seq
);
607 /* Builtin or internal function with one argument. */
610 gimple_simplify (combined_fn fn
, tree type
,
612 gimple_seq
*seq
, tree (*valueize
)(tree
))
614 if (constant_for_folding (arg0
))
616 tree res
= fold_const_call (fn
, type
, arg0
);
617 if (res
&& CONSTANT_CLASS_P (res
))
621 gimple_match_op res_op
;
622 if (!gimple_simplify (&res_op
, seq
, valueize
, fn
, type
, arg0
))
624 return maybe_push_res_to_seq (&res_op
, seq
);
627 /* Builtin or internal function with two arguments. */
630 gimple_simplify (combined_fn fn
, tree type
,
631 tree arg0
, tree arg1
,
632 gimple_seq
*seq
, tree (*valueize
)(tree
))
634 if (constant_for_folding (arg0
)
635 && constant_for_folding (arg1
))
637 tree res
= fold_const_call (fn
, type
, arg0
, arg1
);
638 if (res
&& CONSTANT_CLASS_P (res
))
642 gimple_match_op res_op
;
643 if (!gimple_simplify (&res_op
, seq
, valueize
, fn
, type
, arg0
, arg1
))
645 return maybe_push_res_to_seq (&res_op
, seq
);
648 /* Builtin or internal function with three arguments. */
651 gimple_simplify (combined_fn fn
, tree type
,
652 tree arg0
, tree arg1
, tree arg2
,
653 gimple_seq
*seq
, tree (*valueize
)(tree
))
655 if (constant_for_folding (arg0
)
656 && constant_for_folding (arg1
)
657 && constant_for_folding (arg2
))
659 tree res
= fold_const_call (fn
, type
, arg0
, arg1
, arg2
);
660 if (res
&& CONSTANT_CLASS_P (res
))
664 gimple_match_op res_op
;
665 if (!gimple_simplify (&res_op
, seq
, valueize
, fn
, type
, arg0
, arg1
, arg2
))
667 return maybe_push_res_to_seq (&res_op
, seq
);
670 /* Common subroutine of gimple_extract_op and gimple_simplify. Try to
671 describe STMT in RES_OP, returning true on success. Before recording
674 - VALUEIZE_CONDITION for a COND_EXPR condition
675 - VALUEIZE_OP for every other top-level operand
677 Both routines take a tree argument and returns a tree. */
679 template<typename ValueizeOp
, typename ValueizeCondition
>
681 gimple_extract (gimple
*stmt
, gimple_match_op
*res_op
,
682 ValueizeOp valueize_op
,
683 ValueizeCondition valueize_condition
)
685 switch (gimple_code (stmt
))
689 enum tree_code code
= gimple_assign_rhs_code (stmt
);
690 tree type
= TREE_TYPE (gimple_assign_lhs (stmt
));
691 switch (gimple_assign_rhs_class (stmt
))
693 case GIMPLE_SINGLE_RHS
:
694 if (code
== REALPART_EXPR
695 || code
== IMAGPART_EXPR
696 || code
== VIEW_CONVERT_EXPR
)
698 tree op0
= TREE_OPERAND (gimple_assign_rhs1 (stmt
), 0);
699 res_op
->set_op (code
, type
, valueize_op (op0
));
702 else if (code
== BIT_FIELD_REF
)
704 tree rhs1
= gimple_assign_rhs1 (stmt
);
705 tree op0
= valueize_op (TREE_OPERAND (rhs1
, 0));
706 res_op
->set_op (code
, type
, op0
,
707 TREE_OPERAND (rhs1
, 1),
708 TREE_OPERAND (rhs1
, 2),
709 REF_REVERSE_STORAGE_ORDER (rhs1
));
712 else if (code
== SSA_NAME
)
714 tree op0
= gimple_assign_rhs1 (stmt
);
715 res_op
->set_op (TREE_CODE (op0
), type
, valueize_op (op0
));
719 case GIMPLE_UNARY_RHS
:
721 tree rhs1
= gimple_assign_rhs1 (stmt
);
722 res_op
->set_op (code
, type
, valueize_op (rhs1
));
725 case GIMPLE_BINARY_RHS
:
727 tree rhs1
= valueize_op (gimple_assign_rhs1 (stmt
));
728 tree rhs2
= valueize_op (gimple_assign_rhs2 (stmt
));
729 res_op
->set_op (code
, type
, rhs1
, rhs2
);
732 case GIMPLE_TERNARY_RHS
:
734 tree rhs1
= gimple_assign_rhs1 (stmt
);
735 if (code
== COND_EXPR
&& COMPARISON_CLASS_P (rhs1
))
736 rhs1
= valueize_condition (rhs1
);
738 rhs1
= valueize_op (rhs1
);
739 tree rhs2
= valueize_op (gimple_assign_rhs2 (stmt
));
740 tree rhs3
= valueize_op (gimple_assign_rhs3 (stmt
));
741 res_op
->set_op (code
, type
, rhs1
, rhs2
, rhs3
);
751 /* ??? This way we can't simplify calls with side-effects. */
752 if (gimple_call_lhs (stmt
) != NULL_TREE
753 && gimple_call_num_args (stmt
) >= 1
754 && gimple_call_num_args (stmt
) <= 7)
757 if (gimple_call_internal_p (stmt
))
758 cfn
= as_combined_fn (gimple_call_internal_fn (stmt
));
761 tree fn
= gimple_call_fn (stmt
);
765 fn
= valueize_op (fn
);
766 if (TREE_CODE (fn
) != ADDR_EXPR
767 || TREE_CODE (TREE_OPERAND (fn
, 0)) != FUNCTION_DECL
)
770 tree decl
= TREE_OPERAND (fn
, 0);
771 if (DECL_BUILT_IN_CLASS (decl
) != BUILT_IN_NORMAL
772 || !gimple_builtin_call_types_compatible_p (stmt
, decl
))
775 cfn
= as_combined_fn (DECL_FUNCTION_CODE (decl
));
778 unsigned int num_args
= gimple_call_num_args (stmt
);
779 res_op
->set_op (cfn
, TREE_TYPE (gimple_call_lhs (stmt
)), num_args
);
780 for (unsigned i
= 0; i
< num_args
; ++i
)
781 res_op
->ops
[i
] = valueize_op (gimple_call_arg (stmt
, i
));
788 tree lhs
= valueize_op (gimple_cond_lhs (stmt
));
789 tree rhs
= valueize_op (gimple_cond_rhs (stmt
));
790 res_op
->set_op (gimple_cond_code (stmt
), boolean_type_node
, lhs
, rhs
);
801 /* Try to describe STMT in RES_OP, returning true on success.
802 For GIMPLE_CONDs, describe the condition that is being tested.
803 For GIMPLE_ASSIGNs, describe the rhs of the assignment.
804 For GIMPLE_CALLs, describe the call. */
807 gimple_extract_op (gimple
*stmt
, gimple_match_op
*res_op
)
809 auto nop
= [](tree op
) { return op
; };
810 return gimple_extract (stmt
, res_op
, nop
, nop
);
813 /* The main STMT based simplification entry. It is used by the fold_stmt
814 and the fold_stmt_to_constant APIs. */
817 gimple_simplify (gimple
*stmt
, gimple_match_op
*res_op
, gimple_seq
*seq
,
818 tree (*valueize
)(tree
), tree (*top_valueize
)(tree
))
820 bool valueized
= false;
821 auto valueize_op
= [&](tree op
)
823 return do_valueize (op
, top_valueize
, valueized
);
825 auto valueize_condition
= [&](tree op
) -> tree
827 bool cond_valueized
= false;
828 tree lhs
= do_valueize (TREE_OPERAND (op
, 0), top_valueize
,
830 tree rhs
= do_valueize (TREE_OPERAND (op
, 1), top_valueize
,
832 gimple_match_op
res_op2 (res_op
->cond
, TREE_CODE (op
),
833 TREE_TYPE (op
), lhs
, rhs
);
834 if ((gimple_resimplify2 (seq
, &res_op2
, valueize
)
836 && res_op2
.code
.is_tree_code ())
838 auto code
= tree_code (res_op2
.code
);
839 if (TREE_CODE_CLASS (code
) == tcc_comparison
)
842 return build2 (code
, TREE_TYPE (op
),
843 res_op2
.ops
[0], res_op2
.ops
[1]);
845 else if (code
== SSA_NAME
846 || code
== INTEGER_CST
847 || code
== VECTOR_CST
)
850 return res_op2
.ops
[0];
853 return valueize_op (op
);
856 if (!gimple_extract (stmt
, res_op
, valueize_op
, valueize_condition
))
859 if (res_op
->code
.is_internal_fn ())
861 internal_fn ifn
= internal_fn (res_op
->code
);
862 if (try_conditional_simplification (ifn
, res_op
, seq
, valueize
))
868 && res_op
->resimplify (seq
, valueize
))
874 /* Helper that matches and simplifies the toplevel result from
875 a gimple_simplify run (where we don't want to build
876 a stmt in case it's used in in-place folding). Replaces
877 RES_OP with a simplified and/or canonicalized result and
878 returns whether any change was made. */
881 gimple_resimplify1 (gimple_seq
*seq
, gimple_match_op
*res_op
,
882 tree (*valueize
)(tree
))
884 if (constant_for_folding (res_op
->ops
[0]))
886 tree tem
= NULL_TREE
;
887 if (res_op
->code
.is_tree_code ())
889 auto code
= tree_code (res_op
->code
);
890 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code
))
891 && TREE_CODE_LENGTH (code
) == 1)
892 tem
= const_unop (code
, res_op
->type
, res_op
->ops
[0]);
895 tem
= fold_const_call (combined_fn (res_op
->code
), res_op
->type
,
898 && CONSTANT_CLASS_P (tem
))
900 if (TREE_OVERFLOW_P (tem
))
901 tem
= drop_tree_overflow (tem
);
902 res_op
->set_value (tem
);
903 maybe_resimplify_conditional_op (seq
, res_op
, valueize
);
908 /* Limit recursion, there are cases like PR80887 and others, for
909 example when value-numbering presents us with unfolded expressions
910 that we are really not prepared to handle without eventual
911 oscillation like ((_50 + 0) + 8) where _50 gets mapped to _50
912 itself as available expression. */
913 static unsigned depth
;
916 if (dump_file
&& (dump_flags
& TDF_FOLDING
))
917 fprintf (dump_file
, "Aborting expression simplification due to "
923 gimple_match_op
res_op2 (*res_op
);
924 if (gimple_simplify (&res_op2
, seq
, valueize
,
925 res_op
->code
, res_op
->type
, res_op
->ops
[0]))
933 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
939 /* Helper that matches and simplifies the toplevel result from
940 a gimple_simplify run (where we don't want to build
941 a stmt in case it's used in in-place folding). Replaces
942 RES_OP with a simplified and/or canonicalized result and
943 returns whether any change was made. */
946 gimple_resimplify2 (gimple_seq
*seq
, gimple_match_op
*res_op
,
947 tree (*valueize
)(tree
))
949 if (constant_for_folding (res_op
->ops
[0])
950 && constant_for_folding (res_op
->ops
[1]))
952 tree tem
= NULL_TREE
;
953 if (res_op
->code
.is_tree_code ())
955 auto code
= tree_code (res_op
->code
);
956 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code
))
957 && TREE_CODE_LENGTH (code
) == 2)
958 tem
= const_binop (code
, res_op
->type
,
959 res_op
->ops
[0], res_op
->ops
[1]);
962 tem
= fold_const_call (combined_fn (res_op
->code
), res_op
->type
,
963 res_op
->ops
[0], res_op
->ops
[1]);
965 && CONSTANT_CLASS_P (tem
))
967 if (TREE_OVERFLOW_P (tem
))
968 tem
= drop_tree_overflow (tem
);
969 res_op
->set_value (tem
);
970 maybe_resimplify_conditional_op (seq
, res_op
, valueize
);
975 /* Canonicalize operand order. */
976 bool canonicalized
= false;
978 = (res_op
->code
.is_tree_code ()
979 && TREE_CODE_CLASS (tree_code (res_op
->code
)) == tcc_comparison
);
980 if ((is_comparison
|| commutative_binary_op_p (res_op
->code
, res_op
->type
))
981 && tree_swap_operands_p (res_op
->ops
[0], res_op
->ops
[1]))
983 std::swap (res_op
->ops
[0], res_op
->ops
[1]);
985 res_op
->code
= swap_tree_comparison (tree_code (res_op
->code
));
986 canonicalized
= true;
989 /* Limit recursion, see gimple_resimplify1. */
990 static unsigned depth
;
993 if (dump_file
&& (dump_flags
& TDF_FOLDING
))
994 fprintf (dump_file
, "Aborting expression simplification due to "
1000 gimple_match_op
res_op2 (*res_op
);
1001 if (gimple_simplify (&res_op2
, seq
, valueize
,
1002 res_op
->code
, res_op
->type
,
1003 res_op
->ops
[0], res_op
->ops
[1]))
1011 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1014 return canonicalized
;
1017 /* Helper that matches and simplifies the toplevel result from
1018 a gimple_simplify run (where we don't want to build
1019 a stmt in case it's used in in-place folding). Replaces
1020 RES_OP with a simplified and/or canonicalized result and
1021 returns whether any change was made. */
1024 gimple_resimplify3 (gimple_seq
*seq
, gimple_match_op
*res_op
,
1025 tree (*valueize
)(tree
))
1027 if (constant_for_folding (res_op
->ops
[0])
1028 && constant_for_folding (res_op
->ops
[1])
1029 && constant_for_folding (res_op
->ops
[2]))
1031 tree tem
= NULL_TREE
;
1032 if (res_op
->code
.is_tree_code ())
1034 auto code
= tree_code (res_op
->code
);
1035 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code
))
1036 && TREE_CODE_LENGTH (code
) == 3)
1037 tem
= fold_ternary
/*_to_constant*/ (code
, res_op
->type
,
1038 res_op
->ops
[0], res_op
->ops
[1],
1042 tem
= fold_const_call (combined_fn (res_op
->code
), res_op
->type
,
1043 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2]);
1044 if (tem
!= NULL_TREE
1045 && CONSTANT_CLASS_P (tem
))
1047 if (TREE_OVERFLOW_P (tem
))
1048 tem
= drop_tree_overflow (tem
);
1049 res_op
->set_value (tem
);
1050 maybe_resimplify_conditional_op (seq
, res_op
, valueize
);
1055 /* Canonicalize operand order. */
1056 bool canonicalized
= false;
1057 int argno
= first_commutative_argument (res_op
->code
, res_op
->type
);
1059 && tree_swap_operands_p (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]))
1061 std::swap (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]);
1062 canonicalized
= true;
1065 /* Limit recursion, see gimple_resimplify1. */
1066 static unsigned depth
;
1069 if (dump_file
&& (dump_flags
& TDF_FOLDING
))
1070 fprintf (dump_file
, "Aborting expression simplification due to "
1071 "deep recursion\n");
1076 gimple_match_op
res_op2 (*res_op
);
1077 if (gimple_simplify (&res_op2
, seq
, valueize
,
1078 res_op
->code
, res_op
->type
,
1079 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2]))
1087 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1090 return canonicalized
;
1093 /* Helper that matches and simplifies the toplevel result from
1094 a gimple_simplify run (where we don't want to build
1095 a stmt in case it's used in in-place folding). Replaces
1096 RES_OP with a simplified and/or canonicalized result and
1097 returns whether any change was made. */
1100 gimple_resimplify4 (gimple_seq
*seq
, gimple_match_op
*res_op
,
1101 tree (*valueize
)(tree
))
1103 /* No constant folding is defined for four-operand functions. */
1105 /* Canonicalize operand order. */
1106 bool canonicalized
= false;
1107 int argno
= first_commutative_argument (res_op
->code
, res_op
->type
);
1109 && tree_swap_operands_p (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]))
1111 std::swap (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]);
1112 canonicalized
= true;
1115 /* Limit recursion, see gimple_resimplify1. */
1116 static unsigned depth
;
1119 if (dump_file
&& (dump_flags
& TDF_FOLDING
))
1120 fprintf (dump_file
, "Aborting expression simplification due to "
1121 "deep recursion\n");
1126 gimple_match_op
res_op2 (*res_op
);
1127 if (gimple_simplify (&res_op2
, seq
, valueize
,
1128 res_op
->code
, res_op
->type
,
1129 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2],
1138 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1141 return canonicalized
;
1144 /* Helper that matches and simplifies the toplevel result from
1145 a gimple_simplify run (where we don't want to build
1146 a stmt in case it's used in in-place folding). Replaces
1147 RES_OP with a simplified and/or canonicalized result and
1148 returns whether any change was made. */
1151 gimple_resimplify5 (gimple_seq
*seq
, gimple_match_op
*res_op
,
1152 tree (*valueize
)(tree
))
1154 /* No constant folding is defined for five-operand functions. */
1156 /* Canonicalize operand order. */
1157 bool canonicalized
= false;
1158 int argno
= first_commutative_argument (res_op
->code
, res_op
->type
);
1160 && tree_swap_operands_p (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]))
1162 std::swap (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]);
1163 canonicalized
= true;
1166 gimple_match_op
res_op2 (*res_op
);
1167 if (gimple_simplify (&res_op2
, seq
, valueize
,
1168 res_op
->code
, res_op
->type
,
1169 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2],
1170 res_op
->ops
[3], res_op
->ops
[4]))
1176 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1179 return canonicalized
;
1182 /* Helper that matches and simplifies the toplevel result from
1183 a gimple_simplify run (where we don't want to build
1184 a stmt in case it's used in in-place folding). Replaces
1185 RES_OP with a simplified and/or canonicalized result and
1186 returns whether any change was made. */
1189 gimple_resimplify6 (gimple_seq
*seq
, gimple_match_op
*res_op
,
1190 tree (*valueize
)(tree
))
1192 /* No constant folding is defined for six-operand functions. */
1194 /* Canonicalize operand order. */
1195 bool canonicalized
= false;
1196 int argno
= first_commutative_argument (res_op
->code
, res_op
->type
);
1198 && tree_swap_operands_p (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]))
1200 std::swap (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]);
1201 canonicalized
= true;
1204 gimple_match_op
res_op2 (*res_op
);
1205 if (gimple_simplify (&res_op2
, seq
, valueize
,
1206 res_op
->code
, res_op
->type
,
1207 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2],
1208 res_op
->ops
[3], res_op
->ops
[4], res_op
->ops
[5]))
1214 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1217 return canonicalized
;
1220 /* Helper that matches and simplifies the toplevel result from
1221 a gimple_simplify run (where we don't want to build
1222 a stmt in case it's used in in-place folding). Replaces
1223 RES_OP with a simplified and/or canonicalized result and
1224 returns whether any change was made. */
1227 gimple_resimplify7 (gimple_seq
*seq
, gimple_match_op
*res_op
,
1228 tree (*valueize
)(tree
))
1230 /* No constant folding is defined for seven-operand functions. */
1232 /* Canonicalize operand order. */
1233 bool canonicalized
= false;
1234 int argno
= first_commutative_argument (res_op
->code
, res_op
->type
);
1236 && tree_swap_operands_p (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]))
1238 std::swap (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]);
1239 canonicalized
= true;
1242 gimple_match_op
res_op2 (*res_op
);
1243 if (gimple_simplify (&res_op2
, seq
, valueize
,
1244 res_op
->code
, res_op
->type
,
1245 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2],
1246 res_op
->ops
[3], res_op
->ops
[4], res_op
->ops
[5],
1253 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1256 return canonicalized
;
1259 /* Return a canonical form for CODE when operating on TYPE. The idea
1260 is to remove redundant ways of representing the same operation so
1261 that code_helpers can be hashed and compared for equality.
1263 The only current canonicalization is to replace built-in functions
1264 with internal functions, in cases where internal-fn.def defines
1265 such an internal function.
1267 Note that the new code_helper cannot necessarily be used in place of
1268 the original code_helper. For example, the new code_helper might be
1269 an internal function that the target does not support. */
1272 canonicalize_code (code_helper code
, tree type
)
1274 if (code
.is_fn_code ())
1275 return associated_internal_fn (combined_fn (code
), type
);
1279 /* Return true if CODE is a binary operation and if CODE is commutative when
1280 operating on type TYPE. */
1283 commutative_binary_op_p (code_helper code
, tree type
)
1285 if (code
.is_tree_code ())
1286 return commutative_tree_code (tree_code (code
));
1287 auto cfn
= combined_fn (code
);
1288 return commutative_binary_fn_p (associated_internal_fn (cfn
, type
));
1291 /* Return true if CODE represents a ternary operation and if the first two
1292 operands are commutative when CODE is operating on TYPE. */
1295 commutative_ternary_op_p (code_helper code
, tree type
)
1297 if (code
.is_tree_code ())
1298 return commutative_ternary_tree_code (tree_code (code
));
1299 auto cfn
= combined_fn (code
);
1300 return commutative_ternary_fn_p (associated_internal_fn (cfn
, type
));
1303 /* If CODE is commutative in two consecutive operands, return the
1304 index of the first, otherwise return -1. */
1307 first_commutative_argument (code_helper code
, tree type
)
1309 if (code
.is_tree_code ())
1311 auto tcode
= tree_code (code
);
1312 if (commutative_tree_code (tcode
)
1313 || commutative_ternary_tree_code (tcode
))
1317 auto cfn
= combined_fn (code
);
1318 return first_commutative_argument (associated_internal_fn (cfn
, type
));
1321 /* Return true if CODE is a binary operation that is associative when
1322 operating on type TYPE. */
1325 associative_binary_op_p (code_helper code
, tree type
)
1327 if (code
.is_tree_code ())
1328 return associative_tree_code (tree_code (code
));
1329 auto cfn
= combined_fn (code
);
1330 return associative_binary_fn_p (associated_internal_fn (cfn
, type
));
1333 /* Return true if the target directly supports operation CODE on type TYPE.
1334 QUERY_TYPE acts as for optab_for_tree_code. */
1337 directly_supported_p (code_helper code
, tree type
, optab_subtype query_type
)
1339 if (code
.is_tree_code ())
1341 direct_optab optab
= optab_for_tree_code (tree_code (code
), type
,
1343 return (optab
!= unknown_optab
1344 && optab_handler (optab
, TYPE_MODE (type
)) != CODE_FOR_nothing
);
1346 gcc_assert (query_type
== optab_default
1347 || (query_type
== optab_vector
&& VECTOR_TYPE_P (type
))
1348 || (query_type
== optab_scalar
&& !VECTOR_TYPE_P (type
)));
1349 internal_fn ifn
= associated_internal_fn (combined_fn (code
), type
);
1350 return (direct_internal_fn_p (ifn
)
1351 && direct_internal_fn_supported_p (ifn
, type
, OPTIMIZE_FOR_SPEED
));
1354 /* A wrapper around the internal-fn.cc versions of get_conditional_internal_fn
1355 for a code_helper CODE operating on type TYPE. */
1358 get_conditional_internal_fn (code_helper code
, tree type
)
1360 if (code
.is_tree_code ())
1361 return get_conditional_internal_fn (tree_code (code
));
1362 auto cfn
= combined_fn (code
);
1363 return get_conditional_internal_fn (associated_internal_fn (cfn
, type
));