c++: only cache constexpr calls that are constant exprs
[official-gcc.git] / gcc / gimple-match-exports.cc
blob7aeb4ddb152468ddef19e6361428498371a1ebf2
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
9 version.
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
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "target.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "ssa.h"
29 #include "cgraph.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"
36 #include "calls.h"
37 #include "tree-dfa.h"
38 #include "builtins.h"
39 #include "gimple-match.h"
40 #include "tree-pass.h"
41 #include "internal-fn.h"
42 #include "case-cfn-macros.h"
43 #include "gimplify.h"
44 #include "optabs-tree.h"
45 #include "tree-eh.h"
46 #include "dbgcnt.h"
47 #include "tm.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);
64 /* Functions that are needed by gimple-match but that are exported and used in
65 other places in the compiler. */
67 tree gimple_simplify (enum tree_code, tree, tree, gimple_seq *,
68 tree (*)(tree));
69 tree gimple_simplify (enum tree_code, tree, tree, tree, gimple_seq *,
70 tree (*)(tree));
71 tree gimple_simplify (enum tree_code, tree, tree, tree, tree, gimple_seq *,
72 tree (*)(tree));
73 tree gimple_simplify (combined_fn, tree, tree, gimple_seq *,
74 tree (*)(tree));
75 tree gimple_simplify (combined_fn, tree, tree, tree, gimple_seq *,
76 tree (*)(tree));
77 tree gimple_simplify (combined_fn, tree, tree, tree, tree, gimple_seq *,
78 tree (*)(tree));
80 tree do_valueize (tree, tree (*)(tree), bool &);
81 tree do_valueize (tree (*)(tree), tree);
83 /* Forward declarations of the private auto-generated matchers.
84 They expect valueized operands in canonical order and do not
85 perform simplification of all-constant operands. */
87 static bool gimple_resimplify1 (gimple_seq *, gimple_match_op *, tree (*)(tree));
88 static bool gimple_resimplify2 (gimple_seq *, gimple_match_op *, tree (*)(tree));
89 static bool gimple_resimplify3 (gimple_seq *, gimple_match_op *, tree (*)(tree));
90 static bool gimple_resimplify4 (gimple_seq *, gimple_match_op *, tree (*)(tree));
91 static bool gimple_resimplify5 (gimple_seq *, gimple_match_op *, tree (*)(tree));
93 /* Match and simplify the toplevel valueized operation THIS.
94 Replaces THIS with a simplified and/or canonicalized result and
95 returns whether any change was made. */
97 bool
98 gimple_match_op::resimplify (gimple_seq *seq, tree (*valueize)(tree))
100 switch (num_ops)
102 case 1:
103 return gimple_resimplify1 (seq, this, valueize);
104 case 2:
105 return gimple_resimplify2 (seq, this, valueize);
106 case 3:
107 return gimple_resimplify3 (seq, this, valueize);
108 case 4:
109 return gimple_resimplify4 (seq, this, valueize);
110 case 5:
111 return gimple_resimplify5 (seq, this, valueize);
112 default:
113 gcc_unreachable ();
117 /* Return whether T is a constant that we'll dispatch to fold to
118 evaluate fully constant expressions. */
120 static inline bool
121 constant_for_folding (tree t)
123 return (CONSTANT_CLASS_P (t)
124 /* The following is only interesting to string builtins. */
125 || (TREE_CODE (t) == ADDR_EXPR
126 && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST));
129 /* Try to convert conditional operation ORIG_OP into an IFN_COND_*
130 operation. Return true on success, storing the new operation in NEW_OP. */
132 static bool
133 convert_conditional_op (gimple_match_op *orig_op,
134 gimple_match_op *new_op)
136 internal_fn ifn;
137 if (orig_op->code.is_tree_code ())
138 ifn = get_conditional_internal_fn ((tree_code) orig_op->code);
139 else
141 auto cfn = combined_fn (orig_op->code);
142 if (!internal_fn_p (cfn))
143 return false;
144 ifn = get_conditional_internal_fn (as_internal_fn (cfn));
146 if (ifn == IFN_LAST)
147 return false;
148 unsigned int num_ops = orig_op->num_ops;
149 new_op->set_op (as_combined_fn (ifn), orig_op->type, num_ops + 2);
150 new_op->ops[0] = orig_op->cond.cond;
151 for (unsigned int i = 0; i < num_ops; ++i)
152 new_op->ops[i + 1] = orig_op->ops[i];
153 tree else_value = orig_op->cond.else_value;
154 if (!else_value)
155 else_value = targetm.preferred_else_value (ifn, orig_op->type,
156 num_ops, orig_op->ops);
157 new_op->ops[num_ops + 1] = else_value;
158 return true;
160 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
161 VALUEIZED to true if valueization changed OP. */
163 inline tree
164 do_valueize (tree op, tree (*valueize)(tree), bool &valueized)
166 if (valueize && TREE_CODE (op) == SSA_NAME)
168 tree tem = valueize (op);
169 if (tem && tem != op)
171 op = tem;
172 valueized = true;
175 return op;
178 /* If in GIMPLE the operation described by RES_OP should be single-rhs,
179 build a GENERIC tree for that expression and update RES_OP accordingly. */
181 void
182 maybe_build_generic_op (gimple_match_op *res_op)
184 tree_code code = (tree_code) res_op->code;
185 tree val;
186 switch (code)
188 case REALPART_EXPR:
189 case IMAGPART_EXPR:
190 case VIEW_CONVERT_EXPR:
191 val = build1 (code, res_op->type, res_op->ops[0]);
192 res_op->set_value (val);
193 break;
194 case BIT_FIELD_REF:
195 val = build3 (code, res_op->type, res_op->ops[0], res_op->ops[1],
196 res_op->ops[2]);
197 REF_REVERSE_STORAGE_ORDER (val) = res_op->reverse;
198 res_op->set_value (val);
199 break;
200 default:;
204 /* Try to build RES_OP, which is known to be a call to FN. Return null
205 if the target doesn't support the function. */
207 static gcall *
208 build_call_internal (internal_fn fn, gimple_match_op *res_op)
210 if (direct_internal_fn_p (fn))
212 tree_pair types = direct_internal_fn_types (fn, res_op->type,
213 res_op->ops);
214 if (!direct_internal_fn_supported_p (fn, types, OPTIMIZE_FOR_BOTH))
215 return NULL;
217 return gimple_build_call_internal (fn, res_op->num_ops,
218 res_op->op_or_null (0),
219 res_op->op_or_null (1),
220 res_op->op_or_null (2),
221 res_op->op_or_null (3),
222 res_op->op_or_null (4));
225 /* RES_OP is the result of a simplification. If it is conditional,
226 try to replace it with the equivalent UNCOND form, such as an
227 IFN_COND_* call or a VEC_COND_EXPR. Also try to resimplify the
228 result of the replacement if appropriate, adding any new statements to
229 SEQ and using VALUEIZE as the valueization function. Return true if
230 this resimplification occurred and resulted in at least one change. */
232 static bool
233 maybe_resimplify_conditional_op (gimple_seq *seq, gimple_match_op *res_op,
234 tree (*valueize) (tree))
236 if (!res_op->cond.cond)
237 return false;
239 if (!res_op->cond.else_value
240 && res_op->code.is_tree_code ())
242 /* The "else" value doesn't matter. If the "then" value is a
243 gimple value, just use it unconditionally. This isn't a
244 simplification in itself, since there was no operation to
245 build in the first place. */
246 if (gimple_simplified_result_is_gimple_val (res_op))
248 res_op->cond.cond = NULL_TREE;
249 return false;
252 /* Likewise if the operation would not trap. */
253 bool honor_trapv = (INTEGRAL_TYPE_P (res_op->type)
254 && TYPE_OVERFLOW_TRAPS (res_op->type));
255 tree_code op_code = (tree_code) res_op->code;
256 bool op_could_trap;
258 /* COND_EXPR will trap if, and only if, the condition
259 traps and hence we have to check this. For all other operations, we
260 don't need to consider the operands. */
261 if (op_code == COND_EXPR)
262 op_could_trap = generic_expr_could_trap_p (res_op->ops[0]);
263 else
264 op_could_trap = operation_could_trap_p ((tree_code) res_op->code,
265 FLOAT_TYPE_P (res_op->type),
266 honor_trapv,
267 res_op->op_or_null (1));
269 if (!op_could_trap)
271 res_op->cond.cond = NULL_TREE;
272 return false;
276 /* If the "then" value is a gimple value and the "else" value matters,
277 create a VEC_COND_EXPR between them, then see if it can be further
278 simplified. */
279 gimple_match_op new_op;
280 if (res_op->cond.else_value
281 && VECTOR_TYPE_P (res_op->type)
282 && gimple_simplified_result_is_gimple_val (res_op))
284 new_op.set_op (VEC_COND_EXPR, res_op->type,
285 res_op->cond.cond, res_op->ops[0],
286 res_op->cond.else_value);
287 *res_op = new_op;
288 return gimple_resimplify3 (seq, res_op, valueize);
291 /* Otherwise try rewriting the operation as an IFN_COND_* call.
292 Again, this isn't a simplification in itself, since it's what
293 RES_OP already described. */
294 if (convert_conditional_op (res_op, &new_op))
295 *res_op = new_op;
297 return false;
300 /* If RES_OP is a call to a conditional internal function, try simplifying
301 the associated unconditional operation and using the result to build
302 a new conditional operation. For example, if RES_OP is:
304 IFN_COND_ADD (COND, A, B, ELSE)
306 try simplifying (plus A B) and using the result to build a replacement
307 for the whole IFN_COND_ADD.
309 Return true if this approach led to a simplification, otherwise leave
310 RES_OP unchanged (and so suitable for other simplifications). When
311 returning true, add any new statements to SEQ and use VALUEIZE as the
312 valueization function.
314 RES_OP is known to be a call to IFN. */
316 static bool
317 try_conditional_simplification (internal_fn ifn, gimple_match_op *res_op,
318 gimple_seq *seq, tree (*valueize) (tree))
320 code_helper op;
321 tree_code code = conditional_internal_fn_code (ifn);
322 if (code != ERROR_MARK)
323 op = code;
324 else
326 ifn = get_unconditional_internal_fn (ifn);
327 if (ifn == IFN_LAST)
328 return false;
329 op = as_combined_fn (ifn);
332 unsigned int num_ops = res_op->num_ops;
333 gimple_match_op cond_op (gimple_match_cond (res_op->ops[0],
334 res_op->ops[num_ops - 1]),
335 op, res_op->type, num_ops - 2);
337 memcpy (cond_op.ops, res_op->ops + 1, (num_ops - 1) * sizeof *cond_op.ops);
338 switch (num_ops - 2)
340 case 1:
341 if (!gimple_resimplify1 (seq, &cond_op, valueize))
342 return false;
343 break;
344 case 2:
345 if (!gimple_resimplify2 (seq, &cond_op, valueize))
346 return false;
347 break;
348 case 3:
349 if (!gimple_resimplify3 (seq, &cond_op, valueize))
350 return false;
351 break;
352 default:
353 gcc_unreachable ();
355 *res_op = cond_op;
356 maybe_resimplify_conditional_op (seq, res_op, valueize);
357 return true;
360 /* Helper for the autogenerated code, valueize OP. */
362 tree
363 do_valueize (tree (*valueize)(tree), tree op)
365 if (valueize && TREE_CODE (op) == SSA_NAME)
367 tree tem = valueize (op);
368 if (tem)
369 return tem;
371 return op;
374 /* Push the exploded expression described by RES_OP as a statement to
375 SEQ if necessary and return a gimple value denoting the value of the
376 expression. If RES is not NULL then the result will be always RES
377 and even gimple values are pushed to SEQ. */
379 tree
380 maybe_push_res_to_seq (gimple_match_op *res_op, gimple_seq *seq, tree res)
382 tree *ops = res_op->ops;
383 unsigned num_ops = res_op->num_ops;
385 /* The caller should have converted conditional operations into an UNCOND
386 form and resimplified as appropriate. The conditional form only
387 survives this far if that conversion failed. */
388 if (res_op->cond.cond)
389 return NULL_TREE;
391 if (res_op->code.is_tree_code ())
393 if (!res
394 && gimple_simplified_result_is_gimple_val (res_op))
395 return ops[0];
396 if (mprts_hook)
398 tree tem = mprts_hook (res_op);
399 if (tem)
400 return tem;
404 if (!seq)
405 return NULL_TREE;
407 /* Play safe and do not allow abnormals to be mentioned in
408 newly created statements. */
409 for (unsigned int i = 0; i < num_ops; ++i)
410 if (TREE_CODE (ops[i]) == SSA_NAME
411 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[i]))
412 return NULL_TREE;
414 if (num_ops > 0 && COMPARISON_CLASS_P (ops[0]))
415 for (unsigned int i = 0; i < 2; ++i)
416 if (TREE_CODE (TREE_OPERAND (ops[0], i)) == SSA_NAME
417 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops[0], i)))
418 return NULL_TREE;
420 if (res_op->code.is_tree_code ())
422 auto code = tree_code (res_op->code);
423 if (!res)
425 if (gimple_in_ssa_p (cfun))
426 res = make_ssa_name (res_op->type);
427 else
428 res = create_tmp_reg (res_op->type);
430 maybe_build_generic_op (res_op);
431 gimple *new_stmt = gimple_build_assign (res, code,
432 res_op->op_or_null (0),
433 res_op->op_or_null (1),
434 res_op->op_or_null (2));
435 gimple_seq_add_stmt_without_update (seq, new_stmt);
436 return res;
438 else
440 gcc_assert (num_ops != 0);
441 auto fn = combined_fn (res_op->code);
442 gcall *new_stmt = NULL;
443 if (internal_fn_p (fn))
445 /* Generate the given function if we can. */
446 internal_fn ifn = as_internal_fn (fn);
447 new_stmt = build_call_internal (ifn, res_op);
448 if (!new_stmt)
449 return NULL_TREE;
451 else
453 /* Find the function we want to call. */
454 tree decl = builtin_decl_implicit (as_builtin_fn (fn));
455 if (!decl)
456 return NULL;
458 /* We can't and should not emit calls to non-const functions. */
459 if (!(flags_from_decl_or_type (decl) & ECF_CONST))
460 return NULL;
462 new_stmt = gimple_build_call (decl, num_ops,
463 res_op->op_or_null (0),
464 res_op->op_or_null (1),
465 res_op->op_or_null (2),
466 res_op->op_or_null (3),
467 res_op->op_or_null (4));
469 if (!res)
471 if (gimple_in_ssa_p (cfun))
472 res = make_ssa_name (res_op->type);
473 else
474 res = create_tmp_reg (res_op->type);
476 gimple_call_set_lhs (new_stmt, res);
477 gimple_seq_add_stmt_without_update (seq, new_stmt);
478 return res;
483 /* Public API overloads follow for operation being tree_code or
484 built_in_function and for one to three operands or arguments.
485 They return NULL_TREE if nothing could be simplified or
486 the resulting simplified value with parts pushed to SEQ.
487 If SEQ is NULL then if the simplification needs to create
488 new stmts it will fail. If VALUEIZE is non-NULL then all
489 SSA names will be valueized using that hook prior to
490 applying simplifications. */
492 /* Unary ops. */
494 tree
495 gimple_simplify (enum tree_code code, tree type,
496 tree op0,
497 gimple_seq *seq, tree (*valueize)(tree))
499 if (constant_for_folding (op0))
501 tree res = const_unop (code, type, op0);
502 if (res != NULL_TREE
503 && CONSTANT_CLASS_P (res))
504 return res;
507 gimple_match_op res_op;
508 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0))
509 return NULL_TREE;
510 return maybe_push_res_to_seq (&res_op, seq);
513 /* Binary ops. */
515 tree
516 gimple_simplify (enum tree_code code, tree type,
517 tree op0, tree op1,
518 gimple_seq *seq, tree (*valueize)(tree))
520 if (constant_for_folding (op0) && constant_for_folding (op1))
522 tree res = const_binop (code, type, op0, op1);
523 if (res != NULL_TREE
524 && CONSTANT_CLASS_P (res))
525 return res;
528 /* Canonicalize operand order both for matching and fallback stmt
529 generation. */
530 if ((commutative_tree_code (code)
531 || TREE_CODE_CLASS (code) == tcc_comparison)
532 && tree_swap_operands_p (op0, op1))
534 std::swap (op0, op1);
535 if (TREE_CODE_CLASS (code) == tcc_comparison)
536 code = swap_tree_comparison (code);
539 gimple_match_op res_op;
540 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0, op1))
541 return NULL_TREE;
542 return maybe_push_res_to_seq (&res_op, seq);
545 /* Ternary ops. */
547 tree
548 gimple_simplify (enum tree_code code, tree type,
549 tree op0, tree op1, tree op2,
550 gimple_seq *seq, tree (*valueize)(tree))
552 if (constant_for_folding (op0) && constant_for_folding (op1)
553 && constant_for_folding (op2))
555 tree res = fold_ternary/*_to_constant */ (code, type, op0, op1, op2);
556 if (res != NULL_TREE
557 && CONSTANT_CLASS_P (res))
558 return res;
561 /* Canonicalize operand order both for matching and fallback stmt
562 generation. */
563 if (commutative_ternary_tree_code (code)
564 && tree_swap_operands_p (op0, op1))
565 std::swap (op0, op1);
567 gimple_match_op res_op;
568 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0, op1, op2))
569 return NULL_TREE;
570 return maybe_push_res_to_seq (&res_op, seq);
573 /* Builtin or internal function with one argument. */
575 tree
576 gimple_simplify (combined_fn fn, tree type,
577 tree arg0,
578 gimple_seq *seq, tree (*valueize)(tree))
580 if (constant_for_folding (arg0))
582 tree res = fold_const_call (fn, type, arg0);
583 if (res && CONSTANT_CLASS_P (res))
584 return res;
587 gimple_match_op res_op;
588 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0))
589 return NULL_TREE;
590 return maybe_push_res_to_seq (&res_op, seq);
593 /* Builtin or internal function with two arguments. */
595 tree
596 gimple_simplify (combined_fn fn, tree type,
597 tree arg0, tree arg1,
598 gimple_seq *seq, tree (*valueize)(tree))
600 if (constant_for_folding (arg0)
601 && constant_for_folding (arg1))
603 tree res = fold_const_call (fn, type, arg0, arg1);
604 if (res && CONSTANT_CLASS_P (res))
605 return res;
608 gimple_match_op res_op;
609 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1))
610 return NULL_TREE;
611 return maybe_push_res_to_seq (&res_op, seq);
614 /* Builtin or internal function with three arguments. */
616 tree
617 gimple_simplify (combined_fn fn, tree type,
618 tree arg0, tree arg1, tree arg2,
619 gimple_seq *seq, tree (*valueize)(tree))
621 if (constant_for_folding (arg0)
622 && constant_for_folding (arg1)
623 && constant_for_folding (arg2))
625 tree res = fold_const_call (fn, type, arg0, arg1, arg2);
626 if (res && CONSTANT_CLASS_P (res))
627 return res;
630 gimple_match_op res_op;
631 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1, arg2))
632 return NULL_TREE;
633 return maybe_push_res_to_seq (&res_op, seq);
636 /* Common subroutine of gimple_extract_op and gimple_simplify. Try to
637 describe STMT in RES_OP, returning true on success. Before recording
638 an operand, call:
640 - VALUEIZE_CONDITION for a COND_EXPR condition
641 - VALUEIZE_OP for every other top-level operand
643 Both routines take a tree argument and returns a tree. */
645 template<typename ValueizeOp, typename ValueizeCondition>
646 inline bool
647 gimple_extract (gimple *stmt, gimple_match_op *res_op,
648 ValueizeOp valueize_op,
649 ValueizeCondition valueize_condition)
651 switch (gimple_code (stmt))
653 case GIMPLE_ASSIGN:
655 enum tree_code code = gimple_assign_rhs_code (stmt);
656 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
657 switch (gimple_assign_rhs_class (stmt))
659 case GIMPLE_SINGLE_RHS:
660 if (code == REALPART_EXPR
661 || code == IMAGPART_EXPR
662 || code == VIEW_CONVERT_EXPR)
664 tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
665 res_op->set_op (code, type, valueize_op (op0));
666 return true;
668 else if (code == BIT_FIELD_REF)
670 tree rhs1 = gimple_assign_rhs1 (stmt);
671 tree op0 = valueize_op (TREE_OPERAND (rhs1, 0));
672 res_op->set_op (code, type, op0,
673 TREE_OPERAND (rhs1, 1),
674 TREE_OPERAND (rhs1, 2),
675 REF_REVERSE_STORAGE_ORDER (rhs1));
676 return true;
678 else if (code == SSA_NAME)
680 tree op0 = gimple_assign_rhs1 (stmt);
681 res_op->set_op (TREE_CODE (op0), type, valueize_op (op0));
682 return true;
684 break;
685 case GIMPLE_UNARY_RHS:
687 tree rhs1 = gimple_assign_rhs1 (stmt);
688 res_op->set_op (code, type, valueize_op (rhs1));
689 return true;
691 case GIMPLE_BINARY_RHS:
693 tree rhs1 = valueize_op (gimple_assign_rhs1 (stmt));
694 tree rhs2 = valueize_op (gimple_assign_rhs2 (stmt));
695 res_op->set_op (code, type, rhs1, rhs2);
696 return true;
698 case GIMPLE_TERNARY_RHS:
700 tree rhs1 = gimple_assign_rhs1 (stmt);
701 if (code == COND_EXPR && COMPARISON_CLASS_P (rhs1))
702 rhs1 = valueize_condition (rhs1);
703 else
704 rhs1 = valueize_op (rhs1);
705 tree rhs2 = valueize_op (gimple_assign_rhs2 (stmt));
706 tree rhs3 = valueize_op (gimple_assign_rhs3 (stmt));
707 res_op->set_op (code, type, rhs1, rhs2, rhs3);
708 return true;
710 default:
711 gcc_unreachable ();
713 break;
716 case GIMPLE_CALL:
717 /* ??? This way we can't simplify calls with side-effects. */
718 if (gimple_call_lhs (stmt) != NULL_TREE
719 && gimple_call_num_args (stmt) >= 1
720 && gimple_call_num_args (stmt) <= 5)
722 combined_fn cfn;
723 if (gimple_call_internal_p (stmt))
724 cfn = as_combined_fn (gimple_call_internal_fn (stmt));
725 else
727 tree fn = gimple_call_fn (stmt);
728 if (!fn)
729 return false;
731 fn = valueize_op (fn);
732 if (TREE_CODE (fn) != ADDR_EXPR
733 || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
734 return false;
736 tree decl = TREE_OPERAND (fn, 0);
737 if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL
738 || !gimple_builtin_call_types_compatible_p (stmt, decl))
739 return false;
741 cfn = as_combined_fn (DECL_FUNCTION_CODE (decl));
744 unsigned int num_args = gimple_call_num_args (stmt);
745 res_op->set_op (cfn, TREE_TYPE (gimple_call_lhs (stmt)), num_args);
746 for (unsigned i = 0; i < num_args; ++i)
747 res_op->ops[i] = valueize_op (gimple_call_arg (stmt, i));
748 return true;
750 break;
752 case GIMPLE_COND:
754 tree lhs = valueize_op (gimple_cond_lhs (stmt));
755 tree rhs = valueize_op (gimple_cond_rhs (stmt));
756 res_op->set_op (gimple_cond_code (stmt), boolean_type_node, lhs, rhs);
757 return true;
760 default:
761 break;
764 return false;
767 /* Try to describe STMT in RES_OP, returning true on success.
768 For GIMPLE_CONDs, describe the condition that is being tested.
769 For GIMPLE_ASSIGNs, describe the rhs of the assignment.
770 For GIMPLE_CALLs, describe the call. */
772 bool
773 gimple_extract_op (gimple *stmt, gimple_match_op *res_op)
775 auto nop = [](tree op) { return op; };
776 return gimple_extract (stmt, res_op, nop, nop);
779 /* The main STMT based simplification entry. It is used by the fold_stmt
780 and the fold_stmt_to_constant APIs. */
782 bool
783 gimple_simplify (gimple *stmt, gimple_match_op *res_op, gimple_seq *seq,
784 tree (*valueize)(tree), tree (*top_valueize)(tree))
786 bool valueized = false;
787 auto valueize_op = [&](tree op)
789 return do_valueize (op, top_valueize, valueized);
791 auto valueize_condition = [&](tree op) -> tree
793 bool cond_valueized = false;
794 tree lhs = do_valueize (TREE_OPERAND (op, 0), top_valueize,
795 cond_valueized);
796 tree rhs = do_valueize (TREE_OPERAND (op, 1), top_valueize,
797 cond_valueized);
798 gimple_match_op res_op2 (res_op->cond, TREE_CODE (op),
799 TREE_TYPE (op), lhs, rhs);
800 if ((gimple_resimplify2 (seq, &res_op2, valueize)
801 || cond_valueized)
802 && res_op2.code.is_tree_code ())
804 auto code = tree_code (res_op2.code);
805 if (TREE_CODE_CLASS (code) == tcc_comparison)
807 valueized = true;
808 return build2 (code, TREE_TYPE (op),
809 res_op2.ops[0], res_op2.ops[1]);
811 else if (code == SSA_NAME
812 || code == INTEGER_CST
813 || code == VECTOR_CST)
815 valueized = true;
816 return res_op2.ops[0];
819 return valueize_op (op);
822 if (!gimple_extract (stmt, res_op, valueize_op, valueize_condition))
823 return false;
825 if (res_op->code.is_internal_fn ())
827 internal_fn ifn = internal_fn (res_op->code);
828 if (try_conditional_simplification (ifn, res_op, seq, valueize))
829 return true;
832 if (!res_op->reverse
833 && res_op->num_ops
834 && res_op->resimplify (seq, valueize))
835 return true;
837 return valueized;
840 /* Helper that matches and simplifies the toplevel result from
841 a gimple_simplify run (where we don't want to build
842 a stmt in case it's used in in-place folding). Replaces
843 RES_OP with a simplified and/or canonicalized result and
844 returns whether any change was made. */
846 static bool
847 gimple_resimplify1 (gimple_seq *seq, gimple_match_op *res_op,
848 tree (*valueize)(tree))
850 if (constant_for_folding (res_op->ops[0]))
852 tree tem = NULL_TREE;
853 if (res_op->code.is_tree_code ())
855 auto code = tree_code (res_op->code);
856 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
857 && TREE_CODE_LENGTH (code) == 1)
858 tem = const_unop (code, res_op->type, res_op->ops[0]);
860 else
861 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
862 res_op->ops[0]);
863 if (tem != NULL_TREE
864 && CONSTANT_CLASS_P (tem))
866 if (TREE_OVERFLOW_P (tem))
867 tem = drop_tree_overflow (tem);
868 res_op->set_value (tem);
869 maybe_resimplify_conditional_op (seq, res_op, valueize);
870 return true;
874 /* Limit recursion, there are cases like PR80887 and others, for
875 example when value-numbering presents us with unfolded expressions
876 that we are really not prepared to handle without eventual
877 oscillation like ((_50 + 0) + 8) where _50 gets mapped to _50
878 itself as available expression. */
879 static unsigned depth;
880 if (depth > 10)
882 if (dump_file && (dump_flags & TDF_FOLDING))
883 fprintf (dump_file, "Aborting expression simplification due to "
884 "deep recursion\n");
885 return false;
888 ++depth;
889 gimple_match_op res_op2 (*res_op);
890 if (gimple_simplify (&res_op2, seq, valueize,
891 res_op->code, res_op->type, res_op->ops[0]))
893 --depth;
894 *res_op = res_op2;
895 return true;
897 --depth;
899 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
900 return true;
902 return false;
905 /* Helper that matches and simplifies the toplevel result from
906 a gimple_simplify run (where we don't want to build
907 a stmt in case it's used in in-place folding). Replaces
908 RES_OP with a simplified and/or canonicalized result and
909 returns whether any change was made. */
911 static bool
912 gimple_resimplify2 (gimple_seq *seq, gimple_match_op *res_op,
913 tree (*valueize)(tree))
915 if (constant_for_folding (res_op->ops[0])
916 && constant_for_folding (res_op->ops[1]))
918 tree tem = NULL_TREE;
919 if (res_op->code.is_tree_code ())
921 auto code = tree_code (res_op->code);
922 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
923 && TREE_CODE_LENGTH (code) == 2)
924 tem = const_binop (code, res_op->type,
925 res_op->ops[0], res_op->ops[1]);
927 else
928 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
929 res_op->ops[0], res_op->ops[1]);
930 if (tem != NULL_TREE
931 && CONSTANT_CLASS_P (tem))
933 if (TREE_OVERFLOW_P (tem))
934 tem = drop_tree_overflow (tem);
935 res_op->set_value (tem);
936 maybe_resimplify_conditional_op (seq, res_op, valueize);
937 return true;
941 /* Canonicalize operand order. */
942 bool canonicalized = false;
943 bool is_comparison
944 = (res_op->code.is_tree_code ()
945 && TREE_CODE_CLASS (tree_code (res_op->code)) == tcc_comparison);
946 if ((is_comparison || commutative_binary_op_p (res_op->code, res_op->type))
947 && tree_swap_operands_p (res_op->ops[0], res_op->ops[1]))
949 std::swap (res_op->ops[0], res_op->ops[1]);
950 if (is_comparison)
951 res_op->code = swap_tree_comparison (tree_code (res_op->code));
952 canonicalized = true;
955 /* Limit recursion, see gimple_resimplify1. */
956 static unsigned depth;
957 if (depth > 10)
959 if (dump_file && (dump_flags & TDF_FOLDING))
960 fprintf (dump_file, "Aborting expression simplification due to "
961 "deep recursion\n");
962 return false;
965 ++depth;
966 gimple_match_op res_op2 (*res_op);
967 if (gimple_simplify (&res_op2, seq, valueize,
968 res_op->code, res_op->type,
969 res_op->ops[0], res_op->ops[1]))
971 --depth;
972 *res_op = res_op2;
973 return true;
975 --depth;
977 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
978 return true;
980 return canonicalized;
983 /* Helper that matches and simplifies the toplevel result from
984 a gimple_simplify run (where we don't want to build
985 a stmt in case it's used in in-place folding). Replaces
986 RES_OP with a simplified and/or canonicalized result and
987 returns whether any change was made. */
989 static bool
990 gimple_resimplify3 (gimple_seq *seq, gimple_match_op *res_op,
991 tree (*valueize)(tree))
993 if (constant_for_folding (res_op->ops[0])
994 && constant_for_folding (res_op->ops[1])
995 && constant_for_folding (res_op->ops[2]))
997 tree tem = NULL_TREE;
998 if (res_op->code.is_tree_code ())
1000 auto code = tree_code (res_op->code);
1001 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
1002 && TREE_CODE_LENGTH (code) == 3)
1003 tem = fold_ternary/*_to_constant*/ (code, res_op->type,
1004 res_op->ops[0], res_op->ops[1],
1005 res_op->ops[2]);
1007 else
1008 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
1009 res_op->ops[0], res_op->ops[1], res_op->ops[2]);
1010 if (tem != NULL_TREE
1011 && CONSTANT_CLASS_P (tem))
1013 if (TREE_OVERFLOW_P (tem))
1014 tem = drop_tree_overflow (tem);
1015 res_op->set_value (tem);
1016 maybe_resimplify_conditional_op (seq, res_op, valueize);
1017 return true;
1021 /* Canonicalize operand order. */
1022 bool canonicalized = false;
1023 int argno = first_commutative_argument (res_op->code, res_op->type);
1024 if (argno >= 0
1025 && tree_swap_operands_p (res_op->ops[argno], res_op->ops[argno + 1]))
1027 std::swap (res_op->ops[argno], res_op->ops[argno + 1]);
1028 canonicalized = true;
1031 /* Limit recursion, see gimple_resimplify1. */
1032 static unsigned depth;
1033 if (depth > 10)
1035 if (dump_file && (dump_flags & TDF_FOLDING))
1036 fprintf (dump_file, "Aborting expression simplification due to "
1037 "deep recursion\n");
1038 return false;
1041 ++depth;
1042 gimple_match_op res_op2 (*res_op);
1043 if (gimple_simplify (&res_op2, seq, valueize,
1044 res_op->code, res_op->type,
1045 res_op->ops[0], res_op->ops[1], res_op->ops[2]))
1047 --depth;
1048 *res_op = res_op2;
1049 return true;
1051 --depth;
1053 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
1054 return true;
1056 return canonicalized;
1059 /* Helper that matches and simplifies the toplevel result from
1060 a gimple_simplify run (where we don't want to build
1061 a stmt in case it's used in in-place folding). Replaces
1062 RES_OP with a simplified and/or canonicalized result and
1063 returns whether any change was made. */
1065 static bool
1066 gimple_resimplify4 (gimple_seq *seq, gimple_match_op *res_op,
1067 tree (*valueize)(tree))
1069 /* No constant folding is defined for four-operand functions. */
1071 /* Canonicalize operand order. */
1072 bool canonicalized = false;
1073 int argno = first_commutative_argument (res_op->code, res_op->type);
1074 if (argno >= 0
1075 && tree_swap_operands_p (res_op->ops[argno], res_op->ops[argno + 1]))
1077 std::swap (res_op->ops[argno], res_op->ops[argno + 1]);
1078 canonicalized = true;
1081 /* Limit recursion, see gimple_resimplify1. */
1082 static unsigned depth;
1083 if (depth > 10)
1085 if (dump_file && (dump_flags & TDF_FOLDING))
1086 fprintf (dump_file, "Aborting expression simplification due to "
1087 "deep recursion\n");
1088 return false;
1091 ++depth;
1092 gimple_match_op res_op2 (*res_op);
1093 if (gimple_simplify (&res_op2, seq, valueize,
1094 res_op->code, res_op->type,
1095 res_op->ops[0], res_op->ops[1], res_op->ops[2],
1096 res_op->ops[3]))
1098 --depth;
1099 *res_op = res_op2;
1100 return true;
1102 --depth;
1104 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
1105 return true;
1107 return canonicalized;
1110 /* Helper that matches and simplifies the toplevel result from
1111 a gimple_simplify run (where we don't want to build
1112 a stmt in case it's used in in-place folding). Replaces
1113 RES_OP with a simplified and/or canonicalized result and
1114 returns whether any change was made. */
1116 static bool
1117 gimple_resimplify5 (gimple_seq *seq, gimple_match_op *res_op,
1118 tree (*valueize)(tree))
1120 /* No constant folding is defined for five-operand functions. */
1122 /* Canonicalize operand order. */
1123 bool canonicalized = false;
1124 int argno = first_commutative_argument (res_op->code, res_op->type);
1125 if (argno >= 0
1126 && tree_swap_operands_p (res_op->ops[argno], res_op->ops[argno + 1]))
1128 std::swap (res_op->ops[argno], res_op->ops[argno + 1]);
1129 canonicalized = true;
1132 gimple_match_op res_op2 (*res_op);
1133 if (gimple_simplify (&res_op2, seq, valueize,
1134 res_op->code, res_op->type,
1135 res_op->ops[0], res_op->ops[1], res_op->ops[2],
1136 res_op->ops[3], res_op->ops[4]))
1138 *res_op = res_op2;
1139 return true;
1142 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
1143 return true;
1145 return canonicalized;
1148 /* Return a canonical form for CODE when operating on TYPE. The idea
1149 is to remove redundant ways of representing the same operation so
1150 that code_helpers can be hashed and compared for equality.
1152 The only current canonicalization is to replace built-in functions
1153 with internal functions, in cases where internal-fn.def defines
1154 such an internal function.
1156 Note that the new code_helper cannot necessarily be used in place of
1157 the original code_helper. For example, the new code_helper might be
1158 an internal function that the target does not support. */
1160 code_helper
1161 canonicalize_code (code_helper code, tree type)
1163 if (code.is_fn_code ())
1164 return associated_internal_fn (combined_fn (code), type);
1165 return code;
1168 /* Return true if CODE is a binary operation and if CODE is commutative when
1169 operating on type TYPE. */
1171 bool
1172 commutative_binary_op_p (code_helper code, tree type)
1174 if (code.is_tree_code ())
1175 return commutative_tree_code (tree_code (code));
1176 auto cfn = combined_fn (code);
1177 return commutative_binary_fn_p (associated_internal_fn (cfn, type));
1180 /* Return true if CODE represents a ternary operation and if the first two
1181 operands are commutative when CODE is operating on TYPE. */
1183 bool
1184 commutative_ternary_op_p (code_helper code, tree type)
1186 if (code.is_tree_code ())
1187 return commutative_ternary_tree_code (tree_code (code));
1188 auto cfn = combined_fn (code);
1189 return commutative_ternary_fn_p (associated_internal_fn (cfn, type));
1192 /* If CODE is commutative in two consecutive operands, return the
1193 index of the first, otherwise return -1. */
1196 first_commutative_argument (code_helper code, tree type)
1198 if (code.is_tree_code ())
1200 auto tcode = tree_code (code);
1201 if (commutative_tree_code (tcode)
1202 || commutative_ternary_tree_code (tcode))
1203 return 0;
1204 return -1;
1206 auto cfn = combined_fn (code);
1207 return first_commutative_argument (associated_internal_fn (cfn, type));
1210 /* Return true if CODE is a binary operation that is associative when
1211 operating on type TYPE. */
1213 bool
1214 associative_binary_op_p (code_helper code, tree type)
1216 if (code.is_tree_code ())
1217 return associative_tree_code (tree_code (code));
1218 auto cfn = combined_fn (code);
1219 return associative_binary_fn_p (associated_internal_fn (cfn, type));
1222 /* Return true if the target directly supports operation CODE on type TYPE.
1223 QUERY_TYPE acts as for optab_for_tree_code. */
1225 bool
1226 directly_supported_p (code_helper code, tree type, optab_subtype query_type)
1228 if (code.is_tree_code ())
1230 direct_optab optab = optab_for_tree_code (tree_code (code), type,
1231 query_type);
1232 return (optab != unknown_optab
1233 && optab_handler (optab, TYPE_MODE (type)) != CODE_FOR_nothing);
1235 gcc_assert (query_type == optab_default
1236 || (query_type == optab_vector && VECTOR_TYPE_P (type))
1237 || (query_type == optab_scalar && !VECTOR_TYPE_P (type)));
1238 internal_fn ifn = associated_internal_fn (combined_fn (code), type);
1239 return (direct_internal_fn_p (ifn)
1240 && direct_internal_fn_supported_p (ifn, type, OPTIMIZE_FOR_SPEED));
1243 /* A wrapper around the internal-fn.cc versions of get_conditional_internal_fn
1244 for a code_helper CODE operating on type TYPE. */
1246 internal_fn
1247 get_conditional_internal_fn (code_helper code, tree type)
1249 if (code.is_tree_code ())
1250 return get_conditional_internal_fn (tree_code (code));
1251 auto cfn = combined_fn (code);
1252 return get_conditional_internal_fn (associated_internal_fn (cfn, type));