1 /* Preamble and helpers for the autogenerated gimple-match.c file.
2 Copyright (C) 2014-2020 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
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
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/>. */
22 #include "coretypes.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-fold.h"
38 #include "gimple-match.h"
39 #include "tree-pass.h"
40 #include "internal-fn.h"
41 #include "case-cfn-macros.h"
43 #include "optabs-tree.h"
47 /* Forward declarations of the private auto-generated matchers.
48 They expect valueized operands in canonical order and do not
49 perform simplification of all-constant operands. */
50 static bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
51 code_helper
, tree
, tree
);
52 static bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
53 code_helper
, tree
, tree
, tree
);
54 static bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
55 code_helper
, tree
, tree
, tree
, tree
);
56 static bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
57 code_helper
, tree
, tree
, tree
, tree
, tree
);
58 static bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
59 code_helper
, tree
, tree
, tree
, tree
, tree
, tree
);
60 static bool gimple_resimplify1 (gimple_seq
*, gimple_match_op
*,
62 static bool gimple_resimplify2 (gimple_seq
*, gimple_match_op
*,
64 static bool gimple_resimplify3 (gimple_seq
*, gimple_match_op
*,
66 static bool gimple_resimplify4 (gimple_seq
*, gimple_match_op
*,
68 static bool gimple_resimplify5 (gimple_seq
*, gimple_match_op
*,
71 const unsigned int gimple_match_op::MAX_NUM_OPS
;
73 /* Return whether T is a constant that we'll dispatch to fold to
74 evaluate fully constant expressions. */
77 constant_for_folding (tree t
)
79 return (CONSTANT_CLASS_P (t
)
80 /* The following is only interesting to string builtins. */
81 || (TREE_CODE (t
) == ADDR_EXPR
82 && TREE_CODE (TREE_OPERAND (t
, 0)) == STRING_CST
));
85 /* Try to convert conditional operation ORIG_OP into an IFN_COND_*
86 operation. Return true on success, storing the new operation in NEW_OP. */
89 convert_conditional_op (gimple_match_op
*orig_op
,
90 gimple_match_op
*new_op
)
93 if (orig_op
->code
.is_tree_code ())
94 ifn
= get_conditional_internal_fn ((tree_code
) orig_op
->code
);
97 combined_fn cfn
= orig_op
->code
;
98 if (!internal_fn_p (cfn
))
100 ifn
= get_conditional_internal_fn (as_internal_fn (cfn
));
104 unsigned int num_ops
= orig_op
->num_ops
;
105 new_op
->set_op (as_combined_fn (ifn
), orig_op
->type
, num_ops
+ 2);
106 new_op
->ops
[0] = orig_op
->cond
.cond
;
107 for (unsigned int i
= 0; i
< num_ops
; ++i
)
108 new_op
->ops
[i
+ 1] = orig_op
->ops
[i
];
109 tree else_value
= orig_op
->cond
.else_value
;
111 else_value
= targetm
.preferred_else_value (ifn
, orig_op
->type
,
112 num_ops
, orig_op
->ops
);
113 new_op
->ops
[num_ops
+ 1] = else_value
;
117 /* RES_OP is the result of a simplification. If it is conditional,
118 try to replace it with the equivalent UNCOND form, such as an
119 IFN_COND_* call or a VEC_COND_EXPR. Also try to resimplify the
120 result of the replacement if appropriate, adding any new statements to
121 SEQ and using VALUEIZE as the valueization function. Return true if
122 this resimplification occurred and resulted in at least one change. */
125 maybe_resimplify_conditional_op (gimple_seq
*seq
, gimple_match_op
*res_op
,
126 tree (*valueize
) (tree
))
128 if (!res_op
->cond
.cond
)
131 if (!res_op
->cond
.else_value
132 && res_op
->code
.is_tree_code ())
134 /* The "else" value doesn't matter. If the "then" value is a
135 gimple value, just use it unconditionally. This isn't a
136 simplification in itself, since there was no operation to
137 build in the first place. */
138 if (gimple_simplified_result_is_gimple_val (res_op
))
140 res_op
->cond
.cond
= NULL_TREE
;
144 /* Likewise if the operation would not trap. */
145 bool honor_trapv
= (INTEGRAL_TYPE_P (res_op
->type
)
146 && TYPE_OVERFLOW_TRAPS (res_op
->type
));
147 tree_code op_code
= (tree_code
) res_op
->code
;
150 /* COND_EXPR and VEC_COND_EXPR will trap if, and only if, the condition
151 traps and hence we have to check this. For all other operations, we
152 don't need to consider the operands. */
153 if (op_code
== COND_EXPR
|| op_code
== VEC_COND_EXPR
)
154 op_could_trap
= generic_expr_could_trap_p (res_op
->ops
[0]);
156 op_could_trap
= operation_could_trap_p ((tree_code
) res_op
->code
,
157 FLOAT_TYPE_P (res_op
->type
),
159 res_op
->op_or_null (1));
163 res_op
->cond
.cond
= NULL_TREE
;
168 /* If the "then" value is a gimple value and the "else" value matters,
169 create a VEC_COND_EXPR between them, then see if it can be further
171 gimple_match_op new_op
;
172 if (res_op
->cond
.else_value
173 && VECTOR_TYPE_P (res_op
->type
)
174 && gimple_simplified_result_is_gimple_val (res_op
))
176 new_op
.set_op (VEC_COND_EXPR
, res_op
->type
,
177 res_op
->cond
.cond
, res_op
->ops
[0],
178 res_op
->cond
.else_value
);
180 return gimple_resimplify3 (seq
, res_op
, valueize
);
183 /* Otherwise try rewriting the operation as an IFN_COND_* call.
184 Again, this isn't a simplification in itself, since it's what
185 RES_OP already described. */
186 if (convert_conditional_op (res_op
, &new_op
))
192 /* Helper that matches and simplifies the toplevel result from
193 a gimple_simplify run (where we don't want to build
194 a stmt in case it's used in in-place folding). Replaces
195 RES_OP with a simplified and/or canonicalized result and
196 returns whether any change was made. */
199 gimple_resimplify1 (gimple_seq
*seq
, gimple_match_op
*res_op
,
200 tree (*valueize
)(tree
))
202 if (constant_for_folding (res_op
->ops
[0]))
204 tree tem
= NULL_TREE
;
205 if (res_op
->code
.is_tree_code ())
207 tree_code code
= res_op
->code
;
208 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code
))
209 && TREE_CODE_LENGTH (code
) == 1)
210 tem
= const_unop (res_op
->code
, res_op
->type
, res_op
->ops
[0]);
213 tem
= fold_const_call (combined_fn (res_op
->code
), res_op
->type
,
216 && CONSTANT_CLASS_P (tem
))
218 if (TREE_OVERFLOW_P (tem
))
219 tem
= drop_tree_overflow (tem
);
220 res_op
->set_value (tem
);
221 maybe_resimplify_conditional_op (seq
, res_op
, valueize
);
226 /* Limit recursion, there are cases like PR80887 and others, for
227 example when value-numbering presents us with unfolded expressions
228 that we are really not prepared to handle without eventual
229 oscillation like ((_50 + 0) + 8) where _50 gets mapped to _50
230 itself as available expression. */
231 static unsigned depth
;
234 if (dump_file
&& (dump_flags
& TDF_FOLDING
))
235 fprintf (dump_file
, "Aborting expression simplification due to "
241 gimple_match_op
res_op2 (*res_op
);
242 if (gimple_simplify (&res_op2
, seq
, valueize
,
243 res_op
->code
, res_op
->type
, res_op
->ops
[0]))
251 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
257 /* Helper that matches and simplifies the toplevel result from
258 a gimple_simplify run (where we don't want to build
259 a stmt in case it's used in in-place folding). Replaces
260 RES_OP with a simplified and/or canonicalized result and
261 returns whether any change was made. */
264 gimple_resimplify2 (gimple_seq
*seq
, gimple_match_op
*res_op
,
265 tree (*valueize
)(tree
))
267 if (constant_for_folding (res_op
->ops
[0])
268 && constant_for_folding (res_op
->ops
[1]))
270 tree tem
= NULL_TREE
;
271 if (res_op
->code
.is_tree_code ())
273 tree_code code
= res_op
->code
;
274 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code
))
275 && TREE_CODE_LENGTH (code
) == 2)
276 tem
= const_binop (res_op
->code
, res_op
->type
,
277 res_op
->ops
[0], res_op
->ops
[1]);
280 tem
= fold_const_call (combined_fn (res_op
->code
), res_op
->type
,
281 res_op
->ops
[0], res_op
->ops
[1]);
283 && CONSTANT_CLASS_P (tem
))
285 if (TREE_OVERFLOW_P (tem
))
286 tem
= drop_tree_overflow (tem
);
287 res_op
->set_value (tem
);
288 maybe_resimplify_conditional_op (seq
, res_op
, valueize
);
293 /* Canonicalize operand order. */
294 bool canonicalized
= false;
295 if (res_op
->code
.is_tree_code ()
296 && (TREE_CODE_CLASS ((enum tree_code
) res_op
->code
) == tcc_comparison
297 || commutative_tree_code (res_op
->code
))
298 && tree_swap_operands_p (res_op
->ops
[0], res_op
->ops
[1]))
300 std::swap (res_op
->ops
[0], res_op
->ops
[1]);
301 if (TREE_CODE_CLASS ((enum tree_code
) res_op
->code
) == tcc_comparison
)
302 res_op
->code
= swap_tree_comparison (res_op
->code
);
303 canonicalized
= true;
306 /* Limit recursion, see gimple_resimplify1. */
307 static unsigned depth
;
310 if (dump_file
&& (dump_flags
& TDF_FOLDING
))
311 fprintf (dump_file
, "Aborting expression simplification due to "
317 gimple_match_op
res_op2 (*res_op
);
318 if (gimple_simplify (&res_op2
, seq
, valueize
,
319 res_op
->code
, res_op
->type
,
320 res_op
->ops
[0], res_op
->ops
[1]))
328 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
331 return canonicalized
;
334 /* Helper that matches and simplifies the toplevel result from
335 a gimple_simplify run (where we don't want to build
336 a stmt in case it's used in in-place folding). Replaces
337 RES_OP with a simplified and/or canonicalized result and
338 returns whether any change was made. */
341 gimple_resimplify3 (gimple_seq
*seq
, gimple_match_op
*res_op
,
342 tree (*valueize
)(tree
))
344 if (constant_for_folding (res_op
->ops
[0])
345 && constant_for_folding (res_op
->ops
[1])
346 && constant_for_folding (res_op
->ops
[2]))
348 tree tem
= NULL_TREE
;
349 if (res_op
->code
.is_tree_code ())
351 tree_code code
= res_op
->code
;
352 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code
))
353 && TREE_CODE_LENGTH (code
) == 3)
354 tem
= fold_ternary
/*_to_constant*/ (res_op
->code
, res_op
->type
,
355 res_op
->ops
[0], res_op
->ops
[1],
359 tem
= fold_const_call (combined_fn (res_op
->code
), res_op
->type
,
360 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2]);
362 && CONSTANT_CLASS_P (tem
))
364 if (TREE_OVERFLOW_P (tem
))
365 tem
= drop_tree_overflow (tem
);
366 res_op
->set_value (tem
);
367 maybe_resimplify_conditional_op (seq
, res_op
, valueize
);
372 /* Canonicalize operand order. */
373 bool canonicalized
= false;
374 if (res_op
->code
.is_tree_code ()
375 && commutative_ternary_tree_code (res_op
->code
)
376 && tree_swap_operands_p (res_op
->ops
[0], res_op
->ops
[1]))
378 std::swap (res_op
->ops
[0], res_op
->ops
[1]);
379 canonicalized
= true;
382 /* Limit recursion, see gimple_resimplify1. */
383 static unsigned depth
;
386 if (dump_file
&& (dump_flags
& TDF_FOLDING
))
387 fprintf (dump_file
, "Aborting expression simplification due to "
393 gimple_match_op
res_op2 (*res_op
);
394 if (gimple_simplify (&res_op2
, seq
, valueize
,
395 res_op
->code
, res_op
->type
,
396 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2]))
404 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
407 return canonicalized
;
410 /* Helper that matches and simplifies the toplevel result from
411 a gimple_simplify run (where we don't want to build
412 a stmt in case it's used in in-place folding). Replaces
413 RES_OP with a simplified and/or canonicalized result and
414 returns whether any change was made. */
417 gimple_resimplify4 (gimple_seq
*seq
, gimple_match_op
*res_op
,
418 tree (*valueize
)(tree
))
420 /* No constant folding is defined for four-operand functions. */
422 /* Limit recursion, see gimple_resimplify1. */
423 static unsigned depth
;
426 if (dump_file
&& (dump_flags
& TDF_FOLDING
))
427 fprintf (dump_file
, "Aborting expression simplification due to "
433 gimple_match_op
res_op2 (*res_op
);
434 if (gimple_simplify (&res_op2
, seq
, valueize
,
435 res_op
->code
, res_op
->type
,
436 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2],
445 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
451 /* Helper that matches and simplifies the toplevel result from
452 a gimple_simplify run (where we don't want to build
453 a stmt in case it's used in in-place folding). Replaces
454 RES_OP with a simplified and/or canonicalized result and
455 returns whether any change was made. */
458 gimple_resimplify5 (gimple_seq
*seq
, gimple_match_op
*res_op
,
459 tree (*valueize
)(tree
))
461 /* No constant folding is defined for five-operand functions. */
463 gimple_match_op
res_op2 (*res_op
);
464 if (gimple_simplify (&res_op2
, seq
, valueize
,
465 res_op
->code
, res_op
->type
,
466 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2],
467 res_op
->ops
[3], res_op
->ops
[4]))
473 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
479 /* Match and simplify the toplevel valueized operation THIS.
480 Replaces THIS with a simplified and/or canonicalized result and
481 returns whether any change was made. */
484 gimple_match_op::resimplify (gimple_seq
*seq
, tree (*valueize
)(tree
))
489 return gimple_resimplify1 (seq
, this, valueize
);
491 return gimple_resimplify2 (seq
, this, valueize
);
493 return gimple_resimplify3 (seq
, this, valueize
);
495 return gimple_resimplify4 (seq
, this, valueize
);
497 return gimple_resimplify5 (seq
, this, valueize
);
503 /* If in GIMPLE the operation described by RES_OP should be single-rhs,
504 build a GENERIC tree for that expression and update RES_OP accordingly. */
507 maybe_build_generic_op (gimple_match_op
*res_op
)
509 tree_code code
= (tree_code
) res_op
->code
;
515 case VIEW_CONVERT_EXPR
:
516 val
= build1 (code
, res_op
->type
, res_op
->ops
[0]);
517 res_op
->set_value (val
);
520 val
= build3 (code
, res_op
->type
, res_op
->ops
[0], res_op
->ops
[1],
522 REF_REVERSE_STORAGE_ORDER (val
) = res_op
->reverse
;
523 res_op
->set_value (val
);
529 tree (*mprts_hook
) (gimple_match_op
*);
531 /* Try to build RES_OP, which is known to be a call to FN. Return null
532 if the target doesn't support the function. */
535 build_call_internal (internal_fn fn
, gimple_match_op
*res_op
)
537 if (direct_internal_fn_p (fn
))
539 tree_pair types
= direct_internal_fn_types (fn
, res_op
->type
,
541 if (!direct_internal_fn_supported_p (fn
, types
, OPTIMIZE_FOR_BOTH
))
544 return gimple_build_call_internal (fn
, res_op
->num_ops
,
545 res_op
->op_or_null (0),
546 res_op
->op_or_null (1),
547 res_op
->op_or_null (2),
548 res_op
->op_or_null (3),
549 res_op
->op_or_null (4));
552 /* Push the exploded expression described by RES_OP as a statement to
553 SEQ if necessary and return a gimple value denoting the value of the
554 expression. If RES is not NULL then the result will be always RES
555 and even gimple values are pushed to SEQ. */
558 maybe_push_res_to_seq (gimple_match_op
*res_op
, gimple_seq
*seq
, tree res
)
560 tree
*ops
= res_op
->ops
;
561 unsigned num_ops
= res_op
->num_ops
;
563 /* The caller should have converted conditional operations into an UNCOND
564 form and resimplified as appropriate. The conditional form only
565 survives this far if that conversion failed. */
566 if (res_op
->cond
.cond
)
569 if (res_op
->code
.is_tree_code ())
572 && gimple_simplified_result_is_gimple_val (res_op
))
576 tree tem
= mprts_hook (res_op
);
585 /* Play safe and do not allow abnormals to be mentioned in
586 newly created statements. */
587 for (unsigned int i
= 0; i
< num_ops
; ++i
)
588 if (TREE_CODE (ops
[i
]) == SSA_NAME
589 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[i
]))
592 if (num_ops
> 0 && COMPARISON_CLASS_P (ops
[0]))
593 for (unsigned int i
= 0; i
< 2; ++i
)
594 if (TREE_CODE (TREE_OPERAND (ops
[0], i
)) == SSA_NAME
595 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops
[0], i
)))
598 if (res_op
->code
.is_tree_code ())
602 if (gimple_in_ssa_p (cfun
))
603 res
= make_ssa_name (res_op
->type
);
605 res
= create_tmp_reg (res_op
->type
);
607 maybe_build_generic_op (res_op
);
608 gimple
*new_stmt
= gimple_build_assign (res
, res_op
->code
,
609 res_op
->op_or_null (0),
610 res_op
->op_or_null (1),
611 res_op
->op_or_null (2));
612 gimple_seq_add_stmt_without_update (seq
, new_stmt
);
617 gcc_assert (num_ops
!= 0);
618 combined_fn fn
= res_op
->code
;
619 gcall
*new_stmt
= NULL
;
620 if (internal_fn_p (fn
))
622 /* Generate the given function if we can. */
623 internal_fn ifn
= as_internal_fn (fn
);
624 new_stmt
= build_call_internal (ifn
, res_op
);
630 /* Find the function we want to call. */
631 tree decl
= builtin_decl_implicit (as_builtin_fn (fn
));
635 /* We can't and should not emit calls to non-const functions. */
636 if (!(flags_from_decl_or_type (decl
) & ECF_CONST
))
639 new_stmt
= gimple_build_call (decl
, num_ops
,
640 res_op
->op_or_null (0),
641 res_op
->op_or_null (1),
642 res_op
->op_or_null (2),
643 res_op
->op_or_null (3),
644 res_op
->op_or_null (4));
648 if (gimple_in_ssa_p (cfun
))
649 res
= make_ssa_name (res_op
->type
);
651 res
= create_tmp_reg (res_op
->type
);
653 gimple_call_set_lhs (new_stmt
, res
);
654 gimple_seq_add_stmt_without_update (seq
, new_stmt
);
660 /* Public API overloads follow for operation being tree_code or
661 built_in_function and for one to three operands or arguments.
662 They return NULL_TREE if nothing could be simplified or
663 the resulting simplified value with parts pushed to SEQ.
664 If SEQ is NULL then if the simplification needs to create
665 new stmts it will fail. If VALUEIZE is non-NULL then all
666 SSA names will be valueized using that hook prior to
667 applying simplifications. */
672 gimple_simplify (enum tree_code code
, tree type
,
674 gimple_seq
*seq
, tree (*valueize
)(tree
))
676 if (constant_for_folding (op0
))
678 tree res
= const_unop (code
, type
, op0
);
680 && CONSTANT_CLASS_P (res
))
684 gimple_match_op res_op
;
685 if (!gimple_simplify (&res_op
, seq
, valueize
, code
, type
, op0
))
687 return maybe_push_res_to_seq (&res_op
, seq
);
693 gimple_simplify (enum tree_code code
, tree type
,
695 gimple_seq
*seq
, tree (*valueize
)(tree
))
697 if (constant_for_folding (op0
) && constant_for_folding (op1
))
699 tree res
= const_binop (code
, type
, op0
, op1
);
701 && CONSTANT_CLASS_P (res
))
705 /* Canonicalize operand order both for matching and fallback stmt
707 if ((commutative_tree_code (code
)
708 || TREE_CODE_CLASS (code
) == tcc_comparison
)
709 && tree_swap_operands_p (op0
, op1
))
711 std::swap (op0
, op1
);
712 if (TREE_CODE_CLASS (code
) == tcc_comparison
)
713 code
= swap_tree_comparison (code
);
716 gimple_match_op res_op
;
717 if (!gimple_simplify (&res_op
, seq
, valueize
, code
, type
, op0
, op1
))
719 return maybe_push_res_to_seq (&res_op
, seq
);
725 gimple_simplify (enum tree_code code
, tree type
,
726 tree op0
, tree op1
, tree op2
,
727 gimple_seq
*seq
, tree (*valueize
)(tree
))
729 if (constant_for_folding (op0
) && constant_for_folding (op1
)
730 && constant_for_folding (op2
))
732 tree res
= fold_ternary
/*_to_constant */ (code
, type
, op0
, op1
, op2
);
734 && CONSTANT_CLASS_P (res
))
738 /* Canonicalize operand order both for matching and fallback stmt
740 if (commutative_ternary_tree_code (code
)
741 && tree_swap_operands_p (op0
, op1
))
742 std::swap (op0
, op1
);
744 gimple_match_op res_op
;
745 if (!gimple_simplify (&res_op
, seq
, valueize
, code
, type
, op0
, op1
, op2
))
747 return maybe_push_res_to_seq (&res_op
, seq
);
750 /* Builtin or internal function with one argument. */
753 gimple_simplify (combined_fn fn
, tree type
,
755 gimple_seq
*seq
, tree (*valueize
)(tree
))
757 if (constant_for_folding (arg0
))
759 tree res
= fold_const_call (fn
, type
, arg0
);
760 if (res
&& CONSTANT_CLASS_P (res
))
764 gimple_match_op res_op
;
765 if (!gimple_simplify (&res_op
, seq
, valueize
, fn
, type
, arg0
))
767 return maybe_push_res_to_seq (&res_op
, seq
);
770 /* Builtin or internal function with two arguments. */
773 gimple_simplify (combined_fn fn
, tree type
,
774 tree arg0
, tree arg1
,
775 gimple_seq
*seq
, tree (*valueize
)(tree
))
777 if (constant_for_folding (arg0
)
778 && constant_for_folding (arg1
))
780 tree res
= fold_const_call (fn
, type
, arg0
, arg1
);
781 if (res
&& CONSTANT_CLASS_P (res
))
785 gimple_match_op res_op
;
786 if (!gimple_simplify (&res_op
, seq
, valueize
, fn
, type
, arg0
, arg1
))
788 return maybe_push_res_to_seq (&res_op
, seq
);
791 /* Builtin or internal function with three arguments. */
794 gimple_simplify (combined_fn fn
, tree type
,
795 tree arg0
, tree arg1
, tree arg2
,
796 gimple_seq
*seq
, tree (*valueize
)(tree
))
798 if (constant_for_folding (arg0
)
799 && constant_for_folding (arg1
)
800 && constant_for_folding (arg2
))
802 tree res
= fold_const_call (fn
, type
, arg0
, arg1
, arg2
);
803 if (res
&& CONSTANT_CLASS_P (res
))
807 gimple_match_op res_op
;
808 if (!gimple_simplify (&res_op
, seq
, valueize
, fn
, type
, arg0
, arg1
, arg2
))
810 return maybe_push_res_to_seq (&res_op
, seq
);
813 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
814 VALUEIZED to true if valueization changed OP. */
817 do_valueize (tree op
, tree (*valueize
)(tree
), bool &valueized
)
819 if (valueize
&& TREE_CODE (op
) == SSA_NAME
)
821 tree tem
= valueize (op
);
822 if (tem
&& tem
!= op
)
831 /* If RES_OP is a call to a conditional internal function, try simplifying
832 the associated unconditional operation and using the result to build
833 a new conditional operation. For example, if RES_OP is:
835 IFN_COND_ADD (COND, A, B, ELSE)
837 try simplifying (plus A B) and using the result to build a replacement
838 for the whole IFN_COND_ADD.
840 Return true if this approach led to a simplification, otherwise leave
841 RES_OP unchanged (and so suitable for other simplifications). When
842 returning true, add any new statements to SEQ and use VALUEIZE as the
843 valueization function.
845 RES_OP is known to be a call to IFN. */
848 try_conditional_simplification (internal_fn ifn
, gimple_match_op
*res_op
,
849 gimple_seq
*seq
, tree (*valueize
) (tree
))
852 tree_code code
= conditional_internal_fn_code (ifn
);
853 if (code
!= ERROR_MARK
)
857 ifn
= get_unconditional_internal_fn (ifn
);
860 op
= as_combined_fn (ifn
);
863 unsigned int num_ops
= res_op
->num_ops
;
864 gimple_match_op
cond_op (gimple_match_cond (res_op
->ops
[0],
865 res_op
->ops
[num_ops
- 1]),
866 op
, res_op
->type
, num_ops
- 2);
868 memcpy (cond_op
.ops
, res_op
->ops
+ 1, (num_ops
- 1) * sizeof *cond_op
.ops
);
872 if (!gimple_resimplify2 (seq
, &cond_op
, valueize
))
876 if (!gimple_resimplify3 (seq
, &cond_op
, valueize
))
883 maybe_resimplify_conditional_op (seq
, res_op
, valueize
);
887 /* The main STMT based simplification entry. It is used by the fold_stmt
888 and the fold_stmt_to_constant APIs. */
891 gimple_simplify (gimple
*stmt
, gimple_match_op
*res_op
, gimple_seq
*seq
,
892 tree (*valueize
)(tree
), tree (*top_valueize
)(tree
))
894 switch (gimple_code (stmt
))
898 enum tree_code code
= gimple_assign_rhs_code (stmt
);
899 tree type
= TREE_TYPE (gimple_assign_lhs (stmt
));
900 switch (gimple_assign_rhs_class (stmt
))
902 case GIMPLE_SINGLE_RHS
:
903 if (code
== REALPART_EXPR
904 || code
== IMAGPART_EXPR
905 || code
== VIEW_CONVERT_EXPR
)
907 tree op0
= TREE_OPERAND (gimple_assign_rhs1 (stmt
), 0);
908 bool valueized
= false;
909 op0
= do_valueize (op0
, top_valueize
, valueized
);
910 res_op
->set_op (code
, type
, op0
);
911 return (gimple_resimplify1 (seq
, res_op
, valueize
)
914 else if (code
== BIT_FIELD_REF
)
916 tree rhs1
= gimple_assign_rhs1 (stmt
);
917 tree op0
= TREE_OPERAND (rhs1
, 0);
918 bool valueized
= false;
919 op0
= do_valueize (op0
, top_valueize
, valueized
);
920 res_op
->set_op (code
, type
, op0
,
921 TREE_OPERAND (rhs1
, 1),
922 TREE_OPERAND (rhs1
, 2),
923 REF_REVERSE_STORAGE_ORDER (rhs1
));
926 return (gimple_resimplify3 (seq
, res_op
, valueize
)
929 else if (code
== SSA_NAME
932 tree op0
= gimple_assign_rhs1 (stmt
);
933 tree valueized
= top_valueize (op0
);
934 if (!valueized
|| op0
== valueized
)
936 res_op
->set_op (TREE_CODE (op0
), type
, valueized
);
940 case GIMPLE_UNARY_RHS
:
942 tree rhs1
= gimple_assign_rhs1 (stmt
);
943 bool valueized
= false;
944 rhs1
= do_valueize (rhs1
, top_valueize
, valueized
);
945 res_op
->set_op (code
, type
, rhs1
);
946 return (gimple_resimplify1 (seq
, res_op
, valueize
)
949 case GIMPLE_BINARY_RHS
:
951 tree rhs1
= gimple_assign_rhs1 (stmt
);
952 tree rhs2
= gimple_assign_rhs2 (stmt
);
953 bool valueized
= false;
954 rhs1
= do_valueize (rhs1
, top_valueize
, valueized
);
955 rhs2
= do_valueize (rhs2
, top_valueize
, valueized
);
956 res_op
->set_op (code
, type
, rhs1
, rhs2
);
957 return (gimple_resimplify2 (seq
, res_op
, valueize
)
960 case GIMPLE_TERNARY_RHS
:
962 bool valueized
= false;
963 tree rhs1
= gimple_assign_rhs1 (stmt
);
964 /* If this is a [VEC_]COND_EXPR first try to simplify an
965 embedded GENERIC condition. */
966 if (code
== COND_EXPR
967 || code
== VEC_COND_EXPR
)
969 if (COMPARISON_CLASS_P (rhs1
))
971 tree lhs
= TREE_OPERAND (rhs1
, 0);
972 tree rhs
= TREE_OPERAND (rhs1
, 1);
973 lhs
= do_valueize (lhs
, top_valueize
, valueized
);
974 rhs
= do_valueize (rhs
, top_valueize
, valueized
);
975 gimple_match_op
res_op2 (res_op
->cond
, TREE_CODE (rhs1
),
976 TREE_TYPE (rhs1
), lhs
, rhs
);
977 if ((gimple_resimplify2 (seq
, &res_op2
, valueize
)
979 && res_op2
.code
.is_tree_code ())
982 if (TREE_CODE_CLASS ((enum tree_code
) res_op2
.code
)
984 rhs1
= build2 (res_op2
.code
, TREE_TYPE (rhs1
),
985 res_op2
.ops
[0], res_op2
.ops
[1]);
986 else if (res_op2
.code
== SSA_NAME
987 || res_op2
.code
== INTEGER_CST
988 || res_op2
.code
== VECTOR_CST
)
989 rhs1
= res_op2
.ops
[0];
995 tree rhs2
= gimple_assign_rhs2 (stmt
);
996 tree rhs3
= gimple_assign_rhs3 (stmt
);
997 rhs1
= do_valueize (rhs1
, top_valueize
, valueized
);
998 rhs2
= do_valueize (rhs2
, top_valueize
, valueized
);
999 rhs3
= do_valueize (rhs3
, top_valueize
, valueized
);
1000 res_op
->set_op (code
, type
, rhs1
, rhs2
, rhs3
);
1001 return (gimple_resimplify3 (seq
, res_op
, valueize
)
1011 /* ??? This way we can't simplify calls with side-effects. */
1012 if (gimple_call_lhs (stmt
) != NULL_TREE
1013 && gimple_call_num_args (stmt
) >= 1
1014 && gimple_call_num_args (stmt
) <= 5)
1016 bool valueized
= false;
1018 if (gimple_call_internal_p (stmt
))
1019 cfn
= as_combined_fn (gimple_call_internal_fn (stmt
));
1022 tree fn
= gimple_call_fn (stmt
);
1026 fn
= do_valueize (fn
, top_valueize
, valueized
);
1027 if (TREE_CODE (fn
) != ADDR_EXPR
1028 || TREE_CODE (TREE_OPERAND (fn
, 0)) != FUNCTION_DECL
)
1031 tree decl
= TREE_OPERAND (fn
, 0);
1032 if (DECL_BUILT_IN_CLASS (decl
) != BUILT_IN_NORMAL
1033 || !gimple_builtin_call_types_compatible_p (stmt
, decl
))
1036 cfn
= as_combined_fn (DECL_FUNCTION_CODE (decl
));
1039 unsigned int num_args
= gimple_call_num_args (stmt
);
1040 res_op
->set_op (cfn
, TREE_TYPE (gimple_call_lhs (stmt
)), num_args
);
1041 for (unsigned i
= 0; i
< num_args
; ++i
)
1043 tree arg
= gimple_call_arg (stmt
, i
);
1044 res_op
->ops
[i
] = do_valueize (arg
, top_valueize
, valueized
);
1046 if (internal_fn_p (cfn
)
1047 && try_conditional_simplification (as_internal_fn (cfn
),
1048 res_op
, seq
, valueize
))
1053 return (gimple_resimplify1 (seq
, res_op
, valueize
)
1056 return (gimple_resimplify2 (seq
, res_op
, valueize
)
1059 return (gimple_resimplify3 (seq
, res_op
, valueize
)
1062 return (gimple_resimplify4 (seq
, res_op
, valueize
)
1065 return (gimple_resimplify5 (seq
, res_op
, valueize
)
1075 tree lhs
= gimple_cond_lhs (stmt
);
1076 tree rhs
= gimple_cond_rhs (stmt
);
1077 bool valueized
= false;
1078 lhs
= do_valueize (lhs
, top_valueize
, valueized
);
1079 rhs
= do_valueize (rhs
, top_valueize
, valueized
);
1080 res_op
->set_op (gimple_cond_code (stmt
), boolean_type_node
, lhs
, rhs
);
1081 return (gimple_resimplify2 (seq
, res_op
, valueize
)
1093 /* Helper for the autogenerated code, valueize OP. */
1096 do_valueize (tree (*valueize
)(tree
), tree op
)
1098 if (valueize
&& TREE_CODE (op
) == SSA_NAME
)
1100 tree tem
= valueize (op
);
1107 /* Helper for the autogenerated code, get at the definition of NAME when
1108 VALUEIZE allows that. */
1111 get_def (tree (*valueize
)(tree
), tree name
)
1113 if (valueize
&& ! valueize (name
))
1115 return SSA_NAME_DEF_STMT (name
);
1118 /* Routine to determine if the types T1 and T2 are effectively
1119 the same for GIMPLE. If T1 or T2 is not a type, the test
1120 applies to their TREE_TYPE. */
1123 types_match (tree t1
, tree t2
)
1126 t1
= TREE_TYPE (t1
);
1128 t2
= TREE_TYPE (t2
);
1130 return types_compatible_p (t1
, t2
);
1133 /* Return if T has a single use. For GIMPLE, we also allow any
1134 non-SSA_NAME (ie constants) and zero uses to cope with uses
1135 that aren't linked up yet. */
1140 return TREE_CODE (t
) != SSA_NAME
|| has_zero_uses (t
) || has_single_use (t
);
1143 /* Return true if math operations should be canonicalized,
1144 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
1147 canonicalize_math_p ()
1149 return !cfun
|| (cfun
->curr_properties
& PROP_gimple_opt_math
) == 0;
1152 /* Return true if math operations that are beneficial only after
1153 vectorization should be canonicalized. */
1156 canonicalize_math_after_vectorization_p ()
1158 return !cfun
|| (cfun
->curr_properties
& PROP_gimple_lvec
) != 0;
1161 /* Return true if we can still perform transformations that may introduce
1162 vector operations that are not supported by the target. Vector lowering
1163 normally handles those, but after that pass, it becomes unsafe. */
1166 optimize_vectors_before_lowering_p ()
1168 return !cfun
|| (cfun
->curr_properties
& PROP_gimple_lvec
) == 0;
1171 /* Return true if pow(cst, x) should be optimized into exp(log(cst) * x).
1172 As a workaround for SPEC CPU2017 628.pop2_s, don't do it if arg0
1173 is an exact integer, arg1 = phi_res +/- cst1 and phi_res = PHI <cst2, ...>
1174 where cst2 +/- cst1 is an exact integer, because then pow (arg0, arg1)
1175 will likely be exact, while exp (log (arg0) * arg1) might be not.
1176 Also don't do it if arg1 is phi_res above and cst2 is an exact integer. */
1179 optimize_pow_to_exp (tree arg0
, tree arg1
)
1181 gcc_assert (TREE_CODE (arg0
) == REAL_CST
);
1182 if (!real_isinteger (TREE_REAL_CST_PTR (arg0
), TYPE_MODE (TREE_TYPE (arg0
))))
1185 if (TREE_CODE (arg1
) != SSA_NAME
)
1188 gimple
*def
= SSA_NAME_DEF_STMT (arg1
);
1189 gphi
*phi
= dyn_cast
<gphi
*> (def
);
1190 tree cst1
= NULL_TREE
;
1191 enum tree_code code
= ERROR_MARK
;
1194 if (!is_gimple_assign (def
))
1196 code
= gimple_assign_rhs_code (def
);
1205 if (TREE_CODE (gimple_assign_rhs1 (def
)) != SSA_NAME
1206 || TREE_CODE (gimple_assign_rhs2 (def
)) != REAL_CST
)
1209 cst1
= gimple_assign_rhs2 (def
);
1211 phi
= dyn_cast
<gphi
*> (SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def
)));
1216 tree cst2
= NULL_TREE
;
1217 int n
= gimple_phi_num_args (phi
);
1218 for (int i
= 0; i
< n
; i
++)
1220 tree arg
= PHI_ARG_DEF (phi
, i
);
1221 if (TREE_CODE (arg
) != REAL_CST
)
1223 else if (cst2
== NULL_TREE
)
1225 else if (!operand_equal_p (cst2
, arg
, 0))
1230 cst2
= const_binop (code
, TREE_TYPE (cst2
), cst2
, cst1
);
1232 && TREE_CODE (cst2
) == REAL_CST
1233 && real_isinteger (TREE_REAL_CST_PTR (cst2
),
1234 TYPE_MODE (TREE_TYPE (cst2
))))
1239 /* Return true if a division INNER_DIV / DIVISOR where INNER_DIV
1240 is another division can be optimized. Don't optimize if INNER_DIV
1241 is used in a TRUNC_MOD_EXPR with DIVISOR as second operand. */
1244 optimize_successive_divisions_p (tree divisor
, tree inner_div
)
1246 if (!gimple_in_ssa_p (cfun
))
1249 imm_use_iterator imm_iter
;
1250 use_operand_p use_p
;
1251 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, inner_div
)
1253 gimple
*use_stmt
= USE_STMT (use_p
);
1254 if (!is_gimple_assign (use_stmt
)
1255 || gimple_assign_rhs_code (use_stmt
) != TRUNC_MOD_EXPR
1256 || !operand_equal_p (gimple_assign_rhs2 (use_stmt
), divisor
, 0))