gcc50: Disconnect from buildworld.
[dragonfly.git] / contrib / gcc-5.0 / 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 "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"
34 #include "tree.h"
35 #include "fold-const.h"
36 #include "stringpool.h"
37 #include "stor-layout.h"
38 #include "flags.h"
39 #include "hard-reg-set.h"
40 #include "function.h"
41 #include "predict.h"
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"
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"
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.  */
77 static bool gimple_simplify (code_helper *, tree *,
78                              gimple_seq *, tree (*)(tree),
79                              code_helper, tree, tree);
80 static bool gimple_simplify (code_helper *, tree *,
81                              gimple_seq *, tree (*)(tree),
82                              code_helper, tree, tree, tree);
83 static 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
91 static inline bool
92 constant_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
107 static bool
108 gimple_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 ())
116         tem = const_unop (*res_code, type, res_ops[0]);
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
163 static bool
164 gimple_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 ())
172         tem = const_binop (*res_code, type, res_ops[0], res_ops[1]);
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
234 static bool
235 gimple_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
303 void
304 maybe_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
327 tree
328 maybe_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)
352         res = make_ssa_name (type);
353       maybe_build_generic_op (rcode, type, &ops[0], ops[1], ops[2]);
354       gimple new_stmt = gimple_build_assign (res, rcode,
355                                              ops[0], ops[1], ops[2]);
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)
380         res = make_ssa_name (type);
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
400 tree
401 gimple_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     {
407       tree res = const_unop (code, type, op0);
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
423 tree
424 gimple_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     {
430       tree res = const_binop (code, type, op0, op1);
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
459 tree
460 gimple_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
493 tree
494 gimple_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
525 tree
526 gimple_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
561 tree
562 gimple_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
601 bool
602 gimple_simplify (gimple stmt,
603                  code_helper *rcode, tree *ops,
604                  gimple_seq *seq, tree (*valueize)(tree))
605 {
606   switch (gimple_code (stmt))
607     {
608     case GIMPLE_ASSIGN:
609       {
610         enum tree_code code = gimple_assign_rhs_code (stmt);
611         tree type = TREE_TYPE (gimple_assign_lhs (stmt));
612         switch (gimple_assign_rhs_class (stmt))
613           {
614           case GIMPLE_SINGLE_RHS:
615             if (code == REALPART_EXPR
616                 || code == IMAGPART_EXPR
617                 || code == VIEW_CONVERT_EXPR)
618               {
619                 tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
620                 if (valueize && TREE_CODE (op0) == SSA_NAME)
621                   {
622                     tree tem = valueize (op0);
623                     if (tem)
624                       op0 = tem;
625                   }
626                 *rcode = code;
627                 ops[0] = op0;
628                 return gimple_resimplify1 (seq, rcode, type, ops, valueize);
629               }
630             else if (code == BIT_FIELD_REF)
631               {
632                 tree rhs1 = gimple_assign_rhs1 (stmt);
633                 tree op0 = TREE_OPERAND (rhs1, 0);
634                 if (valueize && TREE_CODE (op0) == SSA_NAME)
635                   {
636                     tree tem = valueize (op0);
637                     if (tem)
638                       op0 = tem;
639                   }
640                 *rcode = code;
641                 ops[0] = op0;
642                 ops[1] = TREE_OPERAND (rhs1, 1);
643                 ops[2] = TREE_OPERAND (rhs1, 2);
644                 return gimple_resimplify3 (seq, rcode, type, ops, valueize);
645               }
646             else if (code == SSA_NAME
647                      && valueize)
648               {
649                 tree op0 = gimple_assign_rhs1 (stmt);
650                 tree valueized = 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               if (valueize && TREE_CODE (rhs1) == SSA_NAME)
662                 {
663                   tree tem = valueize (rhs1);
664                   if (tem)
665                     rhs1 = tem;
666                 }
667               *rcode = code;
668               ops[0] = rhs1;
669               return gimple_resimplify1 (seq, rcode, type, ops, valueize);
670             }
671           case GIMPLE_BINARY_RHS:
672             {
673               tree rhs1 = gimple_assign_rhs1 (stmt);
674               if (valueize && TREE_CODE (rhs1) == SSA_NAME)
675                 {
676                   tree tem = valueize (rhs1);
677                   if (tem)
678                     rhs1 = tem;
679                 }
680               tree rhs2 = gimple_assign_rhs2 (stmt);
681               if (valueize && TREE_CODE (rhs2) == SSA_NAME)
682                 {
683                   tree tem = valueize (rhs2);
684                   if (tem)
685                     rhs2 = tem;
686                 }
687               *rcode = code;
688               ops[0] = rhs1;
689               ops[1] = rhs2;
690               return gimple_resimplify2 (seq, rcode, type, ops, valueize);
691             }
692           case GIMPLE_TERNARY_RHS:
693             {
694               tree rhs1 = gimple_assign_rhs1 (stmt);
695               if (valueize && TREE_CODE (rhs1) == SSA_NAME)
696                 {
697                   tree tem = valueize (rhs1);
698                   if (tem)
699                     rhs1 = tem;
700                 }
701               tree rhs2 = gimple_assign_rhs2 (stmt);
702               if (valueize && TREE_CODE (rhs2) == SSA_NAME)
703                 {
704                   tree tem = valueize (rhs2);
705                   if (tem)
706                     rhs2 = tem;
707                 }
708               tree rhs3 = gimple_assign_rhs3 (stmt);
709               if (valueize && TREE_CODE (rhs3) == SSA_NAME)
710                 {
711                   tree tem = valueize (rhs3);
712                   if (tem)
713                     rhs3 = tem;
714                 }
715               *rcode = code;
716               ops[0] = rhs1;
717               ops[1] = rhs2;
718               ops[2] = rhs3;
719               return gimple_resimplify3 (seq, rcode, type, ops, valueize);
720             }
721           default:
722             gcc_unreachable ();
723           }
724         break;
725       }
726
727     case GIMPLE_CALL:
728       /* ???  This way we can't simplify calls with side-effects.  */
729       if (gimple_call_lhs (stmt) != NULL_TREE)
730         {
731           tree fn = gimple_call_fn (stmt);
732           /* ???  Internal function support missing.  */
733           if (!fn)
734             return false;
735           if (valueize && TREE_CODE (fn) == SSA_NAME)
736             {
737               tree tem = valueize (fn);
738               if (tem)
739                 fn = tem;
740             }
741           if (!fn
742               || TREE_CODE (fn) != ADDR_EXPR
743               || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL
744               || DECL_BUILT_IN_CLASS (TREE_OPERAND (fn, 0)) != BUILT_IN_NORMAL
745               || !builtin_decl_implicit (DECL_FUNCTION_CODE (TREE_OPERAND (fn, 0)))
746               || !gimple_builtin_call_types_compatible_p (stmt,
747                                                           TREE_OPERAND (fn, 0)))
748             return false;
749
750           tree decl = TREE_OPERAND (fn, 0);
751           tree type = TREE_TYPE (gimple_call_lhs (stmt));
752           switch (gimple_call_num_args (stmt))
753             {
754             case 1:
755               {
756                 tree arg1 = gimple_call_arg (stmt, 0);
757                 if (valueize && TREE_CODE (arg1) == SSA_NAME)
758                   {
759                     tree tem = valueize (arg1);
760                     if (tem)
761                       arg1 = tem;
762                   }
763                 *rcode = DECL_FUNCTION_CODE (decl);
764                 ops[0] = arg1;
765                 return gimple_resimplify1 (seq, rcode, type, ops, valueize);
766               }
767             case 2:
768               {
769                 tree arg1 = gimple_call_arg (stmt, 0);
770                 if (valueize && TREE_CODE (arg1) == SSA_NAME)
771                   {
772                     tree tem = valueize (arg1);
773                     if (tem)
774                       arg1 = tem;
775                   }
776                 tree arg2 = gimple_call_arg (stmt, 1);
777                 if (valueize && TREE_CODE (arg2) == SSA_NAME)
778                   {
779                     tree tem = valueize (arg2);
780                     if (tem)
781                       arg2 = tem;
782                   }
783                 *rcode = DECL_FUNCTION_CODE (decl);
784                 ops[0] = arg1;
785                 ops[1] = arg2;
786                 return gimple_resimplify2 (seq, rcode, type, ops, valueize);
787               }
788             case 3:
789               {
790                 tree arg1 = gimple_call_arg (stmt, 0);
791                 if (valueize && TREE_CODE (arg1) == SSA_NAME)
792                   {
793                     tree tem = valueize (arg1);
794                     if (tem)
795                       arg1 = tem;
796                   }
797                 tree arg2 = gimple_call_arg (stmt, 1);
798                 if (valueize && TREE_CODE (arg2) == SSA_NAME)
799                   {
800                     tree tem = valueize (arg2);
801                     if (tem)
802                       arg2 = tem;
803                   }
804                 tree arg3 = gimple_call_arg (stmt, 2);
805                 if (valueize && TREE_CODE (arg3) == SSA_NAME)
806                   {
807                     tree tem = valueize (arg3);
808                     if (tem)
809                       arg3 = tem;
810                   }
811                 *rcode = DECL_FUNCTION_CODE (decl);
812                 ops[0] = arg1;
813                 ops[1] = arg2;
814                 ops[2] = arg3;
815                 return gimple_resimplify3 (seq, rcode, type, ops, valueize);
816               }
817             default:
818               return false;
819             }
820         }
821       break;
822
823     case GIMPLE_COND:
824       {
825         tree lhs = gimple_cond_lhs (stmt);
826         if (valueize && TREE_CODE (lhs) == SSA_NAME)
827           {
828             tree tem = valueize (lhs);
829             if (tem)
830               lhs = tem;
831           }
832         tree rhs = gimple_cond_rhs (stmt);
833         if (valueize && TREE_CODE (rhs) == SSA_NAME)
834           {
835             tree tem = valueize (rhs);
836             if (tem)
837               rhs = tem;
838           }
839         *rcode = gimple_cond_code (stmt);
840         ops[0] = lhs;
841         ops[1] = rhs;
842         return gimple_resimplify2 (seq, rcode, boolean_type_node, ops, valueize);
843       }
844
845     default:
846       break;
847     }
848
849   return false;
850 }
851
852
853 /* Helper for the autogenerated code, valueize OP.  */
854
855 inline tree
856 do_valueize (tree (*valueize)(tree), tree op)
857 {
858   if (valueize && TREE_CODE (op) == SSA_NAME)
859     return valueize (op);
860   return op;
861 }
862