1 /* Preamble and helpers for the autogenerated gimple-match.c file.
2 Copyright (C) 2014-2015 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 "fold-const.h"
31 #include "stor-layout.h"
33 #include "internal-fn.h"
34 #include "gimple-fold.h"
35 #include "gimple-iterator.h"
36 #include "insn-config.h"
50 #include "gimple-match.h"
51 #include "tree-pass.h"
54 /* Forward declarations of the private auto-generated matchers.
55 They expect valueized operands in canonical order and do not
56 perform simplification of all-constant operands. */
57 static bool gimple_simplify (code_helper
*, tree
*,
58 gimple_seq
*, tree (*)(tree
),
59 code_helper
, tree
, tree
);
60 static bool gimple_simplify (code_helper
*, tree
*,
61 gimple_seq
*, tree (*)(tree
),
62 code_helper
, tree
, tree
, tree
);
63 static bool gimple_simplify (code_helper
*, tree
*,
64 gimple_seq
*, tree (*)(tree
),
65 code_helper
, tree
, tree
, tree
, tree
);
68 /* Return whether T is a constant that we'll dispatch to fold to
69 evaluate fully constant expressions. */
72 constant_for_folding (tree t
)
74 return (CONSTANT_CLASS_P (t
)
75 /* The following is only interesting to string builtins. */
76 || (TREE_CODE (t
) == ADDR_EXPR
77 && TREE_CODE (TREE_OPERAND (t
, 0)) == STRING_CST
));
81 /* Helper that matches and simplifies the toplevel result from
82 a gimple_simplify run (where we don't want to build
83 a stmt in case it's used in in-place folding). Replaces
84 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
85 result and returns whether any change was made. */
88 gimple_resimplify1 (gimple_seq
*seq
,
89 code_helper
*res_code
, tree type
, tree
*res_ops
,
90 tree (*valueize
)(tree
))
92 if (constant_for_folding (res_ops
[0]))
95 if (res_code
->is_tree_code ())
96 tem
= const_unop (*res_code
, type
, res_ops
[0]);
99 tree decl
= builtin_decl_implicit (*res_code
);
102 tem
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, res_ops
, 1, false);
105 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
107 tem
= fold_convert (type
, tem
);
112 && CONSTANT_CLASS_P (tem
))
115 res_ops
[1] = NULL_TREE
;
116 res_ops
[2] = NULL_TREE
;
117 *res_code
= TREE_CODE (res_ops
[0]);
122 code_helper res_code2
;
123 tree res_ops2
[3] = {};
124 if (gimple_simplify (&res_code2
, res_ops2
, seq
, valueize
,
125 *res_code
, type
, res_ops
[0]))
127 *res_code
= res_code2
;
128 res_ops
[0] = res_ops2
[0];
129 res_ops
[1] = res_ops2
[1];
130 res_ops
[2] = res_ops2
[2];
137 /* Helper that matches and simplifies the toplevel result from
138 a gimple_simplify run (where we don't want to build
139 a stmt in case it's used in in-place folding). Replaces
140 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
141 result and returns whether any change was made. */
144 gimple_resimplify2 (gimple_seq
*seq
,
145 code_helper
*res_code
, tree type
, tree
*res_ops
,
146 tree (*valueize
)(tree
))
148 if (constant_for_folding (res_ops
[0]) && constant_for_folding (res_ops
[1]))
150 tree tem
= NULL_TREE
;
151 if (res_code
->is_tree_code ())
152 tem
= const_binop (*res_code
, type
, res_ops
[0], res_ops
[1]);
155 tree decl
= builtin_decl_implicit (*res_code
);
158 tem
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, res_ops
, 2, false);
161 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
163 tem
= fold_convert (type
, tem
);
168 && CONSTANT_CLASS_P (tem
))
171 res_ops
[1] = NULL_TREE
;
172 res_ops
[2] = NULL_TREE
;
173 *res_code
= TREE_CODE (res_ops
[0]);
178 /* Canonicalize operand order. */
179 bool canonicalized
= false;
180 if (res_code
->is_tree_code ()
181 && (TREE_CODE_CLASS ((enum tree_code
) *res_code
) == tcc_comparison
182 || commutative_tree_code (*res_code
))
183 && tree_swap_operands_p (res_ops
[0], res_ops
[1], false))
185 std::swap (res_ops
[0], res_ops
[1]);
186 if (TREE_CODE_CLASS ((enum tree_code
) *res_code
) == tcc_comparison
)
187 *res_code
= swap_tree_comparison (*res_code
);
188 canonicalized
= true;
191 code_helper res_code2
;
192 tree res_ops2
[3] = {};
193 if (gimple_simplify (&res_code2
, res_ops2
, seq
, valueize
,
194 *res_code
, type
, res_ops
[0], res_ops
[1]))
196 *res_code
= res_code2
;
197 res_ops
[0] = res_ops2
[0];
198 res_ops
[1] = res_ops2
[1];
199 res_ops
[2] = res_ops2
[2];
203 return canonicalized
;
206 /* Helper that matches and simplifies the toplevel result from
207 a gimple_simplify run (where we don't want to build
208 a stmt in case it's used in in-place folding). Replaces
209 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
210 result and returns whether any change was made. */
213 gimple_resimplify3 (gimple_seq
*seq
,
214 code_helper
*res_code
, tree type
, tree
*res_ops
,
215 tree (*valueize
)(tree
))
217 if (constant_for_folding (res_ops
[0]) && constant_for_folding (res_ops
[1])
218 && constant_for_folding (res_ops
[2]))
220 tree tem
= NULL_TREE
;
221 if (res_code
->is_tree_code ())
222 tem
= fold_ternary
/*_to_constant*/ (*res_code
, type
, res_ops
[0],
223 res_ops
[1], res_ops
[2]);
226 tree decl
= builtin_decl_implicit (*res_code
);
229 tem
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, res_ops
, 3, false);
232 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
234 tem
= fold_convert (type
, tem
);
239 && CONSTANT_CLASS_P (tem
))
242 res_ops
[1] = NULL_TREE
;
243 res_ops
[2] = NULL_TREE
;
244 *res_code
= TREE_CODE (res_ops
[0]);
249 /* Canonicalize operand order. */
250 bool canonicalized
= false;
251 if (res_code
->is_tree_code ()
252 && commutative_ternary_tree_code (*res_code
)
253 && tree_swap_operands_p (res_ops
[0], res_ops
[1], false))
255 std::swap (res_ops
[0], res_ops
[1]);
256 canonicalized
= true;
259 code_helper res_code2
;
260 tree res_ops2
[3] = {};
261 if (gimple_simplify (&res_code2
, res_ops2
, seq
, valueize
,
263 res_ops
[0], res_ops
[1], res_ops
[2]))
265 *res_code
= res_code2
;
266 res_ops
[0] = res_ops2
[0];
267 res_ops
[1] = res_ops2
[1];
268 res_ops
[2] = res_ops2
[2];
272 return canonicalized
;
276 /* If in GIMPLE expressions with CODE go as single-rhs build
277 a GENERIC tree for that expression into *OP0. */
280 maybe_build_generic_op (enum tree_code code
, tree type
,
281 tree
*op0
, tree op1
, tree op2
)
287 case VIEW_CONVERT_EXPR
:
288 *op0
= build1 (code
, type
, *op0
);
291 *op0
= build3 (code
, type
, *op0
, op1
, op2
);
297 tree (*mprts_hook
) (code_helper
, tree
, tree
*);
299 /* Push the exploded expression described by RCODE, TYPE and OPS
300 as a statement to SEQ if necessary and return a gimple value
301 denoting the value of the expression. If RES is not NULL
302 then the result will be always RES and even gimple values are
306 maybe_push_res_to_seq (code_helper rcode
, tree type
, tree
*ops
,
307 gimple_seq
*seq
, tree res
)
309 if (rcode
.is_tree_code ())
312 && gimple_simplified_result_is_gimple_val (rcode
, ops
))
316 tree tem
= mprts_hook (rcode
, type
, ops
);
322 /* Play safe and do not allow abnormals to be mentioned in
323 newly created statements. */
324 if ((TREE_CODE (ops
[0]) == SSA_NAME
325 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[0]))
327 && TREE_CODE (ops
[1]) == SSA_NAME
328 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[1]))
330 && TREE_CODE (ops
[2]) == SSA_NAME
331 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[2])))
334 res
= make_ssa_name (type
);
335 maybe_build_generic_op (rcode
, type
, &ops
[0], ops
[1], ops
[2]);
336 gimple
*new_stmt
= gimple_build_assign (res
, rcode
,
337 ops
[0], ops
[1], ops
[2]);
338 gimple_seq_add_stmt_without_update (seq
, new_stmt
);
345 tree decl
= builtin_decl_implicit (rcode
);
348 /* We can't and should not emit calls to non-const functions. */
349 if (!(flags_from_decl_or_type (decl
) & ECF_CONST
))
351 /* Play safe and do not allow abnormals to be mentioned in
352 newly created statements. */
354 for (nargs
= 0; nargs
< 3; ++nargs
)
358 if (TREE_CODE (ops
[nargs
]) == SSA_NAME
359 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[nargs
]))
362 gcc_assert (nargs
!= 0);
364 res
= make_ssa_name (type
);
365 gimple
*new_stmt
= gimple_build_call (decl
, nargs
, ops
[0], ops
[1], ops
[2]);
366 gimple_call_set_lhs (new_stmt
, res
);
367 gimple_seq_add_stmt_without_update (seq
, new_stmt
);
373 /* Public API overloads follow for operation being tree_code or
374 built_in_function and for one to three operands or arguments.
375 They return NULL_TREE if nothing could be simplified or
376 the resulting simplified value with parts pushed to SEQ.
377 If SEQ is NULL then if the simplification needs to create
378 new stmts it will fail. If VALUEIZE is non-NULL then all
379 SSA names will be valueized using that hook prior to
380 applying simplifications. */
385 gimple_simplify (enum tree_code code
, tree type
,
387 gimple_seq
*seq
, tree (*valueize
)(tree
))
389 if (constant_for_folding (op0
))
391 tree res
= const_unop (code
, type
, op0
);
393 && CONSTANT_CLASS_P (res
))
399 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
402 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
408 gimple_simplify (enum tree_code code
, tree type
,
410 gimple_seq
*seq
, tree (*valueize
)(tree
))
412 if (constant_for_folding (op0
) && constant_for_folding (op1
))
414 tree res
= const_binop (code
, type
, op0
, op1
);
416 && CONSTANT_CLASS_P (res
))
420 /* Canonicalize operand order both for matching and fallback stmt
422 if ((commutative_tree_code (code
)
423 || TREE_CODE_CLASS (code
) == tcc_comparison
)
424 && tree_swap_operands_p (op0
, op1
, false))
426 std::swap (op0
, op1
);
427 if (TREE_CODE_CLASS (code
) == tcc_comparison
)
428 code
= swap_tree_comparison (code
);
433 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
434 code
, type
, op0
, op1
))
436 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
442 gimple_simplify (enum tree_code code
, tree type
,
443 tree op0
, tree op1
, tree op2
,
444 gimple_seq
*seq
, tree (*valueize
)(tree
))
446 if (constant_for_folding (op0
) && constant_for_folding (op1
)
447 && constant_for_folding (op2
))
449 tree res
= fold_ternary
/*_to_constant */ (code
, type
, op0
, op1
, op2
);
451 && CONSTANT_CLASS_P (res
))
455 /* Canonicalize operand order both for matching and fallback stmt
457 if (commutative_ternary_tree_code (code
)
458 && tree_swap_operands_p (op0
, op1
, false))
459 std::swap (op0
, op1
);
463 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
464 code
, type
, op0
, op1
, op2
))
466 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
469 /* Builtin function with one argument. */
472 gimple_simplify (enum built_in_function fn
, tree type
,
474 gimple_seq
*seq
, tree (*valueize
)(tree
))
476 if (constant_for_folding (arg0
))
478 tree decl
= builtin_decl_implicit (fn
);
481 tree res
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, &arg0
, 1, false);
484 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
486 res
= fold_convert (type
, res
);
487 if (CONSTANT_CLASS_P (res
))
495 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
498 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
501 /* Builtin function with two arguments. */
504 gimple_simplify (enum built_in_function fn
, tree type
,
505 tree arg0
, tree arg1
,
506 gimple_seq
*seq
, tree (*valueize
)(tree
))
508 if (constant_for_folding (arg0
)
509 && constant_for_folding (arg1
))
511 tree decl
= builtin_decl_implicit (fn
);
517 tree res
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, args
, 2, false);
520 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
522 res
= fold_convert (type
, res
);
523 if (CONSTANT_CLASS_P (res
))
531 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
532 fn
, type
, arg0
, arg1
))
534 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
537 /* Builtin function with three arguments. */
540 gimple_simplify (enum built_in_function fn
, tree type
,
541 tree arg0
, tree arg1
, tree arg2
,
542 gimple_seq
*seq
, tree (*valueize
)(tree
))
544 if (constant_for_folding (arg0
)
545 && constant_for_folding (arg1
)
546 && constant_for_folding (arg2
))
548 tree decl
= builtin_decl_implicit (fn
);
555 tree res
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, args
, 3, false);
558 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
560 res
= fold_convert (type
, res
);
561 if (CONSTANT_CLASS_P (res
))
569 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
570 fn
, type
, arg0
, arg1
, arg2
))
572 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
575 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
576 VALUEIZED to true if valueization changed OP. */
579 do_valueize (tree op
, tree (*valueize
)(tree
), bool &valueized
)
581 if (valueize
&& TREE_CODE (op
) == SSA_NAME
)
583 tree tem
= valueize (op
);
584 if (tem
&& tem
!= op
)
593 /* The main STMT based simplification entry. It is used by the fold_stmt
594 and the fold_stmt_to_constant APIs. */
597 gimple_simplify (gimple
*stmt
,
598 code_helper
*rcode
, tree
*ops
,
600 tree (*valueize
)(tree
), tree (*top_valueize
)(tree
))
602 switch (gimple_code (stmt
))
606 enum tree_code code
= gimple_assign_rhs_code (stmt
);
607 tree type
= TREE_TYPE (gimple_assign_lhs (stmt
));
608 switch (gimple_assign_rhs_class (stmt
))
610 case GIMPLE_SINGLE_RHS
:
611 if (code
== REALPART_EXPR
612 || code
== IMAGPART_EXPR
613 || code
== VIEW_CONVERT_EXPR
)
615 tree op0
= TREE_OPERAND (gimple_assign_rhs1 (stmt
), 0);
616 bool valueized
= false;
617 op0
= do_valueize (op0
, top_valueize
, valueized
);
620 return (gimple_resimplify1 (seq
, rcode
, type
, ops
, valueize
)
623 else if (code
== BIT_FIELD_REF
)
625 tree rhs1
= gimple_assign_rhs1 (stmt
);
626 tree op0
= TREE_OPERAND (rhs1
, 0);
627 bool valueized
= false;
628 op0
= do_valueize (op0
, top_valueize
, valueized
);
631 ops
[1] = TREE_OPERAND (rhs1
, 1);
632 ops
[2] = TREE_OPERAND (rhs1
, 2);
633 return (gimple_resimplify3 (seq
, rcode
, type
, ops
, valueize
)
636 else if (code
== SSA_NAME
639 tree op0
= gimple_assign_rhs1 (stmt
);
640 tree valueized
= top_valueize (op0
);
641 if (!valueized
|| op0
== valueized
)
644 *rcode
= TREE_CODE (op0
);
648 case GIMPLE_UNARY_RHS
:
650 tree rhs1
= gimple_assign_rhs1 (stmt
);
651 bool valueized
= false;
652 rhs1
= do_valueize (rhs1
, top_valueize
, valueized
);
655 return (gimple_resimplify1 (seq
, rcode
, type
, ops
, valueize
)
658 case GIMPLE_BINARY_RHS
:
660 tree rhs1
= gimple_assign_rhs1 (stmt
);
661 tree rhs2
= gimple_assign_rhs2 (stmt
);
662 bool valueized
= false;
663 rhs1
= do_valueize (rhs1
, top_valueize
, valueized
);
664 rhs2
= do_valueize (rhs2
, top_valueize
, valueized
);
668 return (gimple_resimplify2 (seq
, rcode
, type
, ops
, valueize
)
671 case GIMPLE_TERNARY_RHS
:
673 bool valueized
= false;
674 tree rhs1
= gimple_assign_rhs1 (stmt
);
675 /* If this is a [VEC_]COND_EXPR first try to simplify an
676 embedded GENERIC condition. */
677 if (code
== COND_EXPR
678 || code
== VEC_COND_EXPR
)
680 if (COMPARISON_CLASS_P (rhs1
))
682 tree lhs
= TREE_OPERAND (rhs1
, 0);
683 tree rhs
= TREE_OPERAND (rhs1
, 1);
684 lhs
= do_valueize (lhs
, top_valueize
, valueized
);
685 rhs
= do_valueize (rhs
, top_valueize
, valueized
);
686 code_helper rcode2
= TREE_CODE (rhs1
);
690 if ((gimple_resimplify2 (seq
, &rcode2
, TREE_TYPE (rhs1
),
693 && rcode2
.is_tree_code ())
696 if (TREE_CODE_CLASS ((enum tree_code
)rcode2
)
698 rhs1
= build2 (rcode2
, TREE_TYPE (rhs1
),
700 else if (rcode2
== SSA_NAME
701 || rcode2
== INTEGER_CST
)
708 tree rhs2
= gimple_assign_rhs2 (stmt
);
709 tree rhs3
= gimple_assign_rhs3 (stmt
);
710 rhs1
= do_valueize (rhs1
, top_valueize
, valueized
);
711 rhs2
= do_valueize (rhs2
, top_valueize
, valueized
);
712 rhs3
= do_valueize (rhs3
, top_valueize
, valueized
);
717 return (gimple_resimplify3 (seq
, rcode
, type
, ops
, valueize
)
727 /* ??? This way we can't simplify calls with side-effects. */
728 if (gimple_call_lhs (stmt
) != NULL_TREE
729 && gimple_call_num_args (stmt
) >= 1
730 && gimple_call_num_args (stmt
) <= 3)
732 tree fn
= gimple_call_fn (stmt
);
733 /* ??? Internal function support missing. */
736 bool valueized
= false;
737 fn
= do_valueize (fn
, top_valueize
, valueized
);
738 if (TREE_CODE (fn
) != ADDR_EXPR
739 || TREE_CODE (TREE_OPERAND (fn
, 0)) != FUNCTION_DECL
)
742 tree decl
= TREE_OPERAND (fn
, 0);
743 if (DECL_BUILT_IN_CLASS (decl
) != BUILT_IN_NORMAL
744 || !builtin_decl_implicit (DECL_FUNCTION_CODE (decl
))
745 || !gimple_builtin_call_types_compatible_p (stmt
, decl
))
748 tree type
= TREE_TYPE (gimple_call_lhs (stmt
));
749 *rcode
= DECL_FUNCTION_CODE (decl
);
750 for (unsigned i
= 0; i
< gimple_call_num_args (stmt
); ++i
)
752 tree arg
= gimple_call_arg (stmt
, i
);
753 ops
[i
] = do_valueize (arg
, top_valueize
, valueized
);
755 switch (gimple_call_num_args (stmt
))
758 return (gimple_resimplify1 (seq
, rcode
, type
, ops
, valueize
)
761 return (gimple_resimplify2 (seq
, rcode
, type
, ops
, valueize
)
764 return (gimple_resimplify3 (seq
, rcode
, type
, ops
, valueize
)
774 tree lhs
= gimple_cond_lhs (stmt
);
775 tree rhs
= gimple_cond_rhs (stmt
);
776 bool valueized
= false;
777 lhs
= do_valueize (lhs
, top_valueize
, valueized
);
778 rhs
= do_valueize (rhs
, top_valueize
, valueized
);
779 *rcode
= gimple_cond_code (stmt
);
782 return (gimple_resimplify2 (seq
, rcode
,
783 boolean_type_node
, ops
, valueize
)
795 /* Helper for the autogenerated code, valueize OP. */
798 do_valueize (tree (*valueize
)(tree
), tree op
)
800 if (valueize
&& TREE_CODE (op
) == SSA_NAME
)
801 return valueize (op
);
805 /* Routine to determine if the types T1 and T2 are effectively
806 the same for GIMPLE. If T1 or T2 is not a type, the test
807 applies to their TREE_TYPE. */
810 types_match (tree t1
, tree t2
)
817 return types_compatible_p (t1
, t2
);
820 /* Return if T has a single use. For GIMPLE, we also allow any
821 non-SSA_NAME (ie constants) and zero uses to cope with uses
822 that aren't linked up yet. */
827 return TREE_CODE (t
) != SSA_NAME
|| has_zero_uses (t
) || has_single_use (t
);
830 /* Return true if math operations should be canonicalized,
831 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
834 canonicalize_math_p ()
836 return !cfun
|| (cfun
->curr_properties
& PROP_gimple_opt_math
) == 0;