c++: retval dtor on rethrow [PR112301]
[official-gcc.git] / gcc / gimple-match-exports.cc
blobb36027b0bad783e3180d0ec74deb3a07b12906fc
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);
63 extern bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
64 code_helper, tree, tree, tree, tree, tree, tree,
65 tree);
66 extern bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
67 code_helper, tree, tree, tree, tree, tree, tree,
68 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 *,
74 tree (*)(tree));
75 tree gimple_simplify (enum tree_code, tree, tree, tree, gimple_seq *,
76 tree (*)(tree));
77 tree gimple_simplify (enum tree_code, tree, tree, tree, tree, gimple_seq *,
78 tree (*)(tree));
79 tree gimple_simplify (combined_fn, tree, tree, gimple_seq *,
80 tree (*)(tree));
81 tree gimple_simplify (combined_fn, tree, tree, tree, gimple_seq *,
82 tree (*)(tree));
83 tree gimple_simplify (combined_fn, tree, tree, tree, tree, gimple_seq *,
84 tree (*)(tree));
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. */
105 bool
106 gimple_match_op::resimplify (gimple_seq *seq, tree (*valueize)(tree))
108 switch (num_ops)
110 case 1:
111 return gimple_resimplify1 (seq, this, valueize);
112 case 2:
113 return gimple_resimplify2 (seq, this, valueize);
114 case 3:
115 return gimple_resimplify3 (seq, this, valueize);
116 case 4:
117 return gimple_resimplify4 (seq, this, valueize);
118 case 5:
119 return gimple_resimplify5 (seq, this, valueize);
120 case 6:
121 return gimple_resimplify6 (seq, this, valueize);
122 case 7:
123 return gimple_resimplify7 (seq, this, valueize);
124 default:
125 gcc_unreachable ();
129 /* Return whether T is a constant that we'll dispatch to fold to
130 evaluate fully constant expressions. */
132 static inline bool
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. */
144 static bool
145 convert_conditional_op (gimple_match_op *orig_op,
146 gimple_match_op *new_op)
148 internal_fn ifn;
149 if (orig_op->code.is_tree_code ())
150 ifn = get_conditional_internal_fn ((tree_code) orig_op->code);
151 else
153 auto cfn = combined_fn (orig_op->code);
154 if (!internal_fn_p (cfn))
155 return false;
156 ifn = get_conditional_internal_fn (as_internal_fn (cfn));
158 if (ifn == IFN_LAST)
159 return false;
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);
166 num_cond_ops = 4;
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;
173 if (!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;
182 return true;
184 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
185 VALUEIZED to true if valueization changed OP. */
187 inline tree
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)
195 op = tem;
196 valueized = true;
199 return 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. */
205 void
206 maybe_build_generic_op (gimple_match_op *res_op)
208 tree_code code = (tree_code) res_op->code;
209 tree val;
210 switch (code)
212 case REALPART_EXPR:
213 case IMAGPART_EXPR:
214 case VIEW_CONVERT_EXPR:
215 val = build1 (code, res_op->type, res_op->ops[0]);
216 res_op->set_value (val);
217 break;
218 case BIT_FIELD_REF:
219 val = build3 (code, res_op->type, res_op->ops[0], res_op->ops[1],
220 res_op->ops[2]);
221 REF_REVERSE_STORAGE_ORDER (val) = res_op->reverse;
222 res_op->set_value (val);
223 break;
224 default:;
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. */
231 static gcall *
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,
237 res_op->ops);
238 if (!direct_internal_fn_supported_p (fn, types, OPTIMIZE_FOR_BOTH))
239 return NULL;
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. */
258 static bool
259 maybe_resimplify_conditional_op (gimple_seq *seq, gimple_match_op *res_op,
260 tree (*valueize) (tree))
262 if (!res_op->cond.cond)
263 return false;
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;
275 return false;
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;
282 bool op_could_trap;
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]);
289 else
290 op_could_trap = operation_could_trap_p ((tree_code) res_op->code,
291 FLOAT_TYPE_P (res_op->type),
292 honor_trapv,
293 res_op->op_or_null (1));
295 if (!op_could_trap)
297 res_op->cond.cond = NULL_TREE;
298 return false;
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
304 simplified. */
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);
313 *res_op = new_op;
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))
321 *res_op = new_op;
323 return false;
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. */
342 static bool
343 try_conditional_simplification (internal_fn ifn, gimple_match_op *res_op,
344 gimple_seq *seq, tree (*valueize) (tree))
346 code_helper op;
347 tree_code code = conditional_internal_fn_code (ifn);
348 int len_index = internal_fn_len_index (ifn);
349 if (code != ERROR_MARK)
350 op = code;
351 else
353 ifn = get_unconditional_internal_fn (ifn);
354 if (ifn == IFN_LAST)
355 return false;
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;
363 tree else_value
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)
374 case 1:
375 if (!gimple_resimplify1 (seq, &cond_op, valueize))
376 return false;
377 break;
378 case 2:
379 if (!gimple_resimplify2 (seq, &cond_op, valueize))
380 return false;
381 break;
382 case 3:
383 if (!gimple_resimplify3 (seq, &cond_op, valueize))
384 return false;
385 break;
386 default:
387 gcc_unreachable ();
389 *res_op = cond_op;
390 maybe_resimplify_conditional_op (seq, res_op, valueize);
391 return true;
394 /* Helper for the autogenerated code, valueize OP. */
396 tree
397 do_valueize (tree (*valueize)(tree), tree op)
399 if (valueize && TREE_CODE (op) == SSA_NAME)
401 tree tem = valueize (op);
402 if (tem)
403 return tem;
405 return 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. */
413 tree
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)
423 return NULL_TREE;
425 if (res_op->code.is_tree_code ())
427 if (!res
428 && gimple_simplified_result_is_gimple_val (res_op))
429 return ops[0];
430 if (mprts_hook)
432 tree tem = mprts_hook (res_op);
433 if (tem)
434 return tem;
438 if (!seq)
439 return NULL_TREE;
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]))
446 return NULL_TREE;
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)))
452 return NULL_TREE;
454 if (res_op->code.is_tree_code ())
456 auto code = tree_code (res_op->code);
457 if (!res)
459 if (gimple_in_ssa_p (cfun))
460 res = make_ssa_name (res_op->type);
461 else
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);
470 return res;
472 else
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);
482 if (!new_stmt)
483 return NULL_TREE;
485 else
487 /* Find the function we want to call. */
488 tree decl = builtin_decl_implicit (as_builtin_fn (fn));
489 if (!decl)
490 return NULL;
492 /* We can't and should not emit calls to non-const functions. */
493 if (!(flags_from_decl_or_type (decl) & ECF_CONST))
494 return NULL;
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));
503 if (!res)
505 if (gimple_in_ssa_p (cfun))
506 res = make_ssa_name (res_op->type);
507 else
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);
512 return res;
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. */
526 /* Unary ops. */
528 tree
529 gimple_simplify (enum tree_code code, tree type,
530 tree op0,
531 gimple_seq *seq, tree (*valueize)(tree))
533 if (constant_for_folding (op0))
535 tree res = const_unop (code, type, op0);
536 if (res != NULL_TREE
537 && CONSTANT_CLASS_P (res))
538 return res;
541 gimple_match_op res_op;
542 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0))
543 return NULL_TREE;
544 return maybe_push_res_to_seq (&res_op, seq);
547 /* Binary ops. */
549 tree
550 gimple_simplify (enum tree_code code, tree type,
551 tree op0, tree op1,
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);
557 if (res != NULL_TREE
558 && CONSTANT_CLASS_P (res))
559 return res;
562 /* Canonicalize operand order both for matching and fallback stmt
563 generation. */
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))
575 return NULL_TREE;
576 return maybe_push_res_to_seq (&res_op, seq);
579 /* Ternary ops. */
581 tree
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);
590 if (res != NULL_TREE
591 && CONSTANT_CLASS_P (res))
592 return res;
595 /* Canonicalize operand order both for matching and fallback stmt
596 generation. */
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))
603 return NULL_TREE;
604 return maybe_push_res_to_seq (&res_op, seq);
607 /* Builtin or internal function with one argument. */
609 tree
610 gimple_simplify (combined_fn fn, tree type,
611 tree arg0,
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))
618 return res;
621 gimple_match_op res_op;
622 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0))
623 return NULL_TREE;
624 return maybe_push_res_to_seq (&res_op, seq);
627 /* Builtin or internal function with two arguments. */
629 tree
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))
639 return res;
642 gimple_match_op res_op;
643 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1))
644 return NULL_TREE;
645 return maybe_push_res_to_seq (&res_op, seq);
648 /* Builtin or internal function with three arguments. */
650 tree
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))
661 return res;
664 gimple_match_op res_op;
665 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1, arg2))
666 return NULL_TREE;
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
672 an operand, call:
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>
680 inline bool
681 gimple_extract (gimple *stmt, gimple_match_op *res_op,
682 ValueizeOp valueize_op,
683 ValueizeCondition valueize_condition)
685 switch (gimple_code (stmt))
687 case GIMPLE_ASSIGN:
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));
700 return true;
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));
710 return true;
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));
716 return true;
718 break;
719 case GIMPLE_UNARY_RHS:
721 tree rhs1 = gimple_assign_rhs1 (stmt);
722 res_op->set_op (code, type, valueize_op (rhs1));
723 return true;
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);
730 return true;
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);
737 else
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);
742 return true;
744 default:
745 gcc_unreachable ();
747 break;
750 case GIMPLE_CALL:
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)
756 combined_fn cfn;
757 if (gimple_call_internal_p (stmt))
758 cfn = as_combined_fn (gimple_call_internal_fn (stmt));
759 else
761 tree fn = gimple_call_fn (stmt);
762 if (!fn)
763 return false;
765 fn = valueize_op (fn);
766 if (TREE_CODE (fn) != ADDR_EXPR
767 || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
768 return false;
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))
773 return false;
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));
782 return true;
784 break;
786 case GIMPLE_COND:
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);
791 return true;
794 default:
795 break;
798 return false;
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. */
806 bool
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. */
816 bool
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,
829 cond_valueized);
830 tree rhs = do_valueize (TREE_OPERAND (op, 1), top_valueize,
831 cond_valueized);
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)
835 || cond_valueized)
836 && res_op2.code.is_tree_code ())
838 auto code = tree_code (res_op2.code);
839 if (TREE_CODE_CLASS (code) == tcc_comparison)
841 valueized = true;
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)
849 valueized = true;
850 return res_op2.ops[0];
853 return valueize_op (op);
856 if (!gimple_extract (stmt, res_op, valueize_op, valueize_condition))
857 return false;
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))
863 return true;
866 if (!res_op->reverse
867 && res_op->num_ops
868 && res_op->resimplify (seq, valueize))
869 return true;
871 return valueized;
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. */
880 static bool
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]);
894 else
895 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
896 res_op->ops[0]);
897 if (tem != NULL_TREE
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);
904 return true;
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;
914 if (depth > 10)
916 if (dump_file && (dump_flags & TDF_FOLDING))
917 fprintf (dump_file, "Aborting expression simplification due to "
918 "deep recursion\n");
919 return false;
922 ++depth;
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]))
927 --depth;
928 *res_op = res_op2;
929 return true;
931 --depth;
933 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
934 return true;
936 return false;
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. */
945 static bool
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]);
961 else
962 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
963 res_op->ops[0], res_op->ops[1]);
964 if (tem != NULL_TREE
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);
971 return true;
975 /* Canonicalize operand order. */
976 bool canonicalized = false;
977 bool is_comparison
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]);
984 if (is_comparison)
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;
991 if (depth > 10)
993 if (dump_file && (dump_flags & TDF_FOLDING))
994 fprintf (dump_file, "Aborting expression simplification due to "
995 "deep recursion\n");
996 return false;
999 ++depth;
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]))
1005 --depth;
1006 *res_op = res_op2;
1007 return true;
1009 --depth;
1011 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
1012 return true;
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. */
1023 static bool
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],
1039 res_op->ops[2]);
1041 else
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);
1051 return true;
1055 /* Canonicalize operand order. */
1056 bool canonicalized = false;
1057 int argno = first_commutative_argument (res_op->code, res_op->type);
1058 if (argno >= 0
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;
1067 if (depth > 10)
1069 if (dump_file && (dump_flags & TDF_FOLDING))
1070 fprintf (dump_file, "Aborting expression simplification due to "
1071 "deep recursion\n");
1072 return false;
1075 ++depth;
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]))
1081 --depth;
1082 *res_op = res_op2;
1083 return true;
1085 --depth;
1087 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
1088 return true;
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. */
1099 static bool
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);
1108 if (argno >= 0
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;
1117 if (depth > 10)
1119 if (dump_file && (dump_flags & TDF_FOLDING))
1120 fprintf (dump_file, "Aborting expression simplification due to "
1121 "deep recursion\n");
1122 return false;
1125 ++depth;
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],
1130 res_op->ops[3]))
1132 --depth;
1133 *res_op = res_op2;
1134 return true;
1136 --depth;
1138 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
1139 return true;
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. */
1150 static bool
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);
1159 if (argno >= 0
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]))
1172 *res_op = res_op2;
1173 return true;
1176 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
1177 return true;
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. */
1188 static bool
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);
1197 if (argno >= 0
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]))
1210 *res_op = res_op2;
1211 return true;
1214 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
1215 return true;
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. */
1226 static bool
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);
1235 if (argno >= 0
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],
1247 res_op->ops[6]))
1249 *res_op = res_op2;
1250 return true;
1253 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
1254 return true;
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. */
1271 code_helper
1272 canonicalize_code (code_helper code, tree type)
1274 if (code.is_fn_code ())
1275 return associated_internal_fn (combined_fn (code), type);
1276 return code;
1279 /* Return true if CODE is a binary operation and if CODE is commutative when
1280 operating on type TYPE. */
1282 bool
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. */
1294 bool
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))
1314 return 0;
1315 return -1;
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. */
1324 bool
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. */
1336 bool
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,
1342 query_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. */
1357 internal_fn
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));