]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/gimple-match-head.c
gimple-match-head.c (gimple_simplify): Allow VECTOR_CSTs in simplifying VEC_COND_EXPR...
[thirdparty/gcc.git] / gcc / gimple-match-head.c
1 /* Preamble and helpers for the autogenerated gimple-match.c file.
2 Copyright (C) 2014-2015 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
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.
10
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.
15
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/>. */
19
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"
52
53
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);
66
67
68 /* Return whether T is a constant that we'll dispatch to fold to
69 evaluate fully constant expressions. */
70
71 static inline bool
72 constant_for_folding (tree t)
73 {
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));
78 }
79
80
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. */
86
87 bool
88 gimple_resimplify1 (gimple_seq *seq,
89 code_helper *res_code, tree type, tree *res_ops,
90 tree (*valueize)(tree))
91 {
92 if (constant_for_folding (res_ops[0]))
93 {
94 tree tem = NULL_TREE;
95 if (res_code->is_tree_code ())
96 tem = const_unop (*res_code, type, res_ops[0]);
97 else
98 {
99 tree decl = builtin_decl_implicit (*res_code);
100 if (decl)
101 {
102 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 1, false);
103 if (tem)
104 {
105 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
106 STRIP_NOPS (tem);
107 tem = fold_convert (type, tem);
108 }
109 }
110 }
111 if (tem != NULL_TREE
112 && CONSTANT_CLASS_P (tem))
113 {
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;
119 }
120 }
121
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]))
126 {
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;
132 }
133
134 return false;
135 }
136
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. */
142
143 bool
144 gimple_resimplify2 (gimple_seq *seq,
145 code_helper *res_code, tree type, tree *res_ops,
146 tree (*valueize)(tree))
147 {
148 if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1]))
149 {
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
154 {
155 tree decl = builtin_decl_implicit (*res_code);
156 if (decl)
157 {
158 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 2, false);
159 if (tem)
160 {
161 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
162 STRIP_NOPS (tem);
163 tem = fold_convert (type, tem);
164 }
165 }
166 }
167 if (tem != NULL_TREE
168 && CONSTANT_CLASS_P (tem))
169 {
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;
175 }
176 }
177
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))
184 {
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;
189 }
190
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]))
195 {
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;
201 }
202
203 return canonicalized;
204 }
205
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. */
211
212 bool
213 gimple_resimplify3 (gimple_seq *seq,
214 code_helper *res_code, tree type, tree *res_ops,
215 tree (*valueize)(tree))
216 {
217 if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1])
218 && constant_for_folding (res_ops[2]))
219 {
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
225 {
226 tree decl = builtin_decl_implicit (*res_code);
227 if (decl)
228 {
229 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 3, false);
230 if (tem)
231 {
232 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
233 STRIP_NOPS (tem);
234 tem = fold_convert (type, tem);
235 }
236 }
237 }
238 if (tem != NULL_TREE
239 && CONSTANT_CLASS_P (tem))
240 {
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;
246 }
247 }
248
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))
254 {
255 std::swap (res_ops[0], res_ops[1]);
256 canonicalized = true;
257 }
258
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]))
264 {
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;
270 }
271
272 return canonicalized;
273 }
274
275
276 /* If in GIMPLE expressions with CODE go as single-rhs build
277 a GENERIC tree for that expression into *OP0. */
278
279 void
280 maybe_build_generic_op (enum tree_code code, tree type,
281 tree *op0, tree op1, tree op2)
282 {
283 switch (code)
284 {
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:;
294 }
295 }
296
297 tree (*mprts_hook) (code_helper, tree, tree *);
298
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. */
304
305 tree
306 maybe_push_res_to_seq (code_helper rcode, tree type, tree *ops,
307 gimple_seq *seq, tree res)
308 {
309 if (rcode.is_tree_code ())
310 {
311 if (!res
312 && gimple_simplified_result_is_gimple_val (rcode, ops))
313 return ops[0];
314 if (mprts_hook)
315 {
316 tree tem = mprts_hook (rcode, type, ops);
317 if (tem)
318 return tem;
319 }
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 {
335 if (gimple_in_ssa_p (cfun))
336 res = make_ssa_name (type);
337 else
338 res = create_tmp_reg (type);
339 }
340 maybe_build_generic_op (rcode, type, &ops[0], ops[1], ops[2]);
341 gimple *new_stmt = gimple_build_assign (res, rcode,
342 ops[0], ops[1], ops[2]);
343 gimple_seq_add_stmt_without_update (seq, new_stmt);
344 return res;
345 }
346 else
347 {
348 if (!seq)
349 return NULL_TREE;
350 tree decl = builtin_decl_implicit (rcode);
351 if (!decl)
352 return NULL_TREE;
353 /* We can't and should not emit calls to non-const functions. */
354 if (!(flags_from_decl_or_type (decl) & ECF_CONST))
355 return NULL_TREE;
356 /* Play safe and do not allow abnormals to be mentioned in
357 newly created statements. */
358 unsigned nargs;
359 for (nargs = 0; nargs < 3; ++nargs)
360 {
361 if (!ops[nargs])
362 break;
363 if (TREE_CODE (ops[nargs]) == SSA_NAME
364 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[nargs]))
365 return NULL_TREE;
366 }
367 gcc_assert (nargs != 0);
368 if (!res)
369 {
370 if (gimple_in_ssa_p (cfun))
371 res = make_ssa_name (type);
372 else
373 res = create_tmp_reg (type);
374 }
375 gimple *new_stmt = gimple_build_call (decl, nargs, ops[0], ops[1], ops[2]);
376 gimple_call_set_lhs (new_stmt, res);
377 gimple_seq_add_stmt_without_update (seq, new_stmt);
378 return res;
379 }
380 }
381
382
383 /* Public API overloads follow for operation being tree_code or
384 built_in_function and for one to three operands or arguments.
385 They return NULL_TREE if nothing could be simplified or
386 the resulting simplified value with parts pushed to SEQ.
387 If SEQ is NULL then if the simplification needs to create
388 new stmts it will fail. If VALUEIZE is non-NULL then all
389 SSA names will be valueized using that hook prior to
390 applying simplifications. */
391
392 /* Unary ops. */
393
394 tree
395 gimple_simplify (enum tree_code code, tree type,
396 tree op0,
397 gimple_seq *seq, tree (*valueize)(tree))
398 {
399 if (constant_for_folding (op0))
400 {
401 tree res = const_unop (code, type, op0);
402 if (res != NULL_TREE
403 && CONSTANT_CLASS_P (res))
404 return res;
405 }
406
407 code_helper rcode;
408 tree ops[3] = {};
409 if (!gimple_simplify (&rcode, ops, seq, valueize,
410 code, type, op0))
411 return NULL_TREE;
412 return maybe_push_res_to_seq (rcode, type, ops, seq);
413 }
414
415 /* Binary ops. */
416
417 tree
418 gimple_simplify (enum tree_code code, tree type,
419 tree op0, tree op1,
420 gimple_seq *seq, tree (*valueize)(tree))
421 {
422 if (constant_for_folding (op0) && constant_for_folding (op1))
423 {
424 tree res = const_binop (code, type, op0, op1);
425 if (res != NULL_TREE
426 && CONSTANT_CLASS_P (res))
427 return res;
428 }
429
430 /* Canonicalize operand order both for matching and fallback stmt
431 generation. */
432 if ((commutative_tree_code (code)
433 || TREE_CODE_CLASS (code) == tcc_comparison)
434 && tree_swap_operands_p (op0, op1, false))
435 {
436 std::swap (op0, op1);
437 if (TREE_CODE_CLASS (code) == tcc_comparison)
438 code = swap_tree_comparison (code);
439 }
440
441 code_helper rcode;
442 tree ops[3] = {};
443 if (!gimple_simplify (&rcode, ops, seq, valueize,
444 code, type, op0, op1))
445 return NULL_TREE;
446 return maybe_push_res_to_seq (rcode, type, ops, seq);
447 }
448
449 /* Ternary ops. */
450
451 tree
452 gimple_simplify (enum tree_code code, tree type,
453 tree op0, tree op1, tree op2,
454 gimple_seq *seq, tree (*valueize)(tree))
455 {
456 if (constant_for_folding (op0) && constant_for_folding (op1)
457 && constant_for_folding (op2))
458 {
459 tree res = fold_ternary/*_to_constant */ (code, type, op0, op1, op2);
460 if (res != NULL_TREE
461 && CONSTANT_CLASS_P (res))
462 return res;
463 }
464
465 /* Canonicalize operand order both for matching and fallback stmt
466 generation. */
467 if (commutative_ternary_tree_code (code)
468 && tree_swap_operands_p (op0, op1, false))
469 std::swap (op0, op1);
470
471 code_helper rcode;
472 tree ops[3] = {};
473 if (!gimple_simplify (&rcode, ops, seq, valueize,
474 code, type, op0, op1, op2))
475 return NULL_TREE;
476 return maybe_push_res_to_seq (rcode, type, ops, seq);
477 }
478
479 /* Builtin function with one argument. */
480
481 tree
482 gimple_simplify (enum built_in_function fn, tree type,
483 tree arg0,
484 gimple_seq *seq, tree (*valueize)(tree))
485 {
486 if (constant_for_folding (arg0))
487 {
488 tree decl = builtin_decl_implicit (fn);
489 if (decl)
490 {
491 tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, &arg0, 1, false);
492 if (res)
493 {
494 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
495 STRIP_NOPS (res);
496 res = fold_convert (type, res);
497 if (CONSTANT_CLASS_P (res))
498 return res;
499 }
500 }
501 }
502
503 code_helper rcode;
504 tree ops[3] = {};
505 if (!gimple_simplify (&rcode, ops, seq, valueize,
506 fn, type, arg0))
507 return NULL_TREE;
508 return maybe_push_res_to_seq (rcode, type, ops, seq);
509 }
510
511 /* Builtin function with two arguments. */
512
513 tree
514 gimple_simplify (enum built_in_function fn, tree type,
515 tree arg0, tree arg1,
516 gimple_seq *seq, tree (*valueize)(tree))
517 {
518 if (constant_for_folding (arg0)
519 && constant_for_folding (arg1))
520 {
521 tree decl = builtin_decl_implicit (fn);
522 if (decl)
523 {
524 tree args[2];
525 args[0] = arg0;
526 args[1] = arg1;
527 tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, args, 2, false);
528 if (res)
529 {
530 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
531 STRIP_NOPS (res);
532 res = fold_convert (type, res);
533 if (CONSTANT_CLASS_P (res))
534 return res;
535 }
536 }
537 }
538
539 code_helper rcode;
540 tree ops[3] = {};
541 if (!gimple_simplify (&rcode, ops, seq, valueize,
542 fn, type, arg0, arg1))
543 return NULL_TREE;
544 return maybe_push_res_to_seq (rcode, type, ops, seq);
545 }
546
547 /* Builtin function with three arguments. */
548
549 tree
550 gimple_simplify (enum built_in_function fn, tree type,
551 tree arg0, tree arg1, tree arg2,
552 gimple_seq *seq, tree (*valueize)(tree))
553 {
554 if (constant_for_folding (arg0)
555 && constant_for_folding (arg1)
556 && constant_for_folding (arg2))
557 {
558 tree decl = builtin_decl_implicit (fn);
559 if (decl)
560 {
561 tree args[3];
562 args[0] = arg0;
563 args[1] = arg1;
564 args[2] = arg2;
565 tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, args, 3, false);
566 if (res)
567 {
568 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
569 STRIP_NOPS (res);
570 res = fold_convert (type, res);
571 if (CONSTANT_CLASS_P (res))
572 return res;
573 }
574 }
575 }
576
577 code_helper rcode;
578 tree ops[3] = {};
579 if (!gimple_simplify (&rcode, ops, seq, valueize,
580 fn, type, arg0, arg1, arg2))
581 return NULL_TREE;
582 return maybe_push_res_to_seq (rcode, type, ops, seq);
583 }
584
585 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
586 VALUEIZED to true if valueization changed OP. */
587
588 static inline tree
589 do_valueize (tree op, tree (*valueize)(tree), bool &valueized)
590 {
591 if (valueize && TREE_CODE (op) == SSA_NAME)
592 {
593 tree tem = valueize (op);
594 if (tem && tem != op)
595 {
596 op = tem;
597 valueized = true;
598 }
599 }
600 return op;
601 }
602
603 /* The main STMT based simplification entry. It is used by the fold_stmt
604 and the fold_stmt_to_constant APIs. */
605
606 bool
607 gimple_simplify (gimple *stmt,
608 code_helper *rcode, tree *ops,
609 gimple_seq *seq,
610 tree (*valueize)(tree), tree (*top_valueize)(tree))
611 {
612 switch (gimple_code (stmt))
613 {
614 case GIMPLE_ASSIGN:
615 {
616 enum tree_code code = gimple_assign_rhs_code (stmt);
617 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
618 switch (gimple_assign_rhs_class (stmt))
619 {
620 case GIMPLE_SINGLE_RHS:
621 if (code == REALPART_EXPR
622 || code == IMAGPART_EXPR
623 || code == VIEW_CONVERT_EXPR)
624 {
625 tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
626 bool valueized = false;
627 op0 = do_valueize (op0, top_valueize, valueized);
628 *rcode = code;
629 ops[0] = op0;
630 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
631 || valueized);
632 }
633 else if (code == BIT_FIELD_REF)
634 {
635 tree rhs1 = gimple_assign_rhs1 (stmt);
636 tree op0 = TREE_OPERAND (rhs1, 0);
637 bool valueized = false;
638 op0 = do_valueize (op0, top_valueize, valueized);
639 *rcode = code;
640 ops[0] = op0;
641 ops[1] = TREE_OPERAND (rhs1, 1);
642 ops[2] = TREE_OPERAND (rhs1, 2);
643 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
644 || valueized);
645 }
646 else if (code == SSA_NAME
647 && top_valueize)
648 {
649 tree op0 = gimple_assign_rhs1 (stmt);
650 tree valueized = top_valueize (op0);
651 if (!valueized || op0 == valueized)
652 return false;
653 ops[0] = valueized;
654 *rcode = TREE_CODE (op0);
655 return true;
656 }
657 break;
658 case GIMPLE_UNARY_RHS:
659 {
660 tree rhs1 = gimple_assign_rhs1 (stmt);
661 bool valueized = false;
662 rhs1 = do_valueize (rhs1, top_valueize, valueized);
663 *rcode = code;
664 ops[0] = rhs1;
665 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
666 || valueized);
667 }
668 case GIMPLE_BINARY_RHS:
669 {
670 tree rhs1 = gimple_assign_rhs1 (stmt);
671 tree rhs2 = gimple_assign_rhs2 (stmt);
672 bool valueized = false;
673 rhs1 = do_valueize (rhs1, top_valueize, valueized);
674 rhs2 = do_valueize (rhs2, top_valueize, valueized);
675 *rcode = code;
676 ops[0] = rhs1;
677 ops[1] = rhs2;
678 return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
679 || valueized);
680 }
681 case GIMPLE_TERNARY_RHS:
682 {
683 bool valueized = false;
684 tree rhs1 = gimple_assign_rhs1 (stmt);
685 /* If this is a [VEC_]COND_EXPR first try to simplify an
686 embedded GENERIC condition. */
687 if (code == COND_EXPR
688 || code == VEC_COND_EXPR)
689 {
690 if (COMPARISON_CLASS_P (rhs1))
691 {
692 tree lhs = TREE_OPERAND (rhs1, 0);
693 tree rhs = TREE_OPERAND (rhs1, 1);
694 lhs = do_valueize (lhs, top_valueize, valueized);
695 rhs = do_valueize (rhs, top_valueize, valueized);
696 code_helper rcode2 = TREE_CODE (rhs1);
697 tree ops2[3] = {};
698 ops2[0] = lhs;
699 ops2[1] = rhs;
700 if ((gimple_resimplify2 (seq, &rcode2, TREE_TYPE (rhs1),
701 ops2, valueize)
702 || valueized)
703 && rcode2.is_tree_code ())
704 {
705 valueized = true;
706 if (TREE_CODE_CLASS ((enum tree_code)rcode2)
707 == tcc_comparison)
708 rhs1 = build2 (rcode2, TREE_TYPE (rhs1),
709 ops2[0], ops2[1]);
710 else if (rcode2 == SSA_NAME
711 || rcode2 == INTEGER_CST
712 || rcode2 == VECTOR_CST)
713 rhs1 = ops2[0];
714 else
715 valueized = false;
716 }
717 }
718 }
719 tree rhs2 = gimple_assign_rhs2 (stmt);
720 tree rhs3 = gimple_assign_rhs3 (stmt);
721 rhs1 = do_valueize (rhs1, top_valueize, valueized);
722 rhs2 = do_valueize (rhs2, top_valueize, valueized);
723 rhs3 = do_valueize (rhs3, top_valueize, valueized);
724 *rcode = code;
725 ops[0] = rhs1;
726 ops[1] = rhs2;
727 ops[2] = rhs3;
728 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
729 || valueized);
730 }
731 default:
732 gcc_unreachable ();
733 }
734 break;
735 }
736
737 case GIMPLE_CALL:
738 /* ??? This way we can't simplify calls with side-effects. */
739 if (gimple_call_lhs (stmt) != NULL_TREE
740 && gimple_call_num_args (stmt) >= 1
741 && gimple_call_num_args (stmt) <= 3)
742 {
743 tree fn = gimple_call_fn (stmt);
744 /* ??? Internal function support missing. */
745 if (!fn)
746 return false;
747 bool valueized = false;
748 fn = do_valueize (fn, top_valueize, valueized);
749 if (TREE_CODE (fn) != ADDR_EXPR
750 || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
751 return false;
752
753 tree decl = TREE_OPERAND (fn, 0);
754 if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL
755 || !builtin_decl_implicit (DECL_FUNCTION_CODE (decl))
756 || !gimple_builtin_call_types_compatible_p (stmt, decl))
757 return false;
758
759 tree type = TREE_TYPE (gimple_call_lhs (stmt));
760 *rcode = DECL_FUNCTION_CODE (decl);
761 for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
762 {
763 tree arg = gimple_call_arg (stmt, i);
764 ops[i] = do_valueize (arg, top_valueize, valueized);
765 }
766 switch (gimple_call_num_args (stmt))
767 {
768 case 1:
769 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
770 || valueized);
771 case 2:
772 return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
773 || valueized);
774 case 3:
775 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
776 || valueized);
777 default:
778 gcc_unreachable ();
779 }
780 }
781 break;
782
783 case GIMPLE_COND:
784 {
785 tree lhs = gimple_cond_lhs (stmt);
786 tree rhs = gimple_cond_rhs (stmt);
787 bool valueized = false;
788 lhs = do_valueize (lhs, top_valueize, valueized);
789 rhs = do_valueize (rhs, top_valueize, valueized);
790 *rcode = gimple_cond_code (stmt);
791 ops[0] = lhs;
792 ops[1] = rhs;
793 return (gimple_resimplify2 (seq, rcode,
794 boolean_type_node, ops, valueize)
795 || valueized);
796 }
797
798 default:
799 break;
800 }
801
802 return false;
803 }
804
805
806 /* Helper for the autogenerated code, valueize OP. */
807
808 inline tree
809 do_valueize (tree (*valueize)(tree), tree op)
810 {
811 if (valueize && TREE_CODE (op) == SSA_NAME)
812 return valueize (op);
813 return op;
814 }
815
816 /* Routine to determine if the types T1 and T2 are effectively
817 the same for GIMPLE. If T1 or T2 is not a type, the test
818 applies to their TREE_TYPE. */
819
820 static inline bool
821 types_match (tree t1, tree t2)
822 {
823 if (!TYPE_P (t1))
824 t1 = TREE_TYPE (t1);
825 if (!TYPE_P (t2))
826 t2 = TREE_TYPE (t2);
827
828 return types_compatible_p (t1, t2);
829 }
830
831 /* Return if T has a single use. For GIMPLE, we also allow any
832 non-SSA_NAME (ie constants) and zero uses to cope with uses
833 that aren't linked up yet. */
834
835 static inline bool
836 single_use (tree t)
837 {
838 return TREE_CODE (t) != SSA_NAME || has_zero_uses (t) || has_single_use (t);
839 }
840
841 /* Return true if math operations should be canonicalized,
842 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
843
844 static inline bool
845 canonicalize_math_p ()
846 {
847 return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;
848 }