Small ChangeLog tweak.
[official-gcc.git] / gcc / gimple-match-head.c
blobe7e9839a4b84195cd6bf1c69f83e2d99d5f13d65
1 /* Preamble and helpers for the autogenerated gimple-match.c file.
2 Copyright (C) 2014-2017 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 "target.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "ssa.h"
29 #include "cgraph.h"
30 #include "fold-const.h"
31 #include "fold-const-call.h"
32 #include "stor-layout.h"
33 #include "gimple-fold.h"
34 #include "calls.h"
35 #include "tree-dfa.h"
36 #include "builtins.h"
37 #include "gimple-match.h"
38 #include "tree-pass.h"
39 #include "internal-fn.h"
40 #include "case-cfn-macros.h"
41 #include "gimplify.h"
44 /* Forward declarations of the private auto-generated matchers.
45 They expect valueized operands in canonical order and do not
46 perform simplification of all-constant operands. */
47 static bool gimple_simplify (code_helper *, tree *,
48 gimple_seq *, tree (*)(tree),
49 code_helper, tree, tree);
50 static bool gimple_simplify (code_helper *, tree *,
51 gimple_seq *, tree (*)(tree),
52 code_helper, tree, tree, tree);
53 static bool gimple_simplify (code_helper *, tree *,
54 gimple_seq *, tree (*)(tree),
55 code_helper, tree, tree, tree, tree);
58 /* Return whether T is a constant that we'll dispatch to fold to
59 evaluate fully constant expressions. */
61 static inline bool
62 constant_for_folding (tree t)
64 return (CONSTANT_CLASS_P (t)
65 /* The following is only interesting to string builtins. */
66 || (TREE_CODE (t) == ADDR_EXPR
67 && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST));
71 /* Helper that matches and simplifies the toplevel result from
72 a gimple_simplify run (where we don't want to build
73 a stmt in case it's used in in-place folding). Replaces
74 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
75 result and returns whether any change was made. */
77 bool
78 gimple_resimplify1 (gimple_seq *seq,
79 code_helper *res_code, tree type, tree *res_ops,
80 tree (*valueize)(tree))
82 if (constant_for_folding (res_ops[0]))
84 tree tem = NULL_TREE;
85 if (res_code->is_tree_code ())
86 tem = const_unop (*res_code, type, res_ops[0]);
87 else
88 tem = fold_const_call (combined_fn (*res_code), type, res_ops[0]);
89 if (tem != NULL_TREE
90 && CONSTANT_CLASS_P (tem))
92 if (TREE_OVERFLOW_P (tem))
93 tem = drop_tree_overflow (tem);
94 res_ops[0] = tem;
95 res_ops[1] = NULL_TREE;
96 res_ops[2] = NULL_TREE;
97 *res_code = TREE_CODE (res_ops[0]);
98 return true;
102 code_helper res_code2;
103 tree res_ops2[3] = {};
104 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
105 *res_code, type, res_ops[0]))
107 *res_code = res_code2;
108 res_ops[0] = res_ops2[0];
109 res_ops[1] = res_ops2[1];
110 res_ops[2] = res_ops2[2];
111 return true;
114 return false;
117 /* Helper that matches and simplifies the toplevel result from
118 a gimple_simplify run (where we don't want to build
119 a stmt in case it's used in in-place folding). Replaces
120 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
121 result and returns whether any change was made. */
123 bool
124 gimple_resimplify2 (gimple_seq *seq,
125 code_helper *res_code, tree type, tree *res_ops,
126 tree (*valueize)(tree))
128 if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1]))
130 tree tem = NULL_TREE;
131 if (res_code->is_tree_code ())
132 tem = const_binop (*res_code, type, res_ops[0], res_ops[1]);
133 else
134 tem = fold_const_call (combined_fn (*res_code), type,
135 res_ops[0], res_ops[1]);
136 if (tem != NULL_TREE
137 && CONSTANT_CLASS_P (tem))
139 if (TREE_OVERFLOW_P (tem))
140 tem = drop_tree_overflow (tem);
141 res_ops[0] = tem;
142 res_ops[1] = NULL_TREE;
143 res_ops[2] = NULL_TREE;
144 *res_code = TREE_CODE (res_ops[0]);
145 return true;
149 /* Canonicalize operand order. */
150 bool canonicalized = false;
151 if (res_code->is_tree_code ()
152 && (TREE_CODE_CLASS ((enum tree_code) *res_code) == tcc_comparison
153 || commutative_tree_code (*res_code))
154 && tree_swap_operands_p (res_ops[0], res_ops[1]))
156 std::swap (res_ops[0], res_ops[1]);
157 if (TREE_CODE_CLASS ((enum tree_code) *res_code) == tcc_comparison)
158 *res_code = swap_tree_comparison (*res_code);
159 canonicalized = true;
162 code_helper res_code2;
163 tree res_ops2[3] = {};
164 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
165 *res_code, type, res_ops[0], res_ops[1]))
167 *res_code = res_code2;
168 res_ops[0] = res_ops2[0];
169 res_ops[1] = res_ops2[1];
170 res_ops[2] = res_ops2[2];
171 return true;
174 return canonicalized;
177 /* Helper that matches and simplifies the toplevel result from
178 a gimple_simplify run (where we don't want to build
179 a stmt in case it's used in in-place folding). Replaces
180 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
181 result and returns whether any change was made. */
183 bool
184 gimple_resimplify3 (gimple_seq *seq,
185 code_helper *res_code, tree type, tree *res_ops,
186 tree (*valueize)(tree))
188 if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1])
189 && constant_for_folding (res_ops[2]))
191 tree tem = NULL_TREE;
192 if (res_code->is_tree_code ())
193 tem = fold_ternary/*_to_constant*/ (*res_code, type, res_ops[0],
194 res_ops[1], res_ops[2]);
195 else
196 tem = fold_const_call (combined_fn (*res_code), type,
197 res_ops[0], res_ops[1], res_ops[2]);
198 if (tem != NULL_TREE
199 && CONSTANT_CLASS_P (tem))
201 if (TREE_OVERFLOW_P (tem))
202 tem = drop_tree_overflow (tem);
203 res_ops[0] = tem;
204 res_ops[1] = NULL_TREE;
205 res_ops[2] = NULL_TREE;
206 *res_code = TREE_CODE (res_ops[0]);
207 return true;
211 /* Canonicalize operand order. */
212 bool canonicalized = false;
213 if (res_code->is_tree_code ()
214 && commutative_ternary_tree_code (*res_code)
215 && tree_swap_operands_p (res_ops[0], res_ops[1]))
217 std::swap (res_ops[0], res_ops[1]);
218 canonicalized = true;
221 code_helper res_code2;
222 tree res_ops2[3] = {};
223 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
224 *res_code, type,
225 res_ops[0], res_ops[1], res_ops[2]))
227 *res_code = res_code2;
228 res_ops[0] = res_ops2[0];
229 res_ops[1] = res_ops2[1];
230 res_ops[2] = res_ops2[2];
231 return true;
234 return canonicalized;
238 /* If in GIMPLE expressions with CODE go as single-rhs build
239 a GENERIC tree for that expression into *OP0. */
241 void
242 maybe_build_generic_op (enum tree_code code, tree type, tree *ops)
244 switch (code)
246 case REALPART_EXPR:
247 case IMAGPART_EXPR:
248 case VIEW_CONVERT_EXPR:
249 ops[0] = build1 (code, type, ops[0]);
250 break;
251 case BIT_FIELD_REF:
252 ops[0] = build3 (code, type, ops[0], ops[1], ops[2]);
253 ops[1] = ops[2] = NULL_TREE;
254 break;
255 default:;
259 tree (*mprts_hook) (code_helper, tree, tree *);
261 /* Try to build a call to FN with return type TYPE and the NARGS
262 arguments given in OPS. Return null if the target doesn't support
263 the function. */
265 static gcall *
266 build_call_internal (internal_fn fn, tree type, unsigned int nargs, tree *ops)
268 if (direct_internal_fn_p (fn))
270 tree_pair types = direct_internal_fn_types (fn, type, ops);
271 if (!direct_internal_fn_supported_p (fn, types, OPTIMIZE_FOR_BOTH))
272 return NULL;
274 return gimple_build_call_internal (fn, nargs, ops[0], ops[1], ops[2]);
277 /* Push the exploded expression described by RCODE, TYPE and OPS
278 as a statement to SEQ if necessary and return a gimple value
279 denoting the value of the expression. If RES is not NULL
280 then the result will be always RES and even gimple values are
281 pushed to SEQ. */
283 tree
284 maybe_push_res_to_seq (code_helper rcode, tree type, tree *ops,
285 gimple_seq *seq, tree res)
287 if (rcode.is_tree_code ())
289 if (!res
290 && gimple_simplified_result_is_gimple_val (rcode, ops))
291 return ops[0];
292 if (mprts_hook)
294 tree tem = mprts_hook (rcode, type, ops);
295 if (tem)
296 return tem;
298 if (!seq)
299 return NULL_TREE;
300 /* Play safe and do not allow abnormals to be mentioned in
301 newly created statements. */
302 if ((TREE_CODE (ops[0]) == SSA_NAME
303 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
304 || (ops[1]
305 && TREE_CODE (ops[1]) == SSA_NAME
306 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
307 || (ops[2]
308 && TREE_CODE (ops[2]) == SSA_NAME
309 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2]))
310 || (COMPARISON_CLASS_P (ops[0])
311 && ((TREE_CODE (TREE_OPERAND (ops[0], 0)) == SSA_NAME
312 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops[0],
313 0)))
314 || (TREE_CODE (TREE_OPERAND (ops[0], 1)) == SSA_NAME
315 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops[0],
316 1))))))
317 return NULL_TREE;
318 if (!res)
320 if (gimple_in_ssa_p (cfun))
321 res = make_ssa_name (type);
322 else
323 res = create_tmp_reg (type);
325 maybe_build_generic_op (rcode, type, ops);
326 gimple *new_stmt = gimple_build_assign (res, rcode,
327 ops[0], ops[1], ops[2]);
328 gimple_seq_add_stmt_without_update (seq, new_stmt);
329 return res;
331 else
333 if (!seq)
334 return NULL_TREE;
335 combined_fn fn = rcode;
336 /* Play safe and do not allow abnormals to be mentioned in
337 newly created statements. */
338 unsigned nargs;
339 for (nargs = 0; nargs < 3; ++nargs)
341 if (!ops[nargs])
342 break;
343 if (TREE_CODE (ops[nargs]) == SSA_NAME
344 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[nargs]))
345 return NULL_TREE;
347 gcc_assert (nargs != 0);
348 gcall *new_stmt = NULL;
349 if (internal_fn_p (fn))
351 /* Generate the given function if we can. */
352 internal_fn ifn = as_internal_fn (fn);
353 new_stmt = build_call_internal (ifn, type, nargs, ops);
354 if (!new_stmt)
355 return NULL_TREE;
357 else
359 /* Find the function we want to call. */
360 tree decl = builtin_decl_implicit (as_builtin_fn (fn));
361 if (!decl)
362 return NULL;
364 /* We can't and should not emit calls to non-const functions. */
365 if (!(flags_from_decl_or_type (decl) & ECF_CONST))
366 return NULL;
368 new_stmt = gimple_build_call (decl, nargs, ops[0], ops[1], ops[2]);
370 if (!res)
372 if (gimple_in_ssa_p (cfun))
373 res = make_ssa_name (type);
374 else
375 res = create_tmp_reg (type);
377 gimple_call_set_lhs (new_stmt, res);
378 gimple_seq_add_stmt_without_update (seq, new_stmt);
379 return res;
384 /* Public API overloads follow for operation being tree_code or
385 built_in_function and for one to three operands or arguments.
386 They return NULL_TREE if nothing could be simplified or
387 the resulting simplified value with parts pushed to SEQ.
388 If SEQ is NULL then if the simplification needs to create
389 new stmts it will fail. If VALUEIZE is non-NULL then all
390 SSA names will be valueized using that hook prior to
391 applying simplifications. */
393 /* Unary ops. */
395 tree
396 gimple_simplify (enum tree_code code, tree type,
397 tree op0,
398 gimple_seq *seq, tree (*valueize)(tree))
400 if (constant_for_folding (op0))
402 tree res = const_unop (code, type, op0);
403 if (res != NULL_TREE
404 && CONSTANT_CLASS_P (res))
405 return res;
408 code_helper rcode;
409 tree ops[3] = {};
410 if (!gimple_simplify (&rcode, ops, seq, valueize,
411 code, type, op0))
412 return NULL_TREE;
413 return maybe_push_res_to_seq (rcode, type, ops, seq);
416 /* Binary ops. */
418 tree
419 gimple_simplify (enum tree_code code, tree type,
420 tree op0, tree op1,
421 gimple_seq *seq, tree (*valueize)(tree))
423 if (constant_for_folding (op0) && constant_for_folding (op1))
425 tree res = const_binop (code, type, op0, op1);
426 if (res != NULL_TREE
427 && CONSTANT_CLASS_P (res))
428 return res;
431 /* Canonicalize operand order both for matching and fallback stmt
432 generation. */
433 if ((commutative_tree_code (code)
434 || TREE_CODE_CLASS (code) == tcc_comparison)
435 && tree_swap_operands_p (op0, op1))
437 std::swap (op0, op1);
438 if (TREE_CODE_CLASS (code) == tcc_comparison)
439 code = swap_tree_comparison (code);
442 code_helper rcode;
443 tree ops[3] = {};
444 if (!gimple_simplify (&rcode, ops, seq, valueize,
445 code, type, op0, op1))
446 return NULL_TREE;
447 return maybe_push_res_to_seq (rcode, type, ops, seq);
450 /* Ternary ops. */
452 tree
453 gimple_simplify (enum tree_code code, tree type,
454 tree op0, tree op1, tree op2,
455 gimple_seq *seq, tree (*valueize)(tree))
457 if (constant_for_folding (op0) && constant_for_folding (op1)
458 && constant_for_folding (op2))
460 tree res = fold_ternary/*_to_constant */ (code, type, op0, op1, op2);
461 if (res != NULL_TREE
462 && CONSTANT_CLASS_P (res))
463 return res;
466 /* Canonicalize operand order both for matching and fallback stmt
467 generation. */
468 if (commutative_ternary_tree_code (code)
469 && tree_swap_operands_p (op0, op1))
470 std::swap (op0, op1);
472 code_helper rcode;
473 tree ops[3] = {};
474 if (!gimple_simplify (&rcode, ops, seq, valueize,
475 code, type, op0, op1, op2))
476 return NULL_TREE;
477 return maybe_push_res_to_seq (rcode, type, ops, seq);
480 /* Builtin function with one argument. */
482 tree
483 gimple_simplify (enum built_in_function fn, tree type,
484 tree arg0,
485 gimple_seq *seq, tree (*valueize)(tree))
487 if (constant_for_folding (arg0))
489 tree res = fold_const_call (as_combined_fn (fn), type, arg0);
490 if (res && CONSTANT_CLASS_P (res))
491 return res;
494 code_helper rcode;
495 tree ops[3] = {};
496 if (!gimple_simplify (&rcode, ops, seq, valueize,
497 as_combined_fn (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 res = fold_const_call (as_combined_fn (fn), type, arg0, arg1);
513 if (res && CONSTANT_CLASS_P (res))
514 return res;
517 code_helper rcode;
518 tree ops[3] = {};
519 if (!gimple_simplify (&rcode, ops, seq, valueize,
520 as_combined_fn (fn), type, arg0, arg1))
521 return NULL_TREE;
522 return maybe_push_res_to_seq (rcode, type, ops, seq);
525 /* Builtin function with three arguments. */
527 tree
528 gimple_simplify (enum built_in_function fn, tree type,
529 tree arg0, tree arg1, tree arg2,
530 gimple_seq *seq, tree (*valueize)(tree))
532 if (constant_for_folding (arg0)
533 && constant_for_folding (arg1)
534 && constant_for_folding (arg2))
536 tree res = fold_const_call (as_combined_fn (fn), type, arg0, arg1, arg2);
537 if (res && CONSTANT_CLASS_P (res))
538 return res;
541 code_helper rcode;
542 tree ops[3] = {};
543 if (!gimple_simplify (&rcode, ops, seq, valueize,
544 as_combined_fn (fn), type, arg0, arg1, arg2))
545 return NULL_TREE;
546 return maybe_push_res_to_seq (rcode, type, ops, seq);
549 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
550 VALUEIZED to true if valueization changed OP. */
552 static inline tree
553 do_valueize (tree op, tree (*valueize)(tree), bool &valueized)
555 if (valueize && TREE_CODE (op) == SSA_NAME)
557 tree tem = valueize (op);
558 if (tem && tem != op)
560 op = tem;
561 valueized = true;
564 return op;
567 /* The main STMT based simplification entry. It is used by the fold_stmt
568 and the fold_stmt_to_constant APIs. */
570 bool
571 gimple_simplify (gimple *stmt,
572 code_helper *rcode, tree *ops,
573 gimple_seq *seq,
574 tree (*valueize)(tree), tree (*top_valueize)(tree))
576 switch (gimple_code (stmt))
578 case GIMPLE_ASSIGN:
580 enum tree_code code = gimple_assign_rhs_code (stmt);
581 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
582 switch (gimple_assign_rhs_class (stmt))
584 case GIMPLE_SINGLE_RHS:
585 if (code == REALPART_EXPR
586 || code == IMAGPART_EXPR
587 || code == VIEW_CONVERT_EXPR)
589 tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
590 bool valueized = false;
591 op0 = do_valueize (op0, top_valueize, valueized);
592 *rcode = code;
593 ops[0] = op0;
594 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
595 || valueized);
597 else if (code == BIT_FIELD_REF)
599 tree rhs1 = gimple_assign_rhs1 (stmt);
600 tree op0 = TREE_OPERAND (rhs1, 0);
601 bool valueized = false;
602 op0 = do_valueize (op0, top_valueize, valueized);
603 *rcode = code;
604 ops[0] = op0;
605 ops[1] = TREE_OPERAND (rhs1, 1);
606 ops[2] = TREE_OPERAND (rhs1, 2);
607 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
608 || valueized);
610 else if (code == SSA_NAME
611 && top_valueize)
613 tree op0 = gimple_assign_rhs1 (stmt);
614 tree valueized = top_valueize (op0);
615 if (!valueized || op0 == valueized)
616 return false;
617 ops[0] = valueized;
618 *rcode = TREE_CODE (op0);
619 return true;
621 break;
622 case GIMPLE_UNARY_RHS:
624 tree rhs1 = gimple_assign_rhs1 (stmt);
625 bool valueized = false;
626 rhs1 = do_valueize (rhs1, top_valueize, valueized);
627 *rcode = code;
628 ops[0] = rhs1;
629 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
630 || valueized);
632 case GIMPLE_BINARY_RHS:
634 tree rhs1 = gimple_assign_rhs1 (stmt);
635 tree rhs2 = gimple_assign_rhs2 (stmt);
636 bool valueized = false;
637 rhs1 = do_valueize (rhs1, top_valueize, valueized);
638 rhs2 = do_valueize (rhs2, top_valueize, valueized);
639 *rcode = code;
640 ops[0] = rhs1;
641 ops[1] = rhs2;
642 return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
643 || valueized);
645 case GIMPLE_TERNARY_RHS:
647 bool valueized = false;
648 tree rhs1 = gimple_assign_rhs1 (stmt);
649 /* If this is a [VEC_]COND_EXPR first try to simplify an
650 embedded GENERIC condition. */
651 if (code == COND_EXPR
652 || code == VEC_COND_EXPR)
654 if (COMPARISON_CLASS_P (rhs1))
656 tree lhs = TREE_OPERAND (rhs1, 0);
657 tree rhs = TREE_OPERAND (rhs1, 1);
658 lhs = do_valueize (lhs, top_valueize, valueized);
659 rhs = do_valueize (rhs, top_valueize, valueized);
660 code_helper rcode2 = TREE_CODE (rhs1);
661 tree ops2[3] = {};
662 ops2[0] = lhs;
663 ops2[1] = rhs;
664 if ((gimple_resimplify2 (seq, &rcode2, TREE_TYPE (rhs1),
665 ops2, valueize)
666 || valueized)
667 && rcode2.is_tree_code ())
669 valueized = true;
670 if (TREE_CODE_CLASS ((enum tree_code)rcode2)
671 == tcc_comparison)
672 rhs1 = build2 (rcode2, TREE_TYPE (rhs1),
673 ops2[0], ops2[1]);
674 else if (rcode2 == SSA_NAME
675 || rcode2 == INTEGER_CST
676 || rcode2 == VECTOR_CST)
677 rhs1 = ops2[0];
678 else
679 valueized = false;
683 tree rhs2 = gimple_assign_rhs2 (stmt);
684 tree rhs3 = gimple_assign_rhs3 (stmt);
685 rhs1 = do_valueize (rhs1, top_valueize, valueized);
686 rhs2 = do_valueize (rhs2, top_valueize, valueized);
687 rhs3 = do_valueize (rhs3, top_valueize, valueized);
688 *rcode = code;
689 ops[0] = rhs1;
690 ops[1] = rhs2;
691 ops[2] = rhs3;
692 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
693 || valueized);
695 default:
696 gcc_unreachable ();
698 break;
701 case GIMPLE_CALL:
702 /* ??? This way we can't simplify calls with side-effects. */
703 if (gimple_call_lhs (stmt) != NULL_TREE
704 && gimple_call_num_args (stmt) >= 1
705 && gimple_call_num_args (stmt) <= 3)
707 bool valueized = false;
708 if (gimple_call_internal_p (stmt))
709 *rcode = as_combined_fn (gimple_call_internal_fn (stmt));
710 else
712 tree fn = gimple_call_fn (stmt);
713 if (!fn)
714 return false;
716 fn = do_valueize (fn, top_valueize, valueized);
717 if (TREE_CODE (fn) != ADDR_EXPR
718 || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
719 return false;
721 tree decl = TREE_OPERAND (fn, 0);
722 if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL
723 || !gimple_builtin_call_types_compatible_p (stmt, decl))
724 return false;
726 *rcode = as_combined_fn (DECL_FUNCTION_CODE (decl));
729 tree type = TREE_TYPE (gimple_call_lhs (stmt));
730 for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
732 tree arg = gimple_call_arg (stmt, i);
733 ops[i] = do_valueize (arg, top_valueize, valueized);
735 switch (gimple_call_num_args (stmt))
737 case 1:
738 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
739 || valueized);
740 case 2:
741 return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
742 || valueized);
743 case 3:
744 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
745 || valueized);
746 default:
747 gcc_unreachable ();
750 break;
752 case GIMPLE_COND:
754 tree lhs = gimple_cond_lhs (stmt);
755 tree rhs = gimple_cond_rhs (stmt);
756 bool valueized = false;
757 lhs = do_valueize (lhs, top_valueize, valueized);
758 rhs = do_valueize (rhs, top_valueize, valueized);
759 *rcode = gimple_cond_code (stmt);
760 ops[0] = lhs;
761 ops[1] = rhs;
762 return (gimple_resimplify2 (seq, rcode,
763 boolean_type_node, ops, valueize)
764 || valueized);
767 default:
768 break;
771 return false;
775 /* Helper for the autogenerated code, valueize OP. */
777 inline tree
778 do_valueize (tree (*valueize)(tree), tree op)
780 if (valueize && TREE_CODE (op) == SSA_NAME)
781 return valueize (op);
782 return op;
785 /* Routine to determine if the types T1 and T2 are effectively
786 the same for GIMPLE. If T1 or T2 is not a type, the test
787 applies to their TREE_TYPE. */
789 static inline bool
790 types_match (tree t1, tree t2)
792 if (!TYPE_P (t1))
793 t1 = TREE_TYPE (t1);
794 if (!TYPE_P (t2))
795 t2 = TREE_TYPE (t2);
797 return types_compatible_p (t1, t2);
800 /* Return if T has a single use. For GIMPLE, we also allow any
801 non-SSA_NAME (ie constants) and zero uses to cope with uses
802 that aren't linked up yet. */
804 static inline bool
805 single_use (tree t)
807 return TREE_CODE (t) != SSA_NAME || has_zero_uses (t) || has_single_use (t);
810 /* Return true if math operations should be canonicalized,
811 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
813 static inline bool
814 canonicalize_math_p ()
816 return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;