2015-10-18 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / gimple-match-head.c
blob8f7291912c7a79ed06356773c55895cc31d6ee9e
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"
51 #include "tree-pass.h"
54 /* Forward declarations of the private auto-generated matchers.
55 They expect valueized operands in canonical order and do not
56 perform simplification of all-constant operands. */
57 static bool gimple_simplify (code_helper *, tree *,
58 gimple_seq *, tree (*)(tree),
59 code_helper, tree, tree);
60 static bool gimple_simplify (code_helper *, tree *,
61 gimple_seq *, tree (*)(tree),
62 code_helper, tree, tree, tree);
63 static bool gimple_simplify (code_helper *, tree *,
64 gimple_seq *, tree (*)(tree),
65 code_helper, tree, tree, tree, tree);
68 /* Return whether T is a constant that we'll dispatch to fold to
69 evaluate fully constant expressions. */
71 static inline bool
72 constant_for_folding (tree t)
74 return (CONSTANT_CLASS_P (t)
75 /* The following is only interesting to string builtins. */
76 || (TREE_CODE (t) == ADDR_EXPR
77 && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST));
81 /* Helper that matches and simplifies the toplevel result from
82 a gimple_simplify run (where we don't want to build
83 a stmt in case it's used in in-place folding). Replaces
84 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
85 result and returns whether any change was made. */
87 bool
88 gimple_resimplify1 (gimple_seq *seq,
89 code_helper *res_code, tree type, tree *res_ops,
90 tree (*valueize)(tree))
92 if (constant_for_folding (res_ops[0]))
94 tree tem = NULL_TREE;
95 if (res_code->is_tree_code ())
96 tem = const_unop (*res_code, type, res_ops[0]);
97 else
99 tree decl = builtin_decl_implicit (*res_code);
100 if (decl)
102 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 1, false);
103 if (tem)
105 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
106 STRIP_NOPS (tem);
107 tem = fold_convert (type, tem);
111 if (tem != NULL_TREE
112 && CONSTANT_CLASS_P (tem))
114 res_ops[0] = tem;
115 res_ops[1] = NULL_TREE;
116 res_ops[2] = NULL_TREE;
117 *res_code = TREE_CODE (res_ops[0]);
118 return true;
122 code_helper res_code2;
123 tree res_ops2[3] = {};
124 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
125 *res_code, type, res_ops[0]))
127 *res_code = res_code2;
128 res_ops[0] = res_ops2[0];
129 res_ops[1] = res_ops2[1];
130 res_ops[2] = res_ops2[2];
131 return true;
134 return false;
137 /* Helper that matches and simplifies the toplevel result from
138 a gimple_simplify run (where we don't want to build
139 a stmt in case it's used in in-place folding). Replaces
140 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
141 result and returns whether any change was made. */
143 bool
144 gimple_resimplify2 (gimple_seq *seq,
145 code_helper *res_code, tree type, tree *res_ops,
146 tree (*valueize)(tree))
148 if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1]))
150 tree tem = NULL_TREE;
151 if (res_code->is_tree_code ())
152 tem = const_binop (*res_code, type, res_ops[0], res_ops[1]);
153 else
155 tree decl = builtin_decl_implicit (*res_code);
156 if (decl)
158 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 2, false);
159 if (tem)
161 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
162 STRIP_NOPS (tem);
163 tem = fold_convert (type, tem);
167 if (tem != NULL_TREE
168 && CONSTANT_CLASS_P (tem))
170 res_ops[0] = tem;
171 res_ops[1] = NULL_TREE;
172 res_ops[2] = NULL_TREE;
173 *res_code = TREE_CODE (res_ops[0]);
174 return true;
178 /* Canonicalize operand order. */
179 bool canonicalized = false;
180 if (res_code->is_tree_code ()
181 && (TREE_CODE_CLASS ((enum tree_code) *res_code) == tcc_comparison
182 || commutative_tree_code (*res_code))
183 && tree_swap_operands_p (res_ops[0], res_ops[1], false))
185 std::swap (res_ops[0], res_ops[1]);
186 if (TREE_CODE_CLASS ((enum tree_code) *res_code) == tcc_comparison)
187 *res_code = swap_tree_comparison (*res_code);
188 canonicalized = true;
191 code_helper res_code2;
192 tree res_ops2[3] = {};
193 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
194 *res_code, type, res_ops[0], res_ops[1]))
196 *res_code = res_code2;
197 res_ops[0] = res_ops2[0];
198 res_ops[1] = res_ops2[1];
199 res_ops[2] = res_ops2[2];
200 return true;
203 return canonicalized;
206 /* Helper that matches and simplifies the toplevel result from
207 a gimple_simplify run (where we don't want to build
208 a stmt in case it's used in in-place folding). Replaces
209 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
210 result and returns whether any change was made. */
212 bool
213 gimple_resimplify3 (gimple_seq *seq,
214 code_helper *res_code, tree type, tree *res_ops,
215 tree (*valueize)(tree))
217 if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1])
218 && constant_for_folding (res_ops[2]))
220 tree tem = NULL_TREE;
221 if (res_code->is_tree_code ())
222 tem = fold_ternary/*_to_constant*/ (*res_code, type, res_ops[0],
223 res_ops[1], res_ops[2]);
224 else
226 tree decl = builtin_decl_implicit (*res_code);
227 if (decl)
229 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 3, false);
230 if (tem)
232 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
233 STRIP_NOPS (tem);
234 tem = fold_convert (type, tem);
238 if (tem != NULL_TREE
239 && CONSTANT_CLASS_P (tem))
241 res_ops[0] = tem;
242 res_ops[1] = NULL_TREE;
243 res_ops[2] = NULL_TREE;
244 *res_code = TREE_CODE (res_ops[0]);
245 return true;
249 /* Canonicalize operand order. */
250 bool canonicalized = false;
251 if (res_code->is_tree_code ()
252 && commutative_ternary_tree_code (*res_code)
253 && tree_swap_operands_p (res_ops[0], res_ops[1], false))
255 std::swap (res_ops[0], res_ops[1]);
256 canonicalized = true;
259 code_helper res_code2;
260 tree res_ops2[3] = {};
261 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
262 *res_code, type,
263 res_ops[0], res_ops[1], res_ops[2]))
265 *res_code = res_code2;
266 res_ops[0] = res_ops2[0];
267 res_ops[1] = res_ops2[1];
268 res_ops[2] = res_ops2[2];
269 return true;
272 return canonicalized;
276 /* If in GIMPLE expressions with CODE go as single-rhs build
277 a GENERIC tree for that expression into *OP0. */
279 void
280 maybe_build_generic_op (enum tree_code code, tree type,
281 tree *op0, tree op1, tree op2)
283 switch (code)
285 case REALPART_EXPR:
286 case IMAGPART_EXPR:
287 case VIEW_CONVERT_EXPR:
288 *op0 = build1 (code, type, *op0);
289 break;
290 case BIT_FIELD_REF:
291 *op0 = build3 (code, type, *op0, op1, op2);
292 break;
293 default:;
297 tree (*mprts_hook) (code_helper, tree, tree *);
299 /* Push the exploded expression described by RCODE, TYPE and OPS
300 as a statement to SEQ if necessary and return a gimple value
301 denoting the value of the expression. If RES is not NULL
302 then the result will be always RES and even gimple values are
303 pushed to SEQ. */
305 tree
306 maybe_push_res_to_seq (code_helper rcode, tree type, tree *ops,
307 gimple_seq *seq, tree res)
309 if (rcode.is_tree_code ())
311 if (!res
312 && gimple_simplified_result_is_gimple_val (rcode, ops))
313 return ops[0];
314 if (mprts_hook)
316 tree tem = mprts_hook (rcode, type, ops);
317 if (tem)
318 return tem;
320 if (!seq)
321 return NULL_TREE;
322 /* Play safe and do not allow abnormals to be mentioned in
323 newly created statements. */
324 if ((TREE_CODE (ops[0]) == SSA_NAME
325 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
326 || (ops[1]
327 && TREE_CODE (ops[1]) == SSA_NAME
328 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
329 || (ops[2]
330 && TREE_CODE (ops[2]) == SSA_NAME
331 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
332 return NULL_TREE;
333 if (!res)
334 res = make_ssa_name (type);
335 maybe_build_generic_op (rcode, type, &ops[0], ops[1], ops[2]);
336 gimple *new_stmt = gimple_build_assign (res, rcode,
337 ops[0], ops[1], ops[2]);
338 gimple_seq_add_stmt_without_update (seq, new_stmt);
339 return res;
341 else
343 if (!seq)
344 return NULL_TREE;
345 tree decl = builtin_decl_implicit (rcode);
346 if (!decl)
347 return NULL_TREE;
348 /* We can't and should not emit calls to non-const functions. */
349 if (!(flags_from_decl_or_type (decl) & ECF_CONST))
350 return NULL_TREE;
351 /* Play safe and do not allow abnormals to be mentioned in
352 newly created statements. */
353 unsigned nargs;
354 for (nargs = 0; nargs < 3; ++nargs)
356 if (!ops[nargs])
357 break;
358 if (TREE_CODE (ops[nargs]) == SSA_NAME
359 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[nargs]))
360 return NULL_TREE;
362 gcc_assert (nargs != 0);
363 if (!res)
364 res = make_ssa_name (type);
365 gimple *new_stmt = gimple_build_call (decl, nargs, ops[0], ops[1], ops[2]);
366 gimple_call_set_lhs (new_stmt, res);
367 gimple_seq_add_stmt_without_update (seq, new_stmt);
368 return res;
373 /* Public API overloads follow for operation being tree_code or
374 built_in_function and for one to three operands or arguments.
375 They return NULL_TREE if nothing could be simplified or
376 the resulting simplified value with parts pushed to SEQ.
377 If SEQ is NULL then if the simplification needs to create
378 new stmts it will fail. If VALUEIZE is non-NULL then all
379 SSA names will be valueized using that hook prior to
380 applying simplifications. */
382 /* Unary ops. */
384 tree
385 gimple_simplify (enum tree_code code, tree type,
386 tree op0,
387 gimple_seq *seq, tree (*valueize)(tree))
389 if (constant_for_folding (op0))
391 tree res = const_unop (code, type, op0);
392 if (res != NULL_TREE
393 && CONSTANT_CLASS_P (res))
394 return res;
397 code_helper rcode;
398 tree ops[3] = {};
399 if (!gimple_simplify (&rcode, ops, seq, valueize,
400 code, type, op0))
401 return NULL_TREE;
402 return maybe_push_res_to_seq (rcode, type, ops, seq);
405 /* Binary ops. */
407 tree
408 gimple_simplify (enum tree_code code, tree type,
409 tree op0, tree op1,
410 gimple_seq *seq, tree (*valueize)(tree))
412 if (constant_for_folding (op0) && constant_for_folding (op1))
414 tree res = const_binop (code, type, op0, op1);
415 if (res != NULL_TREE
416 && CONSTANT_CLASS_P (res))
417 return res;
420 /* Canonicalize operand order both for matching and fallback stmt
421 generation. */
422 if ((commutative_tree_code (code)
423 || TREE_CODE_CLASS (code) == tcc_comparison)
424 && tree_swap_operands_p (op0, op1, false))
426 std::swap (op0, op1);
427 if (TREE_CODE_CLASS (code) == tcc_comparison)
428 code = swap_tree_comparison (code);
431 code_helper rcode;
432 tree ops[3] = {};
433 if (!gimple_simplify (&rcode, ops, seq, valueize,
434 code, type, op0, op1))
435 return NULL_TREE;
436 return maybe_push_res_to_seq (rcode, type, ops, seq);
439 /* Ternary ops. */
441 tree
442 gimple_simplify (enum tree_code code, tree type,
443 tree op0, tree op1, tree op2,
444 gimple_seq *seq, tree (*valueize)(tree))
446 if (constant_for_folding (op0) && constant_for_folding (op1)
447 && constant_for_folding (op2))
449 tree res = fold_ternary/*_to_constant */ (code, type, op0, op1, op2);
450 if (res != NULL_TREE
451 && CONSTANT_CLASS_P (res))
452 return res;
455 /* Canonicalize operand order both for matching and fallback stmt
456 generation. */
457 if (commutative_ternary_tree_code (code)
458 && tree_swap_operands_p (op0, op1, false))
459 std::swap (op0, op1);
461 code_helper rcode;
462 tree ops[3] = {};
463 if (!gimple_simplify (&rcode, ops, seq, valueize,
464 code, type, op0, op1, op2))
465 return NULL_TREE;
466 return maybe_push_res_to_seq (rcode, type, ops, seq);
469 /* Builtin function with one argument. */
471 tree
472 gimple_simplify (enum built_in_function fn, tree type,
473 tree arg0,
474 gimple_seq *seq, tree (*valueize)(tree))
476 if (constant_for_folding (arg0))
478 tree decl = builtin_decl_implicit (fn);
479 if (decl)
481 tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, &arg0, 1, false);
482 if (res)
484 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
485 STRIP_NOPS (res);
486 res = fold_convert (type, res);
487 if (CONSTANT_CLASS_P (res))
488 return res;
493 code_helper rcode;
494 tree ops[3] = {};
495 if (!gimple_simplify (&rcode, ops, seq, valueize,
496 fn, type, arg0))
497 return NULL_TREE;
498 return maybe_push_res_to_seq (rcode, type, ops, seq);
501 /* Builtin function with two arguments. */
503 tree
504 gimple_simplify (enum built_in_function fn, tree type,
505 tree arg0, tree arg1,
506 gimple_seq *seq, tree (*valueize)(tree))
508 if (constant_for_folding (arg0)
509 && constant_for_folding (arg1))
511 tree decl = builtin_decl_implicit (fn);
512 if (decl)
514 tree args[2];
515 args[0] = arg0;
516 args[1] = arg1;
517 tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, args, 2, false);
518 if (res)
520 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
521 STRIP_NOPS (res);
522 res = fold_convert (type, res);
523 if (CONSTANT_CLASS_P (res))
524 return res;
529 code_helper rcode;
530 tree ops[3] = {};
531 if (!gimple_simplify (&rcode, ops, seq, valueize,
532 fn, type, arg0, arg1))
533 return NULL_TREE;
534 return maybe_push_res_to_seq (rcode, type, ops, seq);
537 /* Builtin function with three arguments. */
539 tree
540 gimple_simplify (enum built_in_function fn, tree type,
541 tree arg0, tree arg1, tree arg2,
542 gimple_seq *seq, tree (*valueize)(tree))
544 if (constant_for_folding (arg0)
545 && constant_for_folding (arg1)
546 && constant_for_folding (arg2))
548 tree decl = builtin_decl_implicit (fn);
549 if (decl)
551 tree args[3];
552 args[0] = arg0;
553 args[1] = arg1;
554 args[2] = arg2;
555 tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, args, 3, false);
556 if (res)
558 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
559 STRIP_NOPS (res);
560 res = fold_convert (type, res);
561 if (CONSTANT_CLASS_P (res))
562 return res;
567 code_helper rcode;
568 tree ops[3] = {};
569 if (!gimple_simplify (&rcode, ops, seq, valueize,
570 fn, type, arg0, arg1, arg2))
571 return NULL_TREE;
572 return maybe_push_res_to_seq (rcode, type, ops, seq);
575 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
576 VALUEIZED to true if valueization changed OP. */
578 static inline tree
579 do_valueize (tree op, tree (*valueize)(tree), bool &valueized)
581 if (valueize && TREE_CODE (op) == SSA_NAME)
583 tree tem = valueize (op);
584 if (tem && tem != op)
586 op = tem;
587 valueized = true;
590 return op;
593 /* The main STMT based simplification entry. It is used by the fold_stmt
594 and the fold_stmt_to_constant APIs. */
596 bool
597 gimple_simplify (gimple *stmt,
598 code_helper *rcode, tree *ops,
599 gimple_seq *seq,
600 tree (*valueize)(tree), tree (*top_valueize)(tree))
602 switch (gimple_code (stmt))
604 case GIMPLE_ASSIGN:
606 enum tree_code code = gimple_assign_rhs_code (stmt);
607 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
608 switch (gimple_assign_rhs_class (stmt))
610 case GIMPLE_SINGLE_RHS:
611 if (code == REALPART_EXPR
612 || code == IMAGPART_EXPR
613 || code == VIEW_CONVERT_EXPR)
615 tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
616 bool valueized = false;
617 op0 = do_valueize (op0, top_valueize, valueized);
618 *rcode = code;
619 ops[0] = op0;
620 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
621 || valueized);
623 else if (code == BIT_FIELD_REF)
625 tree rhs1 = gimple_assign_rhs1 (stmt);
626 tree op0 = TREE_OPERAND (rhs1, 0);
627 bool valueized = false;
628 op0 = do_valueize (op0, top_valueize, valueized);
629 *rcode = code;
630 ops[0] = op0;
631 ops[1] = TREE_OPERAND (rhs1, 1);
632 ops[2] = TREE_OPERAND (rhs1, 2);
633 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
634 || valueized);
636 else if (code == SSA_NAME
637 && top_valueize)
639 tree op0 = gimple_assign_rhs1 (stmt);
640 tree valueized = top_valueize (op0);
641 if (!valueized || op0 == valueized)
642 return false;
643 ops[0] = valueized;
644 *rcode = TREE_CODE (op0);
645 return true;
647 break;
648 case GIMPLE_UNARY_RHS:
650 tree rhs1 = gimple_assign_rhs1 (stmt);
651 bool valueized = false;
652 rhs1 = do_valueize (rhs1, top_valueize, valueized);
653 *rcode = code;
654 ops[0] = rhs1;
655 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
656 || valueized);
658 case GIMPLE_BINARY_RHS:
660 tree rhs1 = gimple_assign_rhs1 (stmt);
661 tree rhs2 = gimple_assign_rhs2 (stmt);
662 bool valueized = false;
663 rhs1 = do_valueize (rhs1, top_valueize, valueized);
664 rhs2 = do_valueize (rhs2, top_valueize, valueized);
665 *rcode = code;
666 ops[0] = rhs1;
667 ops[1] = rhs2;
668 return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
669 || valueized);
671 case GIMPLE_TERNARY_RHS:
673 bool valueized = false;
674 tree rhs1 = gimple_assign_rhs1 (stmt);
675 /* If this is a [VEC_]COND_EXPR first try to simplify an
676 embedded GENERIC condition. */
677 if (code == COND_EXPR
678 || code == VEC_COND_EXPR)
680 if (COMPARISON_CLASS_P (rhs1))
682 tree lhs = TREE_OPERAND (rhs1, 0);
683 tree rhs = TREE_OPERAND (rhs1, 1);
684 lhs = do_valueize (lhs, top_valueize, valueized);
685 rhs = do_valueize (rhs, top_valueize, valueized);
686 code_helper rcode2 = TREE_CODE (rhs1);
687 tree ops2[3] = {};
688 ops2[0] = lhs;
689 ops2[1] = rhs;
690 if ((gimple_resimplify2 (seq, &rcode2, TREE_TYPE (rhs1),
691 ops2, valueize)
692 || valueized)
693 && rcode2.is_tree_code ())
695 valueized = true;
696 if (TREE_CODE_CLASS ((enum tree_code)rcode2)
697 == tcc_comparison)
698 rhs1 = build2 (rcode2, TREE_TYPE (rhs1),
699 ops2[0], ops2[1]);
700 else if (rcode2 == SSA_NAME
701 || rcode2 == INTEGER_CST)
702 rhs1 = ops2[0];
703 else
704 valueized = false;
708 tree rhs2 = gimple_assign_rhs2 (stmt);
709 tree rhs3 = gimple_assign_rhs3 (stmt);
710 rhs1 = do_valueize (rhs1, top_valueize, valueized);
711 rhs2 = do_valueize (rhs2, top_valueize, valueized);
712 rhs3 = do_valueize (rhs3, top_valueize, valueized);
713 *rcode = code;
714 ops[0] = rhs1;
715 ops[1] = rhs2;
716 ops[2] = rhs3;
717 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
718 || valueized);
720 default:
721 gcc_unreachable ();
723 break;
726 case GIMPLE_CALL:
727 /* ??? This way we can't simplify calls with side-effects. */
728 if (gimple_call_lhs (stmt) != NULL_TREE
729 && gimple_call_num_args (stmt) >= 1
730 && gimple_call_num_args (stmt) <= 3)
732 tree fn = gimple_call_fn (stmt);
733 /* ??? Internal function support missing. */
734 if (!fn)
735 return false;
736 bool valueized = false;
737 fn = do_valueize (fn, top_valueize, valueized);
738 if (TREE_CODE (fn) != ADDR_EXPR
739 || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
740 return false;
742 tree decl = TREE_OPERAND (fn, 0);
743 if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL
744 || !builtin_decl_implicit (DECL_FUNCTION_CODE (decl))
745 || !gimple_builtin_call_types_compatible_p (stmt, decl))
746 return false;
748 tree type = TREE_TYPE (gimple_call_lhs (stmt));
749 *rcode = DECL_FUNCTION_CODE (decl);
750 for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
752 tree arg = gimple_call_arg (stmt, i);
753 ops[i] = do_valueize (arg, top_valueize, valueized);
755 switch (gimple_call_num_args (stmt))
757 case 1:
758 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
759 || valueized);
760 case 2:
761 return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
762 || valueized);
763 case 3:
764 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
765 || valueized);
766 default:
767 gcc_unreachable ();
770 break;
772 case GIMPLE_COND:
774 tree lhs = gimple_cond_lhs (stmt);
775 tree rhs = gimple_cond_rhs (stmt);
776 bool valueized = false;
777 lhs = do_valueize (lhs, top_valueize, valueized);
778 rhs = do_valueize (rhs, top_valueize, valueized);
779 *rcode = gimple_cond_code (stmt);
780 ops[0] = lhs;
781 ops[1] = rhs;
782 return (gimple_resimplify2 (seq, rcode,
783 boolean_type_node, ops, valueize)
784 || valueized);
787 default:
788 break;
791 return false;
795 /* Helper for the autogenerated code, valueize OP. */
797 inline tree
798 do_valueize (tree (*valueize)(tree), tree op)
800 if (valueize && TREE_CODE (op) == SSA_NAME)
801 return valueize (op);
802 return op;
805 /* Routine to determine if the types T1 and T2 are effectively
806 the same for GIMPLE. If T1 or T2 is not a type, the test
807 applies to their TREE_TYPE. */
809 static inline bool
810 types_match (tree t1, tree t2)
812 if (!TYPE_P (t1))
813 t1 = TREE_TYPE (t1);
814 if (!TYPE_P (t2))
815 t2 = TREE_TYPE (t2);
817 return types_compatible_p (t1, t2);
820 /* Return if T has a single use. For GIMPLE, we also allow any
821 non-SSA_NAME (ie constants) and zero uses to cope with uses
822 that aren't linked up yet. */
824 static inline bool
825 single_use (tree t)
827 return TREE_CODE (t) != SSA_NAME || has_zero_uses (t) || has_single_use (t);
830 /* Return true if math operations should be canonicalized,
831 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
833 static inline bool
834 canonicalize_math_p ()
836 return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;