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"
32 #include "gimple-fold.h"
36 #include "gimple-match.h"
37 #include "tree-pass.h"
40 /* Forward declarations of the private auto-generated matchers.
41 They expect valueized operands in canonical order and do not
42 perform simplification of all-constant operands. */
43 static bool gimple_simplify (code_helper
*, tree
*,
44 gimple_seq
*, tree (*)(tree
),
45 code_helper
, tree
, tree
);
46 static bool gimple_simplify (code_helper
*, tree
*,
47 gimple_seq
*, tree (*)(tree
),
48 code_helper
, tree
, tree
, tree
);
49 static bool gimple_simplify (code_helper
*, tree
*,
50 gimple_seq
*, tree (*)(tree
),
51 code_helper
, tree
, tree
, tree
, tree
);
54 /* Return whether T is a constant that we'll dispatch to fold to
55 evaluate fully constant expressions. */
58 constant_for_folding (tree t
)
60 return (CONSTANT_CLASS_P (t
)
61 /* The following is only interesting to string builtins. */
62 || (TREE_CODE (t
) == ADDR_EXPR
63 && TREE_CODE (TREE_OPERAND (t
, 0)) == STRING_CST
));
67 /* Helper that matches and simplifies the toplevel result from
68 a gimple_simplify run (where we don't want to build
69 a stmt in case it's used in in-place folding). Replaces
70 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
71 result and returns whether any change was made. */
74 gimple_resimplify1 (gimple_seq
*seq
,
75 code_helper
*res_code
, tree type
, tree
*res_ops
,
76 tree (*valueize
)(tree
))
78 if (constant_for_folding (res_ops
[0]))
81 if (res_code
->is_tree_code ())
82 tem
= const_unop (*res_code
, type
, res_ops
[0]);
85 tree decl
= builtin_decl_implicit (*res_code
);
88 tem
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, res_ops
, 1, false);
91 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
93 tem
= fold_convert (type
, tem
);
98 && CONSTANT_CLASS_P (tem
))
101 res_ops
[1] = NULL_TREE
;
102 res_ops
[2] = NULL_TREE
;
103 *res_code
= TREE_CODE (res_ops
[0]);
108 code_helper res_code2
;
109 tree res_ops2
[3] = {};
110 if (gimple_simplify (&res_code2
, res_ops2
, seq
, valueize
,
111 *res_code
, type
, res_ops
[0]))
113 *res_code
= res_code2
;
114 res_ops
[0] = res_ops2
[0];
115 res_ops
[1] = res_ops2
[1];
116 res_ops
[2] = res_ops2
[2];
123 /* Helper that matches and simplifies the toplevel result from
124 a gimple_simplify run (where we don't want to build
125 a stmt in case it's used in in-place folding). Replaces
126 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
127 result and returns whether any change was made. */
130 gimple_resimplify2 (gimple_seq
*seq
,
131 code_helper
*res_code
, tree type
, tree
*res_ops
,
132 tree (*valueize
)(tree
))
134 if (constant_for_folding (res_ops
[0]) && constant_for_folding (res_ops
[1]))
136 tree tem
= NULL_TREE
;
137 if (res_code
->is_tree_code ())
138 tem
= const_binop (*res_code
, type
, res_ops
[0], res_ops
[1]);
141 tree decl
= builtin_decl_implicit (*res_code
);
144 tem
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, res_ops
, 2, false);
147 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
149 tem
= fold_convert (type
, tem
);
154 && CONSTANT_CLASS_P (tem
))
157 res_ops
[1] = NULL_TREE
;
158 res_ops
[2] = NULL_TREE
;
159 *res_code
= TREE_CODE (res_ops
[0]);
164 /* Canonicalize operand order. */
165 bool canonicalized
= false;
166 if (res_code
->is_tree_code ()
167 && (TREE_CODE_CLASS ((enum tree_code
) *res_code
) == tcc_comparison
168 || commutative_tree_code (*res_code
))
169 && tree_swap_operands_p (res_ops
[0], res_ops
[1], false))
171 std::swap (res_ops
[0], res_ops
[1]);
172 if (TREE_CODE_CLASS ((enum tree_code
) *res_code
) == tcc_comparison
)
173 *res_code
= swap_tree_comparison (*res_code
);
174 canonicalized
= true;
177 code_helper res_code2
;
178 tree res_ops2
[3] = {};
179 if (gimple_simplify (&res_code2
, res_ops2
, seq
, valueize
,
180 *res_code
, type
, res_ops
[0], res_ops
[1]))
182 *res_code
= res_code2
;
183 res_ops
[0] = res_ops2
[0];
184 res_ops
[1] = res_ops2
[1];
185 res_ops
[2] = res_ops2
[2];
189 return canonicalized
;
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_CODE and *RES_OPS with a simplified and/or canonicalized
196 result and returns whether any change was made. */
199 gimple_resimplify3 (gimple_seq
*seq
,
200 code_helper
*res_code
, tree type
, tree
*res_ops
,
201 tree (*valueize
)(tree
))
203 if (constant_for_folding (res_ops
[0]) && constant_for_folding (res_ops
[1])
204 && constant_for_folding (res_ops
[2]))
206 tree tem
= NULL_TREE
;
207 if (res_code
->is_tree_code ())
208 tem
= fold_ternary
/*_to_constant*/ (*res_code
, type
, res_ops
[0],
209 res_ops
[1], res_ops
[2]);
212 tree decl
= builtin_decl_implicit (*res_code
);
215 tem
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, res_ops
, 3, false);
218 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
220 tem
= fold_convert (type
, tem
);
225 && CONSTANT_CLASS_P (tem
))
228 res_ops
[1] = NULL_TREE
;
229 res_ops
[2] = NULL_TREE
;
230 *res_code
= TREE_CODE (res_ops
[0]);
235 /* Canonicalize operand order. */
236 bool canonicalized
= false;
237 if (res_code
->is_tree_code ()
238 && commutative_ternary_tree_code (*res_code
)
239 && tree_swap_operands_p (res_ops
[0], res_ops
[1], false))
241 std::swap (res_ops
[0], res_ops
[1]);
242 canonicalized
= true;
245 code_helper res_code2
;
246 tree res_ops2
[3] = {};
247 if (gimple_simplify (&res_code2
, res_ops2
, seq
, valueize
,
249 res_ops
[0], res_ops
[1], res_ops
[2]))
251 *res_code
= res_code2
;
252 res_ops
[0] = res_ops2
[0];
253 res_ops
[1] = res_ops2
[1];
254 res_ops
[2] = res_ops2
[2];
258 return canonicalized
;
262 /* If in GIMPLE expressions with CODE go as single-rhs build
263 a GENERIC tree for that expression into *OP0. */
266 maybe_build_generic_op (enum tree_code code
, tree type
,
267 tree
*op0
, tree op1
, tree op2
)
273 case VIEW_CONVERT_EXPR
:
274 *op0
= build1 (code
, type
, *op0
);
277 *op0
= build3 (code
, type
, *op0
, op1
, op2
);
283 tree (*mprts_hook
) (code_helper
, tree
, tree
*);
285 /* Push the exploded expression described by RCODE, TYPE and OPS
286 as a statement to SEQ if necessary and return a gimple value
287 denoting the value of the expression. If RES is not NULL
288 then the result will be always RES and even gimple values are
292 maybe_push_res_to_seq (code_helper rcode
, tree type
, tree
*ops
,
293 gimple_seq
*seq
, tree res
)
295 if (rcode
.is_tree_code ())
298 && gimple_simplified_result_is_gimple_val (rcode
, ops
))
302 tree tem
= mprts_hook (rcode
, type
, ops
);
308 /* Play safe and do not allow abnormals to be mentioned in
309 newly created statements. */
310 if ((TREE_CODE (ops
[0]) == SSA_NAME
311 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[0]))
313 && TREE_CODE (ops
[1]) == SSA_NAME
314 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[1]))
316 && TREE_CODE (ops
[2]) == SSA_NAME
317 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[2])))
321 if (gimple_in_ssa_p (cfun
))
322 res
= make_ssa_name (type
);
324 res
= create_tmp_reg (type
);
326 maybe_build_generic_op (rcode
, type
, &ops
[0], ops
[1], ops
[2]);
327 gimple
*new_stmt
= gimple_build_assign (res
, rcode
,
328 ops
[0], ops
[1], ops
[2]);
329 gimple_seq_add_stmt_without_update (seq
, new_stmt
);
336 tree decl
= builtin_decl_implicit (rcode
);
339 /* We can't and should not emit calls to non-const functions. */
340 if (!(flags_from_decl_or_type (decl
) & ECF_CONST
))
342 /* Play safe and do not allow abnormals to be mentioned in
343 newly created statements. */
345 for (nargs
= 0; nargs
< 3; ++nargs
)
349 if (TREE_CODE (ops
[nargs
]) == SSA_NAME
350 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[nargs
]))
353 gcc_assert (nargs
!= 0);
356 if (gimple_in_ssa_p (cfun
))
357 res
= make_ssa_name (type
);
359 res
= create_tmp_reg (type
);
361 gimple
*new_stmt
= gimple_build_call (decl
, nargs
, ops
[0], ops
[1], ops
[2]);
362 gimple_call_set_lhs (new_stmt
, res
);
363 gimple_seq_add_stmt_without_update (seq
, new_stmt
);
369 /* Public API overloads follow for operation being tree_code or
370 built_in_function and for one to three operands or arguments.
371 They return NULL_TREE if nothing could be simplified or
372 the resulting simplified value with parts pushed to SEQ.
373 If SEQ is NULL then if the simplification needs to create
374 new stmts it will fail. If VALUEIZE is non-NULL then all
375 SSA names will be valueized using that hook prior to
376 applying simplifications. */
381 gimple_simplify (enum tree_code code
, tree type
,
383 gimple_seq
*seq
, tree (*valueize
)(tree
))
385 if (constant_for_folding (op0
))
387 tree res
= const_unop (code
, type
, op0
);
389 && CONSTANT_CLASS_P (res
))
395 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
398 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
404 gimple_simplify (enum tree_code code
, tree type
,
406 gimple_seq
*seq
, tree (*valueize
)(tree
))
408 if (constant_for_folding (op0
) && constant_for_folding (op1
))
410 tree res
= const_binop (code
, type
, op0
, op1
);
412 && CONSTANT_CLASS_P (res
))
416 /* Canonicalize operand order both for matching and fallback stmt
418 if ((commutative_tree_code (code
)
419 || TREE_CODE_CLASS (code
) == tcc_comparison
)
420 && tree_swap_operands_p (op0
, op1
, false))
422 std::swap (op0
, op1
);
423 if (TREE_CODE_CLASS (code
) == tcc_comparison
)
424 code
= swap_tree_comparison (code
);
429 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
430 code
, type
, op0
, op1
))
432 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
438 gimple_simplify (enum tree_code code
, tree type
,
439 tree op0
, tree op1
, tree op2
,
440 gimple_seq
*seq
, tree (*valueize
)(tree
))
442 if (constant_for_folding (op0
) && constant_for_folding (op1
)
443 && constant_for_folding (op2
))
445 tree res
= fold_ternary
/*_to_constant */ (code
, type
, op0
, op1
, op2
);
447 && CONSTANT_CLASS_P (res
))
451 /* Canonicalize operand order both for matching and fallback stmt
453 if (commutative_ternary_tree_code (code
)
454 && tree_swap_operands_p (op0
, op1
, false))
455 std::swap (op0
, op1
);
459 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
460 code
, type
, op0
, op1
, op2
))
462 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
465 /* Builtin function with one argument. */
468 gimple_simplify (enum built_in_function fn
, tree type
,
470 gimple_seq
*seq
, tree (*valueize
)(tree
))
472 if (constant_for_folding (arg0
))
474 tree decl
= builtin_decl_implicit (fn
);
477 tree res
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, &arg0
, 1, false);
480 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
482 res
= fold_convert (type
, res
);
483 if (CONSTANT_CLASS_P (res
))
491 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
494 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
497 /* Builtin function with two arguments. */
500 gimple_simplify (enum built_in_function fn
, tree type
,
501 tree arg0
, tree arg1
,
502 gimple_seq
*seq
, tree (*valueize
)(tree
))
504 if (constant_for_folding (arg0
)
505 && constant_for_folding (arg1
))
507 tree decl
= builtin_decl_implicit (fn
);
513 tree res
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, args
, 2, false);
516 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
518 res
= fold_convert (type
, res
);
519 if (CONSTANT_CLASS_P (res
))
527 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
528 fn
, type
, arg0
, arg1
))
530 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
533 /* Builtin function with three arguments. */
536 gimple_simplify (enum built_in_function fn
, tree type
,
537 tree arg0
, tree arg1
, tree arg2
,
538 gimple_seq
*seq
, tree (*valueize
)(tree
))
540 if (constant_for_folding (arg0
)
541 && constant_for_folding (arg1
)
542 && constant_for_folding (arg2
))
544 tree decl
= builtin_decl_implicit (fn
);
551 tree res
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, args
, 3, false);
554 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
556 res
= fold_convert (type
, res
);
557 if (CONSTANT_CLASS_P (res
))
565 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
566 fn
, type
, arg0
, arg1
, arg2
))
568 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
571 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
572 VALUEIZED to true if valueization changed OP. */
575 do_valueize (tree op
, tree (*valueize
)(tree
), bool &valueized
)
577 if (valueize
&& TREE_CODE (op
) == SSA_NAME
)
579 tree tem
= valueize (op
);
580 if (tem
&& tem
!= op
)
589 /* The main STMT based simplification entry. It is used by the fold_stmt
590 and the fold_stmt_to_constant APIs. */
593 gimple_simplify (gimple
*stmt
,
594 code_helper
*rcode
, tree
*ops
,
596 tree (*valueize
)(tree
), tree (*top_valueize
)(tree
))
598 switch (gimple_code (stmt
))
602 enum tree_code code
= gimple_assign_rhs_code (stmt
);
603 tree type
= TREE_TYPE (gimple_assign_lhs (stmt
));
604 switch (gimple_assign_rhs_class (stmt
))
606 case GIMPLE_SINGLE_RHS
:
607 if (code
== REALPART_EXPR
608 || code
== IMAGPART_EXPR
609 || code
== VIEW_CONVERT_EXPR
)
611 tree op0
= TREE_OPERAND (gimple_assign_rhs1 (stmt
), 0);
612 bool valueized
= false;
613 op0
= do_valueize (op0
, top_valueize
, valueized
);
616 return (gimple_resimplify1 (seq
, rcode
, type
, ops
, valueize
)
619 else if (code
== BIT_FIELD_REF
)
621 tree rhs1
= gimple_assign_rhs1 (stmt
);
622 tree op0
= TREE_OPERAND (rhs1
, 0);
623 bool valueized
= false;
624 op0
= do_valueize (op0
, top_valueize
, valueized
);
627 ops
[1] = TREE_OPERAND (rhs1
, 1);
628 ops
[2] = TREE_OPERAND (rhs1
, 2);
629 return (gimple_resimplify3 (seq
, rcode
, type
, ops
, valueize
)
632 else if (code
== SSA_NAME
635 tree op0
= gimple_assign_rhs1 (stmt
);
636 tree valueized
= top_valueize (op0
);
637 if (!valueized
|| op0
== valueized
)
640 *rcode
= TREE_CODE (op0
);
644 case GIMPLE_UNARY_RHS
:
646 tree rhs1
= gimple_assign_rhs1 (stmt
);
647 bool valueized
= false;
648 rhs1
= do_valueize (rhs1
, top_valueize
, valueized
);
651 return (gimple_resimplify1 (seq
, rcode
, type
, ops
, valueize
)
654 case GIMPLE_BINARY_RHS
:
656 tree rhs1
= gimple_assign_rhs1 (stmt
);
657 tree rhs2
= gimple_assign_rhs2 (stmt
);
658 bool valueized
= false;
659 rhs1
= do_valueize (rhs1
, top_valueize
, valueized
);
660 rhs2
= do_valueize (rhs2
, top_valueize
, valueized
);
664 return (gimple_resimplify2 (seq
, rcode
, type
, ops
, valueize
)
667 case GIMPLE_TERNARY_RHS
:
669 bool valueized
= false;
670 tree rhs1
= gimple_assign_rhs1 (stmt
);
671 /* If this is a [VEC_]COND_EXPR first try to simplify an
672 embedded GENERIC condition. */
673 if (code
== COND_EXPR
674 || code
== VEC_COND_EXPR
)
676 if (COMPARISON_CLASS_P (rhs1
))
678 tree lhs
= TREE_OPERAND (rhs1
, 0);
679 tree rhs
= TREE_OPERAND (rhs1
, 1);
680 lhs
= do_valueize (lhs
, top_valueize
, valueized
);
681 rhs
= do_valueize (rhs
, top_valueize
, valueized
);
682 code_helper rcode2
= TREE_CODE (rhs1
);
686 if ((gimple_resimplify2 (seq
, &rcode2
, TREE_TYPE (rhs1
),
689 && rcode2
.is_tree_code ())
692 if (TREE_CODE_CLASS ((enum tree_code
)rcode2
)
694 rhs1
= build2 (rcode2
, TREE_TYPE (rhs1
),
696 else if (rcode2
== SSA_NAME
697 || rcode2
== INTEGER_CST
698 || rcode2
== VECTOR_CST
)
705 tree rhs2
= gimple_assign_rhs2 (stmt
);
706 tree rhs3
= gimple_assign_rhs3 (stmt
);
707 rhs1
= do_valueize (rhs1
, top_valueize
, valueized
);
708 rhs2
= do_valueize (rhs2
, top_valueize
, valueized
);
709 rhs3
= do_valueize (rhs3
, top_valueize
, valueized
);
714 return (gimple_resimplify3 (seq
, rcode
, type
, ops
, valueize
)
724 /* ??? This way we can't simplify calls with side-effects. */
725 if (gimple_call_lhs (stmt
) != NULL_TREE
726 && gimple_call_num_args (stmt
) >= 1
727 && gimple_call_num_args (stmt
) <= 3)
729 tree fn
= gimple_call_fn (stmt
);
730 /* ??? Internal function support missing. */
733 bool valueized
= false;
734 fn
= do_valueize (fn
, top_valueize
, valueized
);
735 if (TREE_CODE (fn
) != ADDR_EXPR
736 || TREE_CODE (TREE_OPERAND (fn
, 0)) != FUNCTION_DECL
)
739 tree decl
= TREE_OPERAND (fn
, 0);
740 if (DECL_BUILT_IN_CLASS (decl
) != BUILT_IN_NORMAL
741 || !gimple_builtin_call_types_compatible_p (stmt
, decl
))
744 tree type
= TREE_TYPE (gimple_call_lhs (stmt
));
745 *rcode
= DECL_FUNCTION_CODE (decl
);
746 for (unsigned i
= 0; i
< gimple_call_num_args (stmt
); ++i
)
748 tree arg
= gimple_call_arg (stmt
, i
);
749 ops
[i
] = do_valueize (arg
, top_valueize
, valueized
);
751 switch (gimple_call_num_args (stmt
))
754 return (gimple_resimplify1 (seq
, rcode
, type
, ops
, valueize
)
757 return (gimple_resimplify2 (seq
, rcode
, type
, ops
, valueize
)
760 return (gimple_resimplify3 (seq
, rcode
, type
, ops
, valueize
)
770 tree lhs
= gimple_cond_lhs (stmt
);
771 tree rhs
= gimple_cond_rhs (stmt
);
772 bool valueized
= false;
773 lhs
= do_valueize (lhs
, top_valueize
, valueized
);
774 rhs
= do_valueize (rhs
, top_valueize
, valueized
);
775 *rcode
= gimple_cond_code (stmt
);
778 return (gimple_resimplify2 (seq
, rcode
,
779 boolean_type_node
, ops
, valueize
)
791 /* Helper for the autogenerated code, valueize OP. */
794 do_valueize (tree (*valueize
)(tree
), tree op
)
796 if (valueize
&& TREE_CODE (op
) == SSA_NAME
)
797 return valueize (op
);
801 /* Routine to determine if the types T1 and T2 are effectively
802 the same for GIMPLE. If T1 or T2 is not a type, the test
803 applies to their TREE_TYPE. */
806 types_match (tree t1
, tree t2
)
813 return types_compatible_p (t1
, t2
);
816 /* Return if T has a single use. For GIMPLE, we also allow any
817 non-SSA_NAME (ie constants) and zero uses to cope with uses
818 that aren't linked up yet. */
823 return TREE_CODE (t
) != SSA_NAME
|| has_zero_uses (t
) || has_single_use (t
);
826 /* Return true if math operations should be canonicalized,
827 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
830 canonicalize_math_p ()
832 return !cfun
|| (cfun
->curr_properties
& PROP_gimple_opt_math
) == 0;