PR c++/69164
[official-gcc.git] / gcc / gimple-match-head.c
blob3e6d15f1b3651682df4e1179202c5d6c6f5413e1
1 /* Preamble and helpers for the autogenerated gimple-match.c file.
2 Copyright (C) 2014-2016 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"
43 /* Forward declarations of the private auto-generated matchers.
44 They expect valueized operands in canonical order and do not
45 perform simplification of all-constant operands. */
46 static bool gimple_simplify (code_helper *, tree *,
47 gimple_seq *, tree (*)(tree),
48 code_helper, tree, tree);
49 static bool gimple_simplify (code_helper *, tree *,
50 gimple_seq *, tree (*)(tree),
51 code_helper, tree, tree, tree);
52 static bool gimple_simplify (code_helper *, tree *,
53 gimple_seq *, tree (*)(tree),
54 code_helper, tree, tree, tree, tree);
57 /* Return whether T is a constant that we'll dispatch to fold to
58 evaluate fully constant expressions. */
60 static inline bool
61 constant_for_folding (tree t)
63 return (CONSTANT_CLASS_P (t)
64 /* The following is only interesting to string builtins. */
65 || (TREE_CODE (t) == ADDR_EXPR
66 && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST));
70 /* Helper that matches and simplifies the toplevel result from
71 a gimple_simplify run (where we don't want to build
72 a stmt in case it's used in in-place folding). Replaces
73 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
74 result and returns whether any change was made. */
76 bool
77 gimple_resimplify1 (gimple_seq *seq,
78 code_helper *res_code, tree type, tree *res_ops,
79 tree (*valueize)(tree))
81 if (constant_for_folding (res_ops[0]))
83 tree tem = NULL_TREE;
84 if (res_code->is_tree_code ())
85 tem = const_unop (*res_code, type, res_ops[0]);
86 else
87 tem = fold_const_call (combined_fn (*res_code), type, res_ops[0]);
88 if (tem != NULL_TREE
89 && CONSTANT_CLASS_P (tem))
91 res_ops[0] = tem;
92 res_ops[1] = NULL_TREE;
93 res_ops[2] = NULL_TREE;
94 *res_code = TREE_CODE (res_ops[0]);
95 return true;
99 code_helper res_code2;
100 tree res_ops2[3] = {};
101 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
102 *res_code, type, res_ops[0]))
104 *res_code = res_code2;
105 res_ops[0] = res_ops2[0];
106 res_ops[1] = res_ops2[1];
107 res_ops[2] = res_ops2[2];
108 return true;
111 return false;
114 /* Helper that matches and simplifies the toplevel result from
115 a gimple_simplify run (where we don't want to build
116 a stmt in case it's used in in-place folding). Replaces
117 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
118 result and returns whether any change was made. */
120 bool
121 gimple_resimplify2 (gimple_seq *seq,
122 code_helper *res_code, tree type, tree *res_ops,
123 tree (*valueize)(tree))
125 if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1]))
127 tree tem = NULL_TREE;
128 if (res_code->is_tree_code ())
129 tem = const_binop (*res_code, type, res_ops[0], res_ops[1]);
130 else
131 tem = fold_const_call (combined_fn (*res_code), type,
132 res_ops[0], res_ops[1]);
133 if (tem != NULL_TREE
134 && CONSTANT_CLASS_P (tem))
136 res_ops[0] = tem;
137 res_ops[1] = NULL_TREE;
138 res_ops[2] = NULL_TREE;
139 *res_code = TREE_CODE (res_ops[0]);
140 return true;
144 /* Canonicalize operand order. */
145 bool canonicalized = false;
146 if (res_code->is_tree_code ()
147 && (TREE_CODE_CLASS ((enum tree_code) *res_code) == tcc_comparison
148 || commutative_tree_code (*res_code))
149 && tree_swap_operands_p (res_ops[0], res_ops[1], false))
151 std::swap (res_ops[0], res_ops[1]);
152 if (TREE_CODE_CLASS ((enum tree_code) *res_code) == tcc_comparison)
153 *res_code = swap_tree_comparison (*res_code);
154 canonicalized = true;
157 code_helper res_code2;
158 tree res_ops2[3] = {};
159 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
160 *res_code, type, res_ops[0], res_ops[1]))
162 *res_code = res_code2;
163 res_ops[0] = res_ops2[0];
164 res_ops[1] = res_ops2[1];
165 res_ops[2] = res_ops2[2];
166 return true;
169 return canonicalized;
172 /* Helper that matches and simplifies the toplevel result from
173 a gimple_simplify run (where we don't want to build
174 a stmt in case it's used in in-place folding). Replaces
175 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
176 result and returns whether any change was made. */
178 bool
179 gimple_resimplify3 (gimple_seq *seq,
180 code_helper *res_code, tree type, tree *res_ops,
181 tree (*valueize)(tree))
183 if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1])
184 && constant_for_folding (res_ops[2]))
186 tree tem = NULL_TREE;
187 if (res_code->is_tree_code ())
188 tem = fold_ternary/*_to_constant*/ (*res_code, type, res_ops[0],
189 res_ops[1], res_ops[2]);
190 else
191 tem = fold_const_call (combined_fn (*res_code), type,
192 res_ops[0], res_ops[1], res_ops[2]);
193 if (tem != NULL_TREE
194 && CONSTANT_CLASS_P (tem))
196 res_ops[0] = tem;
197 res_ops[1] = NULL_TREE;
198 res_ops[2] = NULL_TREE;
199 *res_code = TREE_CODE (res_ops[0]);
200 return true;
204 /* Canonicalize operand order. */
205 bool canonicalized = false;
206 if (res_code->is_tree_code ()
207 && commutative_ternary_tree_code (*res_code)
208 && tree_swap_operands_p (res_ops[0], res_ops[1], false))
210 std::swap (res_ops[0], res_ops[1]);
211 canonicalized = true;
214 code_helper res_code2;
215 tree res_ops2[3] = {};
216 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
217 *res_code, type,
218 res_ops[0], res_ops[1], res_ops[2]))
220 *res_code = res_code2;
221 res_ops[0] = res_ops2[0];
222 res_ops[1] = res_ops2[1];
223 res_ops[2] = res_ops2[2];
224 return true;
227 return canonicalized;
231 /* If in GIMPLE expressions with CODE go as single-rhs build
232 a GENERIC tree for that expression into *OP0. */
234 void
235 maybe_build_generic_op (enum tree_code code, tree type,
236 tree *op0, tree op1, tree op2)
238 switch (code)
240 case REALPART_EXPR:
241 case IMAGPART_EXPR:
242 case VIEW_CONVERT_EXPR:
243 *op0 = build1 (code, type, *op0);
244 break;
245 case BIT_FIELD_REF:
246 *op0 = build3 (code, type, *op0, op1, op2);
247 break;
248 default:;
252 tree (*mprts_hook) (code_helper, tree, tree *);
254 /* Try to build a call to FN with return type TYPE and the NARGS
255 arguments given in OPS. Return null if the target doesn't support
256 the function. */
258 static gcall *
259 build_call_internal (internal_fn fn, tree type, unsigned int nargs, tree *ops)
261 if (direct_internal_fn_p (fn))
263 tree_pair types = direct_internal_fn_types (fn, type, ops);
264 if (!direct_internal_fn_supported_p (fn, types, OPTIMIZE_FOR_BOTH))
265 return NULL;
267 return gimple_build_call_internal (fn, nargs, ops[0], ops[1], ops[2]);
270 /* Push the exploded expression described by RCODE, TYPE and OPS
271 as a statement to SEQ if necessary and return a gimple value
272 denoting the value of the expression. If RES is not NULL
273 then the result will be always RES and even gimple values are
274 pushed to SEQ. */
276 tree
277 maybe_push_res_to_seq (code_helper rcode, tree type, tree *ops,
278 gimple_seq *seq, tree res)
280 if (rcode.is_tree_code ())
282 if (!res
283 && gimple_simplified_result_is_gimple_val (rcode, ops))
284 return ops[0];
285 if (mprts_hook)
287 tree tem = mprts_hook (rcode, type, ops);
288 if (tem)
289 return tem;
291 if (!seq)
292 return NULL_TREE;
293 /* Play safe and do not allow abnormals to be mentioned in
294 newly created statements. */
295 if ((TREE_CODE (ops[0]) == SSA_NAME
296 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
297 || (ops[1]
298 && TREE_CODE (ops[1]) == SSA_NAME
299 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
300 || (ops[2]
301 && TREE_CODE (ops[2]) == SSA_NAME
302 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2]))
303 || (COMPARISON_CLASS_P (ops[0])
304 && ((TREE_CODE (TREE_OPERAND (ops[0], 0)) == SSA_NAME
305 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops[0],
306 0)))
307 || (TREE_CODE (TREE_OPERAND (ops[0], 1)) == SSA_NAME
308 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops[0],
309 1))))))
310 return NULL_TREE;
311 if (!res)
313 if (gimple_in_ssa_p (cfun))
314 res = make_ssa_name (type);
315 else
316 res = create_tmp_reg (type);
318 maybe_build_generic_op (rcode, type, &ops[0], ops[1], ops[2]);
319 gimple *new_stmt = gimple_build_assign (res, rcode,
320 ops[0], ops[1], ops[2]);
321 gimple_seq_add_stmt_without_update (seq, new_stmt);
322 return res;
324 else
326 if (!seq)
327 return NULL_TREE;
328 combined_fn fn = rcode;
329 /* Play safe and do not allow abnormals to be mentioned in
330 newly created statements. */
331 unsigned nargs;
332 for (nargs = 0; nargs < 3; ++nargs)
334 if (!ops[nargs])
335 break;
336 if (TREE_CODE (ops[nargs]) == SSA_NAME
337 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[nargs]))
338 return NULL_TREE;
340 gcc_assert (nargs != 0);
341 gcall *new_stmt = NULL;
342 if (internal_fn_p (fn))
344 /* Generate the given function if we can. */
345 internal_fn ifn = as_internal_fn (fn);
346 new_stmt = build_call_internal (ifn, type, nargs, ops);
347 if (!new_stmt)
348 return NULL_TREE;
350 else
352 /* Find the function we want to call. */
353 tree decl = builtin_decl_implicit (as_builtin_fn (fn));
354 if (!decl)
355 return NULL;
357 /* We can't and should not emit calls to non-const functions. */
358 if (!(flags_from_decl_or_type (decl) & ECF_CONST))
359 return NULL;
361 new_stmt = gimple_build_call (decl, nargs, ops[0], ops[1], ops[2]);
363 if (!res)
365 if (gimple_in_ssa_p (cfun))
366 res = make_ssa_name (type);
367 else
368 res = create_tmp_reg (type);
370 gimple_call_set_lhs (new_stmt, res);
371 gimple_seq_add_stmt_without_update (seq, new_stmt);
372 return res;
377 /* Public API overloads follow for operation being tree_code or
378 built_in_function and for one to three operands or arguments.
379 They return NULL_TREE if nothing could be simplified or
380 the resulting simplified value with parts pushed to SEQ.
381 If SEQ is NULL then if the simplification needs to create
382 new stmts it will fail. If VALUEIZE is non-NULL then all
383 SSA names will be valueized using that hook prior to
384 applying simplifications. */
386 /* Unary ops. */
388 tree
389 gimple_simplify (enum tree_code code, tree type,
390 tree op0,
391 gimple_seq *seq, tree (*valueize)(tree))
393 if (constant_for_folding (op0))
395 tree res = const_unop (code, type, op0);
396 if (res != NULL_TREE
397 && CONSTANT_CLASS_P (res))
398 return res;
401 code_helper rcode;
402 tree ops[3] = {};
403 if (!gimple_simplify (&rcode, ops, seq, valueize,
404 code, type, op0))
405 return NULL_TREE;
406 return maybe_push_res_to_seq (rcode, type, ops, seq);
409 /* Binary ops. */
411 tree
412 gimple_simplify (enum tree_code code, tree type,
413 tree op0, tree op1,
414 gimple_seq *seq, tree (*valueize)(tree))
416 if (constant_for_folding (op0) && constant_for_folding (op1))
418 tree res = const_binop (code, type, op0, op1);
419 if (res != NULL_TREE
420 && CONSTANT_CLASS_P (res))
421 return res;
424 /* Canonicalize operand order both for matching and fallback stmt
425 generation. */
426 if ((commutative_tree_code (code)
427 || TREE_CODE_CLASS (code) == tcc_comparison)
428 && tree_swap_operands_p (op0, op1, false))
430 std::swap (op0, op1);
431 if (TREE_CODE_CLASS (code) == tcc_comparison)
432 code = swap_tree_comparison (code);
435 code_helper rcode;
436 tree ops[3] = {};
437 if (!gimple_simplify (&rcode, ops, seq, valueize,
438 code, type, op0, op1))
439 return NULL_TREE;
440 return maybe_push_res_to_seq (rcode, type, ops, seq);
443 /* Ternary ops. */
445 tree
446 gimple_simplify (enum tree_code code, tree type,
447 tree op0, tree op1, tree op2,
448 gimple_seq *seq, tree (*valueize)(tree))
450 if (constant_for_folding (op0) && constant_for_folding (op1)
451 && constant_for_folding (op2))
453 tree res = fold_ternary/*_to_constant */ (code, type, op0, op1, op2);
454 if (res != NULL_TREE
455 && CONSTANT_CLASS_P (res))
456 return res;
459 /* Canonicalize operand order both for matching and fallback stmt
460 generation. */
461 if (commutative_ternary_tree_code (code)
462 && tree_swap_operands_p (op0, op1, false))
463 std::swap (op0, op1);
465 code_helper rcode;
466 tree ops[3] = {};
467 if (!gimple_simplify (&rcode, ops, seq, valueize,
468 code, type, op0, op1, op2))
469 return NULL_TREE;
470 return maybe_push_res_to_seq (rcode, type, ops, seq);
473 /* Builtin function with one argument. */
475 tree
476 gimple_simplify (enum built_in_function fn, tree type,
477 tree arg0,
478 gimple_seq *seq, tree (*valueize)(tree))
480 if (constant_for_folding (arg0))
482 tree res = fold_const_call (as_combined_fn (fn), type, arg0);
483 if (res && CONSTANT_CLASS_P (res))
484 return res;
487 code_helper rcode;
488 tree ops[3] = {};
489 if (!gimple_simplify (&rcode, ops, seq, valueize,
490 as_combined_fn (fn), type, arg0))
491 return NULL_TREE;
492 return maybe_push_res_to_seq (rcode, type, ops, seq);
495 /* Builtin function with two arguments. */
497 tree
498 gimple_simplify (enum built_in_function fn, tree type,
499 tree arg0, tree arg1,
500 gimple_seq *seq, tree (*valueize)(tree))
502 if (constant_for_folding (arg0)
503 && constant_for_folding (arg1))
505 tree res = fold_const_call (as_combined_fn (fn), type, arg0, arg1);
506 if (res && CONSTANT_CLASS_P (res))
507 return res;
510 code_helper rcode;
511 tree ops[3] = {};
512 if (!gimple_simplify (&rcode, ops, seq, valueize,
513 as_combined_fn (fn), type, arg0, arg1))
514 return NULL_TREE;
515 return maybe_push_res_to_seq (rcode, type, ops, seq);
518 /* Builtin function with three arguments. */
520 tree
521 gimple_simplify (enum built_in_function fn, tree type,
522 tree arg0, tree arg1, tree arg2,
523 gimple_seq *seq, tree (*valueize)(tree))
525 if (constant_for_folding (arg0)
526 && constant_for_folding (arg1)
527 && constant_for_folding (arg2))
529 tree res = fold_const_call (as_combined_fn (fn), type, arg0, arg1, arg2);
530 if (res && CONSTANT_CLASS_P (res))
531 return res;
534 code_helper rcode;
535 tree ops[3] = {};
536 if (!gimple_simplify (&rcode, ops, seq, valueize,
537 as_combined_fn (fn), type, arg0, arg1, arg2))
538 return NULL_TREE;
539 return maybe_push_res_to_seq (rcode, type, ops, seq);
542 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
543 VALUEIZED to true if valueization changed OP. */
545 static inline tree
546 do_valueize (tree op, tree (*valueize)(tree), bool &valueized)
548 if (valueize && TREE_CODE (op) == SSA_NAME)
550 tree tem = valueize (op);
551 if (tem && tem != op)
553 op = tem;
554 valueized = true;
557 return op;
560 /* The main STMT based simplification entry. It is used by the fold_stmt
561 and the fold_stmt_to_constant APIs. */
563 bool
564 gimple_simplify (gimple *stmt,
565 code_helper *rcode, tree *ops,
566 gimple_seq *seq,
567 tree (*valueize)(tree), tree (*top_valueize)(tree))
569 switch (gimple_code (stmt))
571 case GIMPLE_ASSIGN:
573 enum tree_code code = gimple_assign_rhs_code (stmt);
574 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
575 switch (gimple_assign_rhs_class (stmt))
577 case GIMPLE_SINGLE_RHS:
578 if (code == REALPART_EXPR
579 || code == IMAGPART_EXPR
580 || code == VIEW_CONVERT_EXPR)
582 tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
583 bool valueized = false;
584 op0 = do_valueize (op0, top_valueize, valueized);
585 *rcode = code;
586 ops[0] = op0;
587 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
588 || valueized);
590 else if (code == BIT_FIELD_REF)
592 tree rhs1 = gimple_assign_rhs1 (stmt);
593 tree op0 = TREE_OPERAND (rhs1, 0);
594 bool valueized = false;
595 op0 = do_valueize (op0, top_valueize, valueized);
596 *rcode = code;
597 ops[0] = op0;
598 ops[1] = TREE_OPERAND (rhs1, 1);
599 ops[2] = TREE_OPERAND (rhs1, 2);
600 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
601 || valueized);
603 else if (code == SSA_NAME
604 && top_valueize)
606 tree op0 = gimple_assign_rhs1 (stmt);
607 tree valueized = top_valueize (op0);
608 if (!valueized || op0 == valueized)
609 return false;
610 ops[0] = valueized;
611 *rcode = TREE_CODE (op0);
612 return true;
614 break;
615 case GIMPLE_UNARY_RHS:
617 tree rhs1 = gimple_assign_rhs1 (stmt);
618 bool valueized = false;
619 rhs1 = do_valueize (rhs1, top_valueize, valueized);
620 *rcode = code;
621 ops[0] = rhs1;
622 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
623 || valueized);
625 case GIMPLE_BINARY_RHS:
627 tree rhs1 = gimple_assign_rhs1 (stmt);
628 tree rhs2 = gimple_assign_rhs2 (stmt);
629 bool valueized = false;
630 rhs1 = do_valueize (rhs1, top_valueize, valueized);
631 rhs2 = do_valueize (rhs2, top_valueize, valueized);
632 *rcode = code;
633 ops[0] = rhs1;
634 ops[1] = rhs2;
635 return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
636 || valueized);
638 case GIMPLE_TERNARY_RHS:
640 bool valueized = false;
641 tree rhs1 = gimple_assign_rhs1 (stmt);
642 /* If this is a [VEC_]COND_EXPR first try to simplify an
643 embedded GENERIC condition. */
644 if (code == COND_EXPR
645 || code == VEC_COND_EXPR)
647 if (COMPARISON_CLASS_P (rhs1))
649 tree lhs = TREE_OPERAND (rhs1, 0);
650 tree rhs = TREE_OPERAND (rhs1, 1);
651 lhs = do_valueize (lhs, top_valueize, valueized);
652 rhs = do_valueize (rhs, top_valueize, valueized);
653 code_helper rcode2 = TREE_CODE (rhs1);
654 tree ops2[3] = {};
655 ops2[0] = lhs;
656 ops2[1] = rhs;
657 if ((gimple_resimplify2 (seq, &rcode2, TREE_TYPE (rhs1),
658 ops2, valueize)
659 || valueized)
660 && rcode2.is_tree_code ())
662 valueized = true;
663 if (TREE_CODE_CLASS ((enum tree_code)rcode2)
664 == tcc_comparison)
665 rhs1 = build2 (rcode2, TREE_TYPE (rhs1),
666 ops2[0], ops2[1]);
667 else if (rcode2 == SSA_NAME
668 || rcode2 == INTEGER_CST
669 || rcode2 == VECTOR_CST)
670 rhs1 = ops2[0];
671 else
672 valueized = false;
676 tree rhs2 = gimple_assign_rhs2 (stmt);
677 tree rhs3 = gimple_assign_rhs3 (stmt);
678 rhs1 = do_valueize (rhs1, top_valueize, valueized);
679 rhs2 = do_valueize (rhs2, top_valueize, valueized);
680 rhs3 = do_valueize (rhs3, top_valueize, valueized);
681 *rcode = code;
682 ops[0] = rhs1;
683 ops[1] = rhs2;
684 ops[2] = rhs3;
685 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
686 || valueized);
688 default:
689 gcc_unreachable ();
691 break;
694 case GIMPLE_CALL:
695 /* ??? This way we can't simplify calls with side-effects. */
696 if (gimple_call_lhs (stmt) != NULL_TREE
697 && gimple_call_num_args (stmt) >= 1
698 && gimple_call_num_args (stmt) <= 3)
700 bool valueized = false;
701 if (gimple_call_internal_p (stmt))
702 *rcode = as_combined_fn (gimple_call_internal_fn (stmt));
703 else
705 tree fn = gimple_call_fn (stmt);
706 if (!fn)
707 return false;
709 fn = do_valueize (fn, top_valueize, valueized);
710 if (TREE_CODE (fn) != ADDR_EXPR
711 || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
712 return false;
714 tree decl = TREE_OPERAND (fn, 0);
715 if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL
716 || !gimple_builtin_call_types_compatible_p (stmt, decl))
717 return false;
719 *rcode = as_combined_fn (DECL_FUNCTION_CODE (decl));
722 tree type = TREE_TYPE (gimple_call_lhs (stmt));
723 for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
725 tree arg = gimple_call_arg (stmt, i);
726 ops[i] = do_valueize (arg, top_valueize, valueized);
728 switch (gimple_call_num_args (stmt))
730 case 1:
731 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
732 || valueized);
733 case 2:
734 return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
735 || valueized);
736 case 3:
737 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
738 || valueized);
739 default:
740 gcc_unreachable ();
743 break;
745 case GIMPLE_COND:
747 tree lhs = gimple_cond_lhs (stmt);
748 tree rhs = gimple_cond_rhs (stmt);
749 bool valueized = false;
750 lhs = do_valueize (lhs, top_valueize, valueized);
751 rhs = do_valueize (rhs, top_valueize, valueized);
752 *rcode = gimple_cond_code (stmt);
753 ops[0] = lhs;
754 ops[1] = rhs;
755 return (gimple_resimplify2 (seq, rcode,
756 boolean_type_node, ops, valueize)
757 || valueized);
760 default:
761 break;
764 return false;
768 /* Helper for the autogenerated code, valueize OP. */
770 inline tree
771 do_valueize (tree (*valueize)(tree), tree op)
773 if (valueize && TREE_CODE (op) == SSA_NAME)
774 return valueize (op);
775 return op;
778 /* Routine to determine if the types T1 and T2 are effectively
779 the same for GIMPLE. If T1 or T2 is not a type, the test
780 applies to their TREE_TYPE. */
782 static inline bool
783 types_match (tree t1, tree t2)
785 if (!TYPE_P (t1))
786 t1 = TREE_TYPE (t1);
787 if (!TYPE_P (t2))
788 t2 = TREE_TYPE (t2);
790 return types_compatible_p (t1, t2);
793 /* Return if T has a single use. For GIMPLE, we also allow any
794 non-SSA_NAME (ie constants) and zero uses to cope with uses
795 that aren't linked up yet. */
797 static inline bool
798 single_use (tree t)
800 return TREE_CODE (t) != SSA_NAME || has_zero_uses (t) || has_single_use (t);
803 /* Return true if math operations should be canonicalized,
804 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
806 static inline bool
807 canonicalize_math_p ()
809 return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;