Fix cygwin performance loss on linpack.
[official-gcc.git] / gcc / gimple-match-head.c
blobbdc1f9828644a3793aa1a3a6840beea53112c1de
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 "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))
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 return NULL_TREE;
304 if (!res)
306 if (gimple_in_ssa_p (cfun))
307 res = make_ssa_name (type);
308 else
309 res = create_tmp_reg (type);
311 maybe_build_generic_op (rcode, type, &ops[0], ops[1], ops[2]);
312 gimple *new_stmt = gimple_build_assign (res, rcode,
313 ops[0], ops[1], ops[2]);
314 gimple_seq_add_stmt_without_update (seq, new_stmt);
315 return res;
317 else
319 if (!seq)
320 return NULL_TREE;
321 combined_fn fn = rcode;
322 /* Play safe and do not allow abnormals to be mentioned in
323 newly created statements. */
324 unsigned nargs;
325 for (nargs = 0; nargs < 3; ++nargs)
327 if (!ops[nargs])
328 break;
329 if (TREE_CODE (ops[nargs]) == SSA_NAME
330 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[nargs]))
331 return NULL_TREE;
333 gcc_assert (nargs != 0);
334 gcall *new_stmt = NULL;
335 if (internal_fn_p (fn))
337 /* Generate the given function if we can. */
338 internal_fn ifn = as_internal_fn (fn);
339 new_stmt = build_call_internal (ifn, type, nargs, ops);
340 if (!new_stmt)
341 return NULL_TREE;
343 else
345 /* Find the function we want to call. */
346 tree decl = builtin_decl_implicit (as_builtin_fn (fn));
347 if (!decl)
348 return NULL;
350 /* We can't and should not emit calls to non-const functions. */
351 if (!(flags_from_decl_or_type (decl) & ECF_CONST))
352 return NULL;
354 new_stmt = gimple_build_call (decl, nargs, ops[0], ops[1], ops[2]);
356 if (!res)
358 if (gimple_in_ssa_p (cfun))
359 res = make_ssa_name (type);
360 else
361 res = create_tmp_reg (type);
363 gimple_call_set_lhs (new_stmt, res);
364 gimple_seq_add_stmt_without_update (seq, new_stmt);
365 return res;
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. */
379 /* Unary ops. */
381 tree
382 gimple_simplify (enum tree_code code, tree type,
383 tree op0,
384 gimple_seq *seq, tree (*valueize)(tree))
386 if (constant_for_folding (op0))
388 tree res = const_unop (code, type, op0);
389 if (res != NULL_TREE
390 && CONSTANT_CLASS_P (res))
391 return res;
394 code_helper rcode;
395 tree ops[3] = {};
396 if (!gimple_simplify (&rcode, ops, seq, valueize,
397 code, type, op0))
398 return NULL_TREE;
399 return maybe_push_res_to_seq (rcode, type, ops, seq);
402 /* Binary ops. */
404 tree
405 gimple_simplify (enum tree_code code, tree type,
406 tree op0, tree op1,
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);
412 if (res != NULL_TREE
413 && CONSTANT_CLASS_P (res))
414 return res;
417 /* Canonicalize operand order both for matching and fallback stmt
418 generation. */
419 if ((commutative_tree_code (code)
420 || TREE_CODE_CLASS (code) == tcc_comparison)
421 && tree_swap_operands_p (op0, op1, false))
423 std::swap (op0, op1);
424 if (TREE_CODE_CLASS (code) == tcc_comparison)
425 code = swap_tree_comparison (code);
428 code_helper rcode;
429 tree ops[3] = {};
430 if (!gimple_simplify (&rcode, ops, seq, valueize,
431 code, type, op0, op1))
432 return NULL_TREE;
433 return maybe_push_res_to_seq (rcode, type, ops, seq);
436 /* Ternary ops. */
438 tree
439 gimple_simplify (enum tree_code code, tree type,
440 tree op0, tree op1, tree op2,
441 gimple_seq *seq, tree (*valueize)(tree))
443 if (constant_for_folding (op0) && constant_for_folding (op1)
444 && constant_for_folding (op2))
446 tree res = fold_ternary/*_to_constant */ (code, type, op0, op1, op2);
447 if (res != NULL_TREE
448 && CONSTANT_CLASS_P (res))
449 return res;
452 /* Canonicalize operand order both for matching and fallback stmt
453 generation. */
454 if (commutative_ternary_tree_code (code)
455 && tree_swap_operands_p (op0, op1, false))
456 std::swap (op0, op1);
458 code_helper rcode;
459 tree ops[3] = {};
460 if (!gimple_simplify (&rcode, ops, seq, valueize,
461 code, type, op0, op1, op2))
462 return NULL_TREE;
463 return maybe_push_res_to_seq (rcode, type, ops, seq);
466 /* Builtin function with one argument. */
468 tree
469 gimple_simplify (enum built_in_function fn, tree type,
470 tree arg0,
471 gimple_seq *seq, tree (*valueize)(tree))
473 if (constant_for_folding (arg0))
475 tree res = fold_const_call (as_combined_fn (fn), type, arg0);
476 if (res && CONSTANT_CLASS_P (res))
477 return res;
480 code_helper rcode;
481 tree ops[3] = {};
482 if (!gimple_simplify (&rcode, ops, seq, valueize,
483 as_combined_fn (fn), type, arg0))
484 return NULL_TREE;
485 return maybe_push_res_to_seq (rcode, type, ops, seq);
488 /* Builtin function with two arguments. */
490 tree
491 gimple_simplify (enum built_in_function fn, tree type,
492 tree arg0, tree arg1,
493 gimple_seq *seq, tree (*valueize)(tree))
495 if (constant_for_folding (arg0)
496 && constant_for_folding (arg1))
498 tree res = fold_const_call (as_combined_fn (fn), type, arg0, arg1);
499 if (res && CONSTANT_CLASS_P (res))
500 return res;
503 code_helper rcode;
504 tree ops[3] = {};
505 if (!gimple_simplify (&rcode, ops, seq, valueize,
506 as_combined_fn (fn), type, arg0, arg1))
507 return NULL_TREE;
508 return maybe_push_res_to_seq (rcode, type, ops, seq);
511 /* Builtin function with three arguments. */
513 tree
514 gimple_simplify (enum built_in_function fn, tree type,
515 tree arg0, tree arg1, tree arg2,
516 gimple_seq *seq, tree (*valueize)(tree))
518 if (constant_for_folding (arg0)
519 && constant_for_folding (arg1)
520 && constant_for_folding (arg2))
522 tree res = fold_const_call (as_combined_fn (fn), type, arg0, arg1, arg2);
523 if (res && CONSTANT_CLASS_P (res))
524 return res;
527 code_helper rcode;
528 tree ops[3] = {};
529 if (!gimple_simplify (&rcode, ops, seq, valueize,
530 as_combined_fn (fn), type, arg0, arg1, arg2))
531 return NULL_TREE;
532 return maybe_push_res_to_seq (rcode, type, ops, seq);
535 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
536 VALUEIZED to true if valueization changed OP. */
538 static inline tree
539 do_valueize (tree op, tree (*valueize)(tree), bool &valueized)
541 if (valueize && TREE_CODE (op) == SSA_NAME)
543 tree tem = valueize (op);
544 if (tem && tem != op)
546 op = tem;
547 valueized = true;
550 return op;
553 /* The main STMT based simplification entry. It is used by the fold_stmt
554 and the fold_stmt_to_constant APIs. */
556 bool
557 gimple_simplify (gimple *stmt,
558 code_helper *rcode, tree *ops,
559 gimple_seq *seq,
560 tree (*valueize)(tree), tree (*top_valueize)(tree))
562 switch (gimple_code (stmt))
564 case GIMPLE_ASSIGN:
566 enum tree_code code = gimple_assign_rhs_code (stmt);
567 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
568 switch (gimple_assign_rhs_class (stmt))
570 case GIMPLE_SINGLE_RHS:
571 if (code == REALPART_EXPR
572 || code == IMAGPART_EXPR
573 || code == VIEW_CONVERT_EXPR)
575 tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
576 bool valueized = false;
577 op0 = do_valueize (op0, top_valueize, valueized);
578 *rcode = code;
579 ops[0] = op0;
580 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
581 || valueized);
583 else if (code == BIT_FIELD_REF)
585 tree rhs1 = gimple_assign_rhs1 (stmt);
586 tree op0 = TREE_OPERAND (rhs1, 0);
587 bool valueized = false;
588 op0 = do_valueize (op0, top_valueize, valueized);
589 *rcode = code;
590 ops[0] = op0;
591 ops[1] = TREE_OPERAND (rhs1, 1);
592 ops[2] = TREE_OPERAND (rhs1, 2);
593 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
594 || valueized);
596 else if (code == SSA_NAME
597 && top_valueize)
599 tree op0 = gimple_assign_rhs1 (stmt);
600 tree valueized = top_valueize (op0);
601 if (!valueized || op0 == valueized)
602 return false;
603 ops[0] = valueized;
604 *rcode = TREE_CODE (op0);
605 return true;
607 break;
608 case GIMPLE_UNARY_RHS:
610 tree rhs1 = gimple_assign_rhs1 (stmt);
611 bool valueized = false;
612 rhs1 = do_valueize (rhs1, top_valueize, valueized);
613 *rcode = code;
614 ops[0] = rhs1;
615 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
616 || valueized);
618 case GIMPLE_BINARY_RHS:
620 tree rhs1 = gimple_assign_rhs1 (stmt);
621 tree rhs2 = gimple_assign_rhs2 (stmt);
622 bool valueized = false;
623 rhs1 = do_valueize (rhs1, top_valueize, valueized);
624 rhs2 = do_valueize (rhs2, top_valueize, valueized);
625 *rcode = code;
626 ops[0] = rhs1;
627 ops[1] = rhs2;
628 return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
629 || valueized);
631 case GIMPLE_TERNARY_RHS:
633 bool valueized = false;
634 tree rhs1 = gimple_assign_rhs1 (stmt);
635 /* If this is a [VEC_]COND_EXPR first try to simplify an
636 embedded GENERIC condition. */
637 if (code == COND_EXPR
638 || code == VEC_COND_EXPR)
640 if (COMPARISON_CLASS_P (rhs1))
642 tree lhs = TREE_OPERAND (rhs1, 0);
643 tree rhs = TREE_OPERAND (rhs1, 1);
644 lhs = do_valueize (lhs, top_valueize, valueized);
645 rhs = do_valueize (rhs, top_valueize, valueized);
646 code_helper rcode2 = TREE_CODE (rhs1);
647 tree ops2[3] = {};
648 ops2[0] = lhs;
649 ops2[1] = rhs;
650 if ((gimple_resimplify2 (seq, &rcode2, TREE_TYPE (rhs1),
651 ops2, valueize)
652 || valueized)
653 && rcode2.is_tree_code ())
655 valueized = true;
656 if (TREE_CODE_CLASS ((enum tree_code)rcode2)
657 == tcc_comparison)
658 rhs1 = build2 (rcode2, TREE_TYPE (rhs1),
659 ops2[0], ops2[1]);
660 else if (rcode2 == SSA_NAME
661 || rcode2 == INTEGER_CST
662 || rcode2 == VECTOR_CST)
663 rhs1 = ops2[0];
664 else
665 valueized = false;
669 tree rhs2 = gimple_assign_rhs2 (stmt);
670 tree rhs3 = gimple_assign_rhs3 (stmt);
671 rhs1 = do_valueize (rhs1, top_valueize, valueized);
672 rhs2 = do_valueize (rhs2, top_valueize, valueized);
673 rhs3 = do_valueize (rhs3, top_valueize, valueized);
674 *rcode = code;
675 ops[0] = rhs1;
676 ops[1] = rhs2;
677 ops[2] = rhs3;
678 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
679 || valueized);
681 default:
682 gcc_unreachable ();
684 break;
687 case GIMPLE_CALL:
688 /* ??? This way we can't simplify calls with side-effects. */
689 if (gimple_call_lhs (stmt) != NULL_TREE
690 && gimple_call_num_args (stmt) >= 1
691 && gimple_call_num_args (stmt) <= 3)
693 bool valueized = false;
694 if (gimple_call_internal_p (stmt))
695 *rcode = as_combined_fn (gimple_call_internal_fn (stmt));
696 else
698 tree fn = gimple_call_fn (stmt);
699 if (!fn)
700 return false;
702 fn = do_valueize (fn, top_valueize, valueized);
703 if (TREE_CODE (fn) != ADDR_EXPR
704 || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
705 return false;
707 tree decl = TREE_OPERAND (fn, 0);
708 if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL
709 || !gimple_builtin_call_types_compatible_p (stmt, decl))
710 return false;
712 *rcode = as_combined_fn (DECL_FUNCTION_CODE (decl));
715 tree type = TREE_TYPE (gimple_call_lhs (stmt));
716 for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
718 tree arg = gimple_call_arg (stmt, i);
719 ops[i] = do_valueize (arg, top_valueize, valueized);
721 switch (gimple_call_num_args (stmt))
723 case 1:
724 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
725 || valueized);
726 case 2:
727 return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
728 || valueized);
729 case 3:
730 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
731 || valueized);
732 default:
733 gcc_unreachable ();
736 break;
738 case GIMPLE_COND:
740 tree lhs = gimple_cond_lhs (stmt);
741 tree rhs = gimple_cond_rhs (stmt);
742 bool valueized = false;
743 lhs = do_valueize (lhs, top_valueize, valueized);
744 rhs = do_valueize (rhs, top_valueize, valueized);
745 *rcode = gimple_cond_code (stmt);
746 ops[0] = lhs;
747 ops[1] = rhs;
748 return (gimple_resimplify2 (seq, rcode,
749 boolean_type_node, ops, valueize)
750 || valueized);
753 default:
754 break;
757 return false;
761 /* Helper for the autogenerated code, valueize OP. */
763 inline tree
764 do_valueize (tree (*valueize)(tree), tree op)
766 if (valueize && TREE_CODE (op) == SSA_NAME)
767 return valueize (op);
768 return op;
771 /* Routine to determine if the types T1 and T2 are effectively
772 the same for GIMPLE. If T1 or T2 is not a type, the test
773 applies to their TREE_TYPE. */
775 static inline bool
776 types_match (tree t1, tree t2)
778 if (!TYPE_P (t1))
779 t1 = TREE_TYPE (t1);
780 if (!TYPE_P (t2))
781 t2 = TREE_TYPE (t2);
783 return types_compatible_p (t1, t2);
786 /* Return if T has a single use. For GIMPLE, we also allow any
787 non-SSA_NAME (ie constants) and zero uses to cope with uses
788 that aren't linked up yet. */
790 static inline bool
791 single_use (tree t)
793 return TREE_CODE (t) != SSA_NAME || has_zero_uses (t) || has_single_use (t);
796 /* Return true if math operations should be canonicalized,
797 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
799 static inline bool
800 canonicalize_math_p ()
802 return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;