2018-07-12 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / gimple-match-head.c
blobc5a1923979828276b2a0aeae0560412090ac5315
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"
45 /* Forward declarations of the private auto-generated matchers.
46 They expect valueized operands in canonical order and do not
47 perform simplification of all-constant operands. */
48 static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
49 code_helper, tree, tree);
50 static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
51 code_helper, tree, tree, tree);
52 static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
53 code_helper, tree, tree, tree, tree);
54 static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
55 code_helper, tree, tree, tree, tree, tree);
57 const unsigned int gimple_match_op::MAX_NUM_OPS;
59 /* Return whether T is a constant that we'll dispatch to fold to
60 evaluate fully constant expressions. */
62 static inline bool
63 constant_for_folding (tree t)
65 return (CONSTANT_CLASS_P (t)
66 /* The following is only interesting to string builtins. */
67 || (TREE_CODE (t) == ADDR_EXPR
68 && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST));
72 /* Helper that matches and simplifies the toplevel result from
73 a gimple_simplify run (where we don't want to build
74 a stmt in case it's used in in-place folding). Replaces
75 RES_OP with a simplified and/or canonicalized result and
76 returns whether any change was made. */
78 bool
79 gimple_resimplify1 (gimple_seq *seq, gimple_match_op *res_op,
80 tree (*valueize)(tree))
82 if (constant_for_folding (res_op->ops[0]))
84 tree tem = NULL_TREE;
85 if (res_op->code.is_tree_code ())
86 tem = const_unop (res_op->code, res_op->type, res_op->ops[0]);
87 else
88 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
89 res_op->ops[0]);
90 if (tem != NULL_TREE
91 && CONSTANT_CLASS_P (tem))
93 if (TREE_OVERFLOW_P (tem))
94 tem = drop_tree_overflow (tem);
95 res_op->set_value (tem);
96 return true;
100 /* Limit recursion, there are cases like PR80887 and others, for
101 example when value-numbering presents us with unfolded expressions
102 that we are really not prepared to handle without eventual
103 oscillation like ((_50 + 0) + 8) where _50 gets mapped to _50
104 itself as available expression. */
105 static unsigned depth;
106 if (depth > 10)
108 if (dump_file && (dump_flags & TDF_FOLDING))
109 fprintf (dump_file, "Aborting expression simplification due to "
110 "deep recursion\n");
111 return false;
114 ++depth;
115 gimple_match_op res_op2 (*res_op);
116 if (gimple_simplify (&res_op2, seq, valueize,
117 res_op->code, res_op->type, res_op->ops[0]))
119 --depth;
120 *res_op = res_op2;
121 return true;
123 --depth;
125 return false;
128 /* Helper that matches and simplifies the toplevel result from
129 a gimple_simplify run (where we don't want to build
130 a stmt in case it's used in in-place folding). Replaces
131 RES_OP with a simplified and/or canonicalized result and
132 returns whether any change was made. */
134 bool
135 gimple_resimplify2 (gimple_seq *seq, gimple_match_op *res_op,
136 tree (*valueize)(tree))
138 if (constant_for_folding (res_op->ops[0])
139 && constant_for_folding (res_op->ops[1]))
141 tree tem = NULL_TREE;
142 if (res_op->code.is_tree_code ())
143 tem = const_binop (res_op->code, res_op->type,
144 res_op->ops[0], res_op->ops[1]);
145 else
146 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
147 res_op->ops[0], res_op->ops[1]);
148 if (tem != NULL_TREE
149 && CONSTANT_CLASS_P (tem))
151 if (TREE_OVERFLOW_P (tem))
152 tem = drop_tree_overflow (tem);
153 res_op->set_value (tem);
154 return true;
158 /* Canonicalize operand order. */
159 bool canonicalized = false;
160 if (res_op->code.is_tree_code ()
161 && (TREE_CODE_CLASS ((enum tree_code) res_op->code) == tcc_comparison
162 || commutative_tree_code (res_op->code))
163 && tree_swap_operands_p (res_op->ops[0], res_op->ops[1]))
165 std::swap (res_op->ops[0], res_op->ops[1]);
166 if (TREE_CODE_CLASS ((enum tree_code) res_op->code) == tcc_comparison)
167 res_op->code = swap_tree_comparison (res_op->code);
168 canonicalized = true;
171 /* Limit recursion, see gimple_resimplify1. */
172 static unsigned depth;
173 if (depth > 10)
175 if (dump_file && (dump_flags & TDF_FOLDING))
176 fprintf (dump_file, "Aborting expression simplification due to "
177 "deep recursion\n");
178 return false;
181 ++depth;
182 gimple_match_op res_op2 (*res_op);
183 if (gimple_simplify (&res_op2, seq, valueize,
184 res_op->code, res_op->type,
185 res_op->ops[0], res_op->ops[1]))
187 --depth;
188 *res_op = res_op2;
189 return true;
191 --depth;
193 return canonicalized;
196 /* Helper that matches and simplifies the toplevel result from
197 a gimple_simplify run (where we don't want to build
198 a stmt in case it's used in in-place folding). Replaces
199 RES_OP with a simplified and/or canonicalized result and
200 returns whether any change was made. */
202 bool
203 gimple_resimplify3 (gimple_seq *seq, gimple_match_op *res_op,
204 tree (*valueize)(tree))
206 if (constant_for_folding (res_op->ops[0])
207 && constant_for_folding (res_op->ops[1])
208 && constant_for_folding (res_op->ops[2]))
210 tree tem = NULL_TREE;
211 if (res_op->code.is_tree_code ())
212 tem = fold_ternary/*_to_constant*/ (res_op->code, res_op->type,
213 res_op->ops[0], res_op->ops[1],
214 res_op->ops[2]);
215 else
216 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
217 res_op->ops[0], res_op->ops[1], res_op->ops[2]);
218 if (tem != NULL_TREE
219 && CONSTANT_CLASS_P (tem))
221 if (TREE_OVERFLOW_P (tem))
222 tem = drop_tree_overflow (tem);
223 res_op->set_value (tem);
224 return true;
228 /* Canonicalize operand order. */
229 bool canonicalized = false;
230 if (res_op->code.is_tree_code ()
231 && commutative_ternary_tree_code (res_op->code)
232 && tree_swap_operands_p (res_op->ops[0], res_op->ops[1]))
234 std::swap (res_op->ops[0], res_op->ops[1]);
235 canonicalized = true;
238 /* Limit recursion, see gimple_resimplify1. */
239 static unsigned depth;
240 if (depth > 10)
242 if (dump_file && (dump_flags & TDF_FOLDING))
243 fprintf (dump_file, "Aborting expression simplification due to "
244 "deep recursion\n");
245 return false;
248 ++depth;
249 gimple_match_op res_op2 (*res_op);
250 if (gimple_simplify (&res_op2, seq, valueize,
251 res_op->code, res_op->type,
252 res_op->ops[0], res_op->ops[1], res_op->ops[2]))
254 --depth;
255 *res_op = res_op2;
256 return true;
258 --depth;
260 return canonicalized;
263 /* Helper that matches and simplifies the toplevel result from
264 a gimple_simplify run (where we don't want to build
265 a stmt in case it's used in in-place folding). Replaces
266 RES_OP with a simplified and/or canonicalized result and
267 returns whether any change was made. */
269 bool
270 gimple_resimplify4 (gimple_seq *seq, gimple_match_op *res_op,
271 tree (*valueize)(tree))
273 /* No constant folding is defined for four-operand functions. */
275 /* Limit recursion, see gimple_resimplify1. */
276 static unsigned depth;
277 if (depth > 10)
279 if (dump_file && (dump_flags & TDF_FOLDING))
280 fprintf (dump_file, "Aborting expression simplification due to "
281 "deep recursion\n");
282 return false;
285 ++depth;
286 gimple_match_op res_op2 (*res_op);
287 if (gimple_simplify (&res_op2, seq, valueize,
288 res_op->code, res_op->type,
289 res_op->ops[0], res_op->ops[1], res_op->ops[2],
290 res_op->ops[3]))
292 --depth;
293 *res_op = res_op2;
294 return true;
296 --depth;
298 return false;
301 /* If in GIMPLE the operation described by RES_OP should be single-rhs,
302 build a GENERIC tree for that expression and update RES_OP accordingly. */
304 void
305 maybe_build_generic_op (gimple_match_op *res_op)
307 tree_code code = (tree_code) res_op->code;
308 switch (code)
310 case REALPART_EXPR:
311 case IMAGPART_EXPR:
312 case VIEW_CONVERT_EXPR:
313 res_op->set_value (build1 (code, res_op->type, res_op->ops[0]));
314 break;
315 case BIT_FIELD_REF:
316 res_op->set_value (build3 (code, res_op->type, res_op->ops[0],
317 res_op->ops[1], res_op->ops[2]));
318 break;
319 default:;
323 tree (*mprts_hook) (gimple_match_op *);
325 /* Try to build RES_OP, which is known to be a call to FN. Return null
326 if the target doesn't support the function. */
328 static gcall *
329 build_call_internal (internal_fn fn, gimple_match_op *res_op)
331 if (direct_internal_fn_p (fn))
333 tree_pair types = direct_internal_fn_types (fn, res_op->type,
334 res_op->ops);
335 if (!direct_internal_fn_supported_p (fn, types, OPTIMIZE_FOR_BOTH))
336 return NULL;
338 return gimple_build_call_internal (fn, res_op->num_ops,
339 res_op->op_or_null (0),
340 res_op->op_or_null (1),
341 res_op->op_or_null (2),
342 res_op->op_or_null (3));
345 /* Push the exploded expression described by RES_OP as a statement to
346 SEQ if necessary and return a gimple value denoting the value of the
347 expression. If RES is not NULL then the result will be always RES
348 and even gimple values are pushed to SEQ. */
350 tree
351 maybe_push_res_to_seq (gimple_match_op *res_op, gimple_seq *seq, tree res)
353 tree *ops = res_op->ops;
354 unsigned num_ops = res_op->num_ops;
356 if (res_op->code.is_tree_code ())
358 if (!res
359 && gimple_simplified_result_is_gimple_val (res_op))
360 return ops[0];
361 if (mprts_hook)
363 tree tem = mprts_hook (res_op);
364 if (tem)
365 return tem;
369 if (!seq)
370 return NULL_TREE;
372 /* Play safe and do not allow abnormals to be mentioned in
373 newly created statements. */
374 for (unsigned int i = 0; i < num_ops; ++i)
375 if (TREE_CODE (ops[i]) == SSA_NAME
376 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[i]))
377 return NULL_TREE;
379 if (num_ops > 0 && COMPARISON_CLASS_P (ops[0]))
380 for (unsigned int i = 0; i < 2; ++i)
381 if (TREE_CODE (TREE_OPERAND (ops[0], i)) == SSA_NAME
382 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops[0], i)))
383 return NULL_TREE;
385 if (res_op->code.is_tree_code ())
387 if (!res)
389 if (gimple_in_ssa_p (cfun))
390 res = make_ssa_name (res_op->type);
391 else
392 res = create_tmp_reg (res_op->type);
394 maybe_build_generic_op (res_op);
395 gimple *new_stmt = gimple_build_assign (res, res_op->code,
396 res_op->op_or_null (0),
397 res_op->op_or_null (1),
398 res_op->op_or_null (2));
399 gimple_seq_add_stmt_without_update (seq, new_stmt);
400 return res;
402 else
404 gcc_assert (num_ops != 0);
405 combined_fn fn = res_op->code;
406 gcall *new_stmt = NULL;
407 if (internal_fn_p (fn))
409 /* Generate the given function if we can. */
410 internal_fn ifn = as_internal_fn (fn);
411 new_stmt = build_call_internal (ifn, res_op);
412 if (!new_stmt)
413 return NULL_TREE;
415 else
417 /* Find the function we want to call. */
418 tree decl = builtin_decl_implicit (as_builtin_fn (fn));
419 if (!decl)
420 return NULL;
422 /* We can't and should not emit calls to non-const functions. */
423 if (!(flags_from_decl_or_type (decl) & ECF_CONST))
424 return NULL;
426 new_stmt = gimple_build_call (decl, num_ops,
427 res_op->op_or_null (0),
428 res_op->op_or_null (1),
429 res_op->op_or_null (2),
430 res_op->op_or_null (3));
432 if (!res)
434 if (gimple_in_ssa_p (cfun))
435 res = make_ssa_name (res_op->type);
436 else
437 res = create_tmp_reg (res_op->type);
439 gimple_call_set_lhs (new_stmt, res);
440 gimple_seq_add_stmt_without_update (seq, new_stmt);
441 return res;
446 /* Public API overloads follow for operation being tree_code or
447 built_in_function and for one to three operands or arguments.
448 They return NULL_TREE if nothing could be simplified or
449 the resulting simplified value with parts pushed to SEQ.
450 If SEQ is NULL then if the simplification needs to create
451 new stmts it will fail. If VALUEIZE is non-NULL then all
452 SSA names will be valueized using that hook prior to
453 applying simplifications. */
455 /* Unary ops. */
457 tree
458 gimple_simplify (enum tree_code code, tree type,
459 tree op0,
460 gimple_seq *seq, tree (*valueize)(tree))
462 if (constant_for_folding (op0))
464 tree res = const_unop (code, type, op0);
465 if (res != NULL_TREE
466 && CONSTANT_CLASS_P (res))
467 return res;
470 gimple_match_op res_op;
471 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0))
472 return NULL_TREE;
473 return maybe_push_res_to_seq (&res_op, seq);
476 /* Binary ops. */
478 tree
479 gimple_simplify (enum tree_code code, tree type,
480 tree op0, tree op1,
481 gimple_seq *seq, tree (*valueize)(tree))
483 if (constant_for_folding (op0) && constant_for_folding (op1))
485 tree res = const_binop (code, type, op0, op1);
486 if (res != NULL_TREE
487 && CONSTANT_CLASS_P (res))
488 return res;
491 /* Canonicalize operand order both for matching and fallback stmt
492 generation. */
493 if ((commutative_tree_code (code)
494 || TREE_CODE_CLASS (code) == tcc_comparison)
495 && tree_swap_operands_p (op0, op1))
497 std::swap (op0, op1);
498 if (TREE_CODE_CLASS (code) == tcc_comparison)
499 code = swap_tree_comparison (code);
502 gimple_match_op res_op;
503 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0, op1))
504 return NULL_TREE;
505 return maybe_push_res_to_seq (&res_op, seq);
508 /* Ternary ops. */
510 tree
511 gimple_simplify (enum tree_code code, tree type,
512 tree op0, tree op1, tree op2,
513 gimple_seq *seq, tree (*valueize)(tree))
515 if (constant_for_folding (op0) && constant_for_folding (op1)
516 && constant_for_folding (op2))
518 tree res = fold_ternary/*_to_constant */ (code, type, op0, op1, op2);
519 if (res != NULL_TREE
520 && CONSTANT_CLASS_P (res))
521 return res;
524 /* Canonicalize operand order both for matching and fallback stmt
525 generation. */
526 if (commutative_ternary_tree_code (code)
527 && tree_swap_operands_p (op0, op1))
528 std::swap (op0, op1);
530 gimple_match_op res_op;
531 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0, op1, op2))
532 return NULL_TREE;
533 return maybe_push_res_to_seq (&res_op, seq);
536 /* Builtin or internal function with one argument. */
538 tree
539 gimple_simplify (combined_fn fn, tree type,
540 tree arg0,
541 gimple_seq *seq, tree (*valueize)(tree))
543 if (constant_for_folding (arg0))
545 tree res = fold_const_call (fn, type, arg0);
546 if (res && CONSTANT_CLASS_P (res))
547 return res;
550 gimple_match_op res_op;
551 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0))
552 return NULL_TREE;
553 return maybe_push_res_to_seq (&res_op, seq);
556 /* Builtin or internal function with two arguments. */
558 tree
559 gimple_simplify (combined_fn fn, tree type,
560 tree arg0, tree arg1,
561 gimple_seq *seq, tree (*valueize)(tree))
563 if (constant_for_folding (arg0)
564 && constant_for_folding (arg1))
566 tree res = fold_const_call (fn, type, arg0, arg1);
567 if (res && CONSTANT_CLASS_P (res))
568 return res;
571 gimple_match_op res_op;
572 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1))
573 return NULL_TREE;
574 return maybe_push_res_to_seq (&res_op, seq);
577 /* Builtin or internal function with three arguments. */
579 tree
580 gimple_simplify (combined_fn fn, tree type,
581 tree arg0, tree arg1, tree arg2,
582 gimple_seq *seq, tree (*valueize)(tree))
584 if (constant_for_folding (arg0)
585 && constant_for_folding (arg1)
586 && constant_for_folding (arg2))
588 tree res = fold_const_call (fn, type, arg0, arg1, arg2);
589 if (res && CONSTANT_CLASS_P (res))
590 return res;
593 gimple_match_op res_op;
594 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1, arg2))
595 return NULL_TREE;
596 return maybe_push_res_to_seq (&res_op, seq);
599 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
600 VALUEIZED to true if valueization changed OP. */
602 static inline tree
603 do_valueize (tree op, tree (*valueize)(tree), bool &valueized)
605 if (valueize && TREE_CODE (op) == SSA_NAME)
607 tree tem = valueize (op);
608 if (tem && tem != op)
610 op = tem;
611 valueized = true;
614 return op;
617 /* The main STMT based simplification entry. It is used by the fold_stmt
618 and the fold_stmt_to_constant APIs. */
620 bool
621 gimple_simplify (gimple *stmt, gimple_match_op *res_op, gimple_seq *seq,
622 tree (*valueize)(tree), tree (*top_valueize)(tree))
624 switch (gimple_code (stmt))
626 case GIMPLE_ASSIGN:
628 enum tree_code code = gimple_assign_rhs_code (stmt);
629 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
630 switch (gimple_assign_rhs_class (stmt))
632 case GIMPLE_SINGLE_RHS:
633 if (code == REALPART_EXPR
634 || code == IMAGPART_EXPR
635 || code == VIEW_CONVERT_EXPR)
637 tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
638 bool valueized = false;
639 op0 = do_valueize (op0, top_valueize, valueized);
640 res_op->set_op (code, type, op0);
641 return (gimple_resimplify1 (seq, res_op, valueize)
642 || valueized);
644 else if (code == BIT_FIELD_REF)
646 tree rhs1 = gimple_assign_rhs1 (stmt);
647 tree op0 = TREE_OPERAND (rhs1, 0);
648 bool valueized = false;
649 op0 = do_valueize (op0, top_valueize, valueized);
650 res_op->set_op (code, type, op0,
651 TREE_OPERAND (rhs1, 1),
652 TREE_OPERAND (rhs1, 2));
653 return (gimple_resimplify3 (seq, res_op, valueize)
654 || valueized);
656 else if (code == SSA_NAME
657 && top_valueize)
659 tree op0 = gimple_assign_rhs1 (stmt);
660 tree valueized = top_valueize (op0);
661 if (!valueized || op0 == valueized)
662 return false;
663 res_op->set_op (TREE_CODE (op0), type, valueized);
664 return true;
666 break;
667 case GIMPLE_UNARY_RHS:
669 tree rhs1 = gimple_assign_rhs1 (stmt);
670 bool valueized = false;
671 rhs1 = do_valueize (rhs1, top_valueize, valueized);
672 res_op->set_op (code, type, rhs1);
673 return (gimple_resimplify1 (seq, res_op, valueize)
674 || valueized);
676 case GIMPLE_BINARY_RHS:
678 tree rhs1 = gimple_assign_rhs1 (stmt);
679 tree rhs2 = gimple_assign_rhs2 (stmt);
680 bool valueized = false;
681 rhs1 = do_valueize (rhs1, top_valueize, valueized);
682 rhs2 = do_valueize (rhs2, top_valueize, valueized);
683 res_op->set_op (code, type, rhs1, rhs2);
684 return (gimple_resimplify2 (seq, res_op, valueize)
685 || valueized);
687 case GIMPLE_TERNARY_RHS:
689 bool valueized = false;
690 tree rhs1 = gimple_assign_rhs1 (stmt);
691 /* If this is a [VEC_]COND_EXPR first try to simplify an
692 embedded GENERIC condition. */
693 if (code == COND_EXPR
694 || code == VEC_COND_EXPR)
696 if (COMPARISON_CLASS_P (rhs1))
698 tree lhs = TREE_OPERAND (rhs1, 0);
699 tree rhs = TREE_OPERAND (rhs1, 1);
700 lhs = do_valueize (lhs, top_valueize, valueized);
701 rhs = do_valueize (rhs, top_valueize, valueized);
702 gimple_match_op res_op2 (TREE_CODE (rhs1),
703 TREE_TYPE (rhs1), lhs, rhs);
704 if ((gimple_resimplify2 (seq, &res_op2, valueize)
705 || valueized)
706 && res_op2.code.is_tree_code ())
708 valueized = true;
709 if (TREE_CODE_CLASS ((enum tree_code) res_op2.code)
710 == tcc_comparison)
711 rhs1 = build2 (res_op2.code, TREE_TYPE (rhs1),
712 res_op2.ops[0], res_op2.ops[1]);
713 else if (res_op2.code == SSA_NAME
714 || res_op2.code == INTEGER_CST
715 || res_op2.code == VECTOR_CST)
716 rhs1 = res_op2.ops[0];
717 else
718 valueized = false;
722 tree rhs2 = gimple_assign_rhs2 (stmt);
723 tree rhs3 = gimple_assign_rhs3 (stmt);
724 rhs1 = do_valueize (rhs1, top_valueize, valueized);
725 rhs2 = do_valueize (rhs2, top_valueize, valueized);
726 rhs3 = do_valueize (rhs3, top_valueize, valueized);
727 res_op->set_op (code, type, rhs1, rhs2, rhs3);
728 return (gimple_resimplify3 (seq, res_op, valueize)
729 || valueized);
731 default:
732 gcc_unreachable ();
734 break;
737 case GIMPLE_CALL:
738 /* ??? This way we can't simplify calls with side-effects. */
739 if (gimple_call_lhs (stmt) != NULL_TREE
740 && gimple_call_num_args (stmt) >= 1
741 && gimple_call_num_args (stmt) <= 4)
743 bool valueized = false;
744 combined_fn cfn;
745 if (gimple_call_internal_p (stmt))
746 cfn = as_combined_fn (gimple_call_internal_fn (stmt));
747 else
749 tree fn = gimple_call_fn (stmt);
750 if (!fn)
751 return false;
753 fn = do_valueize (fn, top_valueize, valueized);
754 if (TREE_CODE (fn) != ADDR_EXPR
755 || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
756 return false;
758 tree decl = TREE_OPERAND (fn, 0);
759 if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL
760 || !gimple_builtin_call_types_compatible_p (stmt, decl))
761 return false;
763 cfn = as_combined_fn (DECL_FUNCTION_CODE (decl));
766 unsigned int num_args = gimple_call_num_args (stmt);
767 res_op->set_op (cfn, TREE_TYPE (gimple_call_lhs (stmt)), num_args);
768 for (unsigned i = 0; i < num_args; ++i)
770 tree arg = gimple_call_arg (stmt, i);
771 res_op->ops[i] = do_valueize (arg, top_valueize, valueized);
773 switch (num_args)
775 case 1:
776 return (gimple_resimplify1 (seq, res_op, valueize)
777 || valueized);
778 case 2:
779 return (gimple_resimplify2 (seq, res_op, valueize)
780 || valueized);
781 case 3:
782 return (gimple_resimplify3 (seq, res_op, valueize)
783 || valueized);
784 case 4:
785 return (gimple_resimplify4 (seq, res_op, valueize)
786 || valueized);
787 default:
788 gcc_unreachable ();
791 break;
793 case GIMPLE_COND:
795 tree lhs = gimple_cond_lhs (stmt);
796 tree rhs = gimple_cond_rhs (stmt);
797 bool valueized = false;
798 lhs = do_valueize (lhs, top_valueize, valueized);
799 rhs = do_valueize (rhs, top_valueize, valueized);
800 res_op->set_op (gimple_cond_code (stmt), boolean_type_node, lhs, rhs);
801 return (gimple_resimplify2 (seq, res_op, valueize)
802 || valueized);
805 default:
806 break;
809 return false;
813 /* Helper for the autogenerated code, valueize OP. */
815 inline tree
816 do_valueize (tree (*valueize)(tree), tree op)
818 if (valueize && TREE_CODE (op) == SSA_NAME)
820 tree tem = valueize (op);
821 if (tem)
822 return tem;
824 return op;
827 /* Helper for the autogenerated code, get at the definition of NAME when
828 VALUEIZE allows that. */
830 inline gimple *
831 get_def (tree (*valueize)(tree), tree name)
833 if (valueize && ! valueize (name))
834 return NULL;
835 return SSA_NAME_DEF_STMT (name);
838 /* Routine to determine if the types T1 and T2 are effectively
839 the same for GIMPLE. If T1 or T2 is not a type, the test
840 applies to their TREE_TYPE. */
842 static inline bool
843 types_match (tree t1, tree t2)
845 if (!TYPE_P (t1))
846 t1 = TREE_TYPE (t1);
847 if (!TYPE_P (t2))
848 t2 = TREE_TYPE (t2);
850 return types_compatible_p (t1, t2);
853 /* Return if T has a single use. For GIMPLE, we also allow any
854 non-SSA_NAME (ie constants) and zero uses to cope with uses
855 that aren't linked up yet. */
857 static inline bool
858 single_use (tree t)
860 return TREE_CODE (t) != SSA_NAME || has_zero_uses (t) || has_single_use (t);
863 /* Return true if math operations should be canonicalized,
864 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
866 static inline bool
867 canonicalize_math_p ()
869 return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;
872 /* Return true if math operations that are beneficial only after
873 vectorization should be canonicalized. */
875 static inline bool
876 canonicalize_math_after_vectorization_p ()
878 return !cfun || (cfun->curr_properties & PROP_gimple_lvec) != 0;
881 /* Return true if pow(cst, x) should be optimized into exp(log(cst) * x).
882 As a workaround for SPEC CPU2017 628.pop2_s, don't do it if arg0
883 is an exact integer, arg1 = phi_res +/- cst1 and phi_res = PHI <cst2, ...>
884 where cst2 +/- cst1 is an exact integer, because then pow (arg0, arg1)
885 will likely be exact, while exp (log (arg0) * arg1) might be not.
886 Also don't do it if arg1 is phi_res above and cst2 is an exact integer. */
888 static bool
889 optimize_pow_to_exp (tree arg0, tree arg1)
891 gcc_assert (TREE_CODE (arg0) == REAL_CST);
892 if (!real_isinteger (TREE_REAL_CST_PTR (arg0), TYPE_MODE (TREE_TYPE (arg0))))
893 return true;
895 if (TREE_CODE (arg1) != SSA_NAME)
896 return true;
898 gimple *def = SSA_NAME_DEF_STMT (arg1);
899 gphi *phi = dyn_cast <gphi *> (def);
900 tree cst1 = NULL_TREE;
901 enum tree_code code = ERROR_MARK;
902 if (!phi)
904 if (!is_gimple_assign (def))
905 return true;
906 code = gimple_assign_rhs_code (def);
907 switch (code)
909 case PLUS_EXPR:
910 case MINUS_EXPR:
911 break;
912 default:
913 return true;
915 if (TREE_CODE (gimple_assign_rhs1 (def)) != SSA_NAME
916 || TREE_CODE (gimple_assign_rhs2 (def)) != REAL_CST)
917 return true;
919 cst1 = gimple_assign_rhs2 (def);
921 phi = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def)));
922 if (!phi)
923 return true;
926 tree cst2 = NULL_TREE;
927 int n = gimple_phi_num_args (phi);
928 for (int i = 0; i < n; i++)
930 tree arg = PHI_ARG_DEF (phi, i);
931 if (TREE_CODE (arg) != REAL_CST)
932 continue;
933 else if (cst2 == NULL_TREE)
934 cst2 = arg;
935 else if (!operand_equal_p (cst2, arg, 0))
936 return true;
939 if (cst1 && cst2)
940 cst2 = const_binop (code, TREE_TYPE (cst2), cst2, cst1);
941 if (cst2
942 && TREE_CODE (cst2) == REAL_CST
943 && real_isinteger (TREE_REAL_CST_PTR (cst2),
944 TYPE_MODE (TREE_TYPE (cst2))))
945 return false;
946 return true;