1 /* Preamble and helpers for the autogenerated gimple-match.c file.
2 Copyright (C) 2014 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"
24 #include "stringpool.h"
25 #include "stor-layout.h"
28 #include "hard-reg-set.h"
36 #include "basic-block.h"
37 #include "tree-ssa-alias.h"
38 #include "internal-fn.h"
39 #include "gimple-expr.h"
42 #include "gimple-ssa.h"
43 #include "tree-ssanames.h"
44 #include "gimple-fold.h"
45 #include "gimple-iterator.h"
49 #include "tree-phinodes.h"
50 #include "ssa-iterators.h"
52 #include "gimple-match.h"
55 /* Forward declarations of the private auto-generated matchers.
56 They expect valueized operands in canonical order and do not
57 perform simplification of all-constant operands. */
58 static bool gimple_simplify (code_helper
*, tree
*,
59 gimple_seq
*, tree (*)(tree
),
60 code_helper
, tree
, tree
);
61 static bool gimple_simplify (code_helper
*, tree
*,
62 gimple_seq
*, tree (*)(tree
),
63 code_helper
, tree
, tree
, tree
);
64 static bool gimple_simplify (code_helper
*, tree
*,
65 gimple_seq
*, tree (*)(tree
),
66 code_helper
, tree
, tree
, tree
, tree
);
69 /* Return whether T is a constant that we'll dispatch to fold to
70 evaluate fully constant expressions. */
73 constant_for_folding (tree t
)
75 return (CONSTANT_CLASS_P (t
)
76 /* The following is only interesting to string builtins. */
77 || (TREE_CODE (t
) == ADDR_EXPR
78 && TREE_CODE (TREE_OPERAND (t
, 0)) == STRING_CST
));
82 /* Helper that matches and simplifies the toplevel result from
83 a gimple_simplify run (where we don't want to build
84 a stmt in case it's used in in-place folding). Replaces
85 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
86 result and returns whether any change was made. */
89 gimple_resimplify1 (gimple_seq
*seq
,
90 code_helper
*res_code
, tree type
, tree
*res_ops
,
91 tree (*valueize
)(tree
))
93 if (constant_for_folding (res_ops
[0]))
96 if (res_code
->is_tree_code ())
97 tem
= const_unop (*res_code
, type
, res_ops
[0]);
100 tree decl
= builtin_decl_implicit (*res_code
);
103 tem
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, res_ops
, 1, false);
106 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
108 tem
= fold_convert (type
, tem
);
113 && CONSTANT_CLASS_P (tem
))
116 res_ops
[1] = NULL_TREE
;
117 res_ops
[2] = NULL_TREE
;
118 *res_code
= TREE_CODE (res_ops
[0]);
123 code_helper res_code2
;
124 tree res_ops2
[3] = {};
125 if (gimple_simplify (&res_code2
, res_ops2
, seq
, valueize
,
126 *res_code
, type
, res_ops
[0]))
128 *res_code
= res_code2
;
129 res_ops
[0] = res_ops2
[0];
130 res_ops
[1] = res_ops2
[1];
131 res_ops
[2] = res_ops2
[2];
138 /* Helper that matches and simplifies the toplevel result from
139 a gimple_simplify run (where we don't want to build
140 a stmt in case it's used in in-place folding). Replaces
141 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
142 result and returns whether any change was made. */
145 gimple_resimplify2 (gimple_seq
*seq
,
146 code_helper
*res_code
, tree type
, tree
*res_ops
,
147 tree (*valueize
)(tree
))
149 if (constant_for_folding (res_ops
[0]) && constant_for_folding (res_ops
[1]))
151 tree tem
= NULL_TREE
;
152 if (res_code
->is_tree_code ())
153 tem
= const_binop (*res_code
, type
, res_ops
[0], res_ops
[1]);
156 tree decl
= builtin_decl_implicit (*res_code
);
159 tem
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, res_ops
, 2, false);
162 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
164 tem
= fold_convert (type
, tem
);
169 && CONSTANT_CLASS_P (tem
))
172 res_ops
[1] = NULL_TREE
;
173 res_ops
[2] = NULL_TREE
;
174 *res_code
= TREE_CODE (res_ops
[0]);
179 /* Canonicalize operand order. */
180 bool canonicalized
= false;
181 if (res_code
->is_tree_code ()
182 && (TREE_CODE_CLASS ((enum tree_code
) *res_code
) == tcc_comparison
183 || commutative_tree_code (*res_code
))
184 && tree_swap_operands_p (res_ops
[0], res_ops
[1], false))
186 tree tem
= res_ops
[0];
187 res_ops
[0] = res_ops
[1];
189 if (TREE_CODE_CLASS ((enum tree_code
) *res_code
) == tcc_comparison
)
190 *res_code
= swap_tree_comparison (*res_code
);
191 canonicalized
= true;
194 code_helper res_code2
;
195 tree res_ops2
[3] = {};
196 if (gimple_simplify (&res_code2
, res_ops2
, seq
, valueize
,
197 *res_code
, type
, res_ops
[0], res_ops
[1]))
199 *res_code
= res_code2
;
200 res_ops
[0] = res_ops2
[0];
201 res_ops
[1] = res_ops2
[1];
202 res_ops
[2] = res_ops2
[2];
206 return canonicalized
;
209 /* Helper that matches and simplifies the toplevel result from
210 a gimple_simplify run (where we don't want to build
211 a stmt in case it's used in in-place folding). Replaces
212 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
213 result and returns whether any change was made. */
216 gimple_resimplify3 (gimple_seq
*seq
,
217 code_helper
*res_code
, tree type
, tree
*res_ops
,
218 tree (*valueize
)(tree
))
220 if (constant_for_folding (res_ops
[0]) && constant_for_folding (res_ops
[1])
221 && constant_for_folding (res_ops
[2]))
223 tree tem
= NULL_TREE
;
224 if (res_code
->is_tree_code ())
225 tem
= fold_ternary
/*_to_constant*/ (*res_code
, type
, res_ops
[0],
226 res_ops
[1], res_ops
[2]);
229 tree decl
= builtin_decl_implicit (*res_code
);
232 tem
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, res_ops
, 3, false);
235 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
237 tem
= fold_convert (type
, tem
);
242 && CONSTANT_CLASS_P (tem
))
245 res_ops
[1] = NULL_TREE
;
246 res_ops
[2] = NULL_TREE
;
247 *res_code
= TREE_CODE (res_ops
[0]);
252 /* Canonicalize operand order. */
253 bool canonicalized
= false;
254 if (res_code
->is_tree_code ()
255 && commutative_ternary_tree_code (*res_code
)
256 && tree_swap_operands_p (res_ops
[0], res_ops
[1], false))
258 tree tem
= res_ops
[0];
259 res_ops
[0] = res_ops
[1];
261 canonicalized
= true;
264 code_helper res_code2
;
265 tree res_ops2
[3] = {};
266 if (gimple_simplify (&res_code2
, res_ops2
, seq
, valueize
,
268 res_ops
[0], res_ops
[1], res_ops
[2]))
270 *res_code
= res_code2
;
271 res_ops
[0] = res_ops2
[0];
272 res_ops
[1] = res_ops2
[1];
273 res_ops
[2] = res_ops2
[2];
277 return canonicalized
;
281 /* If in GIMPLE expressions with CODE go as single-rhs build
282 a GENERIC tree for that expression into *OP0. */
285 maybe_build_generic_op (enum tree_code code
, tree type
,
286 tree
*op0
, tree op1
, tree op2
)
292 case VIEW_CONVERT_EXPR
:
293 *op0
= build1 (code
, type
, *op0
);
296 *op0
= build3 (code
, type
, *op0
, op1
, op2
);
302 /* Push the exploded expression described by RCODE, TYPE and OPS
303 as a statement to SEQ if necessary and return a gimple value
304 denoting the value of the expression. If RES is not NULL
305 then the result will be always RES and even gimple values are
309 maybe_push_res_to_seq (code_helper rcode
, tree type
, tree
*ops
,
310 gimple_seq
*seq
, tree res
)
312 if (rcode
.is_tree_code ())
315 && (TREE_CODE_LENGTH ((tree_code
) rcode
) == 0
316 || ((tree_code
) rcode
) == ADDR_EXPR
)
317 && is_gimple_val (ops
[0]))
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 unsigned nargs
= type_num_arguments (TREE_TYPE (decl
));
348 gcc_assert (nargs
<= 3);
349 /* Play safe and do not allow abnormals to be mentioned in
350 newly created statements. */
351 if ((TREE_CODE (ops
[0]) == SSA_NAME
352 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[0]))
354 && TREE_CODE (ops
[1]) == SSA_NAME
355 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[1]))
357 && TREE_CODE (ops
[2]) == SSA_NAME
358 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[2])))
361 res
= make_ssa_name (type
);
362 gimple new_stmt
= gimple_build_call (decl
, nargs
, ops
[0], ops
[1], ops
[2]);
363 gimple_call_set_lhs (new_stmt
, res
);
364 gimple_seq_add_stmt_without_update (seq
, new_stmt
);
370 /* Public API overloads follow for operation being tree_code or
371 built_in_function and for one to three operands or arguments.
372 They return NULL_TREE if nothing could be simplified or
373 the resulting simplified value with parts pushed to SEQ.
374 If SEQ is NULL then if the simplification needs to create
375 new stmts it will fail. If VALUEIZE is non-NULL then all
376 SSA names will be valueized using that hook prior to
377 applying simplifications. */
382 gimple_simplify (enum tree_code code
, tree type
,
384 gimple_seq
*seq
, tree (*valueize
)(tree
))
386 if (constant_for_folding (op0
))
388 tree res
= const_unop (code
, type
, op0
);
390 && CONSTANT_CLASS_P (res
))
396 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
399 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
405 gimple_simplify (enum tree_code code
, tree type
,
407 gimple_seq
*seq
, tree (*valueize
)(tree
))
409 if (constant_for_folding (op0
) && constant_for_folding (op1
))
411 tree res
= const_binop (code
, type
, op0
, op1
);
413 && CONSTANT_CLASS_P (res
))
417 /* Canonicalize operand order both for matching and fallback stmt
419 if ((commutative_tree_code (code
)
420 || TREE_CODE_CLASS (code
) == tcc_comparison
)
421 && tree_swap_operands_p (op0
, op1
, false))
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))
466 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
467 code
, type
, op0
, op1
, op2
))
469 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
472 /* Builtin function with one argument. */
475 gimple_simplify (enum built_in_function fn
, tree type
,
477 gimple_seq
*seq
, tree (*valueize
)(tree
))
479 if (constant_for_folding (arg0
))
481 tree decl
= builtin_decl_implicit (fn
);
484 tree res
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, &arg0
, 1, false);
487 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
489 res
= fold_convert (type
, res
);
490 if (CONSTANT_CLASS_P (res
))
498 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
501 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
504 /* Builtin function with two arguments. */
507 gimple_simplify (enum built_in_function fn
, tree type
,
508 tree arg0
, tree arg1
,
509 gimple_seq
*seq
, tree (*valueize
)(tree
))
511 if (constant_for_folding (arg0
)
512 && constant_for_folding (arg1
))
514 tree decl
= builtin_decl_implicit (fn
);
520 tree res
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, args
, 2, false);
523 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
525 res
= fold_convert (type
, res
);
526 if (CONSTANT_CLASS_P (res
))
534 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
535 fn
, type
, arg0
, arg1
))
537 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
540 /* Builtin function with three arguments. */
543 gimple_simplify (enum built_in_function fn
, tree type
,
544 tree arg0
, tree arg1
, tree arg2
,
545 gimple_seq
*seq
, tree (*valueize
)(tree
))
547 if (constant_for_folding (arg0
)
548 && constant_for_folding (arg1
)
549 && constant_for_folding (arg2
))
551 tree decl
= builtin_decl_implicit (fn
);
558 tree res
= fold_builtin_n (UNKNOWN_LOCATION
, decl
, args
, 3, false);
561 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
563 res
= fold_convert (type
, res
);
564 if (CONSTANT_CLASS_P (res
))
572 if (!gimple_simplify (&rcode
, ops
, seq
, valueize
,
573 fn
, type
, arg0
, arg1
, arg2
))
575 return maybe_push_res_to_seq (rcode
, type
, ops
, seq
);
579 /* The main STMT based simplification entry. It is used by the fold_stmt
580 and the fold_stmt_to_constant APIs. */
583 gimple_simplify (gimple stmt
,
584 code_helper
*rcode
, tree
*ops
,
585 gimple_seq
*seq
, tree (*valueize
)(tree
))
587 switch (gimple_code (stmt
))
591 enum tree_code code
= gimple_assign_rhs_code (stmt
);
592 tree type
= TREE_TYPE (gimple_assign_lhs (stmt
));
593 switch (gimple_assign_rhs_class (stmt
))
595 case GIMPLE_SINGLE_RHS
:
596 if (code
== REALPART_EXPR
597 || code
== IMAGPART_EXPR
598 || code
== VIEW_CONVERT_EXPR
)
600 tree op0
= TREE_OPERAND (gimple_assign_rhs1 (stmt
), 0);
601 if (valueize
&& TREE_CODE (op0
) == SSA_NAME
)
603 tree tem
= valueize (op0
);
609 return gimple_resimplify1 (seq
, rcode
, type
, ops
, valueize
);
611 else if (code
== BIT_FIELD_REF
)
613 tree rhs1
= gimple_assign_rhs1 (stmt
);
614 tree op0
= TREE_OPERAND (rhs1
, 0);
615 if (valueize
&& TREE_CODE (op0
) == SSA_NAME
)
617 tree tem
= valueize (op0
);
623 ops
[1] = TREE_OPERAND (rhs1
, 1);
624 ops
[2] = TREE_OPERAND (rhs1
, 2);
625 return gimple_resimplify3 (seq
, rcode
, type
, ops
, valueize
);
627 else if (code
== SSA_NAME
630 tree op0
= gimple_assign_rhs1 (stmt
);
631 tree valueized
= valueize (op0
);
632 if (!valueized
|| op0
== valueized
)
635 *rcode
= TREE_CODE (op0
);
639 case GIMPLE_UNARY_RHS
:
641 tree rhs1
= gimple_assign_rhs1 (stmt
);
642 if (valueize
&& TREE_CODE (rhs1
) == SSA_NAME
)
644 tree tem
= valueize (rhs1
);
650 return gimple_resimplify1 (seq
, rcode
, type
, ops
, valueize
);
652 case GIMPLE_BINARY_RHS
:
654 tree rhs1
= gimple_assign_rhs1 (stmt
);
655 if (valueize
&& TREE_CODE (rhs1
) == SSA_NAME
)
657 tree tem
= valueize (rhs1
);
661 tree rhs2
= gimple_assign_rhs2 (stmt
);
662 if (valueize
&& TREE_CODE (rhs2
) == SSA_NAME
)
664 tree tem
= valueize (rhs2
);
671 return gimple_resimplify2 (seq
, rcode
, type
, ops
, valueize
);
673 case GIMPLE_TERNARY_RHS
:
675 tree rhs1
= gimple_assign_rhs1 (stmt
);
676 if (valueize
&& TREE_CODE (rhs1
) == SSA_NAME
)
678 tree tem
= valueize (rhs1
);
682 tree rhs2
= gimple_assign_rhs2 (stmt
);
683 if (valueize
&& TREE_CODE (rhs2
) == SSA_NAME
)
685 tree tem
= valueize (rhs2
);
689 tree rhs3
= gimple_assign_rhs3 (stmt
);
690 if (valueize
&& TREE_CODE (rhs3
) == SSA_NAME
)
692 tree tem
= valueize (rhs3
);
700 return gimple_resimplify3 (seq
, rcode
, type
, ops
, valueize
);
709 /* ??? This way we can't simplify calls with side-effects. */
710 if (gimple_call_lhs (stmt
) != NULL_TREE
)
712 tree fn
= gimple_call_fn (stmt
);
713 /* ??? Internal function support missing. */
716 if (valueize
&& TREE_CODE (fn
) == SSA_NAME
)
718 tree tem
= valueize (fn
);
723 || TREE_CODE (fn
) != ADDR_EXPR
724 || TREE_CODE (TREE_OPERAND (fn
, 0)) != FUNCTION_DECL
725 || DECL_BUILT_IN_CLASS (TREE_OPERAND (fn
, 0)) != BUILT_IN_NORMAL
726 || !builtin_decl_implicit (DECL_FUNCTION_CODE (TREE_OPERAND (fn
, 0)))
727 || !gimple_builtin_call_types_compatible_p (stmt
,
728 TREE_OPERAND (fn
, 0)))
731 tree decl
= TREE_OPERAND (fn
, 0);
732 tree type
= TREE_TYPE (gimple_call_lhs (stmt
));
733 switch (gimple_call_num_args (stmt
))
737 tree arg1
= gimple_call_arg (stmt
, 0);
738 if (valueize
&& TREE_CODE (arg1
) == SSA_NAME
)
740 tree tem
= valueize (arg1
);
744 *rcode
= DECL_FUNCTION_CODE (decl
);
746 return gimple_resimplify1 (seq
, rcode
, type
, ops
, valueize
);
750 tree arg1
= gimple_call_arg (stmt
, 0);
751 if (valueize
&& TREE_CODE (arg1
) == SSA_NAME
)
753 tree tem
= valueize (arg1
);
757 tree arg2
= gimple_call_arg (stmt
, 1);
758 if (valueize
&& TREE_CODE (arg2
) == SSA_NAME
)
760 tree tem
= valueize (arg2
);
764 *rcode
= DECL_FUNCTION_CODE (decl
);
767 return gimple_resimplify2 (seq
, rcode
, type
, ops
, valueize
);
771 tree arg1
= gimple_call_arg (stmt
, 0);
772 if (valueize
&& TREE_CODE (arg1
) == SSA_NAME
)
774 tree tem
= valueize (arg1
);
778 tree arg2
= gimple_call_arg (stmt
, 1);
779 if (valueize
&& TREE_CODE (arg2
) == SSA_NAME
)
781 tree tem
= valueize (arg2
);
785 tree arg3
= gimple_call_arg (stmt
, 2);
786 if (valueize
&& TREE_CODE (arg3
) == SSA_NAME
)
788 tree tem
= valueize (arg3
);
792 *rcode
= DECL_FUNCTION_CODE (decl
);
796 return gimple_resimplify3 (seq
, rcode
, type
, ops
, valueize
);
806 tree lhs
= gimple_cond_lhs (stmt
);
807 if (valueize
&& TREE_CODE (lhs
) == SSA_NAME
)
809 tree tem
= valueize (lhs
);
813 tree rhs
= gimple_cond_rhs (stmt
);
814 if (valueize
&& TREE_CODE (rhs
) == SSA_NAME
)
816 tree tem
= valueize (rhs
);
820 *rcode
= gimple_cond_code (stmt
);
823 return gimple_resimplify2 (seq
, rcode
, boolean_type_node
, ops
, valueize
);
834 /* Helper for the autogenerated code, valueize OP. */
837 do_valueize (tree (*valueize
)(tree
), tree op
)
839 if (valueize
&& TREE_CODE (op
) == SSA_NAME
)
840 return valueize (op
);