]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/gimple-match-head.c
2015-06-17 Andrew MacLeod <amacleod@redhat.com>
[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 "tm.h"
24 #include "alias.h"
25 #include "symtab.h"
26 #include "options.h"
27 #include "tree.h"
28 #include "fold-const.h"
29 #include "stringpool.h"
30 #include "stor-layout.h"
31 #include "flags.h"
32 #include "hard-reg-set.h"
33 #include "function.h"
34 #include "predict.h"
35 #include "basic-block.h"
36 #include "tree-ssa-alias.h"
37 #include "internal-fn.h"
38 #include "gimple-expr.h"
39 #include "gimple.h"
40 #include "gimple-ssa.h"
41 #include "tree-ssanames.h"
42 #include "gimple-fold.h"
43 #include "gimple-iterator.h"
44 #include "rtl.h"
45 #include "insn-config.h"
46 #include "expmed.h"
47 #include "dojump.h"
48 #include "explow.h"
49 #include "calls.h"
50 #include "emit-rtl.h"
51 #include "varasm.h"
52 #include "stmt.h"
53 #include "expr.h"
54 #include "tree-dfa.h"
55 #include "builtins.h"
56 #include "tree-phinodes.h"
57 #include "ssa-iterators.h"
58 #include "dumpfile.h"
59 #include "gimple-match.h"
60
61
62 /* Forward declarations of the private auto-generated matchers.
63 They expect valueized operands in canonical order and do not
64 perform simplification of all-constant operands. */
65 static bool gimple_simplify (code_helper *, tree *,
66 gimple_seq *, tree (*)(tree),
67 code_helper, tree, tree);
68 static bool gimple_simplify (code_helper *, tree *,
69 gimple_seq *, tree (*)(tree),
70 code_helper, tree, tree, tree);
71 static bool gimple_simplify (code_helper *, tree *,
72 gimple_seq *, tree (*)(tree),
73 code_helper, tree, tree, tree, tree);
74
75
76 /* Return whether T is a constant that we'll dispatch to fold to
77 evaluate fully constant expressions. */
78
79 static inline bool
80 constant_for_folding (tree t)
81 {
82 return (CONSTANT_CLASS_P (t)
83 /* The following is only interesting to string builtins. */
84 || (TREE_CODE (t) == ADDR_EXPR
85 && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST));
86 }
87
88
89 /* Helper that matches and simplifies the toplevel result from
90 a gimple_simplify run (where we don't want to build
91 a stmt in case it's used in in-place folding). Replaces
92 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
93 result and returns whether any change was made. */
94
95 static bool
96 gimple_resimplify1 (gimple_seq *seq,
97 code_helper *res_code, tree type, tree *res_ops,
98 tree (*valueize)(tree))
99 {
100 if (constant_for_folding (res_ops[0]))
101 {
102 tree tem = NULL_TREE;
103 if (res_code->is_tree_code ())
104 tem = const_unop (*res_code, type, res_ops[0]);
105 else
106 {
107 tree decl = builtin_decl_implicit (*res_code);
108 if (decl)
109 {
110 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 1, false);
111 if (tem)
112 {
113 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
114 STRIP_NOPS (tem);
115 tem = fold_convert (type, tem);
116 }
117 }
118 }
119 if (tem != NULL_TREE
120 && CONSTANT_CLASS_P (tem))
121 {
122 res_ops[0] = tem;
123 res_ops[1] = NULL_TREE;
124 res_ops[2] = NULL_TREE;
125 *res_code = TREE_CODE (res_ops[0]);
126 return true;
127 }
128 }
129
130 code_helper res_code2;
131 tree res_ops2[3] = {};
132 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
133 *res_code, type, res_ops[0]))
134 {
135 *res_code = res_code2;
136 res_ops[0] = res_ops2[0];
137 res_ops[1] = res_ops2[1];
138 res_ops[2] = res_ops2[2];
139 return true;
140 }
141
142 return false;
143 }
144
145 /* Helper that matches and simplifies the toplevel result from
146 a gimple_simplify run (where we don't want to build
147 a stmt in case it's used in in-place folding). Replaces
148 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
149 result and returns whether any change was made. */
150
151 static bool
152 gimple_resimplify2 (gimple_seq *seq,
153 code_helper *res_code, tree type, tree *res_ops,
154 tree (*valueize)(tree))
155 {
156 if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1]))
157 {
158 tree tem = NULL_TREE;
159 if (res_code->is_tree_code ())
160 tem = const_binop (*res_code, type, res_ops[0], res_ops[1]);
161 else
162 {
163 tree decl = builtin_decl_implicit (*res_code);
164 if (decl)
165 {
166 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 2, false);
167 if (tem)
168 {
169 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
170 STRIP_NOPS (tem);
171 tem = fold_convert (type, tem);
172 }
173 }
174 }
175 if (tem != NULL_TREE
176 && CONSTANT_CLASS_P (tem))
177 {
178 res_ops[0] = tem;
179 res_ops[1] = NULL_TREE;
180 res_ops[2] = NULL_TREE;
181 *res_code = TREE_CODE (res_ops[0]);
182 return true;
183 }
184 }
185
186 /* Canonicalize operand order. */
187 bool canonicalized = false;
188 if (res_code->is_tree_code ()
189 && (TREE_CODE_CLASS ((enum tree_code) *res_code) == tcc_comparison
190 || commutative_tree_code (*res_code))
191 && tree_swap_operands_p (res_ops[0], res_ops[1], false))
192 {
193 tree tem = res_ops[0];
194 res_ops[0] = res_ops[1];
195 res_ops[1] = tem;
196 if (TREE_CODE_CLASS ((enum tree_code) *res_code) == tcc_comparison)
197 *res_code = swap_tree_comparison (*res_code);
198 canonicalized = true;
199 }
200
201 code_helper res_code2;
202 tree res_ops2[3] = {};
203 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
204 *res_code, type, res_ops[0], res_ops[1]))
205 {
206 *res_code = res_code2;
207 res_ops[0] = res_ops2[0];
208 res_ops[1] = res_ops2[1];
209 res_ops[2] = res_ops2[2];
210 return true;
211 }
212
213 return canonicalized;
214 }
215
216 /* Helper that matches and simplifies the toplevel result from
217 a gimple_simplify run (where we don't want to build
218 a stmt in case it's used in in-place folding). Replaces
219 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
220 result and returns whether any change was made. */
221
222 static bool
223 gimple_resimplify3 (gimple_seq *seq,
224 code_helper *res_code, tree type, tree *res_ops,
225 tree (*valueize)(tree))
226 {
227 if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1])
228 && constant_for_folding (res_ops[2]))
229 {
230 tree tem = NULL_TREE;
231 if (res_code->is_tree_code ())
232 tem = fold_ternary/*_to_constant*/ (*res_code, type, res_ops[0],
233 res_ops[1], res_ops[2]);
234 else
235 {
236 tree decl = builtin_decl_implicit (*res_code);
237 if (decl)
238 {
239 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 3, false);
240 if (tem)
241 {
242 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
243 STRIP_NOPS (tem);
244 tem = fold_convert (type, tem);
245 }
246 }
247 }
248 if (tem != NULL_TREE
249 && CONSTANT_CLASS_P (tem))
250 {
251 res_ops[0] = tem;
252 res_ops[1] = NULL_TREE;
253 res_ops[2] = NULL_TREE;
254 *res_code = TREE_CODE (res_ops[0]);
255 return true;
256 }
257 }
258
259 /* Canonicalize operand order. */
260 bool canonicalized = false;
261 if (res_code->is_tree_code ()
262 && commutative_ternary_tree_code (*res_code)
263 && tree_swap_operands_p (res_ops[0], res_ops[1], false))
264 {
265 tree tem = res_ops[0];
266 res_ops[0] = res_ops[1];
267 res_ops[1] = tem;
268 canonicalized = true;
269 }
270
271 code_helper res_code2;
272 tree res_ops2[3] = {};
273 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
274 *res_code, type,
275 res_ops[0], res_ops[1], res_ops[2]))
276 {
277 *res_code = res_code2;
278 res_ops[0] = res_ops2[0];
279 res_ops[1] = res_ops2[1];
280 res_ops[2] = res_ops2[2];
281 return true;
282 }
283
284 return canonicalized;
285 }
286
287
288 /* If in GIMPLE expressions with CODE go as single-rhs build
289 a GENERIC tree for that expression into *OP0. */
290
291 void
292 maybe_build_generic_op (enum tree_code code, tree type,
293 tree *op0, tree op1, tree op2)
294 {
295 switch (code)
296 {
297 case REALPART_EXPR:
298 case IMAGPART_EXPR:
299 case VIEW_CONVERT_EXPR:
300 *op0 = build1 (code, type, *op0);
301 break;
302 case BIT_FIELD_REF:
303 *op0 = build3 (code, type, *op0, op1, op2);
304 break;
305 default:;
306 }
307 }
308
309 /* Push the exploded expression described by RCODE, TYPE and OPS
310 as a statement to SEQ if necessary and return a gimple value
311 denoting the value of the expression. If RES is not NULL
312 then the result will be always RES and even gimple values are
313 pushed to SEQ. */
314
315 tree
316 maybe_push_res_to_seq (code_helper rcode, tree type, tree *ops,
317 gimple_seq *seq, tree res)
318 {
319 if (rcode.is_tree_code ())
320 {
321 if (!res
322 && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
323 || ((tree_code) rcode) == ADDR_EXPR)
324 && is_gimple_val (ops[0]))
325 return ops[0];
326 if (!seq)
327 return NULL_TREE;
328 /* Play safe and do not allow abnormals to be mentioned in
329 newly created statements. */
330 if ((TREE_CODE (ops[0]) == SSA_NAME
331 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
332 || (ops[1]
333 && TREE_CODE (ops[1]) == SSA_NAME
334 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
335 || (ops[2]
336 && TREE_CODE (ops[2]) == SSA_NAME
337 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
338 return NULL_TREE;
339 if (!res)
340 res = make_ssa_name (type);
341 maybe_build_generic_op (rcode, type, &ops[0], ops[1], ops[2]);
342 gimple new_stmt = gimple_build_assign (res, rcode,
343 ops[0], ops[1], ops[2]);
344 gimple_seq_add_stmt_without_update (seq, new_stmt);
345 return res;
346 }
347 else
348 {
349 if (!seq)
350 return NULL_TREE;
351 tree decl = builtin_decl_implicit (rcode);
352 if (!decl)
353 return NULL_TREE;
354 unsigned nargs = type_num_arguments (TREE_TYPE (decl));
355 gcc_assert (nargs <= 3);
356 /* Play safe and do not allow abnormals to be mentioned in
357 newly created statements. */
358 if ((TREE_CODE (ops[0]) == SSA_NAME
359 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
360 || (nargs >= 2
361 && TREE_CODE (ops[1]) == SSA_NAME
362 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
363 || (nargs == 3
364 && TREE_CODE (ops[2]) == SSA_NAME
365 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
366 return NULL_TREE;
367 if (!res)
368 res = make_ssa_name (type);
369 gimple new_stmt = gimple_build_call (decl, nargs, ops[0], ops[1], ops[2]);
370 gimple_call_set_lhs (new_stmt, res);
371 gimple_seq_add_stmt_without_update (seq, new_stmt);
372 return res;
373 }
374 }
375
376
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. */
385
386 /* Unary ops. */
387
388 tree
389 gimple_simplify (enum tree_code code, tree type,
390 tree op0,
391 gimple_seq *seq, tree (*valueize)(tree))
392 {
393 if (constant_for_folding (op0))
394 {
395 tree res = const_unop (code, type, op0);
396 if (res != NULL_TREE
397 && CONSTANT_CLASS_P (res))
398 return res;
399 }
400
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);
407 }
408
409 /* Binary ops. */
410
411 tree
412 gimple_simplify (enum tree_code code, tree type,
413 tree op0, tree op1,
414 gimple_seq *seq, tree (*valueize)(tree))
415 {
416 if (constant_for_folding (op0) && constant_for_folding (op1))
417 {
418 tree res = const_binop (code, type, op0, op1);
419 if (res != NULL_TREE
420 && CONSTANT_CLASS_P (res))
421 return res;
422 }
423
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))
429 {
430 tree tem = op0;
431 op0 = op1;
432 op1 = tem;
433 if (TREE_CODE_CLASS (code) == tcc_comparison)
434 code = swap_tree_comparison (code);
435 }
436
437 code_helper rcode;
438 tree ops[3] = {};
439 if (!gimple_simplify (&rcode, ops, seq, valueize,
440 code, type, op0, op1))
441 return NULL_TREE;
442 return maybe_push_res_to_seq (rcode, type, ops, seq);
443 }
444
445 /* Ternary ops. */
446
447 tree
448 gimple_simplify (enum tree_code code, tree type,
449 tree op0, tree op1, tree op2,
450 gimple_seq *seq, tree (*valueize)(tree))
451 {
452 if (constant_for_folding (op0) && constant_for_folding (op1)
453 && constant_for_folding (op2))
454 {
455 tree res = fold_ternary/*_to_constant */ (code, type, op0, op1, op2);
456 if (res != NULL_TREE
457 && CONSTANT_CLASS_P (res))
458 return res;
459 }
460
461 /* Canonicalize operand order both for matching and fallback stmt
462 generation. */
463 if (commutative_ternary_tree_code (code)
464 && tree_swap_operands_p (op0, op1, false))
465 {
466 tree tem = op0;
467 op0 = op1;
468 op1 = tem;
469 }
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
586 /* The main STMT based simplification entry. It is used by the fold_stmt
587 and the fold_stmt_to_constant APIs. */
588
589 bool
590 gimple_simplify (gimple stmt,
591 code_helper *rcode, tree *ops,
592 gimple_seq *seq,
593 tree (*valueize)(tree), tree (*top_valueize)(tree))
594 {
595 switch (gimple_code (stmt))
596 {
597 case GIMPLE_ASSIGN:
598 {
599 enum tree_code code = gimple_assign_rhs_code (stmt);
600 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
601 switch (gimple_assign_rhs_class (stmt))
602 {
603 case GIMPLE_SINGLE_RHS:
604 if (code == REALPART_EXPR
605 || code == IMAGPART_EXPR
606 || code == VIEW_CONVERT_EXPR)
607 {
608 tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
609 if (top_valueize && TREE_CODE (op0) == SSA_NAME)
610 {
611 tree tem = top_valueize (op0);
612 if (tem)
613 op0 = tem;
614 }
615 *rcode = code;
616 ops[0] = op0;
617 return gimple_resimplify1 (seq, rcode, type, ops, valueize);
618 }
619 else if (code == BIT_FIELD_REF)
620 {
621 tree rhs1 = gimple_assign_rhs1 (stmt);
622 tree op0 = TREE_OPERAND (rhs1, 0);
623 if (top_valueize && TREE_CODE (op0) == SSA_NAME)
624 {
625 tree tem = top_valueize (op0);
626 if (tem)
627 op0 = tem;
628 }
629 *rcode = code;
630 ops[0] = op0;
631 ops[1] = TREE_OPERAND (rhs1, 1);
632 ops[2] = TREE_OPERAND (rhs1, 2);
633 return gimple_resimplify3 (seq, rcode, type, ops, valueize);
634 }
635 else if (code == SSA_NAME
636 && top_valueize)
637 {
638 tree op0 = gimple_assign_rhs1 (stmt);
639 tree valueized = top_valueize (op0);
640 if (!valueized || op0 == valueized)
641 return false;
642 ops[0] = valueized;
643 *rcode = TREE_CODE (op0);
644 return true;
645 }
646 break;
647 case GIMPLE_UNARY_RHS:
648 {
649 tree rhs1 = gimple_assign_rhs1 (stmt);
650 if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
651 {
652 tree tem = top_valueize (rhs1);
653 if (tem)
654 rhs1 = tem;
655 }
656 *rcode = code;
657 ops[0] = rhs1;
658 return gimple_resimplify1 (seq, rcode, type, ops, valueize);
659 }
660 case GIMPLE_BINARY_RHS:
661 {
662 tree rhs1 = gimple_assign_rhs1 (stmt);
663 if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
664 {
665 tree tem = top_valueize (rhs1);
666 if (tem)
667 rhs1 = tem;
668 }
669 tree rhs2 = gimple_assign_rhs2 (stmt);
670 if (top_valueize && TREE_CODE (rhs2) == SSA_NAME)
671 {
672 tree tem = top_valueize (rhs2);
673 if (tem)
674 rhs2 = tem;
675 }
676 *rcode = code;
677 ops[0] = rhs1;
678 ops[1] = rhs2;
679 return gimple_resimplify2 (seq, rcode, type, ops, valueize);
680 }
681 case GIMPLE_TERNARY_RHS:
682 {
683 tree rhs1 = gimple_assign_rhs1 (stmt);
684 if (top_valueize && TREE_CODE (rhs1) == SSA_NAME)
685 {
686 tree tem = top_valueize (rhs1);
687 if (tem)
688 rhs1 = tem;
689 }
690 tree rhs2 = gimple_assign_rhs2 (stmt);
691 if (top_valueize && TREE_CODE (rhs2) == SSA_NAME)
692 {
693 tree tem = top_valueize (rhs2);
694 if (tem)
695 rhs2 = tem;
696 }
697 tree rhs3 = gimple_assign_rhs3 (stmt);
698 if (top_valueize && TREE_CODE (rhs3) == SSA_NAME)
699 {
700 tree tem = top_valueize (rhs3);
701 if (tem)
702 rhs3 = tem;
703 }
704 *rcode = code;
705 ops[0] = rhs1;
706 ops[1] = rhs2;
707 ops[2] = rhs3;
708 return gimple_resimplify3 (seq, rcode, type, ops, valueize);
709 }
710 default:
711 gcc_unreachable ();
712 }
713 break;
714 }
715
716 case GIMPLE_CALL:
717 /* ??? This way we can't simplify calls with side-effects. */
718 if (gimple_call_lhs (stmt) != NULL_TREE)
719 {
720 tree fn = gimple_call_fn (stmt);
721 /* ??? Internal function support missing. */
722 if (!fn)
723 return false;
724 if (top_valueize && TREE_CODE (fn) == SSA_NAME)
725 {
726 tree tem = top_valueize (fn);
727 if (tem)
728 fn = tem;
729 }
730 if (!fn
731 || TREE_CODE (fn) != ADDR_EXPR
732 || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL
733 || DECL_BUILT_IN_CLASS (TREE_OPERAND (fn, 0)) != BUILT_IN_NORMAL
734 || !builtin_decl_implicit (DECL_FUNCTION_CODE (TREE_OPERAND (fn, 0)))
735 || !gimple_builtin_call_types_compatible_p (stmt,
736 TREE_OPERAND (fn, 0)))
737 return false;
738
739 tree decl = TREE_OPERAND (fn, 0);
740 tree type = TREE_TYPE (gimple_call_lhs (stmt));
741 switch (gimple_call_num_args (stmt))
742 {
743 case 1:
744 {
745 tree arg1 = gimple_call_arg (stmt, 0);
746 if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
747 {
748 tree tem = top_valueize (arg1);
749 if (tem)
750 arg1 = tem;
751 }
752 *rcode = DECL_FUNCTION_CODE (decl);
753 ops[0] = arg1;
754 return gimple_resimplify1 (seq, rcode, type, ops, valueize);
755 }
756 case 2:
757 {
758 tree arg1 = gimple_call_arg (stmt, 0);
759 if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
760 {
761 tree tem = top_valueize (arg1);
762 if (tem)
763 arg1 = tem;
764 }
765 tree arg2 = gimple_call_arg (stmt, 1);
766 if (top_valueize && TREE_CODE (arg2) == SSA_NAME)
767 {
768 tree tem = top_valueize (arg2);
769 if (tem)
770 arg2 = tem;
771 }
772 *rcode = DECL_FUNCTION_CODE (decl);
773 ops[0] = arg1;
774 ops[1] = arg2;
775 return gimple_resimplify2 (seq, rcode, type, ops, valueize);
776 }
777 case 3:
778 {
779 tree arg1 = gimple_call_arg (stmt, 0);
780 if (top_valueize && TREE_CODE (arg1) == SSA_NAME)
781 {
782 tree tem = top_valueize (arg1);
783 if (tem)
784 arg1 = tem;
785 }
786 tree arg2 = gimple_call_arg (stmt, 1);
787 if (top_valueize && TREE_CODE (arg2) == SSA_NAME)
788 {
789 tree tem = top_valueize (arg2);
790 if (tem)
791 arg2 = tem;
792 }
793 tree arg3 = gimple_call_arg (stmt, 2);
794 if (top_valueize && TREE_CODE (arg3) == SSA_NAME)
795 {
796 tree tem = top_valueize (arg3);
797 if (tem)
798 arg3 = tem;
799 }
800 *rcode = DECL_FUNCTION_CODE (decl);
801 ops[0] = arg1;
802 ops[1] = arg2;
803 ops[2] = arg3;
804 return gimple_resimplify3 (seq, rcode, type, ops, valueize);
805 }
806 default:
807 return false;
808 }
809 }
810 break;
811
812 case GIMPLE_COND:
813 {
814 tree lhs = gimple_cond_lhs (stmt);
815 if (top_valueize && TREE_CODE (lhs) == SSA_NAME)
816 {
817 tree tem = top_valueize (lhs);
818 if (tem)
819 lhs = tem;
820 }
821 tree rhs = gimple_cond_rhs (stmt);
822 if (top_valueize && TREE_CODE (rhs) == SSA_NAME)
823 {
824 tree tem = top_valueize (rhs);
825 if (tem)
826 rhs = tem;
827 }
828 *rcode = gimple_cond_code (stmt);
829 ops[0] = lhs;
830 ops[1] = rhs;
831 return gimple_resimplify2 (seq, rcode, boolean_type_node, ops, valueize);
832 }
833
834 default:
835 break;
836 }
837
838 return false;
839 }
840
841
842 /* Helper for the autogenerated code, valueize OP. */
843
844 inline tree
845 do_valueize (tree (*valueize)(tree), tree op)
846 {
847 if (valueize && TREE_CODE (op) == SSA_NAME)
848 return valueize (op);
849 return op;
850 }
851
852 /* Routine to determine if the types T1 and T2 are effectively
853 the same for GIMPLE. If T1 or T2 is not a type, the test
854 applies to their TREE_TYPE. */
855
856 static inline bool
857 types_match (tree t1, tree t2)
858 {
859 if (!TYPE_P (t1))
860 t1 = TREE_TYPE (t1);
861 if (!TYPE_P (t2))
862 t2 = TREE_TYPE (t2);
863
864 return types_compatible_p (t1, t2);
865 }
866
867 /* Return if T has a single use. For GIMPLE, we also allow any
868 non-SSA_NAME (ie constants) and zero uses to cope with uses
869 that aren't linked up yet. */
870
871 static inline bool
872 single_use (tree t)
873 {
874 return TREE_CODE (t) != SSA_NAME || has_zero_uses (t) || has_single_use (t);
875 }