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 && gimple_simplified_result_is_gimple_val (rcode
, ops
))
315 tree tem
= mprts_hook (rcode
, type
, ops
);
321 /* Play safe and do not allow abnormals to be mentioned in
322 newly created statements. */
323 if ((TREE_CODE (ops
[0]) == SSA_NAME
324 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[0]))
326 && TREE_CODE (ops
[1]) == SSA_NAME
327 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[1]))
329 && TREE_CODE (ops
[2]) == SSA_NAME
330 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[2])))
333 res
= make_ssa_name (type
);
334 maybe_build_generic_op (rcode
, type
, &ops
[0], ops
[1], ops
[2]);
335 gimple
*new_stmt
= gimple_build_assign (res
, rcode
,
336 ops
[0], ops
[1], ops
[2]);
337 gimple_seq_add_stmt_without_update (seq
, new_stmt
);
344 tree decl
= builtin_decl_implicit (rcode
);
347 /* We can't and should not emit calls to non-const functions. */
348 if (!(flags_from_decl_or_type (decl
) & ECF_CONST
))
350 /* Play safe and do not allow abnormals to be mentioned in
351 newly created statements. */
353 for (nargs
= 0; nargs
< 3; ++nargs
)
357 if (TREE_CODE (ops
[nargs
]) == SSA_NAME
358 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[nargs
]))
361 gcc_assert (nargs
!= 0);
363 res
= make_ssa_name (type
);
364 gimple
*new_stmt
= gimple_build_call (decl
, nargs
, ops
[0], ops
[1], ops
[2]);
365 gimple_call_set_lhs (new_stmt
, res
);
366 gimple_seq_add_stmt_without_update (seq
, new_stmt
);
372 /* Public API overloads follow for operation being tree_code or
373 built_in_function and for one to three operands or arguments.
374 They return NULL_TREE if nothing could be simplified or
375 the resulting simplified value with parts pushed to SEQ.
376 If SEQ is NULL then if the simplification needs to create
377 new stmts it will fail. If VALUEIZE is non-NULL then all
378 SSA names will be valueized using that hook prior to
379 applying simplifications. */
384 gimple_simplify (enum tree_code code
, tree type
,
386 gimple_seq
*seq
, tree (*valueize
)(tree
))
388 if (constant_for_folding (op0
))
390 tree res
= const_unop (code
, type
, op0
);
392 && CONSTANT_CLASS_P (res
))
398 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
401 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
407 gimple_simplify (enum tree_code code
, tree type
,
409 gimple_seq
*seq
, tree (*valueize
)(tree
))
411 if (constant_for_folding (op0
) && constant_for_folding (op1
))
413 tree res
= const_binop (code
, type
, op0
, op1
);
415 && CONSTANT_CLASS_P (res
))
419 /* Canonicalize operand order both for matching and fallback stmt
421 if ((commutative_tree_code (code
)
422 || TREE_CODE_CLASS (code
) == tcc_comparison
)
423 && tree_swap_operands_p (op0
, op1
, false))
425 std::swap (op0
, op1
);
426 if (TREE_CODE_CLASS (code
) == tcc_comparison
)
427 code
= swap_tree_comparison (code
);
432 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
433 code
, type
, op0
, op1
))
435 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
441 gimple_simplify (enum tree_code code
, tree type
,
442 tree op0
, tree op1
, tree op2
,
443 gimple_seq
*seq
, tree (*valueize
)(tree
))
445 if (constant_for_folding (op0
) && constant_for_folding (op1
)
446 && constant_for_folding (op2
))
448 tree res
= fold_ternary
/*_to_constant */ (code
, type
, op0
, op1
, op2
);
450 && CONSTANT_CLASS_P (res
))
454 /* Canonicalize operand order both for matching and fallback stmt
456 if (commutative_ternary_tree_code (code
)
457 && tree_swap_operands_p (op0
, op1
, false))
458 std::swap (op0
, op1
);
462 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
463 code
, type
, op0
, op1
, op2
))
465 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
468 /* Builtin function with one argument. */
471 gimple_simplify (enum built_in_function fn
, tree type
,
473 gimple_seq
*seq
, tree (*valueize
)(tree
))
475 if (constant_for_folding (arg0
))
477 tree decl
= builtin_decl_implicit (fn
);
480 tree res
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, &arg0
, 1, false);
483 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
485 res
= fold_convert (type
, res
);
486 if (CONSTANT_CLASS_P (res
))
494 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
497 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
500 /* Builtin function with two arguments. */
503 gimple_simplify (enum built_in_function fn
, tree type
,
504 tree arg0
, tree arg1
,
505 gimple_seq
*seq
, tree (*valueize
)(tree
))
507 if (constant_for_folding (arg0
)
508 && constant_for_folding (arg1
))
510 tree decl
= builtin_decl_implicit (fn
);
516 tree res
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, args
, 2, false);
519 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
521 res
= fold_convert (type
, res
);
522 if (CONSTANT_CLASS_P (res
))
530 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
531 fn
, type
, arg0
, arg1
))
533 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
536 /* Builtin function with three arguments. */
539 gimple_simplify (enum built_in_function fn
, tree type
,
540 tree arg0
, tree arg1
, tree arg2
,
541 gimple_seq
*seq
, tree (*valueize
)(tree
))
543 if (constant_for_folding (arg0
)
544 && constant_for_folding (arg1
)
545 && constant_for_folding (arg2
))
547 tree decl
= builtin_decl_implicit (fn
);
554 tree res
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, args
, 3, false);
557 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
559 res
= fold_convert (type
, res
);
560 if (CONSTANT_CLASS_P (res
))
568 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
569 fn
, type
, arg0
, arg1
, arg2
))
571 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
574 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
575 VALUEIZED to true if valueization changed OP. */
578 do_valueize (tree op
, tree (*valueize
)(tree
), bool &valueized
)
580 if (valueize
&& TREE_CODE (op
) == SSA_NAME
)
582 tree tem
= valueize (op
);
583 if (tem
&& tem
!= op
)
592 /* The main STMT based simplification entry. It is used by the fold_stmt
593 and the fold_stmt_to_constant APIs. */
596 gimple_simplify (gimple
*stmt
,
597 code_helper
*rcode
, tree
*ops
,
599 tree (*valueize
)(tree
), tree (*top_valueize
)(tree
))
601 switch (gimple_code (stmt
))
605 enum tree_code code
= gimple_assign_rhs_code (stmt
);
606 tree type
= TREE_TYPE (gimple_assign_lhs (stmt
));
607 switch (gimple_assign_rhs_class (stmt
))
609 case GIMPLE_SINGLE_RHS
:
610 if (code
== REALPART_EXPR
611 || code
== IMAGPART_EXPR
612 || code
== VIEW_CONVERT_EXPR
)
614 tree op0
= TREE_OPERAND (gimple_assign_rhs1 (stmt
), 0);
615 bool valueized
= false;
616 op0
= do_valueize (op0
, top_valueize
, valueized
);
619 return (gimple_resimplify1 (seq
, rcode
, type
, ops
, valueize
)
622 else if (code
== BIT_FIELD_REF
)
624 tree rhs1
= gimple_assign_rhs1 (stmt
);
625 tree op0
= TREE_OPERAND (rhs1
, 0);
626 bool valueized
= false;
627 op0
= do_valueize (op0
, top_valueize
, valueized
);
630 ops
[1] = TREE_OPERAND (rhs1
, 1);
631 ops
[2] = TREE_OPERAND (rhs1
, 2);
632 return (gimple_resimplify3 (seq
, rcode
, type
, ops
, valueize
)
635 else if (code
== SSA_NAME
638 tree op0
= gimple_assign_rhs1 (stmt
);
639 tree valueized
= top_valueize (op0
);
640 if (!valueized
|| op0
== valueized
)
643 *rcode
= TREE_CODE (op0
);
647 case GIMPLE_UNARY_RHS
:
649 tree rhs1
= gimple_assign_rhs1 (stmt
);
650 bool valueized
= false;
651 rhs1
= do_valueize (rhs1
, top_valueize
, valueized
);
654 return (gimple_resimplify1 (seq
, rcode
, type
, ops
, valueize
)
657 case GIMPLE_BINARY_RHS
:
659 tree rhs1
= gimple_assign_rhs1 (stmt
);
660 tree rhs2
= gimple_assign_rhs2 (stmt
);
661 bool valueized
= false;
662 rhs1
= do_valueize (rhs1
, top_valueize
, valueized
);
663 rhs2
= do_valueize (rhs2
, top_valueize
, valueized
);
667 return (gimple_resimplify2 (seq
, rcode
, type
, ops
, valueize
)
670 case GIMPLE_TERNARY_RHS
:
672 bool valueized
= false;
673 tree rhs1
= gimple_assign_rhs1 (stmt
);
674 /* If this is a [VEC_]COND_EXPR first try to simplify an
675 embedded GENERIC condition. */
676 if (code
== COND_EXPR
677 || code
== VEC_COND_EXPR
)
679 if (COMPARISON_CLASS_P (rhs1
))
681 tree lhs
= TREE_OPERAND (rhs1
, 0);
682 tree rhs
= TREE_OPERAND (rhs1
, 1);
683 lhs
= do_valueize (lhs
, top_valueize
, valueized
);
684 rhs
= do_valueize (rhs
, top_valueize
, valueized
);
685 code_helper rcode2
= TREE_CODE (rhs1
);
689 if ((gimple_resimplify2 (seq
, &rcode2
, TREE_TYPE (rhs1
),
692 && rcode2
.is_tree_code ())
695 if (TREE_CODE_CLASS ((enum tree_code
)rcode2
)
697 rhs1
= build2 (rcode2
, TREE_TYPE (rhs1
),
699 else if (rcode2
== SSA_NAME
700 || rcode2
== INTEGER_CST
)
707 tree rhs2
= gimple_assign_rhs2 (stmt
);
708 tree rhs3
= gimple_assign_rhs3 (stmt
);
709 rhs1
= do_valueize (rhs1
, top_valueize
, valueized
);
710 rhs2
= do_valueize (rhs2
, top_valueize
, valueized
);
711 rhs3
= do_valueize (rhs3
, top_valueize
, valueized
);
716 return (gimple_resimplify3 (seq
, rcode
, type
, ops
, valueize
)
726 /* ??? This way we can't simplify calls with side-effects. */
727 if (gimple_call_lhs (stmt
) != NULL_TREE
728 && gimple_call_num_args (stmt
) >= 1
729 && gimple_call_num_args (stmt
) <= 3)
731 tree fn
= gimple_call_fn (stmt
);
732 /* ??? Internal function support missing. */
735 bool valueized
= false;
736 fn
= do_valueize (fn
, top_valueize
, valueized
);
737 if (TREE_CODE (fn
) != ADDR_EXPR
738 || TREE_CODE (TREE_OPERAND (fn
, 0)) != FUNCTION_DECL
)
741 tree decl
= TREE_OPERAND (fn
, 0);
742 if (DECL_BUILT_IN_CLASS (decl
) != BUILT_IN_NORMAL
743 || !builtin_decl_implicit (DECL_FUNCTION_CODE (decl
))
744 || !gimple_builtin_call_types_compatible_p (stmt
, decl
))
747 tree type
= TREE_TYPE (gimple_call_lhs (stmt
));
748 *rcode
= DECL_FUNCTION_CODE (decl
);
749 for (unsigned i
= 0; i
< gimple_call_num_args (stmt
); ++i
)
751 tree arg
= gimple_call_arg (stmt
, i
);
752 ops
[i
] = do_valueize (arg
, top_valueize
, valueized
);
754 switch (gimple_call_num_args (stmt
))
757 return (gimple_resimplify1 (seq
, rcode
, type
, ops
, valueize
)
760 return (gimple_resimplify2 (seq
, rcode
, type
, ops
, valueize
)
763 return (gimple_resimplify3 (seq
, rcode
, type
, ops
, valueize
)
773 tree lhs
= gimple_cond_lhs (stmt
);
774 tree rhs
= gimple_cond_rhs (stmt
);
775 bool valueized
= false;
776 lhs
= do_valueize (lhs
, top_valueize
, valueized
);
777 rhs
= do_valueize (rhs
, top_valueize
, valueized
);
778 *rcode
= gimple_cond_code (stmt
);
781 return (gimple_resimplify2 (seq
, rcode
,
782 boolean_type_node
, ops
, valueize
)
794 /* Helper for the autogenerated code, valueize OP. */
797 do_valueize (tree (*valueize
)(tree
), tree op
)
799 if (valueize
&& TREE_CODE (op
) == SSA_NAME
)
800 return valueize (op
);
804 /* Routine to determine if the types T1 and T2 are effectively
805 the same for GIMPLE. If T1 or T2 is not a type, the test
806 applies to their TREE_TYPE. */
809 types_match (tree t1
, tree t2
)
816 return types_compatible_p (t1
, t2
);
819 /* Return if T has a single use. For GIMPLE, we also allow any
820 non-SSA_NAME (ie constants) and zero uses to cope with uses
821 that aren't linked up yet. */
826 return TREE_CODE (t
) != SSA_NAME
|| has_zero_uses (t
) || has_single_use (t
);