2015-10-01 Steven G. Kargl <kargl@gcc.gnu.org>
[official-gcc.git] / gcc / gimple-match-head.c
blobcab77a4e18db931e2df5a1f1e7f09eab5a48966f
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
9 version.
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
14 for more details.
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/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "tree.h"
25 #include "gimple.h"
26 #include "rtl.h"
27 #include "ssa.h"
28 #include "alias.h"
29 #include "options.h"
30 #include "fold-const.h"
31 #include "stor-layout.h"
32 #include "flags.h"
33 #include "internal-fn.h"
34 #include "gimple-fold.h"
35 #include "gimple-iterator.h"
36 #include "insn-config.h"
37 #include "expmed.h"
38 #include "dojump.h"
39 #include "explow.h"
40 #include "calls.h"
41 #include "emit-rtl.h"
42 #include "varasm.h"
43 #include "stmt.h"
44 #include "expr.h"
45 #include "tree-dfa.h"
46 #include "builtins.h"
47 #include "dumpfile.h"
48 #include "target.h"
49 #include "cgraph.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. */
70 static inline bool
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. */
86 static bool
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]))
93 tree tem = NULL_TREE;
94 if (res_code->is_tree_code ())
95 tem = const_unop (*res_code, type, res_ops[0]);
96 else
98 tree decl = builtin_decl_implicit (*res_code);
99 if (decl)
101 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 1, false);
102 if (tem)
104 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
105 STRIP_NOPS (tem);
106 tem = fold_convert (type, tem);
110 if (tem != NULL_TREE
111 && CONSTANT_CLASS_P (tem))
113 res_ops[0] = tem;
114 res_ops[1] = NULL_TREE;
115 res_ops[2] = NULL_TREE;
116 *res_code = TREE_CODE (res_ops[0]);
117 return true;
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];
130 return true;
133 return false;
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. */
142 static bool
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]);
152 else
154 tree decl = builtin_decl_implicit (*res_code);
155 if (decl)
157 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 2, false);
158 if (tem)
160 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
161 STRIP_NOPS (tem);
162 tem = fold_convert (type, tem);
166 if (tem != NULL_TREE
167 && CONSTANT_CLASS_P (tem))
169 res_ops[0] = tem;
170 res_ops[1] = NULL_TREE;
171 res_ops[2] = NULL_TREE;
172 *res_code = TREE_CODE (res_ops[0]);
173 return true;
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];
199 return true;
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. */
211 static bool
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]);
223 else
225 tree decl = builtin_decl_implicit (*res_code);
226 if (decl)
228 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 3, false);
229 if (tem)
231 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
232 STRIP_NOPS (tem);
233 tem = fold_convert (type, tem);
237 if (tem != NULL_TREE
238 && CONSTANT_CLASS_P (tem))
240 res_ops[0] = tem;
241 res_ops[1] = NULL_TREE;
242 res_ops[2] = NULL_TREE;
243 *res_code = TREE_CODE (res_ops[0]);
244 return true;
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,
261 *res_code, type,
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];
268 return true;
271 return canonicalized;
275 /* If in GIMPLE expressions with CODE go as single-rhs build
276 a GENERIC tree for that expression into *OP0. */
278 void
279 maybe_build_generic_op (enum tree_code code, tree type,
280 tree *op0, tree op1, tree op2)
282 switch (code)
284 case REALPART_EXPR:
285 case IMAGPART_EXPR:
286 case VIEW_CONVERT_EXPR:
287 *op0 = build1 (code, type, *op0);
288 break;
289 case BIT_FIELD_REF:
290 *op0 = build3 (code, type, *op0, op1, op2);
291 break;
292 default:;
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
302 pushed to SEQ. */
304 tree
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 ())
310 if (!res
311 && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
312 || ((tree_code) rcode) == ADDR_EXPR)
313 && is_gimple_val (ops[0]))
314 return ops[0];
315 if (mprts_hook)
317 tree tem = mprts_hook (rcode, type, ops);
318 if (tem)
319 return tem;
321 if (!seq)
322 return NULL_TREE;
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]))
327 || (ops[1]
328 && TREE_CODE (ops[1]) == SSA_NAME
329 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
330 || (ops[2]
331 && TREE_CODE (ops[2]) == SSA_NAME
332 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
333 return NULL_TREE;
334 if (!res)
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);
340 return res;
342 else
344 if (!seq)
345 return NULL_TREE;
346 tree decl = builtin_decl_implicit (rcode);
347 if (!decl)
348 return NULL_TREE;
349 /* We can't and should not emit calls to non-const functions. */
350 if (!(flags_from_decl_or_type (decl) & ECF_CONST))
351 return NULL_TREE;
352 /* Play safe and do not allow abnormals to be mentioned in
353 newly created statements. */
354 unsigned nargs;
355 for (nargs = 0; nargs < 3; ++nargs)
357 if (!ops[nargs])
358 break;
359 if (TREE_CODE (ops[nargs]) == SSA_NAME
360 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[nargs]))
361 return NULL_TREE;
363 gcc_assert (nargs != 0);
364 if (!res)
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);
369 return res;
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. */
383 /* Unary ops. */
385 tree
386 gimple_simplify (enum tree_code code, tree type,
387 tree op0,
388 gimple_seq *seq, tree (*valueize)(tree))
390 if (constant_for_folding (op0))
392 tree res = const_unop (code, type, op0);
393 if (res != NULL_TREE
394 && CONSTANT_CLASS_P (res))
395 return res;
398 code_helper rcode;
399 tree ops[3] = {};
400 if (!gimple_simplify (&rcode, ops, seq, valueize,
401 code, type, op0))
402 return NULL_TREE;
403 return maybe_push_res_to_seq (rcode, type, ops, seq);
406 /* Binary ops. */
408 tree
409 gimple_simplify (enum tree_code code, tree type,
410 tree op0, tree op1,
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);
416 if (res != NULL_TREE
417 && CONSTANT_CLASS_P (res))
418 return res;
421 /* Canonicalize operand order both for matching and fallback stmt
422 generation. */
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);
432 code_helper rcode;
433 tree ops[3] = {};
434 if (!gimple_simplify (&rcode, ops, seq, valueize,
435 code, type, op0, op1))
436 return NULL_TREE;
437 return maybe_push_res_to_seq (rcode, type, ops, seq);
440 /* Ternary ops. */
442 tree
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);
451 if (res != NULL_TREE
452 && CONSTANT_CLASS_P (res))
453 return res;
456 /* Canonicalize operand order both for matching and fallback stmt
457 generation. */
458 if (commutative_ternary_tree_code (code)
459 && tree_swap_operands_p (op0, op1, false))
460 std::swap (op0, op1);
462 code_helper rcode;
463 tree ops[3] = {};
464 if (!gimple_simplify (&rcode, ops, seq, valueize,
465 code, type, op0, op1, op2))
466 return NULL_TREE;
467 return maybe_push_res_to_seq (rcode, type, ops, seq);
470 /* Builtin function with one argument. */
472 tree
473 gimple_simplify (enum built_in_function fn, tree type,
474 tree arg0,
475 gimple_seq *seq, tree (*valueize)(tree))
477 if (constant_for_folding (arg0))
479 tree decl = builtin_decl_implicit (fn);
480 if (decl)
482 tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, &arg0, 1, false);
483 if (res)
485 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
486 STRIP_NOPS (res);
487 res = fold_convert (type, res);
488 if (CONSTANT_CLASS_P (res))
489 return res;
494 code_helper rcode;
495 tree ops[3] = {};
496 if (!gimple_simplify (&rcode, ops, seq, valueize,
497 fn, type, arg0))
498 return NULL_TREE;
499 return maybe_push_res_to_seq (rcode, type, ops, seq);
502 /* Builtin function with two arguments. */
504 tree
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);
513 if (decl)
515 tree args[2];
516 args[0] = arg0;
517 args[1] = arg1;
518 tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, args, 2, false);
519 if (res)
521 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
522 STRIP_NOPS (res);
523 res = fold_convert (type, res);
524 if (CONSTANT_CLASS_P (res))
525 return res;
530 code_helper rcode;
531 tree ops[3] = {};
532 if (!gimple_simplify (&rcode, ops, seq, valueize,
533 fn, type, arg0, arg1))
534 return NULL_TREE;
535 return maybe_push_res_to_seq (rcode, type, ops, seq);
538 /* Builtin function with three arguments. */
540 tree
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);
550 if (decl)
552 tree args[3];
553 args[0] = arg0;
554 args[1] = arg1;
555 args[2] = arg2;
556 tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, args, 3, false);
557 if (res)
559 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
560 STRIP_NOPS (res);
561 res = fold_convert (type, res);
562 if (CONSTANT_CLASS_P (res))
563 return res;
568 code_helper rcode;
569 tree ops[3] = {};
570 if (!gimple_simplify (&rcode, ops, seq, valueize,
571 fn, type, arg0, arg1, arg2))
572 return NULL_TREE;
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. */
579 static inline tree
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)
587 op = tem;
588 valueized = true;
591 return op;
594 /* The main STMT based simplification entry. It is used by the fold_stmt
595 and the fold_stmt_to_constant APIs. */
597 bool
598 gimple_simplify (gimple *stmt,
599 code_helper *rcode, tree *ops,
600 gimple_seq *seq,
601 tree (*valueize)(tree), tree (*top_valueize)(tree))
603 switch (gimple_code (stmt))
605 case GIMPLE_ASSIGN:
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);
619 *rcode = code;
620 ops[0] = op0;
621 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
622 || valueized);
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);
630 *rcode = code;
631 ops[0] = op0;
632 ops[1] = TREE_OPERAND (rhs1, 1);
633 ops[2] = TREE_OPERAND (rhs1, 2);
634 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
635 || valueized);
637 else if (code == SSA_NAME
638 && top_valueize)
640 tree op0 = gimple_assign_rhs1 (stmt);
641 tree valueized = top_valueize (op0);
642 if (!valueized || op0 == valueized)
643 return false;
644 ops[0] = valueized;
645 *rcode = TREE_CODE (op0);
646 return true;
648 break;
649 case GIMPLE_UNARY_RHS:
651 tree rhs1 = gimple_assign_rhs1 (stmt);
652 bool valueized = false;
653 rhs1 = do_valueize (rhs1, top_valueize, valueized);
654 *rcode = code;
655 ops[0] = rhs1;
656 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
657 || valueized);
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);
666 *rcode = code;
667 ops[0] = rhs1;
668 ops[1] = rhs2;
669 return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
670 || valueized);
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);
688 tree ops2[3] = {};
689 ops2[0] = lhs;
690 ops2[1] = rhs;
691 if ((gimple_resimplify2 (seq, &rcode2, TREE_TYPE (rhs1),
692 ops2, valueize)
693 || valueized)
694 && rcode2.is_tree_code ())
696 valueized = true;
697 if (TREE_CODE_CLASS ((enum tree_code)rcode2)
698 == tcc_comparison)
699 rhs1 = build2 (rcode2, TREE_TYPE (rhs1),
700 ops2[0], ops2[1]);
701 else if (rcode2 == SSA_NAME
702 || rcode2 == INTEGER_CST)
703 rhs1 = ops2[0];
704 else
705 valueized = false;
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);
714 *rcode = code;
715 ops[0] = rhs1;
716 ops[1] = rhs2;
717 ops[2] = rhs3;
718 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
719 || valueized);
721 default:
722 gcc_unreachable ();
724 break;
727 case GIMPLE_CALL:
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. */
735 if (!fn)
736 return false;
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)
741 return false;
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))
747 return false;
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))
758 case 1:
759 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
760 || valueized);
761 case 2:
762 return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
763 || valueized);
764 case 3:
765 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
766 || valueized);
767 default:
768 gcc_unreachable ();
771 break;
773 case GIMPLE_COND:
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);
781 ops[0] = lhs;
782 ops[1] = rhs;
783 return (gimple_resimplify2 (seq, rcode,
784 boolean_type_node, ops, valueize)
785 || valueized);
788 default:
789 break;
792 return false;
796 /* Helper for the autogenerated code, valueize OP. */
798 inline tree
799 do_valueize (tree (*valueize)(tree), tree op)
801 if (valueize && TREE_CODE (op) == SSA_NAME)
802 return valueize (op);
803 return 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. */
810 static inline bool
811 types_match (tree t1, tree t2)
813 if (!TYPE_P (t1))
814 t1 = TREE_TYPE (t1);
815 if (!TYPE_P (t2))
816 t2 = TREE_TYPE (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. */
825 static inline bool
826 single_use (tree t)
828 return TREE_CODE (t) != SSA_NAME || has_zero_uses (t) || has_single_use (t);