Extend tree code folds to IFN_COND_*
[official-gcc.git] / gcc / gimple-match-head.c
blobe165a77132bd057716b6ab0070d2034fb4009a6b
1 /* Preamble and helpers for the autogenerated gimple-match.c file.
2 Copyright (C) 2014-2018 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 "fold-const.h"
31 #include "fold-const-call.h"
32 #include "stor-layout.h"
33 #include "gimple-fold.h"
34 #include "calls.h"
35 #include "tree-dfa.h"
36 #include "builtins.h"
37 #include "gimple-match.h"
38 #include "tree-pass.h"
39 #include "internal-fn.h"
40 #include "case-cfn-macros.h"
41 #include "gimplify.h"
42 #include "optabs-tree.h"
43 #include "tree-eh.h"
46 /* Forward declarations of the private auto-generated matchers.
47 They expect valueized operands in canonical order and do not
48 perform simplification of all-constant operands. */
49 static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
50 code_helper, tree, tree);
51 static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
52 code_helper, tree, tree, tree);
53 static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
54 code_helper, tree, tree, tree, tree);
55 static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
56 code_helper, tree, tree, tree, tree, tree);
58 const unsigned int gimple_match_op::MAX_NUM_OPS;
60 /* Return whether T is a constant that we'll dispatch to fold to
61 evaluate fully constant expressions. */
63 static inline bool
64 constant_for_folding (tree t)
66 return (CONSTANT_CLASS_P (t)
67 /* The following is only interesting to string builtins. */
68 || (TREE_CODE (t) == ADDR_EXPR
69 && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST));
72 /* Try to convert conditional operation ORIG_OP into an IFN_COND_*
73 operation. Return true on success, storing the new operation in NEW_OP. */
75 static bool
76 convert_conditional_op (gimple_match_op *orig_op,
77 gimple_match_op *new_op)
79 internal_fn ifn;
80 if (orig_op->code.is_tree_code ())
81 ifn = get_conditional_internal_fn ((tree_code) orig_op->code);
82 else
83 return false;
84 if (ifn == IFN_LAST)
85 return false;
86 unsigned int num_ops = orig_op->num_ops;
87 new_op->set_op (as_combined_fn (ifn), orig_op->type, num_ops + 2);
88 new_op->ops[0] = orig_op->cond.cond;
89 for (unsigned int i = 0; i < num_ops; ++i)
90 new_op->ops[i + 1] = orig_op->ops[i];
91 tree else_value = orig_op->cond.else_value;
92 if (!else_value)
93 else_value = targetm.preferred_else_value (ifn, orig_op->type,
94 num_ops, orig_op->ops);
95 new_op->ops[num_ops + 1] = else_value;
96 return true;
99 /* RES_OP is the result of a simplification. If it is conditional,
100 try to replace it with the equivalent UNCOND form, such as an
101 IFN_COND_* call or a VEC_COND_EXPR. Also try to resimplify the
102 result of the replacement if appropriate, adding any new statements to
103 SEQ and using VALUEIZE as the valueization function. Return true if
104 this resimplification occurred and resulted in at least one change. */
106 static bool
107 maybe_resimplify_conditional_op (gimple_seq *seq, gimple_match_op *res_op,
108 tree (*valueize) (tree))
110 if (!res_op->cond.cond)
111 return false;
113 if (!res_op->cond.else_value
114 && res_op->code.is_tree_code ())
116 /* The "else" value doesn't matter. If the "then" value is a
117 gimple value, just use it unconditionally. This isn't a
118 simplification in itself, since there was no operation to
119 build in the first place. */
120 if (gimple_simplified_result_is_gimple_val (res_op))
122 res_op->cond.cond = NULL_TREE;
123 return false;
126 /* Likewise if the operation would not trap. */
127 bool honor_trapv = (INTEGRAL_TYPE_P (res_op->type)
128 && TYPE_OVERFLOW_TRAPS (res_op->type));
129 if (!operation_could_trap_p ((tree_code) res_op->code,
130 FLOAT_TYPE_P (res_op->type),
131 honor_trapv, res_op->op_or_null (1)))
133 res_op->cond.cond = NULL_TREE;
134 return false;
138 /* If the "then" value is a gimple value and the "else" value matters,
139 create a VEC_COND_EXPR between them, then see if it can be further
140 simplified. */
141 gimple_match_op new_op;
142 if (res_op->cond.else_value
143 && VECTOR_TYPE_P (res_op->type)
144 && gimple_simplified_result_is_gimple_val (res_op))
146 new_op.set_op (VEC_COND_EXPR, res_op->type,
147 res_op->cond.cond, res_op->ops[0],
148 res_op->cond.else_value);
149 *res_op = new_op;
150 return gimple_resimplify3 (seq, res_op, valueize);
153 /* Otherwise try rewriting the operation as an IFN_COND_* call.
154 Again, this isn't a simplification in itself, since it's what
155 RES_OP already described. */
156 if (convert_conditional_op (res_op, &new_op))
157 *res_op = new_op;
159 return false;
162 /* Helper that matches and simplifies the toplevel result from
163 a gimple_simplify run (where we don't want to build
164 a stmt in case it's used in in-place folding). Replaces
165 RES_OP with a simplified and/or canonicalized result and
166 returns whether any change was made. */
168 bool
169 gimple_resimplify1 (gimple_seq *seq, gimple_match_op *res_op,
170 tree (*valueize)(tree))
172 if (constant_for_folding (res_op->ops[0]))
174 tree tem = NULL_TREE;
175 if (res_op->code.is_tree_code ())
176 tem = const_unop (res_op->code, res_op->type, res_op->ops[0]);
177 else
178 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
179 res_op->ops[0]);
180 if (tem != NULL_TREE
181 && CONSTANT_CLASS_P (tem))
183 if (TREE_OVERFLOW_P (tem))
184 tem = drop_tree_overflow (tem);
185 res_op->set_value (tem);
186 maybe_resimplify_conditional_op (seq, res_op, valueize);
187 return true;
191 /* Limit recursion, there are cases like PR80887 and others, for
192 example when value-numbering presents us with unfolded expressions
193 that we are really not prepared to handle without eventual
194 oscillation like ((_50 + 0) + 8) where _50 gets mapped to _50
195 itself as available expression. */
196 static unsigned depth;
197 if (depth > 10)
199 if (dump_file && (dump_flags & TDF_FOLDING))
200 fprintf (dump_file, "Aborting expression simplification due to "
201 "deep recursion\n");
202 return false;
205 ++depth;
206 gimple_match_op res_op2 (*res_op);
207 if (gimple_simplify (&res_op2, seq, valueize,
208 res_op->code, res_op->type, res_op->ops[0]))
210 --depth;
211 *res_op = res_op2;
212 return true;
214 --depth;
216 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
217 return true;
219 return false;
222 /* Helper that matches and simplifies the toplevel result from
223 a gimple_simplify run (where we don't want to build
224 a stmt in case it's used in in-place folding). Replaces
225 RES_OP with a simplified and/or canonicalized result and
226 returns whether any change was made. */
228 bool
229 gimple_resimplify2 (gimple_seq *seq, gimple_match_op *res_op,
230 tree (*valueize)(tree))
232 if (constant_for_folding (res_op->ops[0])
233 && constant_for_folding (res_op->ops[1]))
235 tree tem = NULL_TREE;
236 if (res_op->code.is_tree_code ())
237 tem = const_binop (res_op->code, res_op->type,
238 res_op->ops[0], res_op->ops[1]);
239 else
240 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
241 res_op->ops[0], res_op->ops[1]);
242 if (tem != NULL_TREE
243 && CONSTANT_CLASS_P (tem))
245 if (TREE_OVERFLOW_P (tem))
246 tem = drop_tree_overflow (tem);
247 res_op->set_value (tem);
248 maybe_resimplify_conditional_op (seq, res_op, valueize);
249 return true;
253 /* Canonicalize operand order. */
254 bool canonicalized = false;
255 if (res_op->code.is_tree_code ()
256 && (TREE_CODE_CLASS ((enum tree_code) res_op->code) == tcc_comparison
257 || commutative_tree_code (res_op->code))
258 && tree_swap_operands_p (res_op->ops[0], res_op->ops[1]))
260 std::swap (res_op->ops[0], res_op->ops[1]);
261 if (TREE_CODE_CLASS ((enum tree_code) res_op->code) == tcc_comparison)
262 res_op->code = swap_tree_comparison (res_op->code);
263 canonicalized = true;
266 /* Limit recursion, see gimple_resimplify1. */
267 static unsigned depth;
268 if (depth > 10)
270 if (dump_file && (dump_flags & TDF_FOLDING))
271 fprintf (dump_file, "Aborting expression simplification due to "
272 "deep recursion\n");
273 return false;
276 ++depth;
277 gimple_match_op res_op2 (*res_op);
278 if (gimple_simplify (&res_op2, seq, valueize,
279 res_op->code, res_op->type,
280 res_op->ops[0], res_op->ops[1]))
282 --depth;
283 *res_op = res_op2;
284 return true;
286 --depth;
288 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
289 return true;
291 return canonicalized;
294 /* Helper that matches and simplifies the toplevel result from
295 a gimple_simplify run (where we don't want to build
296 a stmt in case it's used in in-place folding). Replaces
297 RES_OP with a simplified and/or canonicalized result and
298 returns whether any change was made. */
300 bool
301 gimple_resimplify3 (gimple_seq *seq, gimple_match_op *res_op,
302 tree (*valueize)(tree))
304 if (constant_for_folding (res_op->ops[0])
305 && constant_for_folding (res_op->ops[1])
306 && constant_for_folding (res_op->ops[2]))
308 tree tem = NULL_TREE;
309 if (res_op->code.is_tree_code ())
310 tem = fold_ternary/*_to_constant*/ (res_op->code, res_op->type,
311 res_op->ops[0], res_op->ops[1],
312 res_op->ops[2]);
313 else
314 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
315 res_op->ops[0], res_op->ops[1], res_op->ops[2]);
316 if (tem != NULL_TREE
317 && CONSTANT_CLASS_P (tem))
319 if (TREE_OVERFLOW_P (tem))
320 tem = drop_tree_overflow (tem);
321 res_op->set_value (tem);
322 maybe_resimplify_conditional_op (seq, res_op, valueize);
323 return true;
327 /* Canonicalize operand order. */
328 bool canonicalized = false;
329 if (res_op->code.is_tree_code ()
330 && commutative_ternary_tree_code (res_op->code)
331 && tree_swap_operands_p (res_op->ops[0], res_op->ops[1]))
333 std::swap (res_op->ops[0], res_op->ops[1]);
334 canonicalized = true;
337 /* Limit recursion, see gimple_resimplify1. */
338 static unsigned depth;
339 if (depth > 10)
341 if (dump_file && (dump_flags & TDF_FOLDING))
342 fprintf (dump_file, "Aborting expression simplification due to "
343 "deep recursion\n");
344 return false;
347 ++depth;
348 gimple_match_op res_op2 (*res_op);
349 if (gimple_simplify (&res_op2, seq, valueize,
350 res_op->code, res_op->type,
351 res_op->ops[0], res_op->ops[1], res_op->ops[2]))
353 --depth;
354 *res_op = res_op2;
355 return true;
357 --depth;
359 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
360 return true;
362 return canonicalized;
365 /* Helper that matches and simplifies the toplevel result from
366 a gimple_simplify run (where we don't want to build
367 a stmt in case it's used in in-place folding). Replaces
368 RES_OP with a simplified and/or canonicalized result and
369 returns whether any change was made. */
371 bool
372 gimple_resimplify4 (gimple_seq *seq, gimple_match_op *res_op,
373 tree (*valueize)(tree))
375 /* No constant folding is defined for four-operand functions. */
377 /* Limit recursion, see gimple_resimplify1. */
378 static unsigned depth;
379 if (depth > 10)
381 if (dump_file && (dump_flags & TDF_FOLDING))
382 fprintf (dump_file, "Aborting expression simplification due to "
383 "deep recursion\n");
384 return false;
387 ++depth;
388 gimple_match_op res_op2 (*res_op);
389 if (gimple_simplify (&res_op2, seq, valueize,
390 res_op->code, res_op->type,
391 res_op->ops[0], res_op->ops[1], res_op->ops[2],
392 res_op->ops[3]))
394 --depth;
395 *res_op = res_op2;
396 return true;
398 --depth;
400 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
401 return true;
403 return false;
406 /* If in GIMPLE the operation described by RES_OP should be single-rhs,
407 build a GENERIC tree for that expression and update RES_OP accordingly. */
409 void
410 maybe_build_generic_op (gimple_match_op *res_op)
412 tree_code code = (tree_code) res_op->code;
413 switch (code)
415 case REALPART_EXPR:
416 case IMAGPART_EXPR:
417 case VIEW_CONVERT_EXPR:
418 res_op->set_value (build1 (code, res_op->type, res_op->ops[0]));
419 break;
420 case BIT_FIELD_REF:
421 res_op->set_value (build3 (code, res_op->type, res_op->ops[0],
422 res_op->ops[1], res_op->ops[2]));
423 break;
424 default:;
428 tree (*mprts_hook) (gimple_match_op *);
430 /* Try to build RES_OP, which is known to be a call to FN. Return null
431 if the target doesn't support the function. */
433 static gcall *
434 build_call_internal (internal_fn fn, gimple_match_op *res_op)
436 if (direct_internal_fn_p (fn))
438 tree_pair types = direct_internal_fn_types (fn, res_op->type,
439 res_op->ops);
440 if (!direct_internal_fn_supported_p (fn, types, OPTIMIZE_FOR_BOTH))
441 return NULL;
443 return gimple_build_call_internal (fn, res_op->num_ops,
444 res_op->op_or_null (0),
445 res_op->op_or_null (1),
446 res_op->op_or_null (2),
447 res_op->op_or_null (3));
450 /* Push the exploded expression described by RES_OP as a statement to
451 SEQ if necessary and return a gimple value denoting the value of the
452 expression. If RES is not NULL then the result will be always RES
453 and even gimple values are pushed to SEQ. */
455 tree
456 maybe_push_res_to_seq (gimple_match_op *res_op, gimple_seq *seq, tree res)
458 tree *ops = res_op->ops;
459 unsigned num_ops = res_op->num_ops;
461 /* The caller should have converted conditional operations into an UNCOND
462 form and resimplified as appropriate. The conditional form only
463 survives this far if that conversion failed. */
464 if (res_op->cond.cond)
465 return NULL_TREE;
467 if (res_op->code.is_tree_code ())
469 if (!res
470 && gimple_simplified_result_is_gimple_val (res_op))
471 return ops[0];
472 if (mprts_hook)
474 tree tem = mprts_hook (res_op);
475 if (tem)
476 return tem;
480 if (!seq)
481 return NULL_TREE;
483 /* Play safe and do not allow abnormals to be mentioned in
484 newly created statements. */
485 for (unsigned int i = 0; i < num_ops; ++i)
486 if (TREE_CODE (ops[i]) == SSA_NAME
487 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[i]))
488 return NULL_TREE;
490 if (num_ops > 0 && COMPARISON_CLASS_P (ops[0]))
491 for (unsigned int i = 0; i < 2; ++i)
492 if (TREE_CODE (TREE_OPERAND (ops[0], i)) == SSA_NAME
493 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops[0], i)))
494 return NULL_TREE;
496 if (res_op->code.is_tree_code ())
498 if (!res)
500 if (gimple_in_ssa_p (cfun))
501 res = make_ssa_name (res_op->type);
502 else
503 res = create_tmp_reg (res_op->type);
505 maybe_build_generic_op (res_op);
506 gimple *new_stmt = gimple_build_assign (res, res_op->code,
507 res_op->op_or_null (0),
508 res_op->op_or_null (1),
509 res_op->op_or_null (2));
510 gimple_seq_add_stmt_without_update (seq, new_stmt);
511 return res;
513 else
515 gcc_assert (num_ops != 0);
516 combined_fn fn = res_op->code;
517 gcall *new_stmt = NULL;
518 if (internal_fn_p (fn))
520 /* Generate the given function if we can. */
521 internal_fn ifn = as_internal_fn (fn);
522 new_stmt = build_call_internal (ifn, res_op);
523 if (!new_stmt)
524 return NULL_TREE;
526 else
528 /* Find the function we want to call. */
529 tree decl = builtin_decl_implicit (as_builtin_fn (fn));
530 if (!decl)
531 return NULL;
533 /* We can't and should not emit calls to non-const functions. */
534 if (!(flags_from_decl_or_type (decl) & ECF_CONST))
535 return NULL;
537 new_stmt = gimple_build_call (decl, num_ops,
538 res_op->op_or_null (0),
539 res_op->op_or_null (1),
540 res_op->op_or_null (2),
541 res_op->op_or_null (3));
543 if (!res)
545 if (gimple_in_ssa_p (cfun))
546 res = make_ssa_name (res_op->type);
547 else
548 res = create_tmp_reg (res_op->type);
550 gimple_call_set_lhs (new_stmt, res);
551 gimple_seq_add_stmt_without_update (seq, new_stmt);
552 return res;
557 /* Public API overloads follow for operation being tree_code or
558 built_in_function and for one to three operands or arguments.
559 They return NULL_TREE if nothing could be simplified or
560 the resulting simplified value with parts pushed to SEQ.
561 If SEQ is NULL then if the simplification needs to create
562 new stmts it will fail. If VALUEIZE is non-NULL then all
563 SSA names will be valueized using that hook prior to
564 applying simplifications. */
566 /* Unary ops. */
568 tree
569 gimple_simplify (enum tree_code code, tree type,
570 tree op0,
571 gimple_seq *seq, tree (*valueize)(tree))
573 if (constant_for_folding (op0))
575 tree res = const_unop (code, type, op0);
576 if (res != NULL_TREE
577 && CONSTANT_CLASS_P (res))
578 return res;
581 gimple_match_op res_op;
582 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0))
583 return NULL_TREE;
584 return maybe_push_res_to_seq (&res_op, seq);
587 /* Binary ops. */
589 tree
590 gimple_simplify (enum tree_code code, tree type,
591 tree op0, tree op1,
592 gimple_seq *seq, tree (*valueize)(tree))
594 if (constant_for_folding (op0) && constant_for_folding (op1))
596 tree res = const_binop (code, type, op0, op1);
597 if (res != NULL_TREE
598 && CONSTANT_CLASS_P (res))
599 return res;
602 /* Canonicalize operand order both for matching and fallback stmt
603 generation. */
604 if ((commutative_tree_code (code)
605 || TREE_CODE_CLASS (code) == tcc_comparison)
606 && tree_swap_operands_p (op0, op1))
608 std::swap (op0, op1);
609 if (TREE_CODE_CLASS (code) == tcc_comparison)
610 code = swap_tree_comparison (code);
613 gimple_match_op res_op;
614 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0, op1))
615 return NULL_TREE;
616 return maybe_push_res_to_seq (&res_op, seq);
619 /* Ternary ops. */
621 tree
622 gimple_simplify (enum tree_code code, tree type,
623 tree op0, tree op1, tree op2,
624 gimple_seq *seq, tree (*valueize)(tree))
626 if (constant_for_folding (op0) && constant_for_folding (op1)
627 && constant_for_folding (op2))
629 tree res = fold_ternary/*_to_constant */ (code, type, op0, op1, op2);
630 if (res != NULL_TREE
631 && CONSTANT_CLASS_P (res))
632 return res;
635 /* Canonicalize operand order both for matching and fallback stmt
636 generation. */
637 if (commutative_ternary_tree_code (code)
638 && tree_swap_operands_p (op0, op1))
639 std::swap (op0, op1);
641 gimple_match_op res_op;
642 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0, op1, op2))
643 return NULL_TREE;
644 return maybe_push_res_to_seq (&res_op, seq);
647 /* Builtin or internal function with one argument. */
649 tree
650 gimple_simplify (combined_fn fn, tree type,
651 tree arg0,
652 gimple_seq *seq, tree (*valueize)(tree))
654 if (constant_for_folding (arg0))
656 tree res = fold_const_call (fn, type, arg0);
657 if (res && CONSTANT_CLASS_P (res))
658 return res;
661 gimple_match_op res_op;
662 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0))
663 return NULL_TREE;
664 return maybe_push_res_to_seq (&res_op, seq);
667 /* Builtin or internal function with two arguments. */
669 tree
670 gimple_simplify (combined_fn fn, tree type,
671 tree arg0, tree arg1,
672 gimple_seq *seq, tree (*valueize)(tree))
674 if (constant_for_folding (arg0)
675 && constant_for_folding (arg1))
677 tree res = fold_const_call (fn, type, arg0, arg1);
678 if (res && CONSTANT_CLASS_P (res))
679 return res;
682 gimple_match_op res_op;
683 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1))
684 return NULL_TREE;
685 return maybe_push_res_to_seq (&res_op, seq);
688 /* Builtin or internal function with three arguments. */
690 tree
691 gimple_simplify (combined_fn fn, tree type,
692 tree arg0, tree arg1, tree arg2,
693 gimple_seq *seq, tree (*valueize)(tree))
695 if (constant_for_folding (arg0)
696 && constant_for_folding (arg1)
697 && constant_for_folding (arg2))
699 tree res = fold_const_call (fn, type, arg0, arg1, arg2);
700 if (res && CONSTANT_CLASS_P (res))
701 return res;
704 gimple_match_op res_op;
705 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1, arg2))
706 return NULL_TREE;
707 return maybe_push_res_to_seq (&res_op, seq);
710 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
711 VALUEIZED to true if valueization changed OP. */
713 static inline tree
714 do_valueize (tree op, tree (*valueize)(tree), bool &valueized)
716 if (valueize && TREE_CODE (op) == SSA_NAME)
718 tree tem = valueize (op);
719 if (tem && tem != op)
721 op = tem;
722 valueized = true;
725 return op;
728 /* If RES_OP is a call to a conditional internal function, try simplifying
729 the associated unconditional operation and using the result to build
730 a new conditional operation. For example, if RES_OP is:
732 IFN_COND_ADD (COND, A, B, ELSE)
734 try simplifying (plus A B) and using the result to build a replacement
735 for the whole IFN_COND_ADD.
737 Return true if this approach led to a simplification, otherwise leave
738 RES_OP unchanged (and so suitable for other simplifications). When
739 returning true, add any new statements to SEQ and use VALUEIZE as the
740 valueization function.
742 RES_OP is known to be a call to IFN. */
744 static bool
745 try_conditional_simplification (internal_fn ifn, gimple_match_op *res_op,
746 gimple_seq *seq, tree (*valueize) (tree))
748 tree_code code = conditional_internal_fn_code (ifn);
749 if (code == ERROR_MARK)
750 return false;
752 unsigned int num_ops = res_op->num_ops;
753 gimple_match_op cond_op (gimple_match_cond (res_op->ops[0],
754 res_op->ops[num_ops - 1]),
755 code, res_op->type, num_ops - 2);
756 for (unsigned int i = 1; i < num_ops - 1; ++i)
757 cond_op.ops[i - 1] = res_op->ops[i];
758 switch (num_ops - 2)
760 case 2:
761 if (!gimple_resimplify2 (seq, &cond_op, valueize))
762 return false;
763 break;
764 default:
765 gcc_unreachable ();
767 *res_op = cond_op;
768 maybe_resimplify_conditional_op (seq, res_op, valueize);
769 return true;
772 /* The main STMT based simplification entry. It is used by the fold_stmt
773 and the fold_stmt_to_constant APIs. */
775 bool
776 gimple_simplify (gimple *stmt, gimple_match_op *res_op, gimple_seq *seq,
777 tree (*valueize)(tree), tree (*top_valueize)(tree))
779 switch (gimple_code (stmt))
781 case GIMPLE_ASSIGN:
783 enum tree_code code = gimple_assign_rhs_code (stmt);
784 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
785 switch (gimple_assign_rhs_class (stmt))
787 case GIMPLE_SINGLE_RHS:
788 if (code == REALPART_EXPR
789 || code == IMAGPART_EXPR
790 || code == VIEW_CONVERT_EXPR)
792 tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
793 bool valueized = false;
794 op0 = do_valueize (op0, top_valueize, valueized);
795 res_op->set_op (code, type, op0);
796 return (gimple_resimplify1 (seq, res_op, valueize)
797 || valueized);
799 else if (code == BIT_FIELD_REF)
801 tree rhs1 = gimple_assign_rhs1 (stmt);
802 tree op0 = TREE_OPERAND (rhs1, 0);
803 bool valueized = false;
804 op0 = do_valueize (op0, top_valueize, valueized);
805 res_op->set_op (code, type, op0,
806 TREE_OPERAND (rhs1, 1),
807 TREE_OPERAND (rhs1, 2));
808 return (gimple_resimplify3 (seq, res_op, valueize)
809 || valueized);
811 else if (code == SSA_NAME
812 && top_valueize)
814 tree op0 = gimple_assign_rhs1 (stmt);
815 tree valueized = top_valueize (op0);
816 if (!valueized || op0 == valueized)
817 return false;
818 res_op->set_op (TREE_CODE (op0), type, valueized);
819 return true;
821 break;
822 case GIMPLE_UNARY_RHS:
824 tree rhs1 = gimple_assign_rhs1 (stmt);
825 bool valueized = false;
826 rhs1 = do_valueize (rhs1, top_valueize, valueized);
827 res_op->set_op (code, type, rhs1);
828 return (gimple_resimplify1 (seq, res_op, valueize)
829 || valueized);
831 case GIMPLE_BINARY_RHS:
833 tree rhs1 = gimple_assign_rhs1 (stmt);
834 tree rhs2 = gimple_assign_rhs2 (stmt);
835 bool valueized = false;
836 rhs1 = do_valueize (rhs1, top_valueize, valueized);
837 rhs2 = do_valueize (rhs2, top_valueize, valueized);
838 res_op->set_op (code, type, rhs1, rhs2);
839 return (gimple_resimplify2 (seq, res_op, valueize)
840 || valueized);
842 case GIMPLE_TERNARY_RHS:
844 bool valueized = false;
845 tree rhs1 = gimple_assign_rhs1 (stmt);
846 /* If this is a [VEC_]COND_EXPR first try to simplify an
847 embedded GENERIC condition. */
848 if (code == COND_EXPR
849 || code == VEC_COND_EXPR)
851 if (COMPARISON_CLASS_P (rhs1))
853 tree lhs = TREE_OPERAND (rhs1, 0);
854 tree rhs = TREE_OPERAND (rhs1, 1);
855 lhs = do_valueize (lhs, top_valueize, valueized);
856 rhs = do_valueize (rhs, top_valueize, valueized);
857 gimple_match_op res_op2 (res_op->cond, TREE_CODE (rhs1),
858 TREE_TYPE (rhs1), lhs, rhs);
859 if ((gimple_resimplify2 (seq, &res_op2, valueize)
860 || valueized)
861 && res_op2.code.is_tree_code ())
863 valueized = true;
864 if (TREE_CODE_CLASS ((enum tree_code) res_op2.code)
865 == tcc_comparison)
866 rhs1 = build2 (res_op2.code, TREE_TYPE (rhs1),
867 res_op2.ops[0], res_op2.ops[1]);
868 else if (res_op2.code == SSA_NAME
869 || res_op2.code == INTEGER_CST
870 || res_op2.code == VECTOR_CST)
871 rhs1 = res_op2.ops[0];
872 else
873 valueized = false;
877 tree rhs2 = gimple_assign_rhs2 (stmt);
878 tree rhs3 = gimple_assign_rhs3 (stmt);
879 rhs1 = do_valueize (rhs1, top_valueize, valueized);
880 rhs2 = do_valueize (rhs2, top_valueize, valueized);
881 rhs3 = do_valueize (rhs3, top_valueize, valueized);
882 res_op->set_op (code, type, rhs1, rhs2, rhs3);
883 return (gimple_resimplify3 (seq, res_op, valueize)
884 || valueized);
886 default:
887 gcc_unreachable ();
889 break;
892 case GIMPLE_CALL:
893 /* ??? This way we can't simplify calls with side-effects. */
894 if (gimple_call_lhs (stmt) != NULL_TREE
895 && gimple_call_num_args (stmt) >= 1
896 && gimple_call_num_args (stmt) <= 4)
898 bool valueized = false;
899 combined_fn cfn;
900 if (gimple_call_internal_p (stmt))
901 cfn = as_combined_fn (gimple_call_internal_fn (stmt));
902 else
904 tree fn = gimple_call_fn (stmt);
905 if (!fn)
906 return false;
908 fn = do_valueize (fn, top_valueize, valueized);
909 if (TREE_CODE (fn) != ADDR_EXPR
910 || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
911 return false;
913 tree decl = TREE_OPERAND (fn, 0);
914 if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL
915 || !gimple_builtin_call_types_compatible_p (stmt, decl))
916 return false;
918 cfn = as_combined_fn (DECL_FUNCTION_CODE (decl));
921 unsigned int num_args = gimple_call_num_args (stmt);
922 res_op->set_op (cfn, TREE_TYPE (gimple_call_lhs (stmt)), num_args);
923 for (unsigned i = 0; i < num_args; ++i)
925 tree arg = gimple_call_arg (stmt, i);
926 res_op->ops[i] = do_valueize (arg, top_valueize, valueized);
928 if (internal_fn_p (cfn)
929 && try_conditional_simplification (as_internal_fn (cfn),
930 res_op, seq, valueize))
931 return true;
932 switch (num_args)
934 case 1:
935 return (gimple_resimplify1 (seq, res_op, valueize)
936 || valueized);
937 case 2:
938 return (gimple_resimplify2 (seq, res_op, valueize)
939 || valueized);
940 case 3:
941 return (gimple_resimplify3 (seq, res_op, valueize)
942 || valueized);
943 case 4:
944 return (gimple_resimplify4 (seq, res_op, valueize)
945 || valueized);
946 default:
947 gcc_unreachable ();
950 break;
952 case GIMPLE_COND:
954 tree lhs = gimple_cond_lhs (stmt);
955 tree rhs = gimple_cond_rhs (stmt);
956 bool valueized = false;
957 lhs = do_valueize (lhs, top_valueize, valueized);
958 rhs = do_valueize (rhs, top_valueize, valueized);
959 res_op->set_op (gimple_cond_code (stmt), boolean_type_node, lhs, rhs);
960 return (gimple_resimplify2 (seq, res_op, valueize)
961 || valueized);
964 default:
965 break;
968 return false;
972 /* Helper for the autogenerated code, valueize OP. */
974 inline tree
975 do_valueize (tree (*valueize)(tree), tree op)
977 if (valueize && TREE_CODE (op) == SSA_NAME)
979 tree tem = valueize (op);
980 if (tem)
981 return tem;
983 return op;
986 /* Helper for the autogenerated code, get at the definition of NAME when
987 VALUEIZE allows that. */
989 inline gimple *
990 get_def (tree (*valueize)(tree), tree name)
992 if (valueize && ! valueize (name))
993 return NULL;
994 return SSA_NAME_DEF_STMT (name);
997 /* Routine to determine if the types T1 and T2 are effectively
998 the same for GIMPLE. If T1 or T2 is not a type, the test
999 applies to their TREE_TYPE. */
1001 static inline bool
1002 types_match (tree t1, tree t2)
1004 if (!TYPE_P (t1))
1005 t1 = TREE_TYPE (t1);
1006 if (!TYPE_P (t2))
1007 t2 = TREE_TYPE (t2);
1009 return types_compatible_p (t1, t2);
1012 /* Return if T has a single use. For GIMPLE, we also allow any
1013 non-SSA_NAME (ie constants) and zero uses to cope with uses
1014 that aren't linked up yet. */
1016 static inline bool
1017 single_use (tree t)
1019 return TREE_CODE (t) != SSA_NAME || has_zero_uses (t) || has_single_use (t);
1022 /* Return true if math operations should be canonicalized,
1023 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
1025 static inline bool
1026 canonicalize_math_p ()
1028 return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;
1031 /* Return true if math operations that are beneficial only after
1032 vectorization should be canonicalized. */
1034 static inline bool
1035 canonicalize_math_after_vectorization_p ()
1037 return !cfun || (cfun->curr_properties & PROP_gimple_lvec) != 0;
1040 /* Return true if pow(cst, x) should be optimized into exp(log(cst) * x).
1041 As a workaround for SPEC CPU2017 628.pop2_s, don't do it if arg0
1042 is an exact integer, arg1 = phi_res +/- cst1 and phi_res = PHI <cst2, ...>
1043 where cst2 +/- cst1 is an exact integer, because then pow (arg0, arg1)
1044 will likely be exact, while exp (log (arg0) * arg1) might be not.
1045 Also don't do it if arg1 is phi_res above and cst2 is an exact integer. */
1047 static bool
1048 optimize_pow_to_exp (tree arg0, tree arg1)
1050 gcc_assert (TREE_CODE (arg0) == REAL_CST);
1051 if (!real_isinteger (TREE_REAL_CST_PTR (arg0), TYPE_MODE (TREE_TYPE (arg0))))
1052 return true;
1054 if (TREE_CODE (arg1) != SSA_NAME)
1055 return true;
1057 gimple *def = SSA_NAME_DEF_STMT (arg1);
1058 gphi *phi = dyn_cast <gphi *> (def);
1059 tree cst1 = NULL_TREE;
1060 enum tree_code code = ERROR_MARK;
1061 if (!phi)
1063 if (!is_gimple_assign (def))
1064 return true;
1065 code = gimple_assign_rhs_code (def);
1066 switch (code)
1068 case PLUS_EXPR:
1069 case MINUS_EXPR:
1070 break;
1071 default:
1072 return true;
1074 if (TREE_CODE (gimple_assign_rhs1 (def)) != SSA_NAME
1075 || TREE_CODE (gimple_assign_rhs2 (def)) != REAL_CST)
1076 return true;
1078 cst1 = gimple_assign_rhs2 (def);
1080 phi = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def)));
1081 if (!phi)
1082 return true;
1085 tree cst2 = NULL_TREE;
1086 int n = gimple_phi_num_args (phi);
1087 for (int i = 0; i < n; i++)
1089 tree arg = PHI_ARG_DEF (phi, i);
1090 if (TREE_CODE (arg) != REAL_CST)
1091 continue;
1092 else if (cst2 == NULL_TREE)
1093 cst2 = arg;
1094 else if (!operand_equal_p (cst2, arg, 0))
1095 return true;
1098 if (cst1 && cst2)
1099 cst2 = const_binop (code, TREE_TYPE (cst2), cst2, cst1);
1100 if (cst2
1101 && TREE_CODE (cst2) == REAL_CST
1102 && real_isinteger (TREE_REAL_CST_PTR (cst2),
1103 TYPE_MODE (TREE_TYPE (cst2))))
1104 return false;
1105 return true;