1/* Preamble and helpers for the autogenerated gimple-match.c file.
2   Copyright (C) 2014-2015 Free Software Foundation, Inc.
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"
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.  */
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 ())
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
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 ())
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
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)
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
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    {
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
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    {
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
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,
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
855inline tree
856do_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