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"
53 /* Forward declarations of the private auto-generated matchers.
54 They expect valueized operands in canonical order and do not
55 perform simplification of all-constant operands. */
56 static bool gimple_simplify (code_helper
*, tree
*,
57 gimple_seq
*, tree (*)(tree
),
58 code_helper
, tree
, tree
);
59 static bool gimple_simplify (code_helper
*, tree
*,
60 gimple_seq
*, tree (*)(tree
),
61 code_helper
, tree
, tree
, tree
);
62 static bool gimple_simplify (code_helper
*, tree
*,
63 gimple_seq
*, tree (*)(tree
),
64 code_helper
, tree
, tree
, tree
, tree
);
67 /* Return whether T is a constant that we'll dispatch to fold to
68 evaluate fully constant expressions. */
71 constant_for_folding (tree t
)
73 return (CONSTANT_CLASS_P (t
)
74 /* The following is only interesting to string builtins. */
75 || (TREE_CODE (t
) == ADDR_EXPR
76 && TREE_CODE (TREE_OPERAND (t
, 0)) == STRING_CST
));
80 /* Helper that matches and simplifies the toplevel result from
81 a gimple_simplify run (where we don't want to build
82 a stmt in case it's used in in-place folding). Replaces
83 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
84 result and returns whether any change was made. */
87 gimple_resimplify1 (gimple_seq
*seq
,
88 code_helper
*res_code
, tree type
, tree
*res_ops
,
89 tree (*valueize
)(tree
))
91 if (constant_for_folding (res_ops
[0]))
94 if (res_code
->is_tree_code ())
95 tem
= const_unop (*res_code
, type
, res_ops
[0]);
98 tree decl
= builtin_decl_implicit (*res_code
);
101 tem
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, res_ops
, 1, false);
104 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
106 tem
= fold_convert (type
, tem
);
111 && CONSTANT_CLASS_P (tem
))
114 res_ops
[1] = NULL_TREE
;
115 res_ops
[2] = NULL_TREE
;
116 *res_code
= TREE_CODE (res_ops
[0]);
121 code_helper res_code2
;
122 tree res_ops2
[3] = {};
123 if (gimple_simplify (&res_code2
, res_ops2
, seq
, valueize
,
124 *res_code
, type
, res_ops
[0]))
126 *res_code
= res_code2
;
127 res_ops
[0] = res_ops2
[0];
128 res_ops
[1] = res_ops2
[1];
129 res_ops
[2] = res_ops2
[2];
136 /* Helper that matches and simplifies the toplevel result from
137 a gimple_simplify run (where we don't want to build
138 a stmt in case it's used in in-place folding). Replaces
139 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
140 result and returns whether any change was made. */
143 gimple_resimplify2 (gimple_seq
*seq
,
144 code_helper
*res_code
, tree type
, tree
*res_ops
,
145 tree (*valueize
)(tree
))
147 if (constant_for_folding (res_ops
[0]) && constant_for_folding (res_ops
[1]))
149 tree tem
= NULL_TREE
;
150 if (res_code
->is_tree_code ())
151 tem
= const_binop (*res_code
, type
, res_ops
[0], res_ops
[1]);
154 tree decl
= builtin_decl_implicit (*res_code
);
157 tem
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, res_ops
, 2, false);
160 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
162 tem
= fold_convert (type
, tem
);
167 && CONSTANT_CLASS_P (tem
))
170 res_ops
[1] = NULL_TREE
;
171 res_ops
[2] = NULL_TREE
;
172 *res_code
= TREE_CODE (res_ops
[0]);
177 /* Canonicalize operand order. */
178 bool canonicalized
= false;
179 if (res_code
->is_tree_code ()
180 && (TREE_CODE_CLASS ((enum tree_code
) *res_code
) == tcc_comparison
181 || commutative_tree_code (*res_code
))
182 && tree_swap_operands_p (res_ops
[0], res_ops
[1], false))
184 std::swap (res_ops
[0], res_ops
[1]);
185 if (TREE_CODE_CLASS ((enum tree_code
) *res_code
) == tcc_comparison
)
186 *res_code
= swap_tree_comparison (*res_code
);
187 canonicalized
= true;
190 code_helper res_code2
;
191 tree res_ops2
[3] = {};
192 if (gimple_simplify (&res_code2
, res_ops2
, seq
, valueize
,
193 *res_code
, type
, res_ops
[0], res_ops
[1]))
195 *res_code
= res_code2
;
196 res_ops
[0] = res_ops2
[0];
197 res_ops
[1] = res_ops2
[1];
198 res_ops
[2] = res_ops2
[2];
202 return canonicalized
;
205 /* Helper that matches and simplifies the toplevel result from
206 a gimple_simplify run (where we don't want to build
207 a stmt in case it's used in in-place folding). Replaces
208 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
209 result and returns whether any change was made. */
212 gimple_resimplify3 (gimple_seq
*seq
,
213 code_helper
*res_code
, tree type
, tree
*res_ops
,
214 tree (*valueize
)(tree
))
216 if (constant_for_folding (res_ops
[0]) && constant_for_folding (res_ops
[1])
217 && constant_for_folding (res_ops
[2]))
219 tree tem
= NULL_TREE
;
220 if (res_code
->is_tree_code ())
221 tem
= fold_ternary
/*_to_constant*/ (*res_code
, type
, res_ops
[0],
222 res_ops
[1], res_ops
[2]);
225 tree decl
= builtin_decl_implicit (*res_code
);
228 tem
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, res_ops
, 3, false);
231 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
233 tem
= fold_convert (type
, tem
);
238 && CONSTANT_CLASS_P (tem
))
241 res_ops
[1] = NULL_TREE
;
242 res_ops
[2] = NULL_TREE
;
243 *res_code
= TREE_CODE (res_ops
[0]);
248 /* Canonicalize operand order. */
249 bool canonicalized
= false;
250 if (res_code
->is_tree_code ()
251 && commutative_ternary_tree_code (*res_code
)
252 && tree_swap_operands_p (res_ops
[0], res_ops
[1], false))
254 std::swap (res_ops
[0], res_ops
[1]);
255 canonicalized
= true;
258 code_helper res_code2
;
259 tree res_ops2
[3] = {};
260 if (gimple_simplify (&res_code2
, res_ops2
, seq
, valueize
,
262 res_ops
[0], res_ops
[1], res_ops
[2]))
264 *res_code
= res_code2
;
265 res_ops
[0] = res_ops2
[0];
266 res_ops
[1] = res_ops2
[1];
267 res_ops
[2] = res_ops2
[2];
271 return canonicalized
;
275 /* If in GIMPLE expressions with CODE go as single-rhs build
276 a GENERIC tree for that expression into *OP0. */
279 maybe_build_generic_op (enum tree_code code
, tree type
,
280 tree
*op0
, tree op1
, tree op2
)
286 case VIEW_CONVERT_EXPR
:
287 *op0
= build1 (code
, type
, *op0
);
290 *op0
= build3 (code
, type
, *op0
, op1
, op2
);
296 tree (*mprts_hook
) (code_helper
, tree
, tree
*);
298 /* Push the exploded expression described by RCODE, TYPE and OPS
299 as a statement to SEQ if necessary and return a gimple value
300 denoting the value of the expression. If RES is not NULL
301 then the result will be always RES and even gimple values are
305 maybe_push_res_to_seq (code_helper rcode
, tree type
, tree
*ops
,
306 gimple_seq
*seq
, tree res
)
308 if (rcode
.is_tree_code ())
311 && (TREE_CODE_LENGTH ((tree_code
) rcode
) == 0
312 || ((tree_code
) rcode
) == ADDR_EXPR
)
313 && is_gimple_val (ops
[0]))
317 tree tem
= mprts_hook (rcode
, type
, ops
);
323 /* Play safe and do not allow abnormals to be mentioned in
324 newly created statements. */
325 if ((TREE_CODE (ops
[0]) == SSA_NAME
326 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[0]))
328 && TREE_CODE (ops
[1]) == SSA_NAME
329 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[1]))
331 && TREE_CODE (ops
[2]) == SSA_NAME
332 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[2])))
335 res
= make_ssa_name (type
);
336 maybe_build_generic_op (rcode
, type
, &ops
[0], ops
[1], ops
[2]);
337 gimple
*new_stmt
= gimple_build_assign (res
, rcode
,
338 ops
[0], ops
[1], ops
[2]);
339 gimple_seq_add_stmt_without_update (seq
, new_stmt
);
346 tree decl
= builtin_decl_implicit (rcode
);
349 /* We can't and should not emit calls to non-const functions. */
350 if (!(flags_from_decl_or_type (decl
) & ECF_CONST
))
352 /* Play safe and do not allow abnormals to be mentioned in
353 newly created statements. */
355 for (nargs
= 0; nargs
< 3; ++nargs
)
359 if (TREE_CODE (ops
[nargs
]) == SSA_NAME
360 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[nargs
]))
363 gcc_assert (nargs
!= 0);
365 res
= make_ssa_name (type
);
366 gimple
*new_stmt
= gimple_build_call (decl
, nargs
, ops
[0], ops
[1], ops
[2]);
367 gimple_call_set_lhs (new_stmt
, res
);
368 gimple_seq_add_stmt_without_update (seq
, new_stmt
);
374 /* Public API overloads follow for operation being tree_code or
375 built_in_function and for one to three operands or arguments.
376 They return NULL_TREE if nothing could be simplified or
377 the resulting simplified value with parts pushed to SEQ.
378 If SEQ is NULL then if the simplification needs to create
379 new stmts it will fail. If VALUEIZE is non-NULL then all
380 SSA names will be valueized using that hook prior to
381 applying simplifications. */
386 gimple_simplify (enum tree_code code
, tree type
,
388 gimple_seq
*seq
, tree (*valueize
)(tree
))
390 if (constant_for_folding (op0
))
392 tree res
= const_unop (code
, type
, op0
);
394 && CONSTANT_CLASS_P (res
))
400 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
403 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
409 gimple_simplify (enum tree_code code
, tree type
,
411 gimple_seq
*seq
, tree (*valueize
)(tree
))
413 if (constant_for_folding (op0
) && constant_for_folding (op1
))
415 tree res
= const_binop (code
, type
, op0
, op1
);
417 && CONSTANT_CLASS_P (res
))
421 /* Canonicalize operand order both for matching and fallback stmt
423 if ((commutative_tree_code (code
)
424 || TREE_CODE_CLASS (code
) == tcc_comparison
)
425 && tree_swap_operands_p (op0
, op1
, false))
427 std::swap (op0
, op1
);
428 if (TREE_CODE_CLASS (code
) == tcc_comparison
)
429 code
= swap_tree_comparison (code
);
434 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
435 code
, type
, op0
, op1
))
437 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
443 gimple_simplify (enum tree_code code
, tree type
,
444 tree op0
, tree op1
, tree op2
,
445 gimple_seq
*seq
, tree (*valueize
)(tree
))
447 if (constant_for_folding (op0
) && constant_for_folding (op1
)
448 && constant_for_folding (op2
))
450 tree res
= fold_ternary
/*_to_constant */ (code
, type
, op0
, op1
, op2
);
452 && CONSTANT_CLASS_P (res
))
456 /* Canonicalize operand order both for matching and fallback stmt
458 if (commutative_ternary_tree_code (code
)
459 && tree_swap_operands_p (op0
, op1
, false))
460 std::swap (op0
, op1
);
464 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
465 code
, type
, op0
, op1
, op2
))
467 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
470 /* Builtin function with one argument. */
473 gimple_simplify (enum built_in_function fn
, tree type
,
475 gimple_seq
*seq
, tree (*valueize
)(tree
))
477 if (constant_for_folding (arg0
))
479 tree decl
= builtin_decl_implicit (fn
);
482 tree res
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, &arg0
, 1, false);
485 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
487 res
= fold_convert (type
, res
);
488 if (CONSTANT_CLASS_P (res
))
496 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
499 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
502 /* Builtin function with two arguments. */
505 gimple_simplify (enum built_in_function fn
, tree type
,
506 tree arg0
, tree arg1
,
507 gimple_seq
*seq
, tree (*valueize
)(tree
))
509 if (constant_for_folding (arg0
)
510 && constant_for_folding (arg1
))
512 tree decl
= builtin_decl_implicit (fn
);
518 tree res
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, args
, 2, false);
521 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
523 res
= fold_convert (type
, res
);
524 if (CONSTANT_CLASS_P (res
))
532 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
533 fn
, type
, arg0
, arg1
))
535 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
538 /* Builtin function with three arguments. */
541 gimple_simplify (enum built_in_function fn
, tree type
,
542 tree arg0
, tree arg1
, tree arg2
,
543 gimple_seq
*seq
, tree (*valueize
)(tree
))
545 if (constant_for_folding (arg0
)
546 && constant_for_folding (arg1
)
547 && constant_for_folding (arg2
))
549 tree decl
= builtin_decl_implicit (fn
);
556 tree res
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, args
, 3, false);
559 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
561 res
= fold_convert (type
, res
);
562 if (CONSTANT_CLASS_P (res
))
570 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
571 fn
, type
, arg0
, arg1
, arg2
))
573 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
576 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
577 VALUEIZED to true if valueization changed OP. */
580 do_valueize (tree op
, tree (*valueize
)(tree
), bool &valueized
)
582 if (valueize
&& TREE_CODE (op
) == SSA_NAME
)
584 tree tem
= valueize (op
);
585 if (tem
&& tem
!= op
)
594 /* The main STMT based simplification entry. It is used by the fold_stmt
595 and the fold_stmt_to_constant APIs. */
598 gimple_simplify (gimple
*stmt
,
599 code_helper
*rcode
, tree
*ops
,
601 tree (*valueize
)(tree
), tree (*top_valueize
)(tree
))
603 switch (gimple_code (stmt
))
607 enum tree_code code
= gimple_assign_rhs_code (stmt
);
608 tree type
= TREE_TYPE (gimple_assign_lhs (stmt
));
609 switch (gimple_assign_rhs_class (stmt
))
611 case GIMPLE_SINGLE_RHS
:
612 if (code
== REALPART_EXPR
613 || code
== IMAGPART_EXPR
614 || code
== VIEW_CONVERT_EXPR
)
616 tree op0
= TREE_OPERAND (gimple_assign_rhs1 (stmt
), 0);
617 bool valueized
= false;
618 op0
= do_valueize (op0
, top_valueize
, valueized
);
621 return (gimple_resimplify1 (seq
, rcode
, type
, ops
, valueize
)
624 else if (code
== BIT_FIELD_REF
)
626 tree rhs1
= gimple_assign_rhs1 (stmt
);
627 tree op0
= TREE_OPERAND (rhs1
, 0);
628 bool valueized
= false;
629 op0
= do_valueize (op0
, top_valueize
, valueized
);
632 ops
[1] = TREE_OPERAND (rhs1
, 1);
633 ops
[2] = TREE_OPERAND (rhs1
, 2);
634 return (gimple_resimplify3 (seq
, rcode
, type
, ops
, valueize
)
637 else if (code
== SSA_NAME
640 tree op0
= gimple_assign_rhs1 (stmt
);
641 tree valueized
= top_valueize (op0
);
642 if (!valueized
|| op0
== valueized
)
645 *rcode
= TREE_CODE (op0
);
649 case GIMPLE_UNARY_RHS
:
651 tree rhs1
= gimple_assign_rhs1 (stmt
);
652 bool valueized
= false;
653 rhs1
= do_valueize (rhs1
, top_valueize
, valueized
);
656 return (gimple_resimplify1 (seq
, rcode
, type
, ops
, valueize
)
659 case GIMPLE_BINARY_RHS
:
661 tree rhs1
= gimple_assign_rhs1 (stmt
);
662 tree rhs2
= gimple_assign_rhs2 (stmt
);
663 bool valueized
= false;
664 rhs1
= do_valueize (rhs1
, top_valueize
, valueized
);
665 rhs2
= do_valueize (rhs2
, top_valueize
, valueized
);
669 return (gimple_resimplify2 (seq
, rcode
, type
, ops
, valueize
)
672 case GIMPLE_TERNARY_RHS
:
674 bool valueized
= false;
675 tree rhs1
= gimple_assign_rhs1 (stmt
);
676 /* If this is a [VEC_]COND_EXPR first try to simplify an
677 embedded GENERIC condition. */
678 if (code
== COND_EXPR
679 || code
== VEC_COND_EXPR
)
681 if (COMPARISON_CLASS_P (rhs1
))
683 tree lhs
= TREE_OPERAND (rhs1
, 0);
684 tree rhs
= TREE_OPERAND (rhs1
, 1);
685 lhs
= do_valueize (lhs
, top_valueize
, valueized
);
686 rhs
= do_valueize (rhs
, top_valueize
, valueized
);
687 code_helper rcode2
= TREE_CODE (rhs1
);
691 if ((gimple_resimplify2 (seq
, &rcode2
, TREE_TYPE (rhs1
),
694 && rcode2
.is_tree_code ())
697 if (TREE_CODE_CLASS ((enum tree_code
)rcode2
)
699 rhs1
= build2 (rcode2
, TREE_TYPE (rhs1
),
701 else if (rcode2
== SSA_NAME
702 || rcode2
== INTEGER_CST
)
709 tree rhs2
= gimple_assign_rhs2 (stmt
);
710 tree rhs3
= gimple_assign_rhs3 (stmt
);
711 rhs1
= do_valueize (rhs1
, top_valueize
, valueized
);
712 rhs2
= do_valueize (rhs2
, top_valueize
, valueized
);
713 rhs3
= do_valueize (rhs3
, top_valueize
, valueized
);
718 return (gimple_resimplify3 (seq
, rcode
, type
, ops
, valueize
)
728 /* ??? This way we can't simplify calls with side-effects. */
729 if (gimple_call_lhs (stmt
) != NULL_TREE
730 && gimple_call_num_args (stmt
) >= 1
731 && gimple_call_num_args (stmt
) <= 3)
733 tree fn
= gimple_call_fn (stmt
);
734 /* ??? Internal function support missing. */
737 bool valueized
= false;
738 fn
= do_valueize (fn
, top_valueize
, valueized
);
739 if (TREE_CODE (fn
) != ADDR_EXPR
740 || TREE_CODE (TREE_OPERAND (fn
, 0)) != FUNCTION_DECL
)
743 tree decl
= TREE_OPERAND (fn
, 0);
744 if (DECL_BUILT_IN_CLASS (decl
) != BUILT_IN_NORMAL
745 || !builtin_decl_implicit (DECL_FUNCTION_CODE (decl
))
746 || !gimple_builtin_call_types_compatible_p (stmt
, decl
))
749 tree type
= TREE_TYPE (gimple_call_lhs (stmt
));
750 *rcode
= DECL_FUNCTION_CODE (decl
);
751 for (unsigned i
= 0; i
< gimple_call_num_args (stmt
); ++i
)
753 tree arg
= gimple_call_arg (stmt
, i
);
754 ops
[i
] = do_valueize (arg
, top_valueize
, valueized
);
756 switch (gimple_call_num_args (stmt
))
759 return (gimple_resimplify1 (seq
, rcode
, type
, ops
, valueize
)
762 return (gimple_resimplify2 (seq
, rcode
, type
, ops
, valueize
)
765 return (gimple_resimplify3 (seq
, rcode
, type
, ops
, valueize
)
775 tree lhs
= gimple_cond_lhs (stmt
);
776 tree rhs
= gimple_cond_rhs (stmt
);
777 bool valueized
= false;
778 lhs
= do_valueize (lhs
, top_valueize
, valueized
);
779 rhs
= do_valueize (rhs
, top_valueize
, valueized
);
780 *rcode
= gimple_cond_code (stmt
);
783 return (gimple_resimplify2 (seq
, rcode
,
784 boolean_type_node
, ops
, valueize
)
796 /* Helper for the autogenerated code, valueize OP. */
799 do_valueize (tree (*valueize
)(tree
), tree op
)
801 if (valueize
&& TREE_CODE (op
) == SSA_NAME
)
802 return valueize (op
);
806 /* Routine to determine if the types T1 and T2 are effectively
807 the same for GIMPLE. If T1 or T2 is not a type, the test
808 applies to their TREE_TYPE. */
811 types_match (tree t1
, tree t2
)
818 return types_compatible_p (t1
, t2
);
821 /* Return if T has a single use. For GIMPLE, we also allow any
822 non-SSA_NAME (ie constants) and zero uses to cope with uses
823 that aren't linked up yet. */
828 return TREE_CODE (t
) != SSA_NAME
|| has_zero_uses (t
) || has_single_use (t
);