xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/gimple-match-head.c (revision 16dce51364ebe8aeafbae46bc5aa167b8115bc45)
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 
863