]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/gimple-match-head.c
combine.c (make_compound_operation): Remove checks for PLUS/MINUS rtx type.
[thirdparty/gcc.git] / gcc / gimple-match-head.c
CommitLineData
3d2cf79f 1/* Preamble and helpers for the autogenerated gimple-match.c file.
5624e564 2 Copyright (C) 2014-2015 Free Software Foundation, Inc.
3d2cf79f
RB
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along 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"
40e23961
MC
23#include "tm.h"
24#include "hash-set.h"
25#include "machmode.h"
26#include "vec.h"
27#include "double-int.h"
28#include "input.h"
29#include "alias.h"
30#include "symtab.h"
31#include "options.h"
32#include "wide-int.h"
33#include "inchash.h"
3d2cf79f 34#include "tree.h"
40e23961 35#include "fold-const.h"
3d2cf79f
RB
36#include "stringpool.h"
37#include "stor-layout.h"
38#include "flags.h"
3d2cf79f
RB
39#include "hard-reg-set.h"
40#include "function.h"
60393bbc 41#include "predict.h"
3d2cf79f
RB
42#include "basic-block.h"
43#include "tree-ssa-alias.h"
44#include "internal-fn.h"
45#include "gimple-expr.h"
46#include "is-a.h"
47#include "gimple.h"
48#include "gimple-ssa.h"
49#include "tree-ssanames.h"
50#include "gimple-fold.h"
51#include "gimple-iterator.h"
36566b39
PK
52#include "hashtab.h"
53#include "rtl.h"
54#include "statistics.h"
55#include "real.h"
56#include "fixed-value.h"
57#include "insn-config.h"
58#include "expmed.h"
59#include "dojump.h"
60#include "explow.h"
61#include "calls.h"
62#include "emit-rtl.h"
63#include "varasm.h"
64#include "stmt.h"
3d2cf79f
RB
65#include "expr.h"
66#include "tree-dfa.h"
67#include "builtins.h"
68#include "tree-phinodes.h"
69#include "ssa-iterators.h"
70#include "dumpfile.h"
71#include "gimple-match.h"
72
73
74/* Forward declarations of the private auto-generated matchers.
75 They expect valueized operands in canonical order and do not
76 perform simplification of all-constant operands. */
77static bool gimple_simplify (code_helper *, tree *,
78 gimple_seq *, tree (*)(tree),
79 code_helper, tree, tree);
80static bool gimple_simplify (code_helper *, tree *,
81 gimple_seq *, tree (*)(tree),
82 code_helper, tree, tree, tree);
83static bool gimple_simplify (code_helper *, tree *,
84 gimple_seq *, tree (*)(tree),
85 code_helper, tree, tree, tree, tree);
86
87
88/* Return whether T is a constant that we'll dispatch to fold to
89 evaluate fully constant expressions. */
90
91static inline bool
92constant_for_folding (tree t)
93{
94 return (CONSTANT_CLASS_P (t)
95 /* The following is only interesting to string builtins. */
96 || (TREE_CODE (t) == ADDR_EXPR
97 && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST));
98}
99
100
101/* Helper that matches and simplifies the toplevel result from
102 a gimple_simplify run (where we don't want to build
103 a stmt in case it's used in in-place folding). Replaces
104 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
105 result and returns whether any change was made. */
106
107static bool
108gimple_resimplify1 (gimple_seq *seq,
109 code_helper *res_code, tree type, tree *res_ops,
110 tree (*valueize)(tree))
111{
112 if (constant_for_folding (res_ops[0]))
113 {
114 tree tem = NULL_TREE;
115 if (res_code->is_tree_code ())
8006f46b 116 tem = const_unop (*res_code, type, res_ops[0]);
3d2cf79f
RB
117 else
118 {
119 tree decl = builtin_decl_implicit (*res_code);
120 if (decl)
121 {
122 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 1, false);
123 if (tem)
124 {
125 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
126 STRIP_NOPS (tem);
127 tem = fold_convert (type, tem);
128 }
129 }
130 }
131 if (tem != NULL_TREE
132 && CONSTANT_CLASS_P (tem))
133 {
134 res_ops[0] = tem;
135 res_ops[1] = NULL_TREE;
136 res_ops[2] = NULL_TREE;
137 *res_code = TREE_CODE (res_ops[0]);
138 return true;
139 }
140 }
141
142 code_helper res_code2;
143 tree res_ops2[3] = {};
144 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
145 *res_code, type, res_ops[0]))
146 {
147 *res_code = res_code2;
148 res_ops[0] = res_ops2[0];
149 res_ops[1] = res_ops2[1];
150 res_ops[2] = res_ops2[2];
151 return true;
152 }
153
154 return false;
155}
156
157/* Helper that matches and simplifies the toplevel result from
158 a gimple_simplify run (where we don't want to build
159 a stmt in case it's used in in-place folding). Replaces
160 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
161 result and returns whether any change was made. */
162
163static bool
164gimple_resimplify2 (gimple_seq *seq,
165 code_helper *res_code, tree type, tree *res_ops,
166 tree (*valueize)(tree))
167{
168 if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1]))
169 {
170 tree tem = NULL_TREE;
171 if (res_code->is_tree_code ())
8006f46b 172 tem = const_binop (*res_code, type, res_ops[0], res_ops[1]);
3d2cf79f
RB
173 else
174 {
175 tree decl = builtin_decl_implicit (*res_code);
176 if (decl)
177 {
178 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 2, false);
179 if (tem)
180 {
181 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
182 STRIP_NOPS (tem);
183 tem = fold_convert (type, tem);
184 }
185 }
186 }
187 if (tem != NULL_TREE
188 && CONSTANT_CLASS_P (tem))
189 {
190 res_ops[0] = tem;
191 res_ops[1] = NULL_TREE;
192 res_ops[2] = NULL_TREE;
193 *res_code = TREE_CODE (res_ops[0]);
194 return true;
195 }
196 }
197
198 /* Canonicalize operand order. */
199 bool canonicalized = false;
200 if (res_code->is_tree_code ()
201 && (TREE_CODE_CLASS ((enum tree_code) *res_code) == tcc_comparison
202 || commutative_tree_code (*res_code))
203 && tree_swap_operands_p (res_ops[0], res_ops[1], false))
204 {
205 tree tem = res_ops[0];
206 res_ops[0] = res_ops[1];
207 res_ops[1] = tem;
208 if (TREE_CODE_CLASS ((enum tree_code) *res_code) == tcc_comparison)
209 *res_code = swap_tree_comparison (*res_code);
210 canonicalized = true;
211 }
212
213 code_helper res_code2;
214 tree res_ops2[3] = {};
215 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
216 *res_code, type, res_ops[0], res_ops[1]))
217 {
218 *res_code = res_code2;
219 res_ops[0] = res_ops2[0];
220 res_ops[1] = res_ops2[1];
221 res_ops[2] = res_ops2[2];
222 return true;
223 }
224
225 return canonicalized;
226}
227
228/* Helper that matches and simplifies the toplevel result from
229 a gimple_simplify run (where we don't want to build
230 a stmt in case it's used in in-place folding). Replaces
231 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
232 result and returns whether any change was made. */
233
234static bool
235gimple_resimplify3 (gimple_seq *seq,
236 code_helper *res_code, tree type, tree *res_ops,
237 tree (*valueize)(tree))
238{
239 if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1])
240 && constant_for_folding (res_ops[2]))
241 {
242 tree tem = NULL_TREE;
243 if (res_code->is_tree_code ())
244 tem = fold_ternary/*_to_constant*/ (*res_code, type, res_ops[0],
245 res_ops[1], res_ops[2]);
246 else
247 {
248 tree decl = builtin_decl_implicit (*res_code);
249 if (decl)
250 {
251 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 3, false);
252 if (tem)
253 {
254 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
255 STRIP_NOPS (tem);
256 tem = fold_convert (type, tem);
257 }
258 }
259 }
260 if (tem != NULL_TREE
261 && CONSTANT_CLASS_P (tem))
262 {
263 res_ops[0] = tem;
264 res_ops[1] = NULL_TREE;
265 res_ops[2] = NULL_TREE;
266 *res_code = TREE_CODE (res_ops[0]);
267 return true;
268 }
269 }
270
271 /* Canonicalize operand order. */
272 bool canonicalized = false;
273 if (res_code->is_tree_code ()
274 && commutative_ternary_tree_code (*res_code)
275 && tree_swap_operands_p (res_ops[0], res_ops[1], false))
276 {
277 tree tem = res_ops[0];
278 res_ops[0] = res_ops[1];
279 res_ops[1] = tem;
280 canonicalized = true;
281 }
282
283 code_helper res_code2;
284 tree res_ops2[3] = {};
285 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
286 *res_code, type,
287 res_ops[0], res_ops[1], res_ops[2]))
288 {
289 *res_code = res_code2;
290 res_ops[0] = res_ops2[0];
291 res_ops[1] = res_ops2[1];
292 res_ops[2] = res_ops2[2];
293 return true;
294 }
295
296 return canonicalized;
297}
298
299
300/* If in GIMPLE expressions with CODE go as single-rhs build
301 a GENERIC tree for that expression into *OP0. */
302
303void
304maybe_build_generic_op (enum tree_code code, tree type,
305 tree *op0, tree op1, tree op2)
306{
307 switch (code)
308 {
309 case REALPART_EXPR:
310 case IMAGPART_EXPR:
311 case VIEW_CONVERT_EXPR:
312 *op0 = build1 (code, type, *op0);
313 break;
314 case BIT_FIELD_REF:
315 *op0 = build3 (code, type, *op0, op1, op2);
316 break;
317 default:;
318 }
319}
320
321/* Push the exploded expression described by RCODE, TYPE and OPS
322 as a statement to SEQ if necessary and return a gimple value
323 denoting the value of the expression. If RES is not NULL
324 then the result will be always RES and even gimple values are
325 pushed to SEQ. */
326
327tree
328maybe_push_res_to_seq (code_helper rcode, tree type, tree *ops,
329 gimple_seq *seq, tree res)
330{
331 if (rcode.is_tree_code ())
332 {
333 if (!res
334 && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
335 || ((tree_code) rcode) == ADDR_EXPR)
336 && is_gimple_val (ops[0]))
337 return ops[0];
338 if (!seq)
339 return NULL_TREE;
340 /* Play safe and do not allow abnormals to be mentioned in
341 newly created statements. */
342 if ((TREE_CODE (ops[0]) == SSA_NAME
343 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
344 || (ops[1]
345 && TREE_CODE (ops[1]) == SSA_NAME
346 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
347 || (ops[2]
348 && TREE_CODE (ops[2]) == SSA_NAME
349 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
350 return NULL_TREE;
351 if (!res)
b731b390 352 res = make_ssa_name (type);
3d2cf79f 353 maybe_build_generic_op (rcode, type, &ops[0], ops[1], ops[2]);
0d0e4a03
JJ
354 gimple new_stmt = gimple_build_assign (res, rcode,
355 ops[0], ops[1], ops[2]);
3d2cf79f
RB
356 gimple_seq_add_stmt_without_update (seq, new_stmt);
357 return res;
358 }
359 else
360 {
361 if (!seq)
362 return NULL_TREE;
363 tree decl = builtin_decl_implicit (rcode);
364 if (!decl)
365 return NULL_TREE;
366 unsigned nargs = type_num_arguments (TREE_TYPE (decl));
367 gcc_assert (nargs <= 3);
368 /* Play safe and do not allow abnormals to be mentioned in
369 newly created statements. */
370 if ((TREE_CODE (ops[0]) == SSA_NAME
371 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
372 || (nargs >= 2
373 && TREE_CODE (ops[1]) == SSA_NAME
374 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
375 || (nargs == 3
376 && TREE_CODE (ops[2]) == SSA_NAME
377 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
378 return NULL_TREE;
379 if (!res)
b731b390 380 res = make_ssa_name (type);
3d2cf79f
RB
381 gimple new_stmt = gimple_build_call (decl, nargs, ops[0], ops[1], ops[2]);
382 gimple_call_set_lhs (new_stmt, res);
383 gimple_seq_add_stmt_without_update (seq, new_stmt);
384 return res;
385 }
386}
387
388
389/* Public API overloads follow for operation being tree_code or
390 built_in_function and for one to three operands or arguments.
391 They return NULL_TREE if nothing could be simplified or
392 the resulting simplified value with parts pushed to SEQ.
393 If SEQ is NULL then if the simplification needs to create
394 new stmts it will fail. If VALUEIZE is non-NULL then all
395 SSA names will be valueized using that hook prior to
396 applying simplifications. */
397
398/* Unary ops. */
399
400tree
401gimple_simplify (enum tree_code code, tree type,
402 tree op0,
403 gimple_seq *seq, tree (*valueize)(tree))
404{
405 if (constant_for_folding (op0))
406 {
8006f46b 407 tree res = const_unop (code, type, op0);
3d2cf79f
RB
408 if (res != NULL_TREE
409 && CONSTANT_CLASS_P (res))
410 return res;
411 }
412
413 code_helper rcode;
414 tree ops[3] = {};
415 if (!gimple_simplify (&rcode, ops, seq, valueize,
416 code, type, op0))
417 return NULL_TREE;
418 return maybe_push_res_to_seq (rcode, type, ops, seq);
419}
420
421/* Binary ops. */
422
423tree
424gimple_simplify (enum tree_code code, tree type,
425 tree op0, tree op1,
426 gimple_seq *seq, tree (*valueize)(tree))
427{
428 if (constant_for_folding (op0) && constant_for_folding (op1))
429 {
8006f46b 430 tree res = const_binop (code, type, op0, op1);
3d2cf79f
RB
431 if (res != NULL_TREE
432 && CONSTANT_CLASS_P (res))
433 return res;
434 }
435
436 /* Canonicalize operand order both for matching and fallback stmt
437 generation. */
438 if ((commutative_tree_code (code)
439 || TREE_CODE_CLASS (code) == tcc_comparison)
440 && tree_swap_operands_p (op0, op1, false))
441 {
442 tree tem = op0;
443 op0 = op1;
444 op1 = tem;
445 if (TREE_CODE_CLASS (code) == tcc_comparison)
446 code = swap_tree_comparison (code);
447 }
448
449 code_helper rcode;
450 tree ops[3] = {};
451 if (!gimple_simplify (&rcode, ops, seq, valueize,
452 code, type, op0, op1))
453 return NULL_TREE;
454 return maybe_push_res_to_seq (rcode, type, ops, seq);
455}
456
457/* Ternary ops. */
458
459tree
460gimple_simplify (enum tree_code code, tree type,
461 tree op0, tree op1, tree op2,
462 gimple_seq *seq, tree (*valueize)(tree))
463{
464 if (constant_for_folding (op0) && constant_for_folding (op1)
465 && constant_for_folding (op2))
466 {
467 tree res = fold_ternary/*_to_constant */ (code, type, op0, op1, op2);
468 if (res != NULL_TREE
469 && CONSTANT_CLASS_P (res))
470 return res;
471 }
472
473 /* Canonicalize operand order both for matching and fallback stmt
474 generation. */
475 if (commutative_ternary_tree_code (code)
476 && tree_swap_operands_p (op0, op1, false))
477 {
478 tree tem = op0;
479 op0 = op1;
480 op1 = tem;
481 }
482
483 code_helper rcode;
484 tree ops[3] = {};
485 if (!gimple_simplify (&rcode, ops, seq, valueize,
486 code, type, op0, op1, op2))
487 return NULL_TREE;
488 return maybe_push_res_to_seq (rcode, type, ops, seq);
489}
490
491/* Builtin function with one argument. */
492
493tree
494gimple_simplify (enum built_in_function fn, tree type,
495 tree arg0,
496 gimple_seq *seq, tree (*valueize)(tree))
497{
498 if (constant_for_folding (arg0))
499 {
500 tree decl = builtin_decl_implicit (fn);
501 if (decl)
502 {
503 tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, &arg0, 1, false);
504 if (res)
505 {
506 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
507 STRIP_NOPS (res);
508 res = fold_convert (type, res);
509 if (CONSTANT_CLASS_P (res))
510 return res;
511 }
512 }
513 }
514
515 code_helper rcode;
516 tree ops[3] = {};
517 if (!gimple_simplify (&rcode, ops, seq, valueize,
518 fn, type, arg0))
519 return NULL_TREE;
520 return maybe_push_res_to_seq (rcode, type, ops, seq);
521}
522
523/* Builtin function with two arguments. */
524
525tree
526gimple_simplify (enum built_in_function fn, tree type,
527 tree arg0, tree arg1,
528 gimple_seq *seq, tree (*valueize)(tree))
529{
530 if (constant_for_folding (arg0)
531 && constant_for_folding (arg1))
532 {
533 tree decl = builtin_decl_implicit (fn);
534 if (decl)
535 {
536 tree args[2];
537 args[0] = arg0;
538 args[1] = arg1;
539 tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, args, 2, false);
540 if (res)
541 {
542 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
543 STRIP_NOPS (res);
544 res = fold_convert (type, res);
545 if (CONSTANT_CLASS_P (res))
546 return res;
547 }
548 }
549 }
550
551 code_helper rcode;
552 tree ops[3] = {};
553 if (!gimple_simplify (&rcode, ops, seq, valueize,
554 fn, type, arg0, arg1))
555 return NULL_TREE;
556 return maybe_push_res_to_seq (rcode, type, ops, seq);
557}
558
559/* Builtin function with three arguments. */
560
561tree
562gimple_simplify (enum built_in_function fn, tree type,
563 tree arg0, tree arg1, tree arg2,
564 gimple_seq *seq, tree (*valueize)(tree))
565{
566 if (constant_for_folding (arg0)
567 && constant_for_folding (arg1)
568 && constant_for_folding (arg2))
569 {
570 tree decl = builtin_decl_implicit (fn);
571 if (decl)
572 {
573 tree args[3];
574 args[0] = arg0;
575 args[1] = arg1;
576 args[2] = arg2;
577 tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, args, 3, false);
578 if (res)
579 {
580 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
581 STRIP_NOPS (res);
582 res = fold_convert (type, res);
583 if (CONSTANT_CLASS_P (res))
584 return res;
585 }
586 }
587 }
588
589 code_helper rcode;
590 tree ops[3] = {};
591 if (!gimple_simplify (&rcode, ops, seq, valueize,
592 fn, type, arg0, arg1, arg2))
593 return NULL_TREE;
594 return maybe_push_res_to_seq (rcode, type, ops, seq);
595}
596
597
598/* The main STMT based simplification entry. It is used by the fold_stmt
599 and the fold_stmt_to_constant APIs. */
600
601bool
602gimple_simplify (gimple stmt,
603 code_helper *rcode, tree *ops,
0ff093d8
RB
604 gimple_seq *seq,
605 tree (*valueize)(tree), tree (*top_valueize)(tree))
3d2cf79f
RB
606{
607 switch (gimple_code (stmt))
608 {
609 case GIMPLE_ASSIGN:
610 {
611 enum tree_code code = gimple_assign_rhs_code (stmt);
612 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
613 switch (gimple_assign_rhs_class (stmt))
614 {
615 case GIMPLE_SINGLE_RHS:
616 if (code == REALPART_EXPR
617 || code == IMAGPART_EXPR
618 || code == VIEW_CONVERT_EXPR)
619 {
620 tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
0ff093d8 621 if (top_valueize && TREE_CODE (op0) == SSA_NAME)
3d2cf79f 622 {
0ff093d8 623 tree tem = top_valueize (op0);
3d2cf79f
RB
624 if (tem)
625 op0 = tem;
626 }
627 *rcode = code;
628 ops[0] = op0;
629 return gimple_resimplify1 (seq, rcode, type, ops, valueize);
630 }
631 else if (code == BIT_FIELD_REF)
632 {
633 tree rhs1 = gimple_assign_rhs1 (stmt);
634 tree op0 = TREE_OPERAND (rhs1, 0);
0ff093d8 635 if (top_valueize && TREE_CODE (op0) == SSA_NAME)
3d2cf79f 636 {
0ff093d8 637 tree tem = top_valueize (op0);
3d2cf79f
RB
638 if (tem)
639 op0 = tem;
640 }
641 *rcode = code;
642 ops[0] = op0;
643 ops[1] = TREE_OPERAND (rhs1, 1);
644 ops[2] = TREE_OPERAND (rhs1, 2);
645 return gimple_resimplify3 (seq, rcode, type, ops, valueize);
646 }
647 else if (code == SSA_NAME
0ff093d8 648 && top_valueize)
3d2cf79f
RB
649 {
650 tree op0 = gimple_assign_rhs1 (stmt);
0ff093d8 651 tree valueized = top_valueize (op0);
3d2cf79f
RB
652 if (!valueized || op0 == valueized)
653 return false;
654 ops[0] = valueized;
655 *rcode = TREE_CODE (op0);
656 return true;
657 }
658 break;
659 case GIMPLE_UNARY_RHS:
660 {
661 tree rhs1 = gimple_assign_rhs1 (stmt);
0ff093d8 662 if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
3d2cf79f 663 {
0ff093d8 664 tree tem = top_valueize (rhs1);
3d2cf79f
RB
665 if (tem)
666 rhs1 = tem;
667 }
668 *rcode = code;
669 ops[0] = rhs1;
670 return gimple_resimplify1 (seq, rcode, type, ops, valueize);
671 }
672 case GIMPLE_BINARY_RHS:
673 {
674 tree rhs1 = gimple_assign_rhs1 (stmt);
0ff093d8 675 if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
3d2cf79f 676 {
0ff093d8 677 tree tem = top_valueize (rhs1);
3d2cf79f
RB
678 if (tem)
679 rhs1 = tem;
680 }
681 tree rhs2 = gimple_assign_rhs2 (stmt);
0ff093d8 682 if (top_valueize && TREE_CODE (rhs2) == SSA_NAME)
3d2cf79f 683 {
0ff093d8 684 tree tem = top_valueize (rhs2);
3d2cf79f
RB
685 if (tem)
686 rhs2 = tem;
687 }
688 *rcode = code;
689 ops[0] = rhs1;
690 ops[1] = rhs2;
691 return gimple_resimplify2 (seq, rcode, type, ops, valueize);
692 }
693 case GIMPLE_TERNARY_RHS:
694 {
695 tree rhs1 = gimple_assign_rhs1 (stmt);
0ff093d8 696 if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
3d2cf79f 697 {
0ff093d8 698 tree tem = top_valueize (rhs1);
3d2cf79f
RB
699 if (tem)
700 rhs1 = tem;
701 }
702 tree rhs2 = gimple_assign_rhs2 (stmt);
0ff093d8 703 if (top_valueize && TREE_CODE (rhs2) == SSA_NAME)
3d2cf79f 704 {
0ff093d8 705 tree tem = top_valueize (rhs2);
3d2cf79f
RB
706 if (tem)
707 rhs2 = tem;
708 }
709 tree rhs3 = gimple_assign_rhs3 (stmt);
0ff093d8 710 if (top_valueize && TREE_CODE (rhs3) == SSA_NAME)
3d2cf79f 711 {
0ff093d8 712 tree tem = top_valueize (rhs3);
3d2cf79f
RB
713 if (tem)
714 rhs3 = tem;
715 }
716 *rcode = code;
717 ops[0] = rhs1;
718 ops[1] = rhs2;
719 ops[2] = rhs3;
720 return gimple_resimplify3 (seq, rcode, type, ops, valueize);
721 }
722 default:
723 gcc_unreachable ();
724 }
725 break;
726 }
727
728 case GIMPLE_CALL:
729 /* ??? This way we can't simplify calls with side-effects. */
730 if (gimple_call_lhs (stmt) != NULL_TREE)
731 {
732 tree fn = gimple_call_fn (stmt);
733 /* ??? Internal function support missing. */
734 if (!fn)
735 return false;
0ff093d8 736 if (top_valueize && TREE_CODE (fn) == SSA_NAME)
3d2cf79f 737 {
0ff093d8 738 tree tem = top_valueize (fn);
3d2cf79f
RB
739 if (tem)
740 fn = tem;
741 }
742 if (!fn
743 || TREE_CODE (fn) != ADDR_EXPR
744 || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL
745 || DECL_BUILT_IN_CLASS (TREE_OPERAND (fn, 0)) != BUILT_IN_NORMAL
746 || !builtin_decl_implicit (DECL_FUNCTION_CODE (TREE_OPERAND (fn, 0)))
747 || !gimple_builtin_call_types_compatible_p (stmt,
748 TREE_OPERAND (fn, 0)))
749 return false;
750
751 tree decl = TREE_OPERAND (fn, 0);
752 tree type = TREE_TYPE (gimple_call_lhs (stmt));
753 switch (gimple_call_num_args (stmt))
754 {
755 case 1:
756 {
757 tree arg1 = gimple_call_arg (stmt, 0);
0ff093d8 758 if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
3d2cf79f 759 {
0ff093d8 760 tree tem = top_valueize (arg1);
3d2cf79f
RB
761 if (tem)
762 arg1 = tem;
763 }
764 *rcode = DECL_FUNCTION_CODE (decl);
765 ops[0] = arg1;
766 return gimple_resimplify1 (seq, rcode, type, ops, valueize);
767 }
768 case 2:
769 {
770 tree arg1 = gimple_call_arg (stmt, 0);
0ff093d8 771 if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
3d2cf79f 772 {
0ff093d8 773 tree tem = top_valueize (arg1);
3d2cf79f
RB
774 if (tem)
775 arg1 = tem;
776 }
777 tree arg2 = gimple_call_arg (stmt, 1);
0ff093d8 778 if (top_valueize && TREE_CODE (arg2) == SSA_NAME)
3d2cf79f 779 {
0ff093d8 780 tree tem = top_valueize (arg2);
3d2cf79f
RB
781 if (tem)
782 arg2 = tem;
783 }
784 *rcode = DECL_FUNCTION_CODE (decl);
785 ops[0] = arg1;
786 ops[1] = arg2;
787 return gimple_resimplify2 (seq, rcode, type, ops, valueize);
788 }
789 case 3:
790 {
791 tree arg1 = gimple_call_arg (stmt, 0);
0ff093d8 792 if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
3d2cf79f 793 {
0ff093d8 794 tree tem = top_valueize (arg1);
3d2cf79f
RB
795 if (tem)
796 arg1 = tem;
797 }
798 tree arg2 = gimple_call_arg (stmt, 1);
0ff093d8 799 if (top_valueize && TREE_CODE (arg2) == SSA_NAME)
3d2cf79f 800 {
0ff093d8 801 tree tem = top_valueize (arg2);
3d2cf79f
RB
802 if (tem)
803 arg2 = tem;
804 }
805 tree arg3 = gimple_call_arg (stmt, 2);
0ff093d8 806 if (top_valueize && TREE_CODE (arg3) == SSA_NAME)
3d2cf79f 807 {
0ff093d8 808 tree tem = top_valueize (arg3);
3d2cf79f
RB
809 if (tem)
810 arg3 = tem;
811 }
812 *rcode = DECL_FUNCTION_CODE (decl);
813 ops[0] = arg1;
814 ops[1] = arg2;
815 ops[2] = arg3;
816 return gimple_resimplify3 (seq, rcode, type, ops, valueize);
817 }
818 default:
819 return false;
820 }
821 }
822 break;
823
824 case GIMPLE_COND:
825 {
826 tree lhs = gimple_cond_lhs (stmt);
0ff093d8 827 if (top_valueize && TREE_CODE (lhs) == SSA_NAME)
3d2cf79f 828 {
0ff093d8 829 tree tem = top_valueize (lhs);
3d2cf79f
RB
830 if (tem)
831 lhs = tem;
832 }
833 tree rhs = gimple_cond_rhs (stmt);
0ff093d8 834 if (top_valueize && TREE_CODE (rhs) == SSA_NAME)
3d2cf79f 835 {
0ff093d8 836 tree tem = top_valueize (rhs);
3d2cf79f
RB
837 if (tem)
838 rhs = tem;
839 }
840 *rcode = gimple_cond_code (stmt);
841 ops[0] = lhs;
842 ops[1] = rhs;
843 return gimple_resimplify2 (seq, rcode, boolean_type_node, ops, valueize);
844 }
845
846 default:
847 break;
848 }
849
850 return false;
851}
852
853
854/* Helper for the autogenerated code, valueize OP. */
855
856inline tree
857do_valueize (tree (*valueize)(tree), tree op)
858{
859 if (valueize && TREE_CODE (op) == SSA_NAME)
860 return valueize (op);
861 return op;
862}
863