Avoid is_constant calls in vectorizable_bswap
[official-gcc.git] / gcc / gimple-match-head.c
blob414007ec1f9ece6ba112387c9383938adce87950
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);
57 static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
58 code_helper, tree, tree, tree, tree, tree, tree);
60 const unsigned int gimple_match_op::MAX_NUM_OPS;
62 /* Return whether T is a constant that we'll dispatch to fold to
63 evaluate fully constant expressions. */
65 static inline bool
66 constant_for_folding (tree t)
68 return (CONSTANT_CLASS_P (t)
69 /* The following is only interesting to string builtins. */
70 || (TREE_CODE (t) == ADDR_EXPR
71 && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST));
74 /* Try to convert conditional operation ORIG_OP into an IFN_COND_*
75 operation. Return true on success, storing the new operation in NEW_OP. */
77 static bool
78 convert_conditional_op (gimple_match_op *orig_op,
79 gimple_match_op *new_op)
81 internal_fn ifn;
82 if (orig_op->code.is_tree_code ())
83 ifn = get_conditional_internal_fn ((tree_code) orig_op->code);
84 else
86 combined_fn cfn = orig_op->code;
87 if (!internal_fn_p (cfn))
88 return false;
89 ifn = get_conditional_internal_fn (as_internal_fn (cfn));
91 if (ifn == IFN_LAST)
92 return false;
93 unsigned int num_ops = orig_op->num_ops;
94 new_op->set_op (as_combined_fn (ifn), orig_op->type, num_ops + 2);
95 new_op->ops[0] = orig_op->cond.cond;
96 for (unsigned int i = 0; i < num_ops; ++i)
97 new_op->ops[i + 1] = orig_op->ops[i];
98 tree else_value = orig_op->cond.else_value;
99 if (!else_value)
100 else_value = targetm.preferred_else_value (ifn, orig_op->type,
101 num_ops, orig_op->ops);
102 new_op->ops[num_ops + 1] = else_value;
103 return true;
106 /* RES_OP is the result of a simplification. If it is conditional,
107 try to replace it with the equivalent UNCOND form, such as an
108 IFN_COND_* call or a VEC_COND_EXPR. Also try to resimplify the
109 result of the replacement if appropriate, adding any new statements to
110 SEQ and using VALUEIZE as the valueization function. Return true if
111 this resimplification occurred and resulted in at least one change. */
113 static bool
114 maybe_resimplify_conditional_op (gimple_seq *seq, gimple_match_op *res_op,
115 tree (*valueize) (tree))
117 if (!res_op->cond.cond)
118 return false;
120 if (!res_op->cond.else_value
121 && res_op->code.is_tree_code ())
123 /* The "else" value doesn't matter. If the "then" value is a
124 gimple value, just use it unconditionally. This isn't a
125 simplification in itself, since there was no operation to
126 build in the first place. */
127 if (gimple_simplified_result_is_gimple_val (res_op))
129 res_op->cond.cond = NULL_TREE;
130 return false;
133 /* Likewise if the operation would not trap. */
134 bool honor_trapv = (INTEGRAL_TYPE_P (res_op->type)
135 && TYPE_OVERFLOW_TRAPS (res_op->type));
136 if (!operation_could_trap_p ((tree_code) res_op->code,
137 FLOAT_TYPE_P (res_op->type),
138 honor_trapv, res_op->op_or_null (1)))
140 res_op->cond.cond = NULL_TREE;
141 return false;
145 /* If the "then" value is a gimple value and the "else" value matters,
146 create a VEC_COND_EXPR between them, then see if it can be further
147 simplified. */
148 gimple_match_op new_op;
149 if (res_op->cond.else_value
150 && VECTOR_TYPE_P (res_op->type)
151 && gimple_simplified_result_is_gimple_val (res_op))
153 new_op.set_op (VEC_COND_EXPR, res_op->type,
154 res_op->cond.cond, res_op->ops[0],
155 res_op->cond.else_value);
156 *res_op = new_op;
157 return gimple_resimplify3 (seq, res_op, valueize);
160 /* Otherwise try rewriting the operation as an IFN_COND_* call.
161 Again, this isn't a simplification in itself, since it's what
162 RES_OP already described. */
163 if (convert_conditional_op (res_op, &new_op))
164 *res_op = new_op;
166 return false;
169 /* Helper that matches and simplifies the toplevel result from
170 a gimple_simplify run (where we don't want to build
171 a stmt in case it's used in in-place folding). Replaces
172 RES_OP with a simplified and/or canonicalized result and
173 returns whether any change was made. */
175 bool
176 gimple_resimplify1 (gimple_seq *seq, gimple_match_op *res_op,
177 tree (*valueize)(tree))
179 if (constant_for_folding (res_op->ops[0]))
181 tree tem = NULL_TREE;
182 if (res_op->code.is_tree_code ())
183 tem = const_unop (res_op->code, res_op->type, res_op->ops[0]);
184 else
185 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
186 res_op->ops[0]);
187 if (tem != NULL_TREE
188 && CONSTANT_CLASS_P (tem))
190 if (TREE_OVERFLOW_P (tem))
191 tem = drop_tree_overflow (tem);
192 res_op->set_value (tem);
193 maybe_resimplify_conditional_op (seq, res_op, valueize);
194 return true;
198 /* Limit recursion, there are cases like PR80887 and others, for
199 example when value-numbering presents us with unfolded expressions
200 that we are really not prepared to handle without eventual
201 oscillation like ((_50 + 0) + 8) where _50 gets mapped to _50
202 itself as available expression. */
203 static unsigned depth;
204 if (depth > 10)
206 if (dump_file && (dump_flags & TDF_FOLDING))
207 fprintf (dump_file, "Aborting expression simplification due to "
208 "deep recursion\n");
209 return false;
212 ++depth;
213 gimple_match_op res_op2 (*res_op);
214 if (gimple_simplify (&res_op2, seq, valueize,
215 res_op->code, res_op->type, res_op->ops[0]))
217 --depth;
218 *res_op = res_op2;
219 return true;
221 --depth;
223 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
224 return true;
226 return false;
229 /* Helper that matches and simplifies the toplevel result from
230 a gimple_simplify run (where we don't want to build
231 a stmt in case it's used in in-place folding). Replaces
232 RES_OP with a simplified and/or canonicalized result and
233 returns whether any change was made. */
235 bool
236 gimple_resimplify2 (gimple_seq *seq, gimple_match_op *res_op,
237 tree (*valueize)(tree))
239 if (constant_for_folding (res_op->ops[0])
240 && constant_for_folding (res_op->ops[1]))
242 tree tem = NULL_TREE;
243 if (res_op->code.is_tree_code ())
244 tem = const_binop (res_op->code, res_op->type,
245 res_op->ops[0], res_op->ops[1]);
246 else
247 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
248 res_op->ops[0], res_op->ops[1]);
249 if (tem != NULL_TREE
250 && CONSTANT_CLASS_P (tem))
252 if (TREE_OVERFLOW_P (tem))
253 tem = drop_tree_overflow (tem);
254 res_op->set_value (tem);
255 maybe_resimplify_conditional_op (seq, res_op, valueize);
256 return true;
260 /* Canonicalize operand order. */
261 bool canonicalized = false;
262 if (res_op->code.is_tree_code ()
263 && (TREE_CODE_CLASS ((enum tree_code) res_op->code) == tcc_comparison
264 || commutative_tree_code (res_op->code))
265 && tree_swap_operands_p (res_op->ops[0], res_op->ops[1]))
267 std::swap (res_op->ops[0], res_op->ops[1]);
268 if (TREE_CODE_CLASS ((enum tree_code) res_op->code) == tcc_comparison)
269 res_op->code = swap_tree_comparison (res_op->code);
270 canonicalized = true;
273 /* Limit recursion, see gimple_resimplify1. */
274 static unsigned depth;
275 if (depth > 10)
277 if (dump_file && (dump_flags & TDF_FOLDING))
278 fprintf (dump_file, "Aborting expression simplification due to "
279 "deep recursion\n");
280 return false;
283 ++depth;
284 gimple_match_op res_op2 (*res_op);
285 if (gimple_simplify (&res_op2, seq, valueize,
286 res_op->code, res_op->type,
287 res_op->ops[0], res_op->ops[1]))
289 --depth;
290 *res_op = res_op2;
291 return true;
293 --depth;
295 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
296 return true;
298 return canonicalized;
301 /* Helper that matches and simplifies the toplevel result from
302 a gimple_simplify run (where we don't want to build
303 a stmt in case it's used in in-place folding). Replaces
304 RES_OP with a simplified and/or canonicalized result and
305 returns whether any change was made. */
307 bool
308 gimple_resimplify3 (gimple_seq *seq, gimple_match_op *res_op,
309 tree (*valueize)(tree))
311 if (constant_for_folding (res_op->ops[0])
312 && constant_for_folding (res_op->ops[1])
313 && constant_for_folding (res_op->ops[2]))
315 tree tem = NULL_TREE;
316 if (res_op->code.is_tree_code ())
317 tem = fold_ternary/*_to_constant*/ (res_op->code, res_op->type,
318 res_op->ops[0], res_op->ops[1],
319 res_op->ops[2]);
320 else
321 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
322 res_op->ops[0], res_op->ops[1], res_op->ops[2]);
323 if (tem != NULL_TREE
324 && CONSTANT_CLASS_P (tem))
326 if (TREE_OVERFLOW_P (tem))
327 tem = drop_tree_overflow (tem);
328 res_op->set_value (tem);
329 maybe_resimplify_conditional_op (seq, res_op, valueize);
330 return true;
334 /* Canonicalize operand order. */
335 bool canonicalized = false;
336 if (res_op->code.is_tree_code ()
337 && commutative_ternary_tree_code (res_op->code)
338 && tree_swap_operands_p (res_op->ops[0], res_op->ops[1]))
340 std::swap (res_op->ops[0], res_op->ops[1]);
341 canonicalized = true;
344 /* Limit recursion, see gimple_resimplify1. */
345 static unsigned depth;
346 if (depth > 10)
348 if (dump_file && (dump_flags & TDF_FOLDING))
349 fprintf (dump_file, "Aborting expression simplification due to "
350 "deep recursion\n");
351 return false;
354 ++depth;
355 gimple_match_op res_op2 (*res_op);
356 if (gimple_simplify (&res_op2, seq, valueize,
357 res_op->code, res_op->type,
358 res_op->ops[0], res_op->ops[1], res_op->ops[2]))
360 --depth;
361 *res_op = res_op2;
362 return true;
364 --depth;
366 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
367 return true;
369 return canonicalized;
372 /* Helper that matches and simplifies the toplevel result from
373 a gimple_simplify run (where we don't want to build
374 a stmt in case it's used in in-place folding). Replaces
375 RES_OP with a simplified and/or canonicalized result and
376 returns whether any change was made. */
378 bool
379 gimple_resimplify4 (gimple_seq *seq, gimple_match_op *res_op,
380 tree (*valueize)(tree))
382 /* No constant folding is defined for four-operand functions. */
384 /* Limit recursion, see gimple_resimplify1. */
385 static unsigned depth;
386 if (depth > 10)
388 if (dump_file && (dump_flags & TDF_FOLDING))
389 fprintf (dump_file, "Aborting expression simplification due to "
390 "deep recursion\n");
391 return false;
394 ++depth;
395 gimple_match_op res_op2 (*res_op);
396 if (gimple_simplify (&res_op2, seq, valueize,
397 res_op->code, res_op->type,
398 res_op->ops[0], res_op->ops[1], res_op->ops[2],
399 res_op->ops[3]))
401 --depth;
402 *res_op = res_op2;
403 return true;
405 --depth;
407 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
408 return true;
410 return false;
413 /* Helper that matches and simplifies the toplevel result from
414 a gimple_simplify run (where we don't want to build
415 a stmt in case it's used in in-place folding). Replaces
416 RES_OP with a simplified and/or canonicalized result and
417 returns whether any change was made. */
419 bool
420 gimple_resimplify5 (gimple_seq *seq, gimple_match_op *res_op,
421 tree (*valueize)(tree))
423 /* No constant folding is defined for five-operand functions. */
425 gimple_match_op res_op2 (*res_op);
426 if (gimple_simplify (&res_op2, seq, valueize,
427 res_op->code, res_op->type,
428 res_op->ops[0], res_op->ops[1], res_op->ops[2],
429 res_op->ops[3], res_op->ops[4]))
431 *res_op = res_op2;
432 return true;
435 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
436 return true;
438 return false;
441 /* If in GIMPLE the operation described by RES_OP should be single-rhs,
442 build a GENERIC tree for that expression and update RES_OP accordingly. */
444 void
445 maybe_build_generic_op (gimple_match_op *res_op)
447 tree_code code = (tree_code) res_op->code;
448 switch (code)
450 case REALPART_EXPR:
451 case IMAGPART_EXPR:
452 case VIEW_CONVERT_EXPR:
453 res_op->set_value (build1 (code, res_op->type, res_op->ops[0]));
454 break;
455 case BIT_FIELD_REF:
456 res_op->set_value (build3 (code, res_op->type, res_op->ops[0],
457 res_op->ops[1], res_op->ops[2]));
458 break;
459 default:;
463 tree (*mprts_hook) (gimple_match_op *);
465 /* Try to build RES_OP, which is known to be a call to FN. Return null
466 if the target doesn't support the function. */
468 static gcall *
469 build_call_internal (internal_fn fn, gimple_match_op *res_op)
471 if (direct_internal_fn_p (fn))
473 tree_pair types = direct_internal_fn_types (fn, res_op->type,
474 res_op->ops);
475 if (!direct_internal_fn_supported_p (fn, types, OPTIMIZE_FOR_BOTH))
476 return NULL;
478 return gimple_build_call_internal (fn, res_op->num_ops,
479 res_op->op_or_null (0),
480 res_op->op_or_null (1),
481 res_op->op_or_null (2),
482 res_op->op_or_null (3),
483 res_op->op_or_null (4));
486 /* Push the exploded expression described by RES_OP as a statement to
487 SEQ if necessary and return a gimple value denoting the value of the
488 expression. If RES is not NULL then the result will be always RES
489 and even gimple values are pushed to SEQ. */
491 tree
492 maybe_push_res_to_seq (gimple_match_op *res_op, gimple_seq *seq, tree res)
494 tree *ops = res_op->ops;
495 unsigned num_ops = res_op->num_ops;
497 /* The caller should have converted conditional operations into an UNCOND
498 form and resimplified as appropriate. The conditional form only
499 survives this far if that conversion failed. */
500 if (res_op->cond.cond)
501 return NULL_TREE;
503 if (res_op->code.is_tree_code ())
505 if (!res
506 && gimple_simplified_result_is_gimple_val (res_op))
507 return ops[0];
508 if (mprts_hook)
510 tree tem = mprts_hook (res_op);
511 if (tem)
512 return tem;
516 if (!seq)
517 return NULL_TREE;
519 /* Play safe and do not allow abnormals to be mentioned in
520 newly created statements. */
521 for (unsigned int i = 0; i < num_ops; ++i)
522 if (TREE_CODE (ops[i]) == SSA_NAME
523 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[i]))
524 return NULL_TREE;
526 if (num_ops > 0 && COMPARISON_CLASS_P (ops[0]))
527 for (unsigned int i = 0; i < 2; ++i)
528 if (TREE_CODE (TREE_OPERAND (ops[0], i)) == SSA_NAME
529 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops[0], i)))
530 return NULL_TREE;
532 if (res_op->code.is_tree_code ())
534 if (!res)
536 if (gimple_in_ssa_p (cfun))
537 res = make_ssa_name (res_op->type);
538 else
539 res = create_tmp_reg (res_op->type);
541 maybe_build_generic_op (res_op);
542 gimple *new_stmt = gimple_build_assign (res, res_op->code,
543 res_op->op_or_null (0),
544 res_op->op_or_null (1),
545 res_op->op_or_null (2));
546 gimple_seq_add_stmt_without_update (seq, new_stmt);
547 return res;
549 else
551 gcc_assert (num_ops != 0);
552 combined_fn fn = res_op->code;
553 gcall *new_stmt = NULL;
554 if (internal_fn_p (fn))
556 /* Generate the given function if we can. */
557 internal_fn ifn = as_internal_fn (fn);
558 new_stmt = build_call_internal (ifn, res_op);
559 if (!new_stmt)
560 return NULL_TREE;
562 else
564 /* Find the function we want to call. */
565 tree decl = builtin_decl_implicit (as_builtin_fn (fn));
566 if (!decl)
567 return NULL;
569 /* We can't and should not emit calls to non-const functions. */
570 if (!(flags_from_decl_or_type (decl) & ECF_CONST))
571 return NULL;
573 new_stmt = gimple_build_call (decl, num_ops,
574 res_op->op_or_null (0),
575 res_op->op_or_null (1),
576 res_op->op_or_null (2),
577 res_op->op_or_null (3),
578 res_op->op_or_null (4));
580 if (!res)
582 if (gimple_in_ssa_p (cfun))
583 res = make_ssa_name (res_op->type);
584 else
585 res = create_tmp_reg (res_op->type);
587 gimple_call_set_lhs (new_stmt, res);
588 gimple_seq_add_stmt_without_update (seq, new_stmt);
589 return res;
594 /* Public API overloads follow for operation being tree_code or
595 built_in_function and for one to three operands or arguments.
596 They return NULL_TREE if nothing could be simplified or
597 the resulting simplified value with parts pushed to SEQ.
598 If SEQ is NULL then if the simplification needs to create
599 new stmts it will fail. If VALUEIZE is non-NULL then all
600 SSA names will be valueized using that hook prior to
601 applying simplifications. */
603 /* Unary ops. */
605 tree
606 gimple_simplify (enum tree_code code, tree type,
607 tree op0,
608 gimple_seq *seq, tree (*valueize)(tree))
610 if (constant_for_folding (op0))
612 tree res = const_unop (code, type, op0);
613 if (res != NULL_TREE
614 && CONSTANT_CLASS_P (res))
615 return res;
618 gimple_match_op res_op;
619 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0))
620 return NULL_TREE;
621 return maybe_push_res_to_seq (&res_op, seq);
624 /* Binary ops. */
626 tree
627 gimple_simplify (enum tree_code code, tree type,
628 tree op0, tree op1,
629 gimple_seq *seq, tree (*valueize)(tree))
631 if (constant_for_folding (op0) && constant_for_folding (op1))
633 tree res = const_binop (code, type, op0, op1);
634 if (res != NULL_TREE
635 && CONSTANT_CLASS_P (res))
636 return res;
639 /* Canonicalize operand order both for matching and fallback stmt
640 generation. */
641 if ((commutative_tree_code (code)
642 || TREE_CODE_CLASS (code) == tcc_comparison)
643 && tree_swap_operands_p (op0, op1))
645 std::swap (op0, op1);
646 if (TREE_CODE_CLASS (code) == tcc_comparison)
647 code = swap_tree_comparison (code);
650 gimple_match_op res_op;
651 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0, op1))
652 return NULL_TREE;
653 return maybe_push_res_to_seq (&res_op, seq);
656 /* Ternary ops. */
658 tree
659 gimple_simplify (enum tree_code code, tree type,
660 tree op0, tree op1, tree op2,
661 gimple_seq *seq, tree (*valueize)(tree))
663 if (constant_for_folding (op0) && constant_for_folding (op1)
664 && constant_for_folding (op2))
666 tree res = fold_ternary/*_to_constant */ (code, type, op0, op1, op2);
667 if (res != NULL_TREE
668 && CONSTANT_CLASS_P (res))
669 return res;
672 /* Canonicalize operand order both for matching and fallback stmt
673 generation. */
674 if (commutative_ternary_tree_code (code)
675 && tree_swap_operands_p (op0, op1))
676 std::swap (op0, op1);
678 gimple_match_op res_op;
679 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0, op1, op2))
680 return NULL_TREE;
681 return maybe_push_res_to_seq (&res_op, seq);
684 /* Builtin or internal function with one argument. */
686 tree
687 gimple_simplify (combined_fn fn, tree type,
688 tree arg0,
689 gimple_seq *seq, tree (*valueize)(tree))
691 if (constant_for_folding (arg0))
693 tree res = fold_const_call (fn, type, arg0);
694 if (res && CONSTANT_CLASS_P (res))
695 return res;
698 gimple_match_op res_op;
699 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0))
700 return NULL_TREE;
701 return maybe_push_res_to_seq (&res_op, seq);
704 /* Builtin or internal function with two arguments. */
706 tree
707 gimple_simplify (combined_fn fn, tree type,
708 tree arg0, tree arg1,
709 gimple_seq *seq, tree (*valueize)(tree))
711 if (constant_for_folding (arg0)
712 && constant_for_folding (arg1))
714 tree res = fold_const_call (fn, type, arg0, arg1);
715 if (res && CONSTANT_CLASS_P (res))
716 return res;
719 gimple_match_op res_op;
720 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1))
721 return NULL_TREE;
722 return maybe_push_res_to_seq (&res_op, seq);
725 /* Builtin or internal function with three arguments. */
727 tree
728 gimple_simplify (combined_fn fn, tree type,
729 tree arg0, tree arg1, tree arg2,
730 gimple_seq *seq, tree (*valueize)(tree))
732 if (constant_for_folding (arg0)
733 && constant_for_folding (arg1)
734 && constant_for_folding (arg2))
736 tree res = fold_const_call (fn, type, arg0, arg1, arg2);
737 if (res && CONSTANT_CLASS_P (res))
738 return res;
741 gimple_match_op res_op;
742 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1, arg2))
743 return NULL_TREE;
744 return maybe_push_res_to_seq (&res_op, seq);
747 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
748 VALUEIZED to true if valueization changed OP. */
750 static inline tree
751 do_valueize (tree op, tree (*valueize)(tree), bool &valueized)
753 if (valueize && TREE_CODE (op) == SSA_NAME)
755 tree tem = valueize (op);
756 if (tem && tem != op)
758 op = tem;
759 valueized = true;
762 return op;
765 /* If RES_OP is a call to a conditional internal function, try simplifying
766 the associated unconditional operation and using the result to build
767 a new conditional operation. For example, if RES_OP is:
769 IFN_COND_ADD (COND, A, B, ELSE)
771 try simplifying (plus A B) and using the result to build a replacement
772 for the whole IFN_COND_ADD.
774 Return true if this approach led to a simplification, otherwise leave
775 RES_OP unchanged (and so suitable for other simplifications). When
776 returning true, add any new statements to SEQ and use VALUEIZE as the
777 valueization function.
779 RES_OP is known to be a call to IFN. */
781 static bool
782 try_conditional_simplification (internal_fn ifn, gimple_match_op *res_op,
783 gimple_seq *seq, tree (*valueize) (tree))
785 code_helper op;
786 tree_code code = conditional_internal_fn_code (ifn);
787 if (code != ERROR_MARK)
788 op = code;
789 else
791 ifn = get_unconditional_internal_fn (ifn);
792 if (ifn == IFN_LAST)
793 return false;
794 op = as_combined_fn (ifn);
797 unsigned int num_ops = res_op->num_ops;
798 gimple_match_op cond_op (gimple_match_cond (res_op->ops[0],
799 res_op->ops[num_ops - 1]),
800 op, res_op->type, num_ops - 2);
801 for (unsigned int i = 1; i < num_ops - 1; ++i)
802 cond_op.ops[i - 1] = res_op->ops[i];
803 switch (num_ops - 2)
805 case 2:
806 if (!gimple_resimplify2 (seq, &cond_op, valueize))
807 return false;
808 break;
809 case 3:
810 if (!gimple_resimplify3 (seq, &cond_op, valueize))
811 return false;
812 break;
813 default:
814 gcc_unreachable ();
816 *res_op = cond_op;
817 maybe_resimplify_conditional_op (seq, res_op, valueize);
818 return true;
821 /* The main STMT based simplification entry. It is used by the fold_stmt
822 and the fold_stmt_to_constant APIs. */
824 bool
825 gimple_simplify (gimple *stmt, gimple_match_op *res_op, gimple_seq *seq,
826 tree (*valueize)(tree), tree (*top_valueize)(tree))
828 switch (gimple_code (stmt))
830 case GIMPLE_ASSIGN:
832 enum tree_code code = gimple_assign_rhs_code (stmt);
833 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
834 switch (gimple_assign_rhs_class (stmt))
836 case GIMPLE_SINGLE_RHS:
837 if (code == REALPART_EXPR
838 || code == IMAGPART_EXPR
839 || code == VIEW_CONVERT_EXPR)
841 tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
842 bool valueized = false;
843 op0 = do_valueize (op0, top_valueize, valueized);
844 res_op->set_op (code, type, op0);
845 return (gimple_resimplify1 (seq, res_op, valueize)
846 || valueized);
848 else if (code == BIT_FIELD_REF)
850 tree rhs1 = gimple_assign_rhs1 (stmt);
851 tree op0 = TREE_OPERAND (rhs1, 0);
852 bool valueized = false;
853 op0 = do_valueize (op0, top_valueize, valueized);
854 res_op->set_op (code, type, op0,
855 TREE_OPERAND (rhs1, 1),
856 TREE_OPERAND (rhs1, 2));
857 return (gimple_resimplify3 (seq, res_op, valueize)
858 || valueized);
860 else if (code == SSA_NAME
861 && top_valueize)
863 tree op0 = gimple_assign_rhs1 (stmt);
864 tree valueized = top_valueize (op0);
865 if (!valueized || op0 == valueized)
866 return false;
867 res_op->set_op (TREE_CODE (op0), type, valueized);
868 return true;
870 break;
871 case GIMPLE_UNARY_RHS:
873 tree rhs1 = gimple_assign_rhs1 (stmt);
874 bool valueized = false;
875 rhs1 = do_valueize (rhs1, top_valueize, valueized);
876 res_op->set_op (code, type, rhs1);
877 return (gimple_resimplify1 (seq, res_op, valueize)
878 || valueized);
880 case GIMPLE_BINARY_RHS:
882 tree rhs1 = gimple_assign_rhs1 (stmt);
883 tree rhs2 = gimple_assign_rhs2 (stmt);
884 bool valueized = false;
885 rhs1 = do_valueize (rhs1, top_valueize, valueized);
886 rhs2 = do_valueize (rhs2, top_valueize, valueized);
887 res_op->set_op (code, type, rhs1, rhs2);
888 return (gimple_resimplify2 (seq, res_op, valueize)
889 || valueized);
891 case GIMPLE_TERNARY_RHS:
893 bool valueized = false;
894 tree rhs1 = gimple_assign_rhs1 (stmt);
895 /* If this is a [VEC_]COND_EXPR first try to simplify an
896 embedded GENERIC condition. */
897 if (code == COND_EXPR
898 || code == VEC_COND_EXPR)
900 if (COMPARISON_CLASS_P (rhs1))
902 tree lhs = TREE_OPERAND (rhs1, 0);
903 tree rhs = TREE_OPERAND (rhs1, 1);
904 lhs = do_valueize (lhs, top_valueize, valueized);
905 rhs = do_valueize (rhs, top_valueize, valueized);
906 gimple_match_op res_op2 (res_op->cond, TREE_CODE (rhs1),
907 TREE_TYPE (rhs1), lhs, rhs);
908 if ((gimple_resimplify2 (seq, &res_op2, valueize)
909 || valueized)
910 && res_op2.code.is_tree_code ())
912 valueized = true;
913 if (TREE_CODE_CLASS ((enum tree_code) res_op2.code)
914 == tcc_comparison)
915 rhs1 = build2 (res_op2.code, TREE_TYPE (rhs1),
916 res_op2.ops[0], res_op2.ops[1]);
917 else if (res_op2.code == SSA_NAME
918 || res_op2.code == INTEGER_CST
919 || res_op2.code == VECTOR_CST)
920 rhs1 = res_op2.ops[0];
921 else
922 valueized = false;
926 tree rhs2 = gimple_assign_rhs2 (stmt);
927 tree rhs3 = gimple_assign_rhs3 (stmt);
928 rhs1 = do_valueize (rhs1, top_valueize, valueized);
929 rhs2 = do_valueize (rhs2, top_valueize, valueized);
930 rhs3 = do_valueize (rhs3, top_valueize, valueized);
931 res_op->set_op (code, type, rhs1, rhs2, rhs3);
932 return (gimple_resimplify3 (seq, res_op, valueize)
933 || valueized);
935 default:
936 gcc_unreachable ();
938 break;
941 case GIMPLE_CALL:
942 /* ??? This way we can't simplify calls with side-effects. */
943 if (gimple_call_lhs (stmt) != NULL_TREE
944 && gimple_call_num_args (stmt) >= 1
945 && gimple_call_num_args (stmt) <= 5)
947 bool valueized = false;
948 combined_fn cfn;
949 if (gimple_call_internal_p (stmt))
950 cfn = as_combined_fn (gimple_call_internal_fn (stmt));
951 else
953 tree fn = gimple_call_fn (stmt);
954 if (!fn)
955 return false;
957 fn = do_valueize (fn, top_valueize, valueized);
958 if (TREE_CODE (fn) != ADDR_EXPR
959 || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
960 return false;
962 tree decl = TREE_OPERAND (fn, 0);
963 if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL
964 || !gimple_builtin_call_types_compatible_p (stmt, decl))
965 return false;
967 cfn = as_combined_fn (DECL_FUNCTION_CODE (decl));
970 unsigned int num_args = gimple_call_num_args (stmt);
971 res_op->set_op (cfn, TREE_TYPE (gimple_call_lhs (stmt)), num_args);
972 for (unsigned i = 0; i < num_args; ++i)
974 tree arg = gimple_call_arg (stmt, i);
975 res_op->ops[i] = do_valueize (arg, top_valueize, valueized);
977 if (internal_fn_p (cfn)
978 && try_conditional_simplification (as_internal_fn (cfn),
979 res_op, seq, valueize))
980 return true;
981 switch (num_args)
983 case 1:
984 return (gimple_resimplify1 (seq, res_op, valueize)
985 || valueized);
986 case 2:
987 return (gimple_resimplify2 (seq, res_op, valueize)
988 || valueized);
989 case 3:
990 return (gimple_resimplify3 (seq, res_op, valueize)
991 || valueized);
992 case 4:
993 return (gimple_resimplify4 (seq, res_op, valueize)
994 || valueized);
995 case 5:
996 return (gimple_resimplify5 (seq, res_op, valueize)
997 || valueized);
998 default:
999 gcc_unreachable ();
1002 break;
1004 case GIMPLE_COND:
1006 tree lhs = gimple_cond_lhs (stmt);
1007 tree rhs = gimple_cond_rhs (stmt);
1008 bool valueized = false;
1009 lhs = do_valueize (lhs, top_valueize, valueized);
1010 rhs = do_valueize (rhs, top_valueize, valueized);
1011 res_op->set_op (gimple_cond_code (stmt), boolean_type_node, lhs, rhs);
1012 return (gimple_resimplify2 (seq, res_op, valueize)
1013 || valueized);
1016 default:
1017 break;
1020 return false;
1024 /* Helper for the autogenerated code, valueize OP. */
1026 inline tree
1027 do_valueize (tree (*valueize)(tree), tree op)
1029 if (valueize && TREE_CODE (op) == SSA_NAME)
1031 tree tem = valueize (op);
1032 if (tem)
1033 return tem;
1035 return op;
1038 /* Helper for the autogenerated code, get at the definition of NAME when
1039 VALUEIZE allows that. */
1041 inline gimple *
1042 get_def (tree (*valueize)(tree), tree name)
1044 if (valueize && ! valueize (name))
1045 return NULL;
1046 return SSA_NAME_DEF_STMT (name);
1049 /* Routine to determine if the types T1 and T2 are effectively
1050 the same for GIMPLE. If T1 or T2 is not a type, the test
1051 applies to their TREE_TYPE. */
1053 static inline bool
1054 types_match (tree t1, tree t2)
1056 if (!TYPE_P (t1))
1057 t1 = TREE_TYPE (t1);
1058 if (!TYPE_P (t2))
1059 t2 = TREE_TYPE (t2);
1061 return types_compatible_p (t1, t2);
1064 /* Return if T has a single use. For GIMPLE, we also allow any
1065 non-SSA_NAME (ie constants) and zero uses to cope with uses
1066 that aren't linked up yet. */
1068 static inline bool
1069 single_use (tree t)
1071 return TREE_CODE (t) != SSA_NAME || has_zero_uses (t) || has_single_use (t);
1074 /* Return true if math operations should be canonicalized,
1075 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
1077 static inline bool
1078 canonicalize_math_p ()
1080 return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;
1083 /* Return true if math operations that are beneficial only after
1084 vectorization should be canonicalized. */
1086 static inline bool
1087 canonicalize_math_after_vectorization_p ()
1089 return !cfun || (cfun->curr_properties & PROP_gimple_lvec) != 0;
1092 /* Return true if pow(cst, x) should be optimized into exp(log(cst) * x).
1093 As a workaround for SPEC CPU2017 628.pop2_s, don't do it if arg0
1094 is an exact integer, arg1 = phi_res +/- cst1 and phi_res = PHI <cst2, ...>
1095 where cst2 +/- cst1 is an exact integer, because then pow (arg0, arg1)
1096 will likely be exact, while exp (log (arg0) * arg1) might be not.
1097 Also don't do it if arg1 is phi_res above and cst2 is an exact integer. */
1099 static bool
1100 optimize_pow_to_exp (tree arg0, tree arg1)
1102 gcc_assert (TREE_CODE (arg0) == REAL_CST);
1103 if (!real_isinteger (TREE_REAL_CST_PTR (arg0), TYPE_MODE (TREE_TYPE (arg0))))
1104 return true;
1106 if (TREE_CODE (arg1) != SSA_NAME)
1107 return true;
1109 gimple *def = SSA_NAME_DEF_STMT (arg1);
1110 gphi *phi = dyn_cast <gphi *> (def);
1111 tree cst1 = NULL_TREE;
1112 enum tree_code code = ERROR_MARK;
1113 if (!phi)
1115 if (!is_gimple_assign (def))
1116 return true;
1117 code = gimple_assign_rhs_code (def);
1118 switch (code)
1120 case PLUS_EXPR:
1121 case MINUS_EXPR:
1122 break;
1123 default:
1124 return true;
1126 if (TREE_CODE (gimple_assign_rhs1 (def)) != SSA_NAME
1127 || TREE_CODE (gimple_assign_rhs2 (def)) != REAL_CST)
1128 return true;
1130 cst1 = gimple_assign_rhs2 (def);
1132 phi = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def)));
1133 if (!phi)
1134 return true;
1137 tree cst2 = NULL_TREE;
1138 int n = gimple_phi_num_args (phi);
1139 for (int i = 0; i < n; i++)
1141 tree arg = PHI_ARG_DEF (phi, i);
1142 if (TREE_CODE (arg) != REAL_CST)
1143 continue;
1144 else if (cst2 == NULL_TREE)
1145 cst2 = arg;
1146 else if (!operand_equal_p (cst2, arg, 0))
1147 return true;
1150 if (cst1 && cst2)
1151 cst2 = const_binop (code, TREE_TYPE (cst2), cst2, cst1);
1152 if (cst2
1153 && TREE_CODE (cst2) == REAL_CST
1154 && real_isinteger (TREE_REAL_CST_PTR (cst2),
1155 TYPE_MODE (TREE_TYPE (cst2))))
1156 return false;
1157 return true;