1169689Skan/* Tree lowering pass.  This pass converts the GENERIC functions-as-trees
2169689Skan   tree representation into the GIMPLE form.
3169689Skan   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
4169689Skan   Major work done by Sebastian Pop <s.pop@laposte.net>,
5169689Skan   Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
6169689Skan
7169689SkanThis file is part of GCC.
8169689Skan
9169689SkanGCC is free software; you can redistribute it and/or modify it under
10169689Skanthe terms of the GNU General Public License as published by the Free
11169689SkanSoftware Foundation; either version 2, or (at your option) any later
12169689Skanversion.
13169689Skan
14169689SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY
15169689SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or
16169689SkanFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17169689Skanfor more details.
18169689Skan
19169689SkanYou should have received a copy of the GNU General Public License
20169689Skanalong with GCC; see the file COPYING.  If not, write to the Free
21169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22169689Skan02110-1301, USA.  */
23169689Skan
24169689Skan#include "config.h"
25169689Skan#include "system.h"
26169689Skan#include "coretypes.h"
27169689Skan#include "tm.h"
28169689Skan#include "tree.h"
29169689Skan#include "rtl.h"
30169689Skan#include "varray.h"
31169689Skan#include "tree-gimple.h"
32169689Skan#include "tree-inline.h"
33169689Skan#include "diagnostic.h"
34169689Skan#include "langhooks.h"
35169689Skan#include "langhooks-def.h"
36169689Skan#include "tree-flow.h"
37169689Skan#include "cgraph.h"
38169689Skan#include "timevar.h"
39169689Skan#include "except.h"
40169689Skan#include "hashtab.h"
41169689Skan#include "flags.h"
42169689Skan#include "real.h"
43169689Skan#include "function.h"
44169689Skan#include "output.h"
45169689Skan#include "expr.h"
46169689Skan#include "ggc.h"
47169689Skan#include "toplev.h"
48169689Skan#include "target.h"
49169689Skan#include "optabs.h"
50169689Skan#include "pointer-set.h"
51169689Skan
52169689Skan
53169689Skanenum gimplify_omp_var_data
54169689Skan{
55169689Skan  GOVD_SEEN = 1,
56169689Skan  GOVD_EXPLICIT = 2,
57169689Skan  GOVD_SHARED = 4,
58169689Skan  GOVD_PRIVATE = 8,
59169689Skan  GOVD_FIRSTPRIVATE = 16,
60169689Skan  GOVD_LASTPRIVATE = 32,
61169689Skan  GOVD_REDUCTION = 64,
62169689Skan  GOVD_LOCAL = 128,
63169689Skan  GOVD_DEBUG_PRIVATE = 256,
64169689Skan  GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
65169689Skan			   | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LOCAL)
66169689Skan};
67169689Skan
68169689Skanstruct gimplify_omp_ctx
69169689Skan{
70169689Skan  struct gimplify_omp_ctx *outer_context;
71169689Skan  splay_tree variables;
72169689Skan  struct pointer_set_t *privatized_types;
73169689Skan  location_t location;
74169689Skan  enum omp_clause_default_kind default_kind;
75169689Skan  bool is_parallel;
76169689Skan  bool is_combined_parallel;
77169689Skan};
78169689Skan
79169689Skanstruct gimplify_ctx
80169689Skan{
81169689Skan  struct gimplify_ctx *prev_context;
82169689Skan
83169689Skan  tree current_bind_expr;
84169689Skan  tree temps;
85169689Skan  tree conditional_cleanups;
86169689Skan  tree exit_label;
87169689Skan  tree return_temp;
88169689Skan
89169689Skan  VEC(tree,heap) *case_labels;
90169689Skan  /* The formal temporary table.  Should this be persistent?  */
91169689Skan  htab_t temp_htab;
92169689Skan
93169689Skan  int conditions;
94169689Skan  bool save_stack;
95169689Skan  bool into_ssa;
96169689Skan};
97169689Skan
98169689Skanstatic struct gimplify_ctx *gimplify_ctxp;
99169689Skanstatic struct gimplify_omp_ctx *gimplify_omp_ctxp;
100169689Skan
101169689Skan
102169689Skan
103169689Skan/* Formal (expression) temporary table handling: Multiple occurrences of
104169689Skan   the same scalar expression are evaluated into the same temporary.  */
105169689Skan
106169689Skantypedef struct gimple_temp_hash_elt
107169689Skan{
108169689Skan  tree val;   /* Key */
109169689Skan  tree temp;  /* Value */
110169689Skan} elt_t;
111169689Skan
112169689Skan/* Forward declarations.  */
113169689Skanstatic enum gimplify_status gimplify_compound_expr (tree *, tree *, bool);
114169689Skan#ifdef ENABLE_CHECKING
115169689Skanstatic bool cpt_same_type (tree a, tree b);
116169689Skan#endif
117169689Skan
118169689Skan
119169689Skan/* Return a hash value for a formal temporary table entry.  */
120169689Skan
121169689Skanstatic hashval_t
122169689Skangimple_tree_hash (const void *p)
123169689Skan{
124169689Skan  tree t = ((const elt_t *) p)->val;
125169689Skan  return iterative_hash_expr (t, 0);
126169689Skan}
127169689Skan
128169689Skan/* Compare two formal temporary table entries.  */
129169689Skan
130169689Skanstatic int
131169689Skangimple_tree_eq (const void *p1, const void *p2)
132169689Skan{
133169689Skan  tree t1 = ((const elt_t *) p1)->val;
134169689Skan  tree t2 = ((const elt_t *) p2)->val;
135169689Skan  enum tree_code code = TREE_CODE (t1);
136169689Skan
137169689Skan  if (TREE_CODE (t2) != code
138169689Skan      || TREE_TYPE (t1) != TREE_TYPE (t2))
139169689Skan    return 0;
140169689Skan
141169689Skan  if (!operand_equal_p (t1, t2, 0))
142169689Skan    return 0;
143169689Skan
144169689Skan  /* Only allow them to compare equal if they also hash equal; otherwise
145169689Skan     results are nondeterminate, and we fail bootstrap comparison.  */
146169689Skan  gcc_assert (gimple_tree_hash (p1) == gimple_tree_hash (p2));
147169689Skan
148169689Skan  return 1;
149169689Skan}
150169689Skan
151169689Skan/* Set up a context for the gimplifier.  */
152169689Skan
153169689Skanvoid
154169689Skanpush_gimplify_context (void)
155169689Skan{
156169689Skan  struct gimplify_ctx *c;
157169689Skan
158169689Skan  c = (struct gimplify_ctx *) xcalloc (1, sizeof (struct gimplify_ctx));
159169689Skan  c->prev_context = gimplify_ctxp;
160169689Skan  if (optimize)
161169689Skan    c->temp_htab = htab_create (1000, gimple_tree_hash, gimple_tree_eq, free);
162169689Skan
163169689Skan  gimplify_ctxp = c;
164169689Skan}
165169689Skan
166169689Skan/* Tear down a context for the gimplifier.  If BODY is non-null, then
167169689Skan   put the temporaries into the outer BIND_EXPR.  Otherwise, put them
168169689Skan   in the unexpanded_var_list.  */
169169689Skan
170169689Skanvoid
171169689Skanpop_gimplify_context (tree body)
172169689Skan{
173169689Skan  struct gimplify_ctx *c = gimplify_ctxp;
174169689Skan  tree t;
175169689Skan
176169689Skan  gcc_assert (c && !c->current_bind_expr);
177169689Skan  gimplify_ctxp = c->prev_context;
178169689Skan
179169689Skan  for (t = c->temps; t ; t = TREE_CHAIN (t))
180169689Skan    DECL_GIMPLE_FORMAL_TEMP_P (t) = 0;
181169689Skan
182169689Skan  if (body)
183169689Skan    declare_vars (c->temps, body, false);
184169689Skan  else
185169689Skan    record_vars (c->temps);
186169689Skan
187169689Skan  if (optimize)
188169689Skan    htab_delete (c->temp_htab);
189169689Skan  free (c);
190169689Skan}
191169689Skan
192169689Skanstatic void
193169689Skangimple_push_bind_expr (tree bind)
194169689Skan{
195169689Skan  TREE_CHAIN (bind) = gimplify_ctxp->current_bind_expr;
196169689Skan  gimplify_ctxp->current_bind_expr = bind;
197169689Skan}
198169689Skan
199169689Skanstatic void
200169689Skangimple_pop_bind_expr (void)
201169689Skan{
202169689Skan  gimplify_ctxp->current_bind_expr
203169689Skan    = TREE_CHAIN (gimplify_ctxp->current_bind_expr);
204169689Skan}
205169689Skan
206169689Skantree
207169689Skangimple_current_bind_expr (void)
208169689Skan{
209169689Skan  return gimplify_ctxp->current_bind_expr;
210169689Skan}
211169689Skan
212169689Skan/* Returns true iff there is a COND_EXPR between us and the innermost
213169689Skan   CLEANUP_POINT_EXPR.  This info is used by gimple_push_cleanup.  */
214169689Skan
215169689Skanstatic bool
216169689Skangimple_conditional_context (void)
217169689Skan{
218169689Skan  return gimplify_ctxp->conditions > 0;
219169689Skan}
220169689Skan
221169689Skan/* Note that we've entered a COND_EXPR.  */
222169689Skan
223169689Skanstatic void
224169689Skangimple_push_condition (void)
225169689Skan{
226169689Skan#ifdef ENABLE_CHECKING
227169689Skan  if (gimplify_ctxp->conditions == 0)
228169689Skan    gcc_assert (!gimplify_ctxp->conditional_cleanups);
229169689Skan#endif
230169689Skan  ++(gimplify_ctxp->conditions);
231169689Skan}
232169689Skan
233169689Skan/* Note that we've left a COND_EXPR.  If we're back at unconditional scope
234169689Skan   now, add any conditional cleanups we've seen to the prequeue.  */
235169689Skan
236169689Skanstatic void
237169689Skangimple_pop_condition (tree *pre_p)
238169689Skan{
239169689Skan  int conds = --(gimplify_ctxp->conditions);
240169689Skan
241169689Skan  gcc_assert (conds >= 0);
242169689Skan  if (conds == 0)
243169689Skan    {
244169689Skan      append_to_statement_list (gimplify_ctxp->conditional_cleanups, pre_p);
245169689Skan      gimplify_ctxp->conditional_cleanups = NULL_TREE;
246169689Skan    }
247169689Skan}
248169689Skan
249169689Skan/* A stable comparison routine for use with splay trees and DECLs.  */
250169689Skan
251169689Skanstatic int
252169689Skansplay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
253169689Skan{
254169689Skan  tree a = (tree) xa;
255169689Skan  tree b = (tree) xb;
256169689Skan
257169689Skan  return DECL_UID (a) - DECL_UID (b);
258169689Skan}
259169689Skan
260169689Skan/* Create a new omp construct that deals with variable remapping.  */
261169689Skan
262169689Skanstatic struct gimplify_omp_ctx *
263169689Skannew_omp_context (bool is_parallel, bool is_combined_parallel)
264169689Skan{
265169689Skan  struct gimplify_omp_ctx *c;
266169689Skan
267169689Skan  c = XCNEW (struct gimplify_omp_ctx);
268169689Skan  c->outer_context = gimplify_omp_ctxp;
269169689Skan  c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
270169689Skan  c->privatized_types = pointer_set_create ();
271169689Skan  c->location = input_location;
272169689Skan  c->is_parallel = is_parallel;
273169689Skan  c->is_combined_parallel = is_combined_parallel;
274169689Skan  c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
275169689Skan
276169689Skan  return c;
277169689Skan}
278169689Skan
279169689Skan/* Destroy an omp construct that deals with variable remapping.  */
280169689Skan
281169689Skanstatic void
282169689Skandelete_omp_context (struct gimplify_omp_ctx *c)
283169689Skan{
284169689Skan  splay_tree_delete (c->variables);
285169689Skan  pointer_set_destroy (c->privatized_types);
286169689Skan  XDELETE (c);
287169689Skan}
288169689Skan
289169689Skanstatic void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
290169689Skanstatic bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
291169689Skan
292169689Skan/* A subroutine of append_to_statement_list{,_force}.  T is not NULL.  */
293169689Skan
294169689Skanstatic void
295169689Skanappend_to_statement_list_1 (tree t, tree *list_p)
296169689Skan{
297169689Skan  tree list = *list_p;
298169689Skan  tree_stmt_iterator i;
299169689Skan
300169689Skan  if (!list)
301169689Skan    {
302169689Skan      if (t && TREE_CODE (t) == STATEMENT_LIST)
303169689Skan	{
304169689Skan	  *list_p = t;
305169689Skan	  return;
306169689Skan	}
307169689Skan      *list_p = list = alloc_stmt_list ();
308169689Skan    }
309169689Skan
310169689Skan  i = tsi_last (list);
311169689Skan  tsi_link_after (&i, t, TSI_CONTINUE_LINKING);
312169689Skan}
313169689Skan
314169689Skan/* Add T to the end of the list container pointed to by LIST_P.
315169689Skan   If T is an expression with no effects, it is ignored.  */
316169689Skan
317169689Skanvoid
318169689Skanappend_to_statement_list (tree t, tree *list_p)
319169689Skan{
320169689Skan  if (t && TREE_SIDE_EFFECTS (t))
321169689Skan    append_to_statement_list_1 (t, list_p);
322169689Skan}
323169689Skan
324169689Skan/* Similar, but the statement is always added, regardless of side effects.  */
325169689Skan
326169689Skanvoid
327169689Skanappend_to_statement_list_force (tree t, tree *list_p)
328169689Skan{
329169689Skan  if (t != NULL_TREE)
330169689Skan    append_to_statement_list_1 (t, list_p);
331169689Skan}
332169689Skan
333169689Skan/* Both gimplify the statement T and append it to LIST_P.  */
334169689Skan
335169689Skanvoid
336169689Skangimplify_and_add (tree t, tree *list_p)
337169689Skan{
338169689Skan  gimplify_stmt (&t);
339169689Skan  append_to_statement_list (t, list_p);
340169689Skan}
341169689Skan
342169689Skan/* Strip off a legitimate source ending from the input string NAME of
343169689Skan   length LEN.  Rather than having to know the names used by all of
344169689Skan   our front ends, we strip off an ending of a period followed by
345169689Skan   up to five characters.  (Java uses ".class".)  */
346169689Skan
347169689Skanstatic inline void
348169689Skanremove_suffix (char *name, int len)
349169689Skan{
350169689Skan  int i;
351169689Skan
352169689Skan  for (i = 2;  i < 8 && len > i;  i++)
353169689Skan    {
354169689Skan      if (name[len - i] == '.')
355169689Skan	{
356169689Skan	  name[len - i] = '\0';
357169689Skan	  break;
358169689Skan	}
359169689Skan    }
360169689Skan}
361169689Skan
362169689Skan/* Create a nameless artificial label and put it in the current function
363169689Skan   context.  Returns the newly created label.  */
364169689Skan
365169689Skantree
366169689Skancreate_artificial_label (void)
367169689Skan{
368169689Skan  tree lab = build_decl (LABEL_DECL, NULL_TREE, void_type_node);
369169689Skan
370169689Skan  DECL_ARTIFICIAL (lab) = 1;
371169689Skan  DECL_IGNORED_P (lab) = 1;
372169689Skan  DECL_CONTEXT (lab) = current_function_decl;
373169689Skan  return lab;
374169689Skan}
375169689Skan
376169689Skan/* Subroutine for find_single_pointer_decl.  */
377169689Skan
378169689Skanstatic tree
379169689Skanfind_single_pointer_decl_1 (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
380169689Skan			    void *data)
381169689Skan{
382169689Skan  tree *pdecl = (tree *) data;
383169689Skan
384169689Skan  if (DECL_P (*tp) && POINTER_TYPE_P (TREE_TYPE (*tp)))
385169689Skan    {
386169689Skan      if (*pdecl)
387169689Skan	{
388169689Skan	  /* We already found a pointer decl; return anything other
389169689Skan	     than NULL_TREE to unwind from walk_tree signalling that
390169689Skan	     we have a duplicate.  */
391169689Skan	  return *tp;
392169689Skan	}
393169689Skan      *pdecl = *tp;
394169689Skan    }
395169689Skan
396169689Skan  return NULL_TREE;
397169689Skan}
398169689Skan
399169689Skan/* Find the single DECL of pointer type in the tree T and return it.
400169689Skan   If there are zero or more than one such DECLs, return NULL.  */
401169689Skan
402169689Skanstatic tree
403169689Skanfind_single_pointer_decl (tree t)
404169689Skan{
405169689Skan  tree decl = NULL_TREE;
406169689Skan
407169689Skan  if (walk_tree (&t, find_single_pointer_decl_1, &decl, NULL))
408169689Skan    {
409169689Skan      /* find_single_pointer_decl_1 returns a nonzero value, causing
410169689Skan	 walk_tree to return a nonzero value, to indicate that it
411169689Skan	 found more than one pointer DECL.  */
412169689Skan      return NULL_TREE;
413169689Skan    }
414169689Skan
415169689Skan  return decl;
416169689Skan}
417169689Skan
418169689Skan/* Create a new temporary name with PREFIX.  Returns an identifier.  */
419169689Skan
420169689Skanstatic GTY(()) unsigned int tmp_var_id_num;
421169689Skan
422169689Skantree
423169689Skancreate_tmp_var_name (const char *prefix)
424169689Skan{
425169689Skan  char *tmp_name;
426169689Skan
427169689Skan  if (prefix)
428169689Skan    {
429169689Skan      char *preftmp = ASTRDUP (prefix);
430169689Skan
431169689Skan      remove_suffix (preftmp, strlen (preftmp));
432169689Skan      prefix = preftmp;
433169689Skan    }
434169689Skan
435169689Skan  ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix ? prefix : "T", tmp_var_id_num++);
436169689Skan  return get_identifier (tmp_name);
437169689Skan}
438169689Skan
439169689Skan
440169689Skan/* Create a new temporary variable declaration of type TYPE.
441169689Skan   Does NOT push it into the current binding.  */
442169689Skan
443169689Skantree
444169689Skancreate_tmp_var_raw (tree type, const char *prefix)
445169689Skan{
446169689Skan  tree tmp_var;
447169689Skan  tree new_type;
448169689Skan
449169689Skan  /* Make the type of the variable writable.  */
450169689Skan  new_type = build_type_variant (type, 0, 0);
451169689Skan  TYPE_ATTRIBUTES (new_type) = TYPE_ATTRIBUTES (type);
452169689Skan
453169689Skan  tmp_var = build_decl (VAR_DECL, prefix ? create_tmp_var_name (prefix) : NULL,
454169689Skan			type);
455169689Skan
456169689Skan  /* The variable was declared by the compiler.  */
457169689Skan  DECL_ARTIFICIAL (tmp_var) = 1;
458169689Skan  /* And we don't want debug info for it.  */
459169689Skan  DECL_IGNORED_P (tmp_var) = 1;
460169689Skan
461169689Skan  /* Make the variable writable.  */
462169689Skan  TREE_READONLY (tmp_var) = 0;
463169689Skan
464169689Skan  DECL_EXTERNAL (tmp_var) = 0;
465169689Skan  TREE_STATIC (tmp_var) = 0;
466169689Skan  TREE_USED (tmp_var) = 1;
467169689Skan
468169689Skan  return tmp_var;
469169689Skan}
470169689Skan
471169689Skan/* Create a new temporary variable declaration of type TYPE.  DOES push the
472169689Skan   variable into the current binding.  Further, assume that this is called
473169689Skan   only from gimplification or optimization, at which point the creation of
474169689Skan   certain types are bugs.  */
475169689Skan
476169689Skantree
477169689Skancreate_tmp_var (tree type, const char *prefix)
478169689Skan{
479169689Skan  tree tmp_var;
480169689Skan
481169689Skan  /* We don't allow types that are addressable (meaning we can't make copies),
482169689Skan     or incomplete.  We also used to reject every variable size objects here,
483169689Skan     but now support those for which a constant upper bound can be obtained.
484169689Skan     The processing for variable sizes is performed in gimple_add_tmp_var,
485169689Skan     point at which it really matters and possibly reached via paths not going
486169689Skan     through this function, e.g. after direct calls to create_tmp_var_raw.  */
487169689Skan  gcc_assert (!TREE_ADDRESSABLE (type) && COMPLETE_TYPE_P (type));
488169689Skan
489169689Skan  tmp_var = create_tmp_var_raw (type, prefix);
490169689Skan  gimple_add_tmp_var (tmp_var);
491169689Skan  return tmp_var;
492169689Skan}
493169689Skan
494169689Skan/*  Given a tree, try to return a useful variable name that we can use
495169689Skan    to prefix a temporary that is being assigned the value of the tree.
496169689Skan    I.E. given  <temp> = &A, return A.  */
497169689Skan
498169689Skanconst char *
499169689Skanget_name (tree t)
500169689Skan{
501169689Skan  tree stripped_decl;
502169689Skan
503169689Skan  stripped_decl = t;
504169689Skan  STRIP_NOPS (stripped_decl);
505169689Skan  if (DECL_P (stripped_decl) && DECL_NAME (stripped_decl))
506169689Skan    return IDENTIFIER_POINTER (DECL_NAME (stripped_decl));
507169689Skan  else
508169689Skan    {
509169689Skan      switch (TREE_CODE (stripped_decl))
510169689Skan	{
511169689Skan	case ADDR_EXPR:
512169689Skan	  return get_name (TREE_OPERAND (stripped_decl, 0));
513169689Skan	  break;
514169689Skan	default:
515169689Skan	  return NULL;
516169689Skan	}
517169689Skan    }
518169689Skan}
519169689Skan
520169689Skan/* Create a temporary with a name derived from VAL.  Subroutine of
521169689Skan   lookup_tmp_var; nobody else should call this function.  */
522169689Skan
523169689Skanstatic inline tree
524169689Skancreate_tmp_from_val (tree val)
525169689Skan{
526169689Skan  return create_tmp_var (TYPE_MAIN_VARIANT (TREE_TYPE (val)), get_name (val));
527169689Skan}
528169689Skan
529169689Skan/* Create a temporary to hold the value of VAL.  If IS_FORMAL, try to reuse
530169689Skan   an existing expression temporary.  */
531169689Skan
532169689Skanstatic tree
533169689Skanlookup_tmp_var (tree val, bool is_formal)
534169689Skan{
535169689Skan  tree ret;
536169689Skan
537169689Skan  /* If not optimizing, never really reuse a temporary.  local-alloc
538169689Skan     won't allocate any variable that is used in more than one basic
539169689Skan     block, which means it will go into memory, causing much extra
540169689Skan     work in reload and final and poorer code generation, outweighing
541169689Skan     the extra memory allocation here.  */
542169689Skan  if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
543169689Skan    ret = create_tmp_from_val (val);
544169689Skan  else
545169689Skan    {
546169689Skan      elt_t elt, *elt_p;
547169689Skan      void **slot;
548169689Skan
549169689Skan      elt.val = val;
550169689Skan      slot = htab_find_slot (gimplify_ctxp->temp_htab, (void *)&elt, INSERT);
551169689Skan      if (*slot == NULL)
552169689Skan	{
553169689Skan	  elt_p = XNEW (elt_t);
554169689Skan	  elt_p->val = val;
555169689Skan	  elt_p->temp = ret = create_tmp_from_val (val);
556169689Skan	  *slot = (void *) elt_p;
557169689Skan	}
558169689Skan      else
559169689Skan	{
560169689Skan	  elt_p = (elt_t *) *slot;
561169689Skan          ret = elt_p->temp;
562169689Skan	}
563169689Skan    }
564169689Skan
565169689Skan  if (is_formal)
566169689Skan    DECL_GIMPLE_FORMAL_TEMP_P (ret) = 1;
567169689Skan
568169689Skan  return ret;
569169689Skan}
570169689Skan
571169689Skan/* Returns a formal temporary variable initialized with VAL.  PRE_P is as
572169689Skan   in gimplify_expr.  Only use this function if:
573169689Skan
574169689Skan   1) The value of the unfactored expression represented by VAL will not
575169689Skan      change between the initialization and use of the temporary, and
576169689Skan   2) The temporary will not be otherwise modified.
577169689Skan
578169689Skan   For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
579169689Skan   and #2 means it is inappropriate for && temps.
580169689Skan
581169689Skan   For other cases, use get_initialized_tmp_var instead.  */
582169689Skan
583169689Skanstatic tree
584169689Skaninternal_get_tmp_var (tree val, tree *pre_p, tree *post_p, bool is_formal)
585169689Skan{
586169689Skan  tree t, mod;
587169689Skan
588169689Skan  gimplify_expr (&val, pre_p, post_p, is_gimple_formal_tmp_rhs, fb_rvalue);
589169689Skan
590169689Skan  t = lookup_tmp_var (val, is_formal);
591169689Skan
592169689Skan  if (is_formal)
593169689Skan    {
594169689Skan      tree u = find_single_pointer_decl (val);
595169689Skan
596169689Skan      if (u && TREE_CODE (u) == VAR_DECL && DECL_BASED_ON_RESTRICT_P (u))
597169689Skan	u = DECL_GET_RESTRICT_BASE (u);
598169689Skan      if (u && TYPE_RESTRICT (TREE_TYPE (u)))
599169689Skan	{
600169689Skan	  if (DECL_BASED_ON_RESTRICT_P (t))
601169689Skan	    gcc_assert (u == DECL_GET_RESTRICT_BASE (t));
602169689Skan	  else
603169689Skan	    {
604169689Skan	      DECL_BASED_ON_RESTRICT_P (t) = 1;
605169689Skan	      SET_DECL_RESTRICT_BASE (t, u);
606169689Skan	    }
607169689Skan	}
608169689Skan    }
609169689Skan
610169689Skan  if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE)
611169689Skan    DECL_COMPLEX_GIMPLE_REG_P (t) = 1;
612169689Skan
613169689Skan  mod = build2 (INIT_EXPR, TREE_TYPE (t), t, val);
614169689Skan
615169689Skan  if (EXPR_HAS_LOCATION (val))
616169689Skan    SET_EXPR_LOCUS (mod, EXPR_LOCUS (val));
617169689Skan  else
618169689Skan    SET_EXPR_LOCATION (mod, input_location);
619169689Skan
620169689Skan  /* gimplify_modify_expr might want to reduce this further.  */
621169689Skan  gimplify_and_add (mod, pre_p);
622169689Skan
623169689Skan  /* If we're gimplifying into ssa, gimplify_modify_expr will have
624169689Skan     given our temporary an ssa name.  Find and return it.  */
625169689Skan  if (gimplify_ctxp->into_ssa)
626169689Skan    t = TREE_OPERAND (mod, 0);
627169689Skan
628169689Skan  return t;
629169689Skan}
630169689Skan
631169689Skan/* Returns a formal temporary variable initialized with VAL.  PRE_P
632169689Skan   points to a statement list where side-effects needed to compute VAL
633169689Skan   should be stored.  */
634169689Skan
635169689Skantree
636169689Skanget_formal_tmp_var (tree val, tree *pre_p)
637169689Skan{
638169689Skan  return internal_get_tmp_var (val, pre_p, NULL, true);
639169689Skan}
640169689Skan
641169689Skan/* Returns a temporary variable initialized with VAL.  PRE_P and POST_P
642169689Skan   are as in gimplify_expr.  */
643169689Skan
644169689Skantree
645169689Skanget_initialized_tmp_var (tree val, tree *pre_p, tree *post_p)
646169689Skan{
647169689Skan  return internal_get_tmp_var (val, pre_p, post_p, false);
648169689Skan}
649169689Skan
650169689Skan/* Declares all the variables in VARS in SCOPE.  If DEBUG_INFO is
651169689Skan   true, generate debug info for them; otherwise don't.  */
652169689Skan
653169689Skanvoid
654169689Skandeclare_vars (tree vars, tree scope, bool debug_info)
655169689Skan{
656169689Skan  tree last = vars;
657169689Skan  if (last)
658169689Skan    {
659169689Skan      tree temps, block;
660169689Skan
661169689Skan      /* C99 mode puts the default 'return 0;' for main outside the outer
662169689Skan	 braces.  So drill down until we find an actual scope.  */
663169689Skan      while (TREE_CODE (scope) == COMPOUND_EXPR)
664169689Skan	scope = TREE_OPERAND (scope, 0);
665169689Skan
666169689Skan      gcc_assert (TREE_CODE (scope) == BIND_EXPR);
667169689Skan
668169689Skan      temps = nreverse (last);
669169689Skan
670169689Skan      block = BIND_EXPR_BLOCK (scope);
671169689Skan      if (!block || !debug_info)
672169689Skan	{
673169689Skan	  TREE_CHAIN (last) = BIND_EXPR_VARS (scope);
674169689Skan	  BIND_EXPR_VARS (scope) = temps;
675169689Skan	}
676169689Skan      else
677169689Skan	{
678169689Skan	  /* We need to attach the nodes both to the BIND_EXPR and to its
679169689Skan	     associated BLOCK for debugging purposes.  The key point here
680169689Skan	     is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
681169689Skan	     is a subchain of the BIND_EXPR_VARS of the BIND_EXPR.  */
682169689Skan	  if (BLOCK_VARS (block))
683169689Skan	    BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
684169689Skan	  else
685169689Skan	    {
686169689Skan	      BIND_EXPR_VARS (scope) = chainon (BIND_EXPR_VARS (scope), temps);
687169689Skan	      BLOCK_VARS (block) = temps;
688169689Skan	    }
689169689Skan	}
690169689Skan    }
691169689Skan}
692169689Skan
693169689Skan/* For VAR a VAR_DECL of variable size, try to find a constant upper bound
694169689Skan   for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly.  Abort if
695169689Skan   no such upper bound can be obtained.  */
696169689Skan
697169689Skanstatic void
698169689Skanforce_constant_size (tree var)
699169689Skan{
700169689Skan  /* The only attempt we make is by querying the maximum size of objects
701169689Skan     of the variable's type.  */
702169689Skan
703169689Skan  HOST_WIDE_INT max_size;
704169689Skan
705169689Skan  gcc_assert (TREE_CODE (var) == VAR_DECL);
706169689Skan
707169689Skan  max_size = max_int_size_in_bytes (TREE_TYPE (var));
708169689Skan
709169689Skan  gcc_assert (max_size >= 0);
710169689Skan
711169689Skan  DECL_SIZE_UNIT (var)
712169689Skan    = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
713169689Skan  DECL_SIZE (var)
714169689Skan    = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
715169689Skan}
716169689Skan
717169689Skanvoid
718169689Skangimple_add_tmp_var (tree tmp)
719169689Skan{
720169689Skan  gcc_assert (!TREE_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
721169689Skan
722169689Skan  /* Later processing assumes that the object size is constant, which might
723169689Skan     not be true at this point.  Force the use of a constant upper bound in
724169689Skan     this case.  */
725169689Skan  if (!host_integerp (DECL_SIZE_UNIT (tmp), 1))
726169689Skan    force_constant_size (tmp);
727169689Skan
728169689Skan  DECL_CONTEXT (tmp) = current_function_decl;
729169689Skan  DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
730169689Skan
731169689Skan  if (gimplify_ctxp)
732169689Skan    {
733169689Skan      TREE_CHAIN (tmp) = gimplify_ctxp->temps;
734169689Skan      gimplify_ctxp->temps = tmp;
735169689Skan
736169689Skan      /* Mark temporaries local within the nearest enclosing parallel.  */
737169689Skan      if (gimplify_omp_ctxp)
738169689Skan	{
739169689Skan	  struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
740169689Skan	  while (ctx && !ctx->is_parallel)
741169689Skan	    ctx = ctx->outer_context;
742169689Skan	  if (ctx)
743169689Skan	    omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN);
744169689Skan	}
745169689Skan    }
746169689Skan  else if (cfun)
747169689Skan    record_vars (tmp);
748169689Skan  else
749169689Skan    declare_vars (tmp, DECL_SAVED_TREE (current_function_decl), false);
750169689Skan}
751169689Skan
752169689Skan/* Determines whether to assign a locus to the statement STMT.  */
753169689Skan
754169689Skanstatic bool
755169689Skanshould_carry_locus_p (tree stmt)
756169689Skan{
757169689Skan  /* Don't emit a line note for a label.  We particularly don't want to
758169689Skan     emit one for the break label, since it doesn't actually correspond
759169689Skan     to the beginning of the loop/switch.  */
760169689Skan  if (TREE_CODE (stmt) == LABEL_EXPR)
761169689Skan    return false;
762169689Skan
763169689Skan  /* Do not annotate empty statements, since it confuses gcov.  */
764169689Skan  if (!TREE_SIDE_EFFECTS (stmt))
765169689Skan    return false;
766169689Skan
767169689Skan  return true;
768169689Skan}
769169689Skan
770169689Skanstatic void
771169689Skanannotate_one_with_locus (tree t, location_t locus)
772169689Skan{
773169689Skan  if (EXPR_P (t) && ! EXPR_HAS_LOCATION (t) && should_carry_locus_p (t))
774169689Skan    SET_EXPR_LOCATION (t, locus);
775169689Skan}
776169689Skan
777169689Skanvoid
778169689Skanannotate_all_with_locus (tree *stmt_p, location_t locus)
779169689Skan{
780169689Skan  tree_stmt_iterator i;
781169689Skan
782169689Skan  if (!*stmt_p)
783169689Skan    return;
784169689Skan
785169689Skan  for (i = tsi_start (*stmt_p); !tsi_end_p (i); tsi_next (&i))
786169689Skan    {
787169689Skan      tree t = tsi_stmt (i);
788169689Skan
789169689Skan      /* Assuming we've already been gimplified, we shouldn't
790169689Skan	  see nested chaining constructs anymore.  */
791169689Skan      gcc_assert (TREE_CODE (t) != STATEMENT_LIST
792169689Skan		  && TREE_CODE (t) != COMPOUND_EXPR);
793169689Skan
794169689Skan      annotate_one_with_locus (t, locus);
795169689Skan    }
796169689Skan}
797169689Skan
798169689Skan/* Similar to copy_tree_r() but do not copy SAVE_EXPR or TARGET_EXPR nodes.
799169689Skan   These nodes model computations that should only be done once.  If we
800169689Skan   were to unshare something like SAVE_EXPR(i++), the gimplification
801169689Skan   process would create wrong code.  */
802169689Skan
803169689Skanstatic tree
804169689Skanmostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
805169689Skan{
806169689Skan  enum tree_code code = TREE_CODE (*tp);
807169689Skan  /* Don't unshare types, decls, constants and SAVE_EXPR nodes.  */
808169689Skan  if (TREE_CODE_CLASS (code) == tcc_type
809169689Skan      || TREE_CODE_CLASS (code) == tcc_declaration
810169689Skan      || TREE_CODE_CLASS (code) == tcc_constant
811169689Skan      || code == SAVE_EXPR || code == TARGET_EXPR
812169689Skan      /* We can't do anything sensible with a BLOCK used as an expression,
813169689Skan	 but we also can't just die when we see it because of non-expression
814169689Skan	 uses.  So just avert our eyes and cross our fingers.  Silly Java.  */
815169689Skan      || code == BLOCK)
816169689Skan    *walk_subtrees = 0;
817169689Skan  else
818169689Skan    {
819169689Skan      gcc_assert (code != BIND_EXPR);
820169689Skan      copy_tree_r (tp, walk_subtrees, data);
821169689Skan    }
822169689Skan
823169689Skan  return NULL_TREE;
824169689Skan}
825169689Skan
826169689Skan/* Callback for walk_tree to unshare most of the shared trees rooted at
827169689Skan   *TP.  If *TP has been visited already (i.e., TREE_VISITED (*TP) == 1),
828169689Skan   then *TP is deep copied by calling copy_tree_r.
829169689Skan
830169689Skan   This unshares the same trees as copy_tree_r with the exception of
831169689Skan   SAVE_EXPR nodes.  These nodes model computations that should only be
832169689Skan   done once.  If we were to unshare something like SAVE_EXPR(i++), the
833169689Skan   gimplification process would create wrong code.  */
834169689Skan
835169689Skanstatic tree
836169689Skancopy_if_shared_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
837169689Skan		  void *data ATTRIBUTE_UNUSED)
838169689Skan{
839169689Skan  tree t = *tp;
840169689Skan  enum tree_code code = TREE_CODE (t);
841169689Skan
842169689Skan  /* Skip types, decls, and constants.  But we do want to look at their
843169689Skan     types and the bounds of types.  Mark them as visited so we properly
844169689Skan     unmark their subtrees on the unmark pass.  If we've already seen them,
845169689Skan     don't look down further.  */
846169689Skan  if (TREE_CODE_CLASS (code) == tcc_type
847169689Skan      || TREE_CODE_CLASS (code) == tcc_declaration
848169689Skan      || TREE_CODE_CLASS (code) == tcc_constant)
849169689Skan    {
850169689Skan      if (TREE_VISITED (t))
851169689Skan	*walk_subtrees = 0;
852169689Skan      else
853169689Skan	TREE_VISITED (t) = 1;
854169689Skan    }
855169689Skan
856169689Skan  /* If this node has been visited already, unshare it and don't look
857169689Skan     any deeper.  */
858169689Skan  else if (TREE_VISITED (t))
859169689Skan    {
860169689Skan      walk_tree (tp, mostly_copy_tree_r, NULL, NULL);
861169689Skan      *walk_subtrees = 0;
862169689Skan    }
863169689Skan
864169689Skan  /* Otherwise, mark the tree as visited and keep looking.  */
865169689Skan  else
866169689Skan    TREE_VISITED (t) = 1;
867169689Skan
868169689Skan  return NULL_TREE;
869169689Skan}
870169689Skan
871169689Skanstatic tree
872169689Skanunmark_visited_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
873169689Skan		  void *data ATTRIBUTE_UNUSED)
874169689Skan{
875169689Skan  if (TREE_VISITED (*tp))
876169689Skan    TREE_VISITED (*tp) = 0;
877169689Skan  else
878169689Skan    *walk_subtrees = 0;
879169689Skan
880169689Skan  return NULL_TREE;
881169689Skan}
882169689Skan
883169689Skan/* Unshare all the trees in BODY_P, a pointer into the body of FNDECL, and the
884169689Skan   bodies of any nested functions if we are unsharing the entire body of
885169689Skan   FNDECL.  */
886169689Skan
887169689Skanstatic void
888169689Skanunshare_body (tree *body_p, tree fndecl)
889169689Skan{
890169689Skan  struct cgraph_node *cgn = cgraph_node (fndecl);
891169689Skan
892169689Skan  walk_tree (body_p, copy_if_shared_r, NULL, NULL);
893169689Skan  if (body_p == &DECL_SAVED_TREE (fndecl))
894169689Skan    for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
895169689Skan      unshare_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
896169689Skan}
897169689Skan
898169689Skan/* Likewise, but mark all trees as not visited.  */
899169689Skan
900169689Skanstatic void
901169689Skanunvisit_body (tree *body_p, tree fndecl)
902169689Skan{
903169689Skan  struct cgraph_node *cgn = cgraph_node (fndecl);
904169689Skan
905169689Skan  walk_tree (body_p, unmark_visited_r, NULL, NULL);
906169689Skan  if (body_p == &DECL_SAVED_TREE (fndecl))
907169689Skan    for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
908169689Skan      unvisit_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
909169689Skan}
910169689Skan
911169689Skan/* Unshare T and all the trees reached from T via TREE_CHAIN.  */
912169689Skan
913169689Skanstatic void
914169689Skanunshare_all_trees (tree t)
915169689Skan{
916169689Skan  walk_tree (&t, copy_if_shared_r, NULL, NULL);
917169689Skan  walk_tree (&t, unmark_visited_r, NULL, NULL);
918169689Skan}
919169689Skan
920169689Skan/* Unconditionally make an unshared copy of EXPR.  This is used when using
921169689Skan   stored expressions which span multiple functions, such as BINFO_VTABLE,
922169689Skan   as the normal unsharing process can't tell that they're shared.  */
923169689Skan
924169689Skantree
925169689Skanunshare_expr (tree expr)
926169689Skan{
927169689Skan  walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
928169689Skan  return expr;
929169689Skan}
930169689Skan
931169689Skan/* A terser interface for building a representation of an exception
932169689Skan   specification.  */
933169689Skan
934169689Skantree
935169689Skangimple_build_eh_filter (tree body, tree allowed, tree failure)
936169689Skan{
937169689Skan  tree t;
938169689Skan
939169689Skan  /* FIXME should the allowed types go in TREE_TYPE?  */
940169689Skan  t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
941169689Skan  append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
942169689Skan
943169689Skan  t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
944169689Skan  append_to_statement_list (body, &TREE_OPERAND (t, 0));
945169689Skan
946169689Skan  return t;
947169689Skan}
948169689Skan
949169689Skan
950169689Skan/* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
951169689Skan   contain statements and have a value.  Assign its value to a temporary
952169689Skan   and give it void_type_node.  Returns the temporary, or NULL_TREE if
953169689Skan   WRAPPER was already void.  */
954169689Skan
955169689Skantree
956169689Skanvoidify_wrapper_expr (tree wrapper, tree temp)
957169689Skan{
958169689Skan  tree type = TREE_TYPE (wrapper);
959169689Skan  if (type && !VOID_TYPE_P (type))
960169689Skan    {
961169689Skan      tree *p;
962169689Skan
963169689Skan      /* Set p to point to the body of the wrapper.  Loop until we find
964169689Skan	 something that isn't a wrapper.  */
965169689Skan      for (p = &wrapper; p && *p; )
966169689Skan	{
967169689Skan	  switch (TREE_CODE (*p))
968169689Skan	    {
969169689Skan	    case BIND_EXPR:
970169689Skan	      TREE_SIDE_EFFECTS (*p) = 1;
971169689Skan	      TREE_TYPE (*p) = void_type_node;
972169689Skan	      /* For a BIND_EXPR, the body is operand 1.  */
973169689Skan	      p = &BIND_EXPR_BODY (*p);
974169689Skan	      break;
975169689Skan
976169689Skan	    case CLEANUP_POINT_EXPR:
977169689Skan	    case TRY_FINALLY_EXPR:
978169689Skan	    case TRY_CATCH_EXPR:
979169689Skan	      TREE_SIDE_EFFECTS (*p) = 1;
980169689Skan	      TREE_TYPE (*p) = void_type_node;
981169689Skan	      p = &TREE_OPERAND (*p, 0);
982169689Skan	      break;
983169689Skan
984169689Skan	    case STATEMENT_LIST:
985169689Skan	      {
986169689Skan		tree_stmt_iterator i = tsi_last (*p);
987169689Skan		TREE_SIDE_EFFECTS (*p) = 1;
988169689Skan		TREE_TYPE (*p) = void_type_node;
989169689Skan		p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
990169689Skan	      }
991169689Skan	      break;
992169689Skan
993169689Skan	    case COMPOUND_EXPR:
994169689Skan	      /* Advance to the last statement.  Set all container types to void.  */
995169689Skan	      for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
996169689Skan		{
997169689Skan		  TREE_SIDE_EFFECTS (*p) = 1;
998169689Skan		  TREE_TYPE (*p) = void_type_node;
999169689Skan		}
1000169689Skan	      break;
1001169689Skan
1002169689Skan	    default:
1003169689Skan	      goto out;
1004169689Skan	    }
1005169689Skan	}
1006169689Skan
1007169689Skan    out:
1008169689Skan      if (p == NULL || IS_EMPTY_STMT (*p))
1009169689Skan	temp = NULL_TREE;
1010169689Skan      else if (temp)
1011169689Skan	{
1012169689Skan	  /* The wrapper is on the RHS of an assignment that we're pushing
1013169689Skan	     down.  */
1014169689Skan	  gcc_assert (TREE_CODE (temp) == INIT_EXPR
1015169689Skan		      || TREE_CODE (temp) == MODIFY_EXPR);
1016169689Skan	  TREE_OPERAND (temp, 1) = *p;
1017169689Skan	  *p = temp;
1018169689Skan	}
1019169689Skan      else
1020169689Skan	{
1021169689Skan	  temp = create_tmp_var (type, "retval");
1022169689Skan	  *p = build2 (INIT_EXPR, type, temp, *p);
1023169689Skan	}
1024169689Skan
1025169689Skan      return temp;
1026169689Skan    }
1027169689Skan
1028169689Skan  return NULL_TREE;
1029169689Skan}
1030169689Skan
1031169689Skan/* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1032169689Skan   a temporary through which they communicate.  */
1033169689Skan
1034169689Skanstatic void
1035169689Skanbuild_stack_save_restore (tree *save, tree *restore)
1036169689Skan{
1037169689Skan  tree save_call, tmp_var;
1038169689Skan
1039169689Skan  save_call =
1040169689Skan      build_function_call_expr (implicit_built_in_decls[BUILT_IN_STACK_SAVE],
1041169689Skan				NULL_TREE);
1042169689Skan  tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1043169689Skan
1044169689Skan  *save = build2 (MODIFY_EXPR, ptr_type_node, tmp_var, save_call);
1045169689Skan  *restore =
1046169689Skan    build_function_call_expr (implicit_built_in_decls[BUILT_IN_STACK_RESTORE],
1047169689Skan			      tree_cons (NULL_TREE, tmp_var, NULL_TREE));
1048169689Skan}
1049169689Skan
1050169689Skan/* Gimplify a BIND_EXPR.  Just voidify and recurse.  */
1051169689Skan
1052169689Skanstatic enum gimplify_status
1053169689Skangimplify_bind_expr (tree *expr_p, tree *pre_p)
1054169689Skan{
1055169689Skan  tree bind_expr = *expr_p;
1056169689Skan  bool old_save_stack = gimplify_ctxp->save_stack;
1057169689Skan  tree t;
1058169689Skan
1059169689Skan  tree temp = voidify_wrapper_expr (bind_expr, NULL);
1060169689Skan
1061169689Skan  /* Mark variables seen in this bind expr.  */
1062169689Skan  for (t = BIND_EXPR_VARS (bind_expr); t ; t = TREE_CHAIN (t))
1063169689Skan    {
1064169689Skan      if (TREE_CODE (t) == VAR_DECL)
1065169689Skan	{
1066169689Skan	  struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1067169689Skan
1068169689Skan	  /* Mark variable as local.  */
1069169689Skan	  if (ctx && !is_global_var (t)
1070169689Skan	      && (! DECL_SEEN_IN_BIND_EXPR_P (t)
1071169689Skan		  || splay_tree_lookup (ctx->variables,
1072169689Skan					(splay_tree_key) t) == NULL))
1073169689Skan	    omp_add_variable (gimplify_omp_ctxp, t, GOVD_LOCAL | GOVD_SEEN);
1074169689Skan
1075169689Skan	  DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1076169689Skan	}
1077169689Skan
1078169689Skan      /* Preliminarily mark non-addressed complex variables as eligible
1079169689Skan	 for promotion to gimple registers.  We'll transform their uses
1080169689Skan	 as we find them.  */
1081169689Skan      if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
1082169689Skan	  && !TREE_THIS_VOLATILE (t)
1083169689Skan	  && (TREE_CODE (t) == VAR_DECL && !DECL_HARD_REGISTER (t))
1084169689Skan	  && !needs_to_live_in_memory (t))
1085169689Skan	DECL_COMPLEX_GIMPLE_REG_P (t) = 1;
1086169689Skan    }
1087169689Skan
1088169689Skan  gimple_push_bind_expr (bind_expr);
1089169689Skan  gimplify_ctxp->save_stack = false;
1090169689Skan
1091169689Skan  gimplify_to_stmt_list (&BIND_EXPR_BODY (bind_expr));
1092169689Skan
1093169689Skan  if (gimplify_ctxp->save_stack)
1094169689Skan    {
1095169689Skan      tree stack_save, stack_restore;
1096169689Skan
1097169689Skan      /* Save stack on entry and restore it on exit.  Add a try_finally
1098169689Skan	 block to achieve this.  Note that mudflap depends on the
1099169689Skan	 format of the emitted code: see mx_register_decls().  */
1100169689Skan      build_stack_save_restore (&stack_save, &stack_restore);
1101169689Skan
1102169689Skan      t = build2 (TRY_FINALLY_EXPR, void_type_node,
1103169689Skan		  BIND_EXPR_BODY (bind_expr), NULL_TREE);
1104169689Skan      append_to_statement_list (stack_restore, &TREE_OPERAND (t, 1));
1105169689Skan
1106169689Skan      BIND_EXPR_BODY (bind_expr) = NULL_TREE;
1107169689Skan      append_to_statement_list (stack_save, &BIND_EXPR_BODY (bind_expr));
1108169689Skan      append_to_statement_list (t, &BIND_EXPR_BODY (bind_expr));
1109169689Skan    }
1110169689Skan
1111169689Skan  gimplify_ctxp->save_stack = old_save_stack;
1112169689Skan  gimple_pop_bind_expr ();
1113169689Skan
1114169689Skan  if (temp)
1115169689Skan    {
1116169689Skan      *expr_p = temp;
1117169689Skan      append_to_statement_list (bind_expr, pre_p);
1118169689Skan      return GS_OK;
1119169689Skan    }
1120169689Skan  else
1121169689Skan    return GS_ALL_DONE;
1122169689Skan}
1123169689Skan
1124169689Skan/* Gimplify a RETURN_EXPR.  If the expression to be returned is not a
1125169689Skan   GIMPLE value, it is assigned to a new temporary and the statement is
1126169689Skan   re-written to return the temporary.
1127169689Skan
1128169689Skan   PRE_P points to the list where side effects that must happen before
1129169689Skan   STMT should be stored.  */
1130169689Skan
1131169689Skanstatic enum gimplify_status
1132169689Skangimplify_return_expr (tree stmt, tree *pre_p)
1133169689Skan{
1134169689Skan  tree ret_expr = TREE_OPERAND (stmt, 0);
1135169689Skan  tree result_decl, result;
1136169689Skan
1137169689Skan  if (!ret_expr || TREE_CODE (ret_expr) == RESULT_DECL
1138169689Skan      || ret_expr == error_mark_node)
1139169689Skan    return GS_ALL_DONE;
1140169689Skan
1141169689Skan  if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1142169689Skan    result_decl = NULL_TREE;
1143169689Skan  else
1144169689Skan    {
1145169689Skan      result_decl = TREE_OPERAND (ret_expr, 0);
1146169689Skan      if (TREE_CODE (result_decl) == INDIRECT_REF)
1147169689Skan	/* See through a return by reference.  */
1148169689Skan	result_decl = TREE_OPERAND (result_decl, 0);
1149169689Skan
1150169689Skan      gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1151169689Skan		   || TREE_CODE (ret_expr) == INIT_EXPR)
1152169689Skan		  && TREE_CODE (result_decl) == RESULT_DECL);
1153169689Skan    }
1154169689Skan
1155169689Skan  /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1156169689Skan     Recall that aggregate_value_p is FALSE for any aggregate type that is
1157169689Skan     returned in registers.  If we're returning values in registers, then
1158169689Skan     we don't want to extend the lifetime of the RESULT_DECL, particularly
1159169689Skan     across another call.  In addition, for those aggregates for which
1160169689Skan     hard_function_value generates a PARALLEL, we'll die during normal
1161169689Skan     expansion of structure assignments; there's special code in expand_return
1162169689Skan     to handle this case that does not exist in expand_expr.  */
1163169689Skan  if (!result_decl
1164169689Skan      || aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1165169689Skan    result = result_decl;
1166169689Skan  else if (gimplify_ctxp->return_temp)
1167169689Skan    result = gimplify_ctxp->return_temp;
1168169689Skan  else
1169169689Skan    {
1170169689Skan      result = create_tmp_var (TREE_TYPE (result_decl), NULL);
1171169689Skan
1172169689Skan      /* ??? With complex control flow (usually involving abnormal edges),
1173169689Skan	 we can wind up warning about an uninitialized value for this.  Due
1174169689Skan	 to how this variable is constructed and initialized, this is never
1175169689Skan	 true.  Give up and never warn.  */
1176169689Skan      TREE_NO_WARNING (result) = 1;
1177169689Skan
1178169689Skan      gimplify_ctxp->return_temp = result;
1179169689Skan    }
1180169689Skan
1181169689Skan  /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1182169689Skan     Then gimplify the whole thing.  */
1183169689Skan  if (result != result_decl)
1184169689Skan    TREE_OPERAND (ret_expr, 0) = result;
1185169689Skan
1186169689Skan  gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1187169689Skan
1188169689Skan  /* If we didn't use a temporary, then the result is just the result_decl.
1189169689Skan     Otherwise we need a simple copy.  This should already be gimple.  */
1190169689Skan  if (result == result_decl)
1191169689Skan    ret_expr = result;
1192169689Skan  else
1193169689Skan    ret_expr = build2 (MODIFY_EXPR, TREE_TYPE (result), result_decl, result);
1194169689Skan  TREE_OPERAND (stmt, 0) = ret_expr;
1195169689Skan
1196169689Skan  return GS_ALL_DONE;
1197169689Skan}
1198169689Skan
1199169689Skan/* Gimplifies a DECL_EXPR node *STMT_P by making any necessary allocation
1200169689Skan   and initialization explicit.  */
1201169689Skan
1202169689Skanstatic enum gimplify_status
1203169689Skangimplify_decl_expr (tree *stmt_p)
1204169689Skan{
1205169689Skan  tree stmt = *stmt_p;
1206169689Skan  tree decl = DECL_EXPR_DECL (stmt);
1207169689Skan
1208169689Skan  *stmt_p = NULL_TREE;
1209169689Skan
1210169689Skan  if (TREE_TYPE (decl) == error_mark_node)
1211169689Skan    return GS_ERROR;
1212169689Skan
1213169689Skan  if ((TREE_CODE (decl) == TYPE_DECL
1214169689Skan       || TREE_CODE (decl) == VAR_DECL)
1215169689Skan      && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1216169689Skan    gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
1217169689Skan
1218169689Skan  if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
1219169689Skan    {
1220169689Skan      tree init = DECL_INITIAL (decl);
1221169689Skan
1222169689Skan      if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
1223169689Skan	{
1224169689Skan	  /* This is a variable-sized decl.  Simplify its size and mark it
1225169689Skan	     for deferred expansion.  Note that mudflap depends on the format
1226169689Skan	     of the emitted code: see mx_register_decls().  */
1227169689Skan	  tree t, args, addr, ptr_type;
1228169689Skan
1229169689Skan	  gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
1230169689Skan	  gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
1231169689Skan
1232169689Skan	  /* All occurrences of this decl in final gimplified code will be
1233169689Skan	     replaced by indirection.  Setting DECL_VALUE_EXPR does two
1234169689Skan	     things: First, it lets the rest of the gimplifier know what
1235169689Skan	     replacement to use.  Second, it lets the debug info know
1236169689Skan	     where to find the value.  */
1237169689Skan	  ptr_type = build_pointer_type (TREE_TYPE (decl));
1238169689Skan	  addr = create_tmp_var (ptr_type, get_name (decl));
1239169689Skan	  DECL_IGNORED_P (addr) = 0;
1240169689Skan	  t = build_fold_indirect_ref (addr);
1241169689Skan	  SET_DECL_VALUE_EXPR (decl, t);
1242169689Skan	  DECL_HAS_VALUE_EXPR_P (decl) = 1;
1243169689Skan
1244169689Skan	  args = tree_cons (NULL, DECL_SIZE_UNIT (decl), NULL);
1245169689Skan	  t = built_in_decls[BUILT_IN_ALLOCA];
1246169689Skan	  t = build_function_call_expr (t, args);
1247169689Skan	  t = fold_convert (ptr_type, t);
1248169689Skan	  t = build2 (MODIFY_EXPR, void_type_node, addr, t);
1249169689Skan
1250169689Skan	  gimplify_and_add (t, stmt_p);
1251169689Skan
1252169689Skan	  /* Indicate that we need to restore the stack level when the
1253169689Skan	     enclosing BIND_EXPR is exited.  */
1254169689Skan	  gimplify_ctxp->save_stack = true;
1255169689Skan	}
1256169689Skan
1257169689Skan      if (init && init != error_mark_node)
1258169689Skan	{
1259169689Skan	  if (!TREE_STATIC (decl))
1260169689Skan	    {
1261169689Skan	      DECL_INITIAL (decl) = NULL_TREE;
1262169689Skan	      init = build2 (INIT_EXPR, void_type_node, decl, init);
1263169689Skan	      gimplify_and_add (init, stmt_p);
1264169689Skan	    }
1265169689Skan	  else
1266169689Skan	    /* We must still examine initializers for static variables
1267169689Skan	       as they may contain a label address.  */
1268169689Skan	    walk_tree (&init, force_labels_r, NULL, NULL);
1269169689Skan	}
1270169689Skan
1271169689Skan      /* Some front ends do not explicitly declare all anonymous
1272169689Skan	 artificial variables.  We compensate here by declaring the
1273169689Skan	 variables, though it would be better if the front ends would
1274169689Skan	 explicitly declare them.  */
1275169689Skan      if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1276169689Skan	  && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1277169689Skan	gimple_add_tmp_var (decl);
1278169689Skan    }
1279169689Skan
1280169689Skan  return GS_ALL_DONE;
1281169689Skan}
1282169689Skan
1283169689Skan/* Gimplify a LOOP_EXPR.  Normally this just involves gimplifying the body
1284169689Skan   and replacing the LOOP_EXPR with goto, but if the loop contains an
1285169689Skan   EXIT_EXPR, we need to append a label for it to jump to.  */
1286169689Skan
1287169689Skanstatic enum gimplify_status
1288169689Skangimplify_loop_expr (tree *expr_p, tree *pre_p)
1289169689Skan{
1290169689Skan  tree saved_label = gimplify_ctxp->exit_label;
1291169689Skan  tree start_label = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
1292169689Skan  tree jump_stmt = build_and_jump (&LABEL_EXPR_LABEL (start_label));
1293169689Skan
1294169689Skan  append_to_statement_list (start_label, pre_p);
1295169689Skan
1296169689Skan  gimplify_ctxp->exit_label = NULL_TREE;
1297169689Skan
1298169689Skan  gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1299169689Skan
1300169689Skan  if (gimplify_ctxp->exit_label)
1301169689Skan    {
1302169689Skan      append_to_statement_list (jump_stmt, pre_p);
1303169689Skan      *expr_p = build1 (LABEL_EXPR, void_type_node, gimplify_ctxp->exit_label);
1304169689Skan    }
1305169689Skan  else
1306169689Skan    *expr_p = jump_stmt;
1307169689Skan
1308169689Skan  gimplify_ctxp->exit_label = saved_label;
1309169689Skan
1310169689Skan  return GS_ALL_DONE;
1311169689Skan}
1312169689Skan
1313169689Skan/* Compare two case labels.  Because the front end should already have
1314169689Skan   made sure that case ranges do not overlap, it is enough to only compare
1315169689Skan   the CASE_LOW values of each case label.  */
1316169689Skan
1317169689Skanstatic int
1318169689Skancompare_case_labels (const void *p1, const void *p2)
1319169689Skan{
1320169689Skan  tree case1 = *(tree *)p1;
1321169689Skan  tree case2 = *(tree *)p2;
1322169689Skan
1323169689Skan  return tree_int_cst_compare (CASE_LOW (case1), CASE_LOW (case2));
1324169689Skan}
1325169689Skan
1326169689Skan/* Sort the case labels in LABEL_VEC in place in ascending order.  */
1327169689Skan
1328169689Skanvoid
1329169689Skansort_case_labels (tree label_vec)
1330169689Skan{
1331169689Skan  size_t len = TREE_VEC_LENGTH (label_vec);
1332169689Skan  tree default_case = TREE_VEC_ELT (label_vec, len - 1);
1333169689Skan
1334169689Skan  if (CASE_LOW (default_case))
1335169689Skan    {
1336169689Skan      size_t i;
1337169689Skan
1338169689Skan      /* The last label in the vector should be the default case
1339169689Skan         but it is not.  */
1340169689Skan      for (i = 0; i < len; ++i)
1341169689Skan	{
1342169689Skan	  tree t = TREE_VEC_ELT (label_vec, i);
1343169689Skan	  if (!CASE_LOW (t))
1344169689Skan	    {
1345169689Skan	      default_case = t;
1346169689Skan	      TREE_VEC_ELT (label_vec, i) = TREE_VEC_ELT (label_vec, len - 1);
1347169689Skan	      TREE_VEC_ELT (label_vec, len - 1) = default_case;
1348169689Skan	      break;
1349169689Skan	    }
1350169689Skan	}
1351169689Skan    }
1352169689Skan
1353169689Skan  qsort (&TREE_VEC_ELT (label_vec, 0), len - 1, sizeof (tree),
1354169689Skan	 compare_case_labels);
1355169689Skan}
1356169689Skan
1357169689Skan/* Gimplify a SWITCH_EXPR, and collect a TREE_VEC of the labels it can
1358169689Skan   branch to.  */
1359169689Skan
1360169689Skanstatic enum gimplify_status
1361169689Skangimplify_switch_expr (tree *expr_p, tree *pre_p)
1362169689Skan{
1363169689Skan  tree switch_expr = *expr_p;
1364169689Skan  enum gimplify_status ret;
1365169689Skan
1366169689Skan  ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL,
1367169689Skan		       is_gimple_val, fb_rvalue);
1368169689Skan
1369169689Skan  if (SWITCH_BODY (switch_expr))
1370169689Skan    {
1371169689Skan      VEC(tree,heap) *labels, *saved_labels;
1372169689Skan      tree label_vec, default_case = NULL_TREE;
1373169689Skan      size_t i, len;
1374169689Skan
1375169689Skan      /* If someone can be bothered to fill in the labels, they can
1376169689Skan	 be bothered to null out the body too.  */
1377169689Skan      gcc_assert (!SWITCH_LABELS (switch_expr));
1378169689Skan
1379169689Skan      saved_labels = gimplify_ctxp->case_labels;
1380169689Skan      gimplify_ctxp->case_labels = VEC_alloc (tree, heap, 8);
1381169689Skan
1382169689Skan      gimplify_to_stmt_list (&SWITCH_BODY (switch_expr));
1383169689Skan
1384169689Skan      labels = gimplify_ctxp->case_labels;
1385169689Skan      gimplify_ctxp->case_labels = saved_labels;
1386169689Skan
1387169689Skan      i = 0;
1388169689Skan      while (i < VEC_length (tree, labels))
1389169689Skan	{
1390169689Skan	  tree elt = VEC_index (tree, labels, i);
1391169689Skan	  tree low = CASE_LOW (elt);
1392169689Skan	  bool remove_element = FALSE;
1393169689Skan
1394169689Skan	  if (low)
1395169689Skan	    {
1396169689Skan	      /* Discard empty ranges.  */
1397169689Skan	      tree high = CASE_HIGH (elt);
1398169689Skan	      if (high && INT_CST_LT (high, low))
1399169689Skan	        remove_element = TRUE;
1400169689Skan	    }
1401169689Skan	  else
1402169689Skan	    {
1403169689Skan	      /* The default case must be the last label in the list.  */
1404169689Skan	      gcc_assert (!default_case);
1405169689Skan	      default_case = elt;
1406169689Skan	      remove_element = TRUE;
1407169689Skan	    }
1408169689Skan
1409169689Skan	  if (remove_element)
1410169689Skan	    VEC_ordered_remove (tree, labels, i);
1411169689Skan	  else
1412169689Skan	    i++;
1413169689Skan	}
1414169689Skan      len = i;
1415169689Skan
1416169689Skan      label_vec = make_tree_vec (len + 1);
1417169689Skan      SWITCH_LABELS (*expr_p) = label_vec;
1418169689Skan      append_to_statement_list (switch_expr, pre_p);
1419169689Skan
1420169689Skan      if (! default_case)
1421169689Skan	{
1422169689Skan	  /* If the switch has no default label, add one, so that we jump
1423169689Skan	     around the switch body.  */
1424169689Skan	  default_case = build3 (CASE_LABEL_EXPR, void_type_node, NULL_TREE,
1425169689Skan				 NULL_TREE, create_artificial_label ());
1426169689Skan	  append_to_statement_list (SWITCH_BODY (switch_expr), pre_p);
1427169689Skan	  *expr_p = build1 (LABEL_EXPR, void_type_node,
1428169689Skan			    CASE_LABEL (default_case));
1429169689Skan	}
1430169689Skan      else
1431169689Skan	*expr_p = SWITCH_BODY (switch_expr);
1432169689Skan
1433169689Skan      for (i = 0; i < len; ++i)
1434169689Skan	TREE_VEC_ELT (label_vec, i) = VEC_index (tree, labels, i);
1435169689Skan      TREE_VEC_ELT (label_vec, len) = default_case;
1436169689Skan
1437169689Skan      VEC_free (tree, heap, labels);
1438169689Skan
1439169689Skan      sort_case_labels (label_vec);
1440169689Skan
1441169689Skan      SWITCH_BODY (switch_expr) = NULL;
1442169689Skan    }
1443169689Skan  else
1444169689Skan    gcc_assert (SWITCH_LABELS (switch_expr));
1445169689Skan
1446169689Skan  return ret;
1447169689Skan}
1448169689Skan
1449169689Skanstatic enum gimplify_status
1450169689Skangimplify_case_label_expr (tree *expr_p)
1451169689Skan{
1452169689Skan  tree expr = *expr_p;
1453169689Skan  struct gimplify_ctx *ctxp;
1454169689Skan
1455169689Skan  /* Invalid OpenMP programs can play Duff's Device type games with
1456169689Skan     #pragma omp parallel.  At least in the C front end, we don't
1457169689Skan     detect such invalid branches until after gimplification.  */
1458169689Skan  for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
1459169689Skan    if (ctxp->case_labels)
1460169689Skan      break;
1461169689Skan
1462169689Skan  VEC_safe_push (tree, heap, ctxp->case_labels, expr);
1463169689Skan  *expr_p = build1 (LABEL_EXPR, void_type_node, CASE_LABEL (expr));
1464169689Skan  return GS_ALL_DONE;
1465169689Skan}
1466169689Skan
1467169689Skan/* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
1468169689Skan   if necessary.  */
1469169689Skan
1470169689Skantree
1471169689Skanbuild_and_jump (tree *label_p)
1472169689Skan{
1473169689Skan  if (label_p == NULL)
1474169689Skan    /* If there's nowhere to jump, just fall through.  */
1475169689Skan    return NULL_TREE;
1476169689Skan
1477169689Skan  if (*label_p == NULL_TREE)
1478169689Skan    {
1479169689Skan      tree label = create_artificial_label ();
1480169689Skan      *label_p = label;
1481169689Skan    }
1482169689Skan
1483169689Skan  return build1 (GOTO_EXPR, void_type_node, *label_p);
1484169689Skan}
1485169689Skan
1486169689Skan/* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
1487169689Skan   This also involves building a label to jump to and communicating it to
1488169689Skan   gimplify_loop_expr through gimplify_ctxp->exit_label.  */
1489169689Skan
1490169689Skanstatic enum gimplify_status
1491169689Skangimplify_exit_expr (tree *expr_p)
1492169689Skan{
1493169689Skan  tree cond = TREE_OPERAND (*expr_p, 0);
1494169689Skan  tree expr;
1495169689Skan
1496169689Skan  expr = build_and_jump (&gimplify_ctxp->exit_label);
1497169689Skan  expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
1498169689Skan  *expr_p = expr;
1499169689Skan
1500169689Skan  return GS_OK;
1501169689Skan}
1502169689Skan
1503169689Skan/* A helper function to be called via walk_tree.  Mark all labels under *TP
1504169689Skan   as being forced.  To be called for DECL_INITIAL of static variables.  */
1505169689Skan
1506169689Skantree
1507169689Skanforce_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1508169689Skan{
1509169689Skan  if (TYPE_P (*tp))
1510169689Skan    *walk_subtrees = 0;
1511169689Skan  if (TREE_CODE (*tp) == LABEL_DECL)
1512169689Skan    FORCED_LABEL (*tp) = 1;
1513169689Skan
1514169689Skan  return NULL_TREE;
1515169689Skan}
1516169689Skan
1517169689Skan/* *EXPR_P is a COMPONENT_REF being used as an rvalue.  If its type is
1518169689Skan   different from its canonical type, wrap the whole thing inside a
1519169689Skan   NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
1520169689Skan   type.
1521169689Skan
1522169689Skan   The canonical type of a COMPONENT_REF is the type of the field being
1523169689Skan   referenced--unless the field is a bit-field which can be read directly
1524169689Skan   in a smaller mode, in which case the canonical type is the
1525169689Skan   sign-appropriate type corresponding to that mode.  */
1526169689Skan
1527169689Skanstatic void
1528169689Skancanonicalize_component_ref (tree *expr_p)
1529169689Skan{
1530169689Skan  tree expr = *expr_p;
1531169689Skan  tree type;
1532169689Skan
1533169689Skan  gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
1534169689Skan
1535169689Skan  if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
1536169689Skan    type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
1537169689Skan  else
1538169689Skan    type = TREE_TYPE (TREE_OPERAND (expr, 1));
1539169689Skan
1540169689Skan  if (TREE_TYPE (expr) != type)
1541169689Skan    {
1542169689Skan      tree old_type = TREE_TYPE (expr);
1543169689Skan
1544169689Skan      /* Set the type of the COMPONENT_REF to the underlying type.  */
1545169689Skan      TREE_TYPE (expr) = type;
1546169689Skan
1547169689Skan      /* And wrap the whole thing inside a NOP_EXPR.  */
1548169689Skan      expr = build1 (NOP_EXPR, old_type, expr);
1549169689Skan
1550169689Skan      *expr_p = expr;
1551169689Skan    }
1552169689Skan}
1553169689Skan
1554169689Skan/* If a NOP conversion is changing a pointer to array of foo to a pointer
1555169689Skan   to foo, embed that change in the ADDR_EXPR by converting
1556169689Skan      T array[U];
1557169689Skan      (T *)&array
1558169689Skan   ==>
1559169689Skan      &array[L]
1560169689Skan   where L is the lower bound.  For simplicity, only do this for constant
1561169689Skan   lower bound.  */
1562169689Skan
1563169689Skanstatic void
1564169689Skancanonicalize_addr_expr (tree *expr_p)
1565169689Skan{
1566169689Skan  tree expr = *expr_p;
1567169689Skan  tree ctype = TREE_TYPE (expr);
1568169689Skan  tree addr_expr = TREE_OPERAND (expr, 0);
1569169689Skan  tree atype = TREE_TYPE (addr_expr);
1570169689Skan  tree dctype, datype, ddatype, otype, obj_expr;
1571169689Skan
1572169689Skan  /* Both cast and addr_expr types should be pointers.  */
1573169689Skan  if (!POINTER_TYPE_P (ctype) || !POINTER_TYPE_P (atype))
1574169689Skan    return;
1575169689Skan
1576169689Skan  /* The addr_expr type should be a pointer to an array.  */
1577169689Skan  datype = TREE_TYPE (atype);
1578169689Skan  if (TREE_CODE (datype) != ARRAY_TYPE)
1579169689Skan    return;
1580169689Skan
1581169689Skan  /* Both cast and addr_expr types should address the same object type.  */
1582169689Skan  dctype = TREE_TYPE (ctype);
1583169689Skan  ddatype = TREE_TYPE (datype);
1584169689Skan  if (!lang_hooks.types_compatible_p (ddatype, dctype))
1585169689Skan    return;
1586169689Skan
1587169689Skan  /* The addr_expr and the object type should match.  */
1588169689Skan  obj_expr = TREE_OPERAND (addr_expr, 0);
1589169689Skan  otype = TREE_TYPE (obj_expr);
1590169689Skan  if (!lang_hooks.types_compatible_p (otype, datype))
1591169689Skan    return;
1592169689Skan
1593169689Skan  /* The lower bound and element sizes must be constant.  */
1594169689Skan  if (!TYPE_SIZE_UNIT (dctype)
1595169689Skan      || TREE_CODE (TYPE_SIZE_UNIT (dctype)) != INTEGER_CST
1596169689Skan      || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
1597169689Skan      || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
1598169689Skan    return;
1599169689Skan
1600169689Skan  /* All checks succeeded.  Build a new node to merge the cast.  */
1601169689Skan  *expr_p = build4 (ARRAY_REF, dctype, obj_expr,
1602169689Skan		    TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
1603237406Spfg		    NULL_TREE, NULL_TREE);
1604169689Skan  *expr_p = build1 (ADDR_EXPR, ctype, *expr_p);
1605169689Skan}
1606169689Skan
1607169689Skan/* *EXPR_P is a NOP_EXPR or CONVERT_EXPR.  Remove it and/or other conversions
1608169689Skan   underneath as appropriate.  */
1609169689Skan
1610169689Skanstatic enum gimplify_status
1611169689Skangimplify_conversion (tree *expr_p)
1612169689Skan{
1613169689Skan  gcc_assert (TREE_CODE (*expr_p) == NOP_EXPR
1614169689Skan	      || TREE_CODE (*expr_p) == CONVERT_EXPR);
1615169689Skan
1616169689Skan  /* Then strip away all but the outermost conversion.  */
1617169689Skan  STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
1618169689Skan
1619169689Skan  /* And remove the outermost conversion if it's useless.  */
1620169689Skan  if (tree_ssa_useless_type_conversion (*expr_p))
1621169689Skan    *expr_p = TREE_OPERAND (*expr_p, 0);
1622169689Skan
1623169689Skan  /* If we still have a conversion at the toplevel,
1624169689Skan     then canonicalize some constructs.  */
1625169689Skan  if (TREE_CODE (*expr_p) == NOP_EXPR || TREE_CODE (*expr_p) == CONVERT_EXPR)
1626169689Skan    {
1627169689Skan      tree sub = TREE_OPERAND (*expr_p, 0);
1628169689Skan
1629169689Skan      /* If a NOP conversion is changing the type of a COMPONENT_REF
1630169689Skan	 expression, then canonicalize its type now in order to expose more
1631169689Skan	 redundant conversions.  */
1632169689Skan      if (TREE_CODE (sub) == COMPONENT_REF)
1633169689Skan	canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
1634169689Skan
1635169689Skan      /* If a NOP conversion is changing a pointer to array of foo
1636169689Skan	 to a pointer to foo, embed that change in the ADDR_EXPR.  */
1637169689Skan      else if (TREE_CODE (sub) == ADDR_EXPR)
1638169689Skan	canonicalize_addr_expr (expr_p);
1639169689Skan    }
1640169689Skan
1641169689Skan  return GS_OK;
1642169689Skan}
1643169689Skan
1644169689Skan/* Gimplify a VAR_DECL or PARM_DECL.  Returns GS_OK if we expanded a
1645169689Skan   DECL_VALUE_EXPR, and it's worth re-examining things.  */
1646169689Skan
1647169689Skanstatic enum gimplify_status
1648169689Skangimplify_var_or_parm_decl (tree *expr_p)
1649169689Skan{
1650169689Skan  tree decl = *expr_p;
1651169689Skan
1652169689Skan  /* ??? If this is a local variable, and it has not been seen in any
1653169689Skan     outer BIND_EXPR, then it's probably the result of a duplicate
1654169689Skan     declaration, for which we've already issued an error.  It would
1655169689Skan     be really nice if the front end wouldn't leak these at all.
1656169689Skan     Currently the only known culprit is C++ destructors, as seen
1657169689Skan     in g++.old-deja/g++.jason/binding.C.  */
1658169689Skan  if (TREE_CODE (decl) == VAR_DECL
1659169689Skan      && !DECL_SEEN_IN_BIND_EXPR_P (decl)
1660169689Skan      && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
1661169689Skan      && decl_function_context (decl) == current_function_decl)
1662169689Skan    {
1663169689Skan      gcc_assert (errorcount || sorrycount);
1664169689Skan      return GS_ERROR;
1665169689Skan    }
1666169689Skan
1667169689Skan  /* When within an OpenMP context, notice uses of variables.  */
1668169689Skan  if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
1669169689Skan    return GS_ALL_DONE;
1670169689Skan
1671169689Skan  /* If the decl is an alias for another expression, substitute it now.  */
1672169689Skan  if (DECL_HAS_VALUE_EXPR_P (decl))
1673169689Skan    {
1674169689Skan      *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
1675169689Skan      return GS_OK;
1676169689Skan    }
1677169689Skan
1678169689Skan  return GS_ALL_DONE;
1679169689Skan}
1680169689Skan
1681169689Skan
1682169689Skan/* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
1683169689Skan   node pointed to by EXPR_P.
1684169689Skan
1685169689Skan      compound_lval
1686169689Skan	      : min_lval '[' val ']'
1687169689Skan	      | min_lval '.' ID
1688169689Skan	      | compound_lval '[' val ']'
1689169689Skan	      | compound_lval '.' ID
1690169689Skan
1691169689Skan   This is not part of the original SIMPLE definition, which separates
1692169689Skan   array and member references, but it seems reasonable to handle them
1693169689Skan   together.  Also, this way we don't run into problems with union
1694169689Skan   aliasing; gcc requires that for accesses through a union to alias, the
1695169689Skan   union reference must be explicit, which was not always the case when we
1696169689Skan   were splitting up array and member refs.
1697169689Skan
1698169689Skan   PRE_P points to the list where side effects that must happen before
1699169689Skan     *EXPR_P should be stored.
1700169689Skan
1701169689Skan   POST_P points to the list where side effects that must happen after
1702169689Skan     *EXPR_P should be stored.  */
1703169689Skan
1704169689Skanstatic enum gimplify_status
1705169689Skangimplify_compound_lval (tree *expr_p, tree *pre_p,
1706169689Skan			tree *post_p, fallback_t fallback)
1707169689Skan{
1708169689Skan  tree *p;
1709169689Skan  VEC(tree,heap) *stack;
1710169689Skan  enum gimplify_status ret = GS_OK, tret;
1711169689Skan  int i;
1712169689Skan
1713169689Skan  /* Create a stack of the subexpressions so later we can walk them in
1714169689Skan     order from inner to outer.  */
1715169689Skan  stack = VEC_alloc (tree, heap, 10);
1716169689Skan
1717169689Skan  /* We can handle anything that get_inner_reference can deal with.  */
1718169689Skan  for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
1719169689Skan    {
1720169689Skan    restart:
1721169689Skan      /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs.  */
1722169689Skan      if (TREE_CODE (*p) == INDIRECT_REF)
1723169689Skan	*p = fold_indirect_ref (*p);
1724169689Skan
1725169689Skan      if (handled_component_p (*p))
1726169689Skan	;
1727169689Skan      /* Expand DECL_VALUE_EXPR now.  In some cases that may expose
1728169689Skan	 additional COMPONENT_REFs.  */
1729169689Skan      else if ((TREE_CODE (*p) == VAR_DECL || TREE_CODE (*p) == PARM_DECL)
1730169689Skan	       && gimplify_var_or_parm_decl (p) == GS_OK)
1731169689Skan	goto restart;
1732169689Skan      else
1733169689Skan	break;
1734169689Skan
1735169689Skan      VEC_safe_push (tree, heap, stack, *p);
1736169689Skan    }
1737169689Skan
1738169689Skan  gcc_assert (VEC_length (tree, stack));
1739169689Skan
1740169689Skan  /* Now STACK is a stack of pointers to all the refs we've walked through
1741169689Skan     and P points to the innermost expression.
1742169689Skan
1743169689Skan     Java requires that we elaborated nodes in source order.  That
1744169689Skan     means we must gimplify the inner expression followed by each of
1745169689Skan     the indices, in order.  But we can't gimplify the inner
1746169689Skan     expression until we deal with any variable bounds, sizes, or
1747169689Skan     positions in order to deal with PLACEHOLDER_EXPRs.
1748169689Skan
1749169689Skan     So we do this in three steps.  First we deal with the annotations
1750169689Skan     for any variables in the components, then we gimplify the base,
1751169689Skan     then we gimplify any indices, from left to right.  */
1752169689Skan  for (i = VEC_length (tree, stack) - 1; i >= 0; i--)
1753169689Skan    {
1754169689Skan      tree t = VEC_index (tree, stack, i);
1755169689Skan
1756169689Skan      if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
1757169689Skan	{
1758169689Skan	  /* Gimplify the low bound and element type size and put them into
1759169689Skan	     the ARRAY_REF.  If these values are set, they have already been
1760169689Skan	     gimplified.  */
1761169689Skan	  if (!TREE_OPERAND (t, 2))
1762169689Skan	    {
1763169689Skan	      tree low = unshare_expr (array_ref_low_bound (t));
1764169689Skan	      if (!is_gimple_min_invariant (low))
1765169689Skan		{
1766169689Skan	          TREE_OPERAND (t, 2) = low;
1767169689Skan		  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
1768169689Skan					is_gimple_formal_tmp_reg, fb_rvalue);
1769169689Skan		  ret = MIN (ret, tret);
1770169689Skan		}
1771169689Skan	    }
1772169689Skan
1773169689Skan	  if (!TREE_OPERAND (t, 3))
1774169689Skan	    {
1775169689Skan	      tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
1776169689Skan	      tree elmt_size = unshare_expr (array_ref_element_size (t));
1777169689Skan	      tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
1778169689Skan
1779169689Skan	      /* Divide the element size by the alignment of the element
1780169689Skan		 type (above).  */
1781169689Skan	      elmt_size = size_binop (EXACT_DIV_EXPR, elmt_size, factor);
1782169689Skan
1783169689Skan	      if (!is_gimple_min_invariant (elmt_size))
1784169689Skan		{
1785169689Skan	          TREE_OPERAND (t, 3) = elmt_size;
1786169689Skan		  tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
1787169689Skan					is_gimple_formal_tmp_reg, fb_rvalue);
1788169689Skan		  ret = MIN (ret, tret);
1789169689Skan		}
1790169689Skan	    }
1791169689Skan	}
1792169689Skan      else if (TREE_CODE (t) == COMPONENT_REF)
1793169689Skan	{
1794169689Skan	  /* Set the field offset into T and gimplify it.  */
1795169689Skan	  if (!TREE_OPERAND (t, 2))
1796169689Skan	    {
1797169689Skan	      tree offset = unshare_expr (component_ref_field_offset (t));
1798169689Skan	      tree field = TREE_OPERAND (t, 1);
1799169689Skan	      tree factor
1800169689Skan		= size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
1801169689Skan
1802169689Skan	      /* Divide the offset by its alignment.  */
1803169689Skan	      offset = size_binop (EXACT_DIV_EXPR, offset, factor);
1804169689Skan
1805169689Skan	      if (!is_gimple_min_invariant (offset))
1806169689Skan		{
1807169689Skan	          TREE_OPERAND (t, 2) = offset;
1808169689Skan		  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
1809169689Skan					is_gimple_formal_tmp_reg, fb_rvalue);
1810169689Skan		  ret = MIN (ret, tret);
1811169689Skan		}
1812169689Skan	    }
1813169689Skan	}
1814169689Skan    }
1815169689Skan
1816169689Skan  /* Step 2 is to gimplify the base expression.  Make sure lvalue is set
1817169689Skan     so as to match the min_lval predicate.  Failure to do so may result
1818169689Skan     in the creation of large aggregate temporaries.  */
1819169689Skan  tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
1820169689Skan			fallback | fb_lvalue);
1821169689Skan  ret = MIN (ret, tret);
1822169689Skan
1823169689Skan  /* And finally, the indices and operands to BIT_FIELD_REF.  During this
1824169689Skan     loop we also remove any useless conversions.  */
1825169689Skan  for (; VEC_length (tree, stack) > 0; )
1826169689Skan    {
1827169689Skan      tree t = VEC_pop (tree, stack);
1828169689Skan
1829169689Skan      if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
1830169689Skan	{
1831169689Skan	  /* Gimplify the dimension.
1832169689Skan	     Temporary fix for gcc.c-torture/execute/20040313-1.c.
1833169689Skan	     Gimplify non-constant array indices into a temporary
1834169689Skan	     variable.
1835169689Skan	     FIXME - The real fix is to gimplify post-modify
1836169689Skan	     expressions into a minimal gimple lvalue.  However, that
1837169689Skan	     exposes bugs in alias analysis.  The alias analyzer does
1838169689Skan	     not handle &PTR->FIELD very well.  Will fix after the
1839169689Skan	     branch is merged into mainline (dnovillo 2004-05-03).  */
1840169689Skan	  if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
1841169689Skan	    {
1842169689Skan	      tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
1843169689Skan				    is_gimple_formal_tmp_reg, fb_rvalue);
1844169689Skan	      ret = MIN (ret, tret);
1845169689Skan	    }
1846169689Skan	}
1847169689Skan      else if (TREE_CODE (t) == BIT_FIELD_REF)
1848169689Skan	{
1849169689Skan	  tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
1850169689Skan				is_gimple_val, fb_rvalue);
1851169689Skan	  ret = MIN (ret, tret);
1852169689Skan	  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
1853169689Skan				is_gimple_val, fb_rvalue);
1854169689Skan	  ret = MIN (ret, tret);
1855169689Skan	}
1856169689Skan
1857169689Skan      STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
1858169689Skan
1859169689Skan      /* The innermost expression P may have originally had TREE_SIDE_EFFECTS
1860169689Skan	 set which would have caused all the outer expressions in EXPR_P
1861169689Skan	 leading to P to also have had TREE_SIDE_EFFECTS set.  */
1862169689Skan      recalculate_side_effects (t);
1863169689Skan    }
1864169689Skan
1865169689Skan  tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fallback);
1866169689Skan  ret = MIN (ret, tret);
1867169689Skan
1868169689Skan  /* If the outermost expression is a COMPONENT_REF, canonicalize its type.  */
1869169689Skan  if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
1870169689Skan    {
1871169689Skan      canonicalize_component_ref (expr_p);
1872169689Skan      ret = MIN (ret, GS_OK);
1873169689Skan    }
1874169689Skan
1875169689Skan  VEC_free (tree, heap, stack);
1876169689Skan
1877169689Skan  return ret;
1878169689Skan}
1879169689Skan
1880169689Skan/*  Gimplify the self modifying expression pointed to by EXPR_P
1881169689Skan    (++, --, +=, -=).
1882169689Skan
1883169689Skan    PRE_P points to the list where side effects that must happen before
1884169689Skan	*EXPR_P should be stored.
1885169689Skan
1886169689Skan    POST_P points to the list where side effects that must happen after
1887169689Skan	*EXPR_P should be stored.
1888169689Skan
1889169689Skan    WANT_VALUE is nonzero iff we want to use the value of this expression
1890169689Skan	in another expression.  */
1891169689Skan
1892169689Skanstatic enum gimplify_status
1893169689Skangimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p,
1894169689Skan			bool want_value)
1895169689Skan{
1896169689Skan  enum tree_code code;
1897169689Skan  tree lhs, lvalue, rhs, t1, post = NULL, *orig_post_p = post_p;
1898169689Skan  bool postfix;
1899169689Skan  enum tree_code arith_code;
1900169689Skan  enum gimplify_status ret;
1901169689Skan
1902169689Skan  code = TREE_CODE (*expr_p);
1903169689Skan
1904169689Skan  gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
1905169689Skan	      || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
1906169689Skan
1907169689Skan  /* Prefix or postfix?  */
1908169689Skan  if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
1909169689Skan    /* Faster to treat as prefix if result is not used.  */
1910169689Skan    postfix = want_value;
1911169689Skan  else
1912169689Skan    postfix = false;
1913169689Skan
1914169689Skan  /* For postfix, make sure the inner expression's post side effects
1915169689Skan     are executed after side effects from this expression.  */
1916169689Skan  if (postfix)
1917169689Skan    post_p = &post;
1918169689Skan
1919169689Skan  /* Add or subtract?  */
1920169689Skan  if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
1921169689Skan    arith_code = PLUS_EXPR;
1922169689Skan  else
1923169689Skan    arith_code = MINUS_EXPR;
1924169689Skan
1925169689Skan  /* Gimplify the LHS into a GIMPLE lvalue.  */
1926169689Skan  lvalue = TREE_OPERAND (*expr_p, 0);
1927169689Skan  ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
1928169689Skan  if (ret == GS_ERROR)
1929169689Skan    return ret;
1930169689Skan
1931169689Skan  /* Extract the operands to the arithmetic operation.  */
1932169689Skan  lhs = lvalue;
1933169689Skan  rhs = TREE_OPERAND (*expr_p, 1);
1934169689Skan
1935169689Skan  /* For postfix operator, we evaluate the LHS to an rvalue and then use
1936169689Skan     that as the result value and in the postqueue operation.  */
1937169689Skan  if (postfix)
1938169689Skan    {
1939169689Skan      ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
1940169689Skan      if (ret == GS_ERROR)
1941169689Skan	return ret;
1942169689Skan    }
1943169689Skan
1944169689Skan  t1 = build2 (arith_code, TREE_TYPE (*expr_p), lhs, rhs);
1945169689Skan  t1 = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
1946169689Skan
1947169689Skan  if (postfix)
1948169689Skan    {
1949169689Skan      gimplify_and_add (t1, orig_post_p);
1950169689Skan      append_to_statement_list (post, orig_post_p);
1951169689Skan      *expr_p = lhs;
1952169689Skan      return GS_ALL_DONE;
1953169689Skan    }
1954169689Skan  else
1955169689Skan    {
1956169689Skan      *expr_p = t1;
1957169689Skan      return GS_OK;
1958169689Skan    }
1959169689Skan}
1960169689Skan
1961169689Skan/* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR.  */
1962169689Skan
1963169689Skanstatic void
1964169689Skanmaybe_with_size_expr (tree *expr_p)
1965169689Skan{
1966169689Skan  tree expr = *expr_p;
1967169689Skan  tree type = TREE_TYPE (expr);
1968169689Skan  tree size;
1969169689Skan
1970169689Skan  /* If we've already wrapped this or the type is error_mark_node, we can't do
1971169689Skan     anything.  */
1972169689Skan  if (TREE_CODE (expr) == WITH_SIZE_EXPR
1973169689Skan      || type == error_mark_node)
1974169689Skan    return;
1975169689Skan
1976169689Skan  /* If the size isn't known or is a constant, we have nothing to do.  */
1977169689Skan  size = TYPE_SIZE_UNIT (type);
1978169689Skan  if (!size || TREE_CODE (size) == INTEGER_CST)
1979169689Skan    return;
1980169689Skan
1981169689Skan  /* Otherwise, make a WITH_SIZE_EXPR.  */
1982169689Skan  size = unshare_expr (size);
1983169689Skan  size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
1984169689Skan  *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
1985169689Skan}
1986169689Skan
1987169689Skan/* Subroutine of gimplify_call_expr:  Gimplify a single argument.  */
1988169689Skan
1989169689Skanstatic enum gimplify_status
1990169689Skangimplify_arg (tree *expr_p, tree *pre_p)
1991169689Skan{
1992169689Skan  bool (*test) (tree);
1993169689Skan  fallback_t fb;
1994169689Skan
1995169689Skan  /* In general, we allow lvalues for function arguments to avoid
1996169689Skan     extra overhead of copying large aggregates out of even larger
1997169689Skan     aggregates into temporaries only to copy the temporaries to
1998169689Skan     the argument list.  Make optimizers happy by pulling out to
1999169689Skan     temporaries those types that fit in registers.  */
2000169689Skan  if (is_gimple_reg_type (TREE_TYPE (*expr_p)))
2001169689Skan    test = is_gimple_val, fb = fb_rvalue;
2002169689Skan  else
2003169689Skan    test = is_gimple_lvalue, fb = fb_either;
2004169689Skan
2005169689Skan  /* If this is a variable sized type, we must remember the size.  */
2006169689Skan  maybe_with_size_expr (expr_p);
2007169689Skan
2008169689Skan  /* There is a sequence point before a function call.  Side effects in
2009169689Skan     the argument list must occur before the actual call. So, when
2010169689Skan     gimplifying arguments, force gimplify_expr to use an internal
2011169689Skan     post queue which is then appended to the end of PRE_P.  */
2012169689Skan  return gimplify_expr (expr_p, pre_p, NULL, test, fb);
2013169689Skan}
2014169689Skan
2015169689Skan/* Gimplify the CALL_EXPR node pointed to by EXPR_P.  PRE_P points to the
2016169689Skan   list where side effects that must happen before *EXPR_P should be stored.
2017169689Skan   WANT_VALUE is true if the result of the call is desired.  */
2018169689Skan
2019169689Skanstatic enum gimplify_status
2020169689Skangimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
2021169689Skan{
2022169689Skan  tree decl;
2023169689Skan  tree arglist;
2024169689Skan  enum gimplify_status ret;
2025169689Skan
2026169689Skan  gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
2027169689Skan
2028169689Skan  /* For reliable diagnostics during inlining, it is necessary that
2029169689Skan     every call_expr be annotated with file and line.  */
2030169689Skan  if (! EXPR_HAS_LOCATION (*expr_p))
2031169689Skan    SET_EXPR_LOCATION (*expr_p, input_location);
2032169689Skan
2033169689Skan  /* This may be a call to a builtin function.
2034169689Skan
2035169689Skan     Builtin function calls may be transformed into different
2036169689Skan     (and more efficient) builtin function calls under certain
2037169689Skan     circumstances.  Unfortunately, gimplification can muck things
2038169689Skan     up enough that the builtin expanders are not aware that certain
2039169689Skan     transformations are still valid.
2040169689Skan
2041169689Skan     So we attempt transformation/gimplification of the call before
2042169689Skan     we gimplify the CALL_EXPR.  At this time we do not manage to
2043169689Skan     transform all calls in the same manner as the expanders do, but
2044169689Skan     we do transform most of them.  */
2045169689Skan  decl = get_callee_fndecl (*expr_p);
2046169689Skan  if (decl && DECL_BUILT_IN (decl))
2047169689Skan    {
2048169689Skan      tree arglist = TREE_OPERAND (*expr_p, 1);
2049169689Skan      tree new = fold_builtin (decl, arglist, !want_value);
2050169689Skan
2051169689Skan      if (new && new != *expr_p)
2052169689Skan	{
2053169689Skan	  /* There was a transformation of this call which computes the
2054169689Skan	     same value, but in a more efficient way.  Return and try
2055169689Skan	     again.  */
2056169689Skan	  *expr_p = new;
2057169689Skan	  return GS_OK;
2058169689Skan	}
2059169689Skan
2060169689Skan      if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
2061169689Skan	  && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_START)
2062169689Skan        {
2063169689Skan	  if (!arglist || !TREE_CHAIN (arglist))
2064169689Skan	    {
2065169689Skan	      error ("too few arguments to function %<va_start%>");
2066169689Skan	      *expr_p = build_empty_stmt ();
2067169689Skan	      return GS_OK;
2068169689Skan	    }
2069169689Skan
2070169689Skan	  if (fold_builtin_next_arg (TREE_CHAIN (arglist)))
2071169689Skan	    {
2072169689Skan	      *expr_p = build_empty_stmt ();
2073169689Skan	      return GS_OK;
2074169689Skan	    }
2075169689Skan	  /* Avoid gimplifying the second argument to va_start, which needs
2076169689Skan	     to be the plain PARM_DECL.  */
2077169689Skan	  return gimplify_arg (&TREE_VALUE (TREE_OPERAND (*expr_p, 1)), pre_p);
2078169689Skan	}
2079169689Skan    }
2080169689Skan
2081169689Skan  /* There is a sequence point before the call, so any side effects in
2082169689Skan     the calling expression must occur before the actual call.  Force
2083169689Skan     gimplify_expr to use an internal post queue.  */
2084169689Skan  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, NULL,
2085169689Skan		       is_gimple_call_addr, fb_rvalue);
2086169689Skan
2087169689Skan  if (PUSH_ARGS_REVERSED)
2088169689Skan    TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1));
2089169689Skan  for (arglist = TREE_OPERAND (*expr_p, 1); arglist;
2090169689Skan       arglist = TREE_CHAIN (arglist))
2091169689Skan    {
2092169689Skan      enum gimplify_status t;
2093169689Skan
2094169689Skan      t = gimplify_arg (&TREE_VALUE (arglist), pre_p);
2095169689Skan
2096169689Skan      if (t == GS_ERROR)
2097169689Skan	ret = GS_ERROR;
2098169689Skan    }
2099169689Skan  if (PUSH_ARGS_REVERSED)
2100169689Skan    TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1));
2101169689Skan
2102169689Skan  /* Try this again in case gimplification exposed something.  */
2103169689Skan  if (ret != GS_ERROR)
2104169689Skan    {
2105169689Skan      decl = get_callee_fndecl (*expr_p);
2106169689Skan      if (decl && DECL_BUILT_IN (decl))
2107169689Skan	{
2108169689Skan	  tree arglist = TREE_OPERAND (*expr_p, 1);
2109169689Skan	  tree new = fold_builtin (decl, arglist, !want_value);
2110169689Skan
2111169689Skan	  if (new && new != *expr_p)
2112169689Skan	    {
2113169689Skan	      /* There was a transformation of this call which computes the
2114169689Skan		 same value, but in a more efficient way.  Return and try
2115169689Skan		 again.  */
2116169689Skan	      *expr_p = new;
2117169689Skan	      return GS_OK;
2118169689Skan	    }
2119169689Skan	}
2120169689Skan    }
2121169689Skan
2122169689Skan  /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
2123169689Skan     decl.  This allows us to eliminate redundant or useless
2124169689Skan     calls to "const" functions.  */
2125169689Skan  if (TREE_CODE (*expr_p) == CALL_EXPR
2126169689Skan      && (call_expr_flags (*expr_p) & (ECF_CONST | ECF_PURE)))
2127169689Skan    TREE_SIDE_EFFECTS (*expr_p) = 0;
2128169689Skan
2129169689Skan  return ret;
2130169689Skan}
2131169689Skan
2132169689Skan/* Handle shortcut semantics in the predicate operand of a COND_EXPR by
2133169689Skan   rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
2134169689Skan
2135169689Skan   TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
2136169689Skan   condition is true or false, respectively.  If null, we should generate
2137169689Skan   our own to skip over the evaluation of this specific expression.
2138169689Skan
2139169689Skan   This function is the tree equivalent of do_jump.
2140169689Skan
2141169689Skan   shortcut_cond_r should only be called by shortcut_cond_expr.  */
2142169689Skan
2143169689Skanstatic tree
2144169689Skanshortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p)
2145169689Skan{
2146169689Skan  tree local_label = NULL_TREE;
2147169689Skan  tree t, expr = NULL;
2148169689Skan
2149169689Skan  /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
2150169689Skan     retain the shortcut semantics.  Just insert the gotos here;
2151169689Skan     shortcut_cond_expr will append the real blocks later.  */
2152169689Skan  if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
2153169689Skan    {
2154169689Skan      /* Turn if (a && b) into
2155169689Skan
2156169689Skan	 if (a); else goto no;
2157169689Skan	 if (b) goto yes; else goto no;
2158169689Skan	 (no:) */
2159169689Skan
2160169689Skan      if (false_label_p == NULL)
2161169689Skan	false_label_p = &local_label;
2162169689Skan
2163169689Skan      t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p);
2164169689Skan      append_to_statement_list (t, &expr);
2165169689Skan
2166169689Skan      t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
2167169689Skan			   false_label_p);
2168169689Skan      append_to_statement_list (t, &expr);
2169169689Skan    }
2170169689Skan  else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
2171169689Skan    {
2172169689Skan      /* Turn if (a || b) into
2173169689Skan
2174169689Skan	 if (a) goto yes;
2175169689Skan	 if (b) goto yes; else goto no;
2176169689Skan	 (yes:) */
2177169689Skan
2178169689Skan      if (true_label_p == NULL)
2179169689Skan	true_label_p = &local_label;
2180169689Skan
2181169689Skan      t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL);
2182169689Skan      append_to_statement_list (t, &expr);
2183169689Skan
2184169689Skan      t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
2185169689Skan			   false_label_p);
2186169689Skan      append_to_statement_list (t, &expr);
2187169689Skan    }
2188169689Skan  else if (TREE_CODE (pred) == COND_EXPR)
2189169689Skan    {
2190169689Skan      /* As long as we're messing with gotos, turn if (a ? b : c) into
2191169689Skan	 if (a)
2192169689Skan	   if (b) goto yes; else goto no;
2193169689Skan	 else
2194169689Skan	   if (c) goto yes; else goto no;  */
2195169689Skan      expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
2196169689Skan		     shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
2197169689Skan				      false_label_p),
2198169689Skan		     shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
2199169689Skan				      false_label_p));
2200169689Skan    }
2201169689Skan  else
2202169689Skan    {
2203169689Skan      expr = build3 (COND_EXPR, void_type_node, pred,
2204169689Skan		     build_and_jump (true_label_p),
2205169689Skan		     build_and_jump (false_label_p));
2206169689Skan    }
2207169689Skan
2208169689Skan  if (local_label)
2209169689Skan    {
2210169689Skan      t = build1 (LABEL_EXPR, void_type_node, local_label);
2211169689Skan      append_to_statement_list (t, &expr);
2212169689Skan    }
2213169689Skan
2214169689Skan  return expr;
2215169689Skan}
2216169689Skan
2217169689Skanstatic tree
2218169689Skanshortcut_cond_expr (tree expr)
2219169689Skan{
2220169689Skan  tree pred = TREE_OPERAND (expr, 0);
2221169689Skan  tree then_ = TREE_OPERAND (expr, 1);
2222169689Skan  tree else_ = TREE_OPERAND (expr, 2);
2223169689Skan  tree true_label, false_label, end_label, t;
2224169689Skan  tree *true_label_p;
2225169689Skan  tree *false_label_p;
2226169689Skan  bool emit_end, emit_false, jump_over_else;
2227169689Skan  bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
2228169689Skan  bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
2229169689Skan
2230169689Skan  /* First do simple transformations.  */
2231169689Skan  if (!else_se)
2232169689Skan    {
2233169689Skan      /* If there is no 'else', turn (a && b) into if (a) if (b).  */
2234169689Skan      while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
2235169689Skan	{
2236169689Skan	  TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
2237169689Skan	  then_ = shortcut_cond_expr (expr);
2238169689Skan	  then_se = then_ && TREE_SIDE_EFFECTS (then_);
2239169689Skan	  pred = TREE_OPERAND (pred, 0);
2240169689Skan	  expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
2241169689Skan	}
2242169689Skan    }
2243169689Skan  if (!then_se)
2244169689Skan    {
2245169689Skan      /* If there is no 'then', turn
2246169689Skan	   if (a || b); else d
2247169689Skan	 into
2248169689Skan	   if (a); else if (b); else d.  */
2249169689Skan      while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
2250169689Skan	{
2251169689Skan	  TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
2252169689Skan	  else_ = shortcut_cond_expr (expr);
2253169689Skan	  else_se = else_ && TREE_SIDE_EFFECTS (else_);
2254169689Skan	  pred = TREE_OPERAND (pred, 0);
2255169689Skan	  expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
2256169689Skan	}
2257169689Skan    }
2258169689Skan
2259169689Skan  /* If we're done, great.  */
2260169689Skan  if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
2261169689Skan      && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
2262169689Skan    return expr;
2263169689Skan
2264169689Skan  /* Otherwise we need to mess with gotos.  Change
2265169689Skan       if (a) c; else d;
2266169689Skan     to
2267169689Skan       if (a); else goto no;
2268169689Skan       c; goto end;
2269169689Skan       no: d; end:
2270169689Skan     and recursively gimplify the condition.  */
2271169689Skan
2272169689Skan  true_label = false_label = end_label = NULL_TREE;
2273169689Skan
2274169689Skan  /* If our arms just jump somewhere, hijack those labels so we don't
2275169689Skan     generate jumps to jumps.  */
2276169689Skan
2277169689Skan  if (then_
2278169689Skan      && TREE_CODE (then_) == GOTO_EXPR
2279169689Skan      && TREE_CODE (GOTO_DESTINATION (then_)) == LABEL_DECL)
2280169689Skan    {
2281169689Skan      true_label = GOTO_DESTINATION (then_);
2282169689Skan      then_ = NULL;
2283169689Skan      then_se = false;
2284169689Skan    }
2285169689Skan
2286169689Skan  if (else_
2287169689Skan      && TREE_CODE (else_) == GOTO_EXPR
2288169689Skan      && TREE_CODE (GOTO_DESTINATION (else_)) == LABEL_DECL)
2289169689Skan    {
2290169689Skan      false_label = GOTO_DESTINATION (else_);
2291169689Skan      else_ = NULL;
2292169689Skan      else_se = false;
2293169689Skan    }
2294169689Skan
2295169689Skan  /* If we aren't hijacking a label for the 'then' branch, it falls through.  */
2296169689Skan  if (true_label)
2297169689Skan    true_label_p = &true_label;
2298169689Skan  else
2299169689Skan    true_label_p = NULL;
2300169689Skan
2301169689Skan  /* The 'else' branch also needs a label if it contains interesting code.  */
2302169689Skan  if (false_label || else_se)
2303169689Skan    false_label_p = &false_label;
2304169689Skan  else
2305169689Skan    false_label_p = NULL;
2306169689Skan
2307169689Skan  /* If there was nothing else in our arms, just forward the label(s).  */
2308169689Skan  if (!then_se && !else_se)
2309169689Skan    return shortcut_cond_r (pred, true_label_p, false_label_p);
2310169689Skan
2311169689Skan  /* If our last subexpression already has a terminal label, reuse it.  */
2312169689Skan  if (else_se)
2313169689Skan    expr = expr_last (else_);
2314169689Skan  else if (then_se)
2315169689Skan    expr = expr_last (then_);
2316169689Skan  else
2317169689Skan    expr = NULL;
2318169689Skan  if (expr && TREE_CODE (expr) == LABEL_EXPR)
2319169689Skan    end_label = LABEL_EXPR_LABEL (expr);
2320169689Skan
2321169689Skan  /* If we don't care about jumping to the 'else' branch, jump to the end
2322169689Skan     if the condition is false.  */
2323169689Skan  if (!false_label_p)
2324169689Skan    false_label_p = &end_label;
2325169689Skan
2326169689Skan  /* We only want to emit these labels if we aren't hijacking them.  */
2327169689Skan  emit_end = (end_label == NULL_TREE);
2328169689Skan  emit_false = (false_label == NULL_TREE);
2329169689Skan
2330169689Skan  /* We only emit the jump over the else clause if we have to--if the
2331169689Skan     then clause may fall through.  Otherwise we can wind up with a
2332169689Skan     useless jump and a useless label at the end of gimplified code,
2333169689Skan     which will cause us to think that this conditional as a whole
2334169689Skan     falls through even if it doesn't.  If we then inline a function
2335169689Skan     which ends with such a condition, that can cause us to issue an
2336169689Skan     inappropriate warning about control reaching the end of a
2337169689Skan     non-void function.  */
2338169689Skan  jump_over_else = block_may_fallthru (then_);
2339169689Skan
2340169689Skan  pred = shortcut_cond_r (pred, true_label_p, false_label_p);
2341169689Skan
2342169689Skan  expr = NULL;
2343169689Skan  append_to_statement_list (pred, &expr);
2344169689Skan
2345169689Skan  append_to_statement_list (then_, &expr);
2346169689Skan  if (else_se)
2347169689Skan    {
2348169689Skan      if (jump_over_else)
2349169689Skan	{
2350169689Skan	  t = build_and_jump (&end_label);
2351169689Skan	  append_to_statement_list (t, &expr);
2352169689Skan	}
2353169689Skan      if (emit_false)
2354169689Skan	{
2355169689Skan	  t = build1 (LABEL_EXPR, void_type_node, false_label);
2356169689Skan	  append_to_statement_list (t, &expr);
2357169689Skan	}
2358169689Skan      append_to_statement_list (else_, &expr);
2359169689Skan    }
2360169689Skan  if (emit_end && end_label)
2361169689Skan    {
2362169689Skan      t = build1 (LABEL_EXPR, void_type_node, end_label);
2363169689Skan      append_to_statement_list (t, &expr);
2364169689Skan    }
2365169689Skan
2366169689Skan  return expr;
2367169689Skan}
2368169689Skan
2369169689Skan/* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE.  */
2370169689Skan
2371169689Skantree
2372169689Skangimple_boolify (tree expr)
2373169689Skan{
2374169689Skan  tree type = TREE_TYPE (expr);
2375169689Skan
2376169689Skan  if (TREE_CODE (type) == BOOLEAN_TYPE)
2377169689Skan    return expr;
2378169689Skan
2379169689Skan  switch (TREE_CODE (expr))
2380169689Skan    {
2381169689Skan    case TRUTH_AND_EXPR:
2382169689Skan    case TRUTH_OR_EXPR:
2383169689Skan    case TRUTH_XOR_EXPR:
2384169689Skan    case TRUTH_ANDIF_EXPR:
2385169689Skan    case TRUTH_ORIF_EXPR:
2386169689Skan      /* Also boolify the arguments of truth exprs.  */
2387169689Skan      TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
2388169689Skan      /* FALLTHRU */
2389169689Skan
2390169689Skan    case TRUTH_NOT_EXPR:
2391169689Skan      TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
2392169689Skan      /* FALLTHRU */
2393169689Skan
2394169689Skan    case EQ_EXPR: case NE_EXPR:
2395169689Skan    case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
2396169689Skan      /* These expressions always produce boolean results.  */
2397169689Skan      TREE_TYPE (expr) = boolean_type_node;
2398169689Skan      return expr;
2399169689Skan
2400169689Skan    default:
2401169689Skan      /* Other expressions that get here must have boolean values, but
2402169689Skan	 might need to be converted to the appropriate mode.  */
2403169689Skan      return fold_convert (boolean_type_node, expr);
2404169689Skan    }
2405169689Skan}
2406169689Skan
2407169689Skan/*  Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
2408169689Skan    into
2409169689Skan
2410169689Skan    if (p)			if (p)
2411169689Skan      t1 = a;			  a;
2412169689Skan    else		or	else
2413169689Skan      t1 = b;			  b;
2414169689Skan    t1;
2415169689Skan
2416169689Skan    The second form is used when *EXPR_P is of type void.
2417169689Skan
2418169689Skan    TARGET is the tree for T1 above.
2419169689Skan
2420169689Skan    PRE_P points to the list where side effects that must happen before
2421169689Skan      *EXPR_P should be stored.  */
2422169689Skan
2423169689Skanstatic enum gimplify_status
2424169689Skangimplify_cond_expr (tree *expr_p, tree *pre_p, fallback_t fallback)
2425169689Skan{
2426169689Skan  tree expr = *expr_p;
2427169689Skan  tree tmp, tmp2, type;
2428169689Skan  enum gimplify_status ret;
2429169689Skan
2430169689Skan  type = TREE_TYPE (expr);
2431169689Skan
2432169689Skan  /* If this COND_EXPR has a value, copy the values into a temporary within
2433169689Skan     the arms.  */
2434169689Skan  if (! VOID_TYPE_P (type))
2435169689Skan    {
2436169689Skan      tree result;
2437169689Skan
2438169689Skan      if ((fallback & fb_lvalue) == 0)
2439169689Skan	{
2440169689Skan	  result = tmp2 = tmp = create_tmp_var (TREE_TYPE (expr), "iftmp");
2441169689Skan	  ret = GS_ALL_DONE;
2442169689Skan	}
2443169689Skan      else
2444169689Skan	{
2445169689Skan	  tree type = build_pointer_type (TREE_TYPE (expr));
2446169689Skan
2447169689Skan	  if (TREE_TYPE (TREE_OPERAND (expr, 1)) != void_type_node)
2448169689Skan	    TREE_OPERAND (expr, 1) =
2449169689Skan	      build_fold_addr_expr (TREE_OPERAND (expr, 1));
2450169689Skan
2451169689Skan	  if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node)
2452169689Skan	    TREE_OPERAND (expr, 2) =
2453169689Skan	      build_fold_addr_expr (TREE_OPERAND (expr, 2));
2454169689Skan
2455169689Skan	  tmp2 = tmp = create_tmp_var (type, "iftmp");
2456169689Skan
2457169689Skan	  expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (expr, 0),
2458169689Skan			 TREE_OPERAND (expr, 1), TREE_OPERAND (expr, 2));
2459169689Skan
2460169689Skan	  result = build_fold_indirect_ref (tmp);
2461169689Skan	  ret = GS_ALL_DONE;
2462169689Skan	}
2463169689Skan
2464169689Skan      /* Build the then clause, 't1 = a;'.  But don't build an assignment
2465169689Skan	 if this branch is void; in C++ it can be, if it's a throw.  */
2466169689Skan      if (TREE_TYPE (TREE_OPERAND (expr, 1)) != void_type_node)
2467169689Skan	TREE_OPERAND (expr, 1)
2468169689Skan	  = build2 (MODIFY_EXPR, void_type_node, tmp, TREE_OPERAND (expr, 1));
2469169689Skan
2470169689Skan      /* Build the else clause, 't1 = b;'.  */
2471169689Skan      if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node)
2472169689Skan	TREE_OPERAND (expr, 2)
2473169689Skan	  = build2 (MODIFY_EXPR, void_type_node, tmp2, TREE_OPERAND (expr, 2));
2474169689Skan
2475169689Skan      TREE_TYPE (expr) = void_type_node;
2476169689Skan      recalculate_side_effects (expr);
2477169689Skan
2478169689Skan      /* Move the COND_EXPR to the prequeue.  */
2479169689Skan      gimplify_and_add (expr, pre_p);
2480169689Skan
2481169689Skan      *expr_p = result;
2482169689Skan      return ret;
2483169689Skan    }
2484169689Skan
2485169689Skan  /* Make sure the condition has BOOLEAN_TYPE.  */
2486169689Skan  TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
2487169689Skan
2488169689Skan  /* Break apart && and || conditions.  */
2489169689Skan  if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
2490169689Skan      || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
2491169689Skan    {
2492169689Skan      expr = shortcut_cond_expr (expr);
2493169689Skan
2494169689Skan      if (expr != *expr_p)
2495169689Skan	{
2496169689Skan	  *expr_p = expr;
2497169689Skan
2498169689Skan	  /* We can't rely on gimplify_expr to re-gimplify the expanded
2499169689Skan	     form properly, as cleanups might cause the target labels to be
2500169689Skan	     wrapped in a TRY_FINALLY_EXPR.  To prevent that, we need to
2501169689Skan	     set up a conditional context.  */
2502169689Skan	  gimple_push_condition ();
2503169689Skan	  gimplify_stmt (expr_p);
2504169689Skan	  gimple_pop_condition (pre_p);
2505169689Skan
2506169689Skan	  return GS_ALL_DONE;
2507169689Skan	}
2508169689Skan    }
2509169689Skan
2510169689Skan  /* Now do the normal gimplification.  */
2511169689Skan  ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
2512169689Skan		       is_gimple_condexpr, fb_rvalue);
2513169689Skan
2514169689Skan  gimple_push_condition ();
2515169689Skan
2516169689Skan  gimplify_to_stmt_list (&TREE_OPERAND (expr, 1));
2517169689Skan  gimplify_to_stmt_list (&TREE_OPERAND (expr, 2));
2518169689Skan  recalculate_side_effects (expr);
2519169689Skan
2520169689Skan  gimple_pop_condition (pre_p);
2521169689Skan
2522169689Skan  if (ret == GS_ERROR)
2523169689Skan    ;
2524169689Skan  else if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
2525169689Skan    ret = GS_ALL_DONE;
2526169689Skan  else if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2)))
2527169689Skan    /* Rewrite "if (a); else b" to "if (!a) b"  */
2528169689Skan    {
2529169689Skan      TREE_OPERAND (expr, 0) = invert_truthvalue (TREE_OPERAND (expr, 0));
2530169689Skan      ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
2531169689Skan			   is_gimple_condexpr, fb_rvalue);
2532169689Skan
2533169689Skan      tmp = TREE_OPERAND (expr, 1);
2534169689Skan      TREE_OPERAND (expr, 1) = TREE_OPERAND (expr, 2);
2535169689Skan      TREE_OPERAND (expr, 2) = tmp;
2536169689Skan    }
2537169689Skan  else
2538169689Skan    /* Both arms are empty; replace the COND_EXPR with its predicate.  */
2539169689Skan    expr = TREE_OPERAND (expr, 0);
2540169689Skan
2541169689Skan  *expr_p = expr;
2542169689Skan  return ret;
2543169689Skan}
2544169689Skan
2545169689Skan/* A subroutine of gimplify_modify_expr.  Replace a MODIFY_EXPR with
2546169689Skan   a call to __builtin_memcpy.  */
2547169689Skan
2548169689Skanstatic enum gimplify_status
2549169689Skangimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value)
2550169689Skan{
2551169689Skan  tree args, t, to, to_ptr, from;
2552169689Skan
2553169689Skan  to = TREE_OPERAND (*expr_p, 0);
2554169689Skan  from = TREE_OPERAND (*expr_p, 1);
2555169689Skan
2556169689Skan  args = tree_cons (NULL, size, NULL);
2557169689Skan
2558169689Skan  t = build_fold_addr_expr (from);
2559169689Skan  args = tree_cons (NULL, t, args);
2560169689Skan
2561169689Skan  to_ptr = build_fold_addr_expr (to);
2562169689Skan  args = tree_cons (NULL, to_ptr, args);
2563169689Skan  t = implicit_built_in_decls[BUILT_IN_MEMCPY];
2564169689Skan  t = build_function_call_expr (t, args);
2565169689Skan
2566169689Skan  if (want_value)
2567169689Skan    {
2568169689Skan      t = build1 (NOP_EXPR, TREE_TYPE (to_ptr), t);
2569169689Skan      t = build1 (INDIRECT_REF, TREE_TYPE (to), t);
2570169689Skan    }
2571169689Skan
2572169689Skan  *expr_p = t;
2573169689Skan  return GS_OK;
2574169689Skan}
2575169689Skan
2576169689Skan/* A subroutine of gimplify_modify_expr.  Replace a MODIFY_EXPR with
2577169689Skan   a call to __builtin_memset.  In this case we know that the RHS is
2578169689Skan   a CONSTRUCTOR with an empty element list.  */
2579169689Skan
2580169689Skanstatic enum gimplify_status
2581169689Skangimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value)
2582169689Skan{
2583169689Skan  tree args, t, to, to_ptr;
2584169689Skan
2585169689Skan  to = TREE_OPERAND (*expr_p, 0);
2586169689Skan
2587169689Skan  args = tree_cons (NULL, size, NULL);
2588169689Skan
2589169689Skan  args = tree_cons (NULL, integer_zero_node, args);
2590169689Skan
2591169689Skan  to_ptr = build_fold_addr_expr (to);
2592169689Skan  args = tree_cons (NULL, to_ptr, args);
2593169689Skan  t = implicit_built_in_decls[BUILT_IN_MEMSET];
2594169689Skan  t = build_function_call_expr (t, args);
2595169689Skan
2596169689Skan  if (want_value)
2597169689Skan    {
2598169689Skan      t = build1 (NOP_EXPR, TREE_TYPE (to_ptr), t);
2599169689Skan      t = build1 (INDIRECT_REF, TREE_TYPE (to), t);
2600169689Skan    }
2601169689Skan
2602169689Skan  *expr_p = t;
2603169689Skan  return GS_OK;
2604169689Skan}
2605169689Skan
2606169689Skan/* A subroutine of gimplify_init_ctor_preeval.  Called via walk_tree,
2607169689Skan   determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
2608169689Skan   assignment.  Returns non-null if we detect a potential overlap.  */
2609169689Skan
2610169689Skanstruct gimplify_init_ctor_preeval_data
2611169689Skan{
2612169689Skan  /* The base decl of the lhs object.  May be NULL, in which case we
2613169689Skan     have to assume the lhs is indirect.  */
2614169689Skan  tree lhs_base_decl;
2615169689Skan
2616169689Skan  /* The alias set of the lhs object.  */
2617169689Skan  int lhs_alias_set;
2618169689Skan};
2619169689Skan
2620169689Skanstatic tree
2621169689Skangimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
2622169689Skan{
2623169689Skan  struct gimplify_init_ctor_preeval_data *data
2624169689Skan    = (struct gimplify_init_ctor_preeval_data *) xdata;
2625169689Skan  tree t = *tp;
2626169689Skan
2627169689Skan  /* If we find the base object, obviously we have overlap.  */
2628169689Skan  if (data->lhs_base_decl == t)
2629169689Skan    return t;
2630169689Skan
2631169689Skan  /* If the constructor component is indirect, determine if we have a
2632169689Skan     potential overlap with the lhs.  The only bits of information we
2633169689Skan     have to go on at this point are addressability and alias sets.  */
2634169689Skan  if (TREE_CODE (t) == INDIRECT_REF
2635169689Skan      && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
2636169689Skan      && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
2637169689Skan    return t;
2638169689Skan
2639169689Skan  /* If the constructor component is a call, determine if it can hide a
2640169689Skan     potential overlap with the lhs through an INDIRECT_REF like above.  */
2641169689Skan  if (TREE_CODE (t) == CALL_EXPR)
2642169689Skan    {
2643169689Skan      tree type, fntype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
2644169689Skan
2645169689Skan      for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
2646169689Skan	if (POINTER_TYPE_P (TREE_VALUE (type))
2647169689Skan	    && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
2648169689Skan	    && alias_sets_conflict_p (data->lhs_alias_set,
2649169689Skan				      get_alias_set
2650169689Skan				        (TREE_TYPE (TREE_VALUE (type)))))
2651169689Skan	  return t;
2652169689Skan    }
2653169689Skan
2654169689Skan  if (IS_TYPE_OR_DECL_P (t))
2655169689Skan    *walk_subtrees = 0;
2656169689Skan  return NULL;
2657169689Skan}
2658169689Skan
2659169689Skan/* A subroutine of gimplify_init_constructor.  Pre-evaluate *EXPR_P,
2660169689Skan   force values that overlap with the lhs (as described by *DATA)
2661169689Skan   into temporaries.  */
2662169689Skan
2663169689Skanstatic void
2664169689Skangimplify_init_ctor_preeval (tree *expr_p, tree *pre_p, tree *post_p,
2665169689Skan			    struct gimplify_init_ctor_preeval_data *data)
2666169689Skan{
2667169689Skan  enum gimplify_status one;
2668169689Skan
2669169689Skan  /* If the value is invariant, then there's nothing to pre-evaluate.
2670169689Skan     But ensure it doesn't have any side-effects since a SAVE_EXPR is
2671169689Skan     invariant but has side effects and might contain a reference to
2672169689Skan     the object we're initializing.  */
2673169689Skan  if (TREE_INVARIANT (*expr_p) && !TREE_SIDE_EFFECTS (*expr_p))
2674169689Skan    return;
2675169689Skan
2676169689Skan  /* If the type has non-trivial constructors, we can't pre-evaluate.  */
2677169689Skan  if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
2678169689Skan    return;
2679169689Skan
2680169689Skan  /* Recurse for nested constructors.  */
2681169689Skan  if (TREE_CODE (*expr_p) == CONSTRUCTOR)
2682169689Skan    {
2683169689Skan      unsigned HOST_WIDE_INT ix;
2684169689Skan      constructor_elt *ce;
2685169689Skan      VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (*expr_p);
2686169689Skan
2687169689Skan      for (ix = 0; VEC_iterate (constructor_elt, v, ix, ce); ix++)
2688169689Skan	gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
2689169689Skan      return;
2690169689Skan    }
2691169689Skan
2692169689Skan  /* If this is a variable sized type, we must remember the size.  */
2693169689Skan  maybe_with_size_expr (expr_p);
2694169689Skan
2695169689Skan  /* Gimplify the constructor element to something appropriate for the rhs
2696169689Skan     of a MODIFY_EXPR.  Given that we know the lhs is an aggregate, we know
2697169689Skan     the gimplifier will consider this a store to memory.  Doing this
2698169689Skan     gimplification now means that we won't have to deal with complicated
2699169689Skan     language-specific trees, nor trees like SAVE_EXPR that can induce
2700169689Skan     exponential search behavior.  */
2701169689Skan  one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
2702169689Skan  if (one == GS_ERROR)
2703169689Skan    {
2704169689Skan      *expr_p = NULL;
2705169689Skan      return;
2706169689Skan    }
2707169689Skan
2708169689Skan  /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
2709169689Skan     with the lhs, since "a = { .x=a }" doesn't make sense.  This will
2710169689Skan     always be true for all scalars, since is_gimple_mem_rhs insists on a
2711169689Skan     temporary variable for them.  */
2712169689Skan  if (DECL_P (*expr_p))
2713169689Skan    return;
2714169689Skan
2715169689Skan  /* If this is of variable size, we have no choice but to assume it doesn't
2716169689Skan     overlap since we can't make a temporary for it.  */
2717169689Skan  if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
2718169689Skan    return;
2719169689Skan
2720169689Skan  /* Otherwise, we must search for overlap ...  */
2721169689Skan  if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
2722169689Skan    return;
2723169689Skan
2724169689Skan  /* ... and if found, force the value into a temporary.  */
2725169689Skan  *expr_p = get_formal_tmp_var (*expr_p, pre_p);
2726169689Skan}
2727169689Skan
2728169689Skan/* A subroutine of gimplify_init_ctor_eval.  Create a loop for
2729169689Skan   a RANGE_EXPR in a CONSTRUCTOR for an array.
2730169689Skan
2731169689Skan      var = lower;
2732169689Skan    loop_entry:
2733169689Skan      object[var] = value;
2734169689Skan      if (var == upper)
2735169689Skan	goto loop_exit;
2736169689Skan      var = var + 1;
2737169689Skan      goto loop_entry;
2738169689Skan    loop_exit:
2739169689Skan
2740169689Skan   We increment var _after_ the loop exit check because we might otherwise
2741169689Skan   fail if upper == TYPE_MAX_VALUE (type for upper).
2742169689Skan
2743169689Skan   Note that we never have to deal with SAVE_EXPRs here, because this has
2744169689Skan   already been taken care of for us, in gimplify_init_ctor_preeval().  */
2745169689Skan
2746169689Skanstatic void gimplify_init_ctor_eval (tree, VEC(constructor_elt,gc) *,
2747169689Skan				     tree *, bool);
2748169689Skan
2749169689Skanstatic void
2750169689Skangimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
2751169689Skan			       tree value, tree array_elt_type,
2752169689Skan			       tree *pre_p, bool cleared)
2753169689Skan{
2754169689Skan  tree loop_entry_label, loop_exit_label;
2755169689Skan  tree var, var_type, cref;
2756169689Skan
2757169689Skan  loop_entry_label = create_artificial_label ();
2758169689Skan  loop_exit_label = create_artificial_label ();
2759169689Skan
2760169689Skan  /* Create and initialize the index variable.  */
2761169689Skan  var_type = TREE_TYPE (upper);
2762169689Skan  var = create_tmp_var (var_type, NULL);
2763169689Skan  append_to_statement_list (build2 (MODIFY_EXPR, var_type, var, lower), pre_p);
2764169689Skan
2765169689Skan  /* Add the loop entry label.  */
2766169689Skan  append_to_statement_list (build1 (LABEL_EXPR,
2767169689Skan				    void_type_node,
2768169689Skan				    loop_entry_label),
2769169689Skan			    pre_p);
2770169689Skan
2771169689Skan  /* Build the reference.  */
2772169689Skan  cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
2773169689Skan		 var, NULL_TREE, NULL_TREE);
2774169689Skan
2775169689Skan  /* If we are a constructor, just call gimplify_init_ctor_eval to do
2776169689Skan     the store.  Otherwise just assign value to the reference.  */
2777169689Skan
2778169689Skan  if (TREE_CODE (value) == CONSTRUCTOR)
2779169689Skan    /* NB we might have to call ourself recursively through
2780169689Skan       gimplify_init_ctor_eval if the value is a constructor.  */
2781169689Skan    gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
2782169689Skan			     pre_p, cleared);
2783169689Skan  else
2784169689Skan    append_to_statement_list (build2 (MODIFY_EXPR, TREE_TYPE (cref),
2785169689Skan				      cref, value),
2786169689Skan			      pre_p);
2787169689Skan
2788169689Skan  /* We exit the loop when the index var is equal to the upper bound.  */
2789169689Skan  gimplify_and_add (build3 (COND_EXPR, void_type_node,
2790169689Skan			    build2 (EQ_EXPR, boolean_type_node,
2791169689Skan				    var, upper),
2792169689Skan			    build1 (GOTO_EXPR,
2793169689Skan				    void_type_node,
2794169689Skan				    loop_exit_label),
2795169689Skan			    NULL_TREE),
2796169689Skan		    pre_p);
2797169689Skan
2798169689Skan  /* Otherwise, increment the index var...  */
2799169689Skan  append_to_statement_list (build2 (MODIFY_EXPR, var_type, var,
2800169689Skan				    build2 (PLUS_EXPR, var_type, var,
2801169689Skan					    fold_convert (var_type,
2802169689Skan							  integer_one_node))),
2803169689Skan			    pre_p);
2804169689Skan
2805169689Skan  /* ...and jump back to the loop entry.  */
2806169689Skan  append_to_statement_list (build1 (GOTO_EXPR,
2807169689Skan				    void_type_node,
2808169689Skan				    loop_entry_label),
2809169689Skan			    pre_p);
2810169689Skan
2811169689Skan  /* Add the loop exit label.  */
2812169689Skan  append_to_statement_list (build1 (LABEL_EXPR,
2813169689Skan				    void_type_node,
2814169689Skan				    loop_exit_label),
2815169689Skan			    pre_p);
2816169689Skan}
2817169689Skan
2818169689Skan/* Return true if FDECL is accessing a field that is zero sized.  */
2819169689Skan
2820169689Skanstatic bool
2821169689Skanzero_sized_field_decl (tree fdecl)
2822169689Skan{
2823169689Skan  if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl)
2824169689Skan      && integer_zerop (DECL_SIZE (fdecl)))
2825169689Skan    return true;
2826169689Skan  return false;
2827169689Skan}
2828169689Skan
2829169689Skan/* Return true if TYPE is zero sized.  */
2830169689Skan
2831169689Skanstatic bool
2832169689Skanzero_sized_type (tree type)
2833169689Skan{
2834169689Skan  if (AGGREGATE_TYPE_P (type) && TYPE_SIZE (type)
2835169689Skan      && integer_zerop (TYPE_SIZE (type)))
2836169689Skan    return true;
2837169689Skan  return false;
2838169689Skan}
2839169689Skan
2840169689Skan/* A subroutine of gimplify_init_constructor.  Generate individual
2841169689Skan   MODIFY_EXPRs for a CONSTRUCTOR.  OBJECT is the LHS against which the
2842169689Skan   assignments should happen.  ELTS is the CONSTRUCTOR_ELTS of the
2843169689Skan   CONSTRUCTOR.  CLEARED is true if the entire LHS object has been
2844169689Skan   zeroed first.  */
2845169689Skan
2846169689Skanstatic void
2847169689Skangimplify_init_ctor_eval (tree object, VEC(constructor_elt,gc) *elts,
2848169689Skan			 tree *pre_p, bool cleared)
2849169689Skan{
2850169689Skan  tree array_elt_type = NULL;
2851169689Skan  unsigned HOST_WIDE_INT ix;
2852169689Skan  tree purpose, value;
2853169689Skan
2854169689Skan  if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
2855169689Skan    array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
2856169689Skan
2857169689Skan  FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
2858169689Skan    {
2859169689Skan      tree cref, init;
2860169689Skan
2861169689Skan      /* NULL values are created above for gimplification errors.  */
2862169689Skan      if (value == NULL)
2863169689Skan	continue;
2864169689Skan
2865169689Skan      if (cleared && initializer_zerop (value))
2866169689Skan	continue;
2867169689Skan
2868169689Skan      /* ??? Here's to hoping the front end fills in all of the indices,
2869169689Skan	 so we don't have to figure out what's missing ourselves.  */
2870169689Skan      gcc_assert (purpose);
2871169689Skan
2872169689Skan      /* Skip zero-sized fields, unless value has side-effects.  This can
2873169689Skan	 happen with calls to functions returning a zero-sized type, which
2874169689Skan	 we shouldn't discard.  As a number of downstream passes don't
2875169689Skan	 expect sets of zero-sized fields, we rely on the gimplification of
2876169689Skan	 the MODIFY_EXPR we make below to drop the assignment statement.  */
2877169689Skan      if (! TREE_SIDE_EFFECTS (value) && zero_sized_field_decl (purpose))
2878169689Skan	continue;
2879169689Skan
2880169689Skan      /* If we have a RANGE_EXPR, we have to build a loop to assign the
2881169689Skan	 whole range.  */
2882169689Skan      if (TREE_CODE (purpose) == RANGE_EXPR)
2883169689Skan	{
2884169689Skan	  tree lower = TREE_OPERAND (purpose, 0);
2885169689Skan	  tree upper = TREE_OPERAND (purpose, 1);
2886169689Skan
2887169689Skan	  /* If the lower bound is equal to upper, just treat it as if
2888169689Skan	     upper was the index.  */
2889169689Skan	  if (simple_cst_equal (lower, upper))
2890169689Skan	    purpose = upper;
2891169689Skan	  else
2892169689Skan	    {
2893169689Skan	      gimplify_init_ctor_eval_range (object, lower, upper, value,
2894169689Skan					     array_elt_type, pre_p, cleared);
2895169689Skan	      continue;
2896169689Skan	    }
2897169689Skan	}
2898169689Skan
2899169689Skan      if (array_elt_type)
2900169689Skan	{
2901169689Skan	  cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
2902169689Skan			 purpose, NULL_TREE, NULL_TREE);
2903169689Skan	}
2904169689Skan      else
2905169689Skan	{
2906169689Skan	  gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
2907169689Skan	  cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
2908169689Skan			 unshare_expr (object), purpose, NULL_TREE);
2909169689Skan	}
2910169689Skan
2911169689Skan      if (TREE_CODE (value) == CONSTRUCTOR
2912169689Skan	  && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
2913169689Skan	gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
2914169689Skan				 pre_p, cleared);
2915169689Skan      else
2916169689Skan	{
2917169689Skan	  init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
2918169689Skan	  gimplify_and_add (init, pre_p);
2919169689Skan	}
2920169689Skan    }
2921169689Skan}
2922169689Skan
2923169689Skan/* A subroutine of gimplify_modify_expr.  Break out elements of a
2924169689Skan   CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
2925169689Skan
2926169689Skan   Note that we still need to clear any elements that don't have explicit
2927169689Skan   initializers, so if not all elements are initialized we keep the
2928169689Skan   original MODIFY_EXPR, we just remove all of the constructor elements.  */
2929169689Skan
2930169689Skanstatic enum gimplify_status
2931169689Skangimplify_init_constructor (tree *expr_p, tree *pre_p,
2932169689Skan			   tree *post_p, bool want_value)
2933169689Skan{
2934169689Skan  tree object;
2935169689Skan  tree ctor = TREE_OPERAND (*expr_p, 1);
2936169689Skan  tree type = TREE_TYPE (ctor);
2937169689Skan  enum gimplify_status ret;
2938169689Skan  VEC(constructor_elt,gc) *elts;
2939169689Skan
2940169689Skan  if (TREE_CODE (ctor) != CONSTRUCTOR)
2941169689Skan    return GS_UNHANDLED;
2942169689Skan
2943169689Skan  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
2944169689Skan		       is_gimple_lvalue, fb_lvalue);
2945169689Skan  if (ret == GS_ERROR)
2946169689Skan    return ret;
2947169689Skan  object = TREE_OPERAND (*expr_p, 0);
2948169689Skan
2949169689Skan  elts = CONSTRUCTOR_ELTS (ctor);
2950169689Skan
2951169689Skan  ret = GS_ALL_DONE;
2952169689Skan  switch (TREE_CODE (type))
2953169689Skan    {
2954169689Skan    case RECORD_TYPE:
2955169689Skan    case UNION_TYPE:
2956169689Skan    case QUAL_UNION_TYPE:
2957169689Skan    case ARRAY_TYPE:
2958169689Skan      {
2959169689Skan	struct gimplify_init_ctor_preeval_data preeval_data;
2960169689Skan	HOST_WIDE_INT num_type_elements, num_ctor_elements;
2961169689Skan	HOST_WIDE_INT num_nonzero_elements;
2962169689Skan	bool cleared, valid_const_initializer;
2963169689Skan
2964169689Skan	/* Aggregate types must lower constructors to initialization of
2965169689Skan	   individual elements.  The exception is that a CONSTRUCTOR node
2966169689Skan	   with no elements indicates zero-initialization of the whole.  */
2967169689Skan	if (VEC_empty (constructor_elt, elts))
2968169689Skan	  break;
2969169689Skan
2970169689Skan	/* Fetch information about the constructor to direct later processing.
2971169689Skan	   We might want to make static versions of it in various cases, and
2972169689Skan	   can only do so if it known to be a valid constant initializer.  */
2973169689Skan	valid_const_initializer
2974169689Skan	  = categorize_ctor_elements (ctor, &num_nonzero_elements,
2975169689Skan				      &num_ctor_elements, &cleared);
2976169689Skan
2977169689Skan	/* If a const aggregate variable is being initialized, then it
2978169689Skan	   should never be a lose to promote the variable to be static.  */
2979169689Skan	if (valid_const_initializer
2980169689Skan	    && num_nonzero_elements > 1
2981169689Skan	    && TREE_READONLY (object)
2982169689Skan	    && TREE_CODE (object) == VAR_DECL)
2983169689Skan	  {
2984169689Skan	    DECL_INITIAL (object) = ctor;
2985169689Skan	    TREE_STATIC (object) = 1;
2986169689Skan	    if (!DECL_NAME (object))
2987169689Skan	      DECL_NAME (object) = create_tmp_var_name ("C");
2988169689Skan	    walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
2989169689Skan
2990169689Skan	    /* ??? C++ doesn't automatically append a .<number> to the
2991169689Skan	       assembler name, and even when it does, it looks a FE private
2992169689Skan	       data structures to figure out what that number should be,
2993169689Skan	       which are not set for this variable.  I suppose this is
2994169689Skan	       important for local statics for inline functions, which aren't
2995169689Skan	       "local" in the object file sense.  So in order to get a unique
2996169689Skan	       TU-local symbol, we must invoke the lhd version now.  */
2997169689Skan	    lhd_set_decl_assembler_name (object);
2998169689Skan
2999169689Skan	    *expr_p = NULL_TREE;
3000169689Skan	    break;
3001169689Skan	  }
3002169689Skan
3003169689Skan	/* If there are "lots" of initialized elements, even discounting
3004169689Skan	   those that are not address constants (and thus *must* be
3005169689Skan	   computed at runtime), then partition the constructor into
3006169689Skan	   constant and non-constant parts.  Block copy the constant
3007169689Skan	   parts in, then generate code for the non-constant parts.  */
3008169689Skan	/* TODO.  There's code in cp/typeck.c to do this.  */
3009169689Skan
3010169689Skan	num_type_elements = count_type_elements (type, true);
3011169689Skan
3012169689Skan	/* If count_type_elements could not determine number of type elements
3013169689Skan	   for a constant-sized object, assume clearing is needed.
3014169689Skan	   Don't do this for variable-sized objects, as store_constructor
3015169689Skan	   will ignore the clearing of variable-sized objects.  */
3016169689Skan	if (num_type_elements < 0 && int_size_in_bytes (type) >= 0)
3017169689Skan	  cleared = true;
3018169689Skan	/* If there are "lots" of zeros, then block clear the object first.  */
3019169689Skan	else if (num_type_elements - num_nonzero_elements > CLEAR_RATIO
3020169689Skan		 && num_nonzero_elements < num_type_elements/4)
3021169689Skan	  cleared = true;
3022169689Skan	/* ??? This bit ought not be needed.  For any element not present
3023169689Skan	   in the initializer, we should simply set them to zero.  Except
3024169689Skan	   we'd need to *find* the elements that are not present, and that
3025169689Skan	   requires trickery to avoid quadratic compile-time behavior in
3026169689Skan	   large cases or excessive memory use in small cases.  */
3027169689Skan	else if (num_ctor_elements < num_type_elements)
3028169689Skan	  cleared = true;
3029169689Skan
3030169689Skan	/* If there are "lots" of initialized elements, and all of them
3031169689Skan	   are valid address constants, then the entire initializer can
3032169689Skan	   be dropped to memory, and then memcpy'd out.  Don't do this
3033169689Skan	   for sparse arrays, though, as it's more efficient to follow
3034169689Skan	   the standard CONSTRUCTOR behavior of memset followed by
3035169689Skan	   individual element initialization.  */
3036169689Skan	if (valid_const_initializer && !cleared)
3037169689Skan	  {
3038169689Skan	    HOST_WIDE_INT size = int_size_in_bytes (type);
3039169689Skan	    unsigned int align;
3040169689Skan
3041169689Skan	    /* ??? We can still get unbounded array types, at least
3042169689Skan	       from the C++ front end.  This seems wrong, but attempt
3043169689Skan	       to work around it for now.  */
3044169689Skan	    if (size < 0)
3045169689Skan	      {
3046169689Skan		size = int_size_in_bytes (TREE_TYPE (object));
3047169689Skan		if (size >= 0)
3048169689Skan		  TREE_TYPE (ctor) = type = TREE_TYPE (object);
3049169689Skan	      }
3050169689Skan
3051169689Skan	    /* Find the maximum alignment we can assume for the object.  */
3052169689Skan	    /* ??? Make use of DECL_OFFSET_ALIGN.  */
3053169689Skan	    if (DECL_P (object))
3054169689Skan	      align = DECL_ALIGN (object);
3055169689Skan	    else
3056169689Skan	      align = TYPE_ALIGN (type);
3057169689Skan
3058169689Skan	    if (size > 0 && !can_move_by_pieces (size, align))
3059169689Skan	      {
3060169689Skan		tree new = create_tmp_var_raw (type, "C");
3061169689Skan
3062169689Skan		gimple_add_tmp_var (new);
3063169689Skan		TREE_STATIC (new) = 1;
3064169689Skan		TREE_READONLY (new) = 1;
3065169689Skan		DECL_INITIAL (new) = ctor;
3066169689Skan		if (align > DECL_ALIGN (new))
3067169689Skan		  {
3068169689Skan		    DECL_ALIGN (new) = align;
3069169689Skan		    DECL_USER_ALIGN (new) = 1;
3070169689Skan		  }
3071169689Skan	        walk_tree (&DECL_INITIAL (new), force_labels_r, NULL, NULL);
3072169689Skan
3073169689Skan		TREE_OPERAND (*expr_p, 1) = new;
3074169689Skan
3075169689Skan		/* This is no longer an assignment of a CONSTRUCTOR, but
3076169689Skan		   we still may have processing to do on the LHS.  So
3077169689Skan		   pretend we didn't do anything here to let that happen.  */
3078169689Skan		return GS_UNHANDLED;
3079169689Skan	      }
3080169689Skan	  }
3081169689Skan
3082169689Skan	/* If there are nonzero elements, pre-evaluate to capture elements
3083169689Skan	   overlapping with the lhs into temporaries.  We must do this before
3084169689Skan	   clearing to fetch the values before they are zeroed-out.  */
3085169689Skan	if (num_nonzero_elements > 0)
3086169689Skan	  {
3087169689Skan	    preeval_data.lhs_base_decl = get_base_address (object);
3088169689Skan	    if (!DECL_P (preeval_data.lhs_base_decl))
3089169689Skan	      preeval_data.lhs_base_decl = NULL;
3090169689Skan	    preeval_data.lhs_alias_set = get_alias_set (object);
3091169689Skan
3092169689Skan	    gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
3093169689Skan					pre_p, post_p, &preeval_data);
3094169689Skan	  }
3095169689Skan
3096169689Skan	if (cleared)
3097169689Skan	  {
3098169689Skan	    /* Zap the CONSTRUCTOR element list, which simplifies this case.
3099169689Skan	       Note that we still have to gimplify, in order to handle the
3100169689Skan	       case of variable sized types.  Avoid shared tree structures.  */
3101169689Skan	    CONSTRUCTOR_ELTS (ctor) = NULL;
3102169689Skan	    object = unshare_expr (object);
3103169689Skan	    gimplify_stmt (expr_p);
3104169689Skan	    append_to_statement_list (*expr_p, pre_p);
3105169689Skan	  }
3106169689Skan
3107169689Skan	/* If we have not block cleared the object, or if there are nonzero
3108169689Skan	   elements in the constructor, add assignments to the individual
3109169689Skan	   scalar fields of the object.  */
3110169689Skan	if (!cleared || num_nonzero_elements > 0)
3111169689Skan	  gimplify_init_ctor_eval (object, elts, pre_p, cleared);
3112169689Skan
3113169689Skan	*expr_p = NULL_TREE;
3114169689Skan      }
3115169689Skan      break;
3116169689Skan
3117169689Skan    case COMPLEX_TYPE:
3118169689Skan      {
3119169689Skan	tree r, i;
3120169689Skan
3121169689Skan	/* Extract the real and imaginary parts out of the ctor.  */
3122169689Skan	gcc_assert (VEC_length (constructor_elt, elts) == 2);
3123169689Skan	r = VEC_index (constructor_elt, elts, 0)->value;
3124169689Skan	i = VEC_index (constructor_elt, elts, 1)->value;
3125169689Skan	if (r == NULL || i == NULL)
3126169689Skan	  {
3127169689Skan	    tree zero = fold_convert (TREE_TYPE (type), integer_zero_node);
3128169689Skan	    if (r == NULL)
3129169689Skan	      r = zero;
3130169689Skan	    if (i == NULL)
3131169689Skan	      i = zero;
3132169689Skan	  }
3133169689Skan
3134169689Skan	/* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
3135169689Skan	   represent creation of a complex value.  */
3136169689Skan	if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
3137169689Skan	  {
3138169689Skan	    ctor = build_complex (type, r, i);
3139169689Skan	    TREE_OPERAND (*expr_p, 1) = ctor;
3140169689Skan	  }
3141169689Skan	else
3142169689Skan	  {
3143169689Skan	    ctor = build2 (COMPLEX_EXPR, type, r, i);
3144169689Skan	    TREE_OPERAND (*expr_p, 1) = ctor;
3145169689Skan	    ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
3146169689Skan				 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
3147169689Skan				 fb_rvalue);
3148169689Skan	  }
3149169689Skan      }
3150169689Skan      break;
3151169689Skan
3152169689Skan    case VECTOR_TYPE:
3153169689Skan      {
3154169689Skan	unsigned HOST_WIDE_INT ix;
3155169689Skan	constructor_elt *ce;
3156169689Skan
3157169689Skan	/* Go ahead and simplify constant constructors to VECTOR_CST.  */
3158169689Skan	if (TREE_CONSTANT (ctor))
3159169689Skan	  {
3160169689Skan	    bool constant_p = true;
3161169689Skan	    tree value;
3162169689Skan
3163169689Skan	    /* Even when ctor is constant, it might contain non-*_CST
3164169689Skan	      elements (e.g. { 1.0/0.0 - 1.0/0.0, 0.0 }) and those don't
3165169689Skan	      belong into VECTOR_CST nodes.  */
3166169689Skan	    FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
3167169689Skan	      if (!CONSTANT_CLASS_P (value))
3168169689Skan		{
3169169689Skan		  constant_p = false;
3170169689Skan		  break;
3171169689Skan		}
3172169689Skan
3173169689Skan	    if (constant_p)
3174169689Skan	      {
3175169689Skan		TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
3176169689Skan		break;
3177169689Skan	      }
3178169689Skan
3179169689Skan	    /* Don't reduce a TREE_CONSTANT vector ctor even if we can't
3180169689Skan	       make a VECTOR_CST.  It won't do anything for us, and it'll
3181169689Skan	       prevent us from representing it as a single constant.  */
3182169689Skan	    break;
3183169689Skan	  }
3184169689Skan
3185169689Skan	/* Vector types use CONSTRUCTOR all the way through gimple
3186169689Skan	  compilation as a general initializer.  */
3187169689Skan	for (ix = 0; VEC_iterate (constructor_elt, elts, ix, ce); ix++)
3188169689Skan	  {
3189169689Skan	    enum gimplify_status tret;
3190169689Skan	    tret = gimplify_expr (&ce->value, pre_p, post_p,
3191169689Skan				  is_gimple_val, fb_rvalue);
3192169689Skan	    if (tret == GS_ERROR)
3193169689Skan	      ret = GS_ERROR;
3194169689Skan	  }
3195169689Skan      }
3196169689Skan      break;
3197169689Skan
3198169689Skan    default:
3199169689Skan      /* So how did we get a CONSTRUCTOR for a scalar type?  */
3200169689Skan      gcc_unreachable ();
3201169689Skan    }
3202169689Skan
3203169689Skan  if (ret == GS_ERROR)
3204169689Skan    return GS_ERROR;
3205169689Skan  else if (want_value)
3206169689Skan    {
3207169689Skan      append_to_statement_list (*expr_p, pre_p);
3208169689Skan      *expr_p = object;
3209169689Skan      return GS_OK;
3210169689Skan    }
3211169689Skan  else
3212169689Skan    return GS_ALL_DONE;
3213169689Skan}
3214169689Skan
3215169689Skan/* Given a pointer value OP0, return a simplified version of an
3216169689Skan   indirection through OP0, or NULL_TREE if no simplification is
3217169689Skan   possible.  This may only be applied to a rhs of an expression.
3218169689Skan   Note that the resulting type may be different from the type pointed
3219169689Skan   to in the sense that it is still compatible from the langhooks
3220169689Skan   point of view. */
3221169689Skan
3222169689Skanstatic tree
3223169689Skanfold_indirect_ref_rhs (tree t)
3224169689Skan{
3225169689Skan  tree type = TREE_TYPE (TREE_TYPE (t));
3226169689Skan  tree sub = t;
3227169689Skan  tree subtype;
3228169689Skan
3229169689Skan  STRIP_USELESS_TYPE_CONVERSION (sub);
3230169689Skan  subtype = TREE_TYPE (sub);
3231169689Skan  if (!POINTER_TYPE_P (subtype))
3232169689Skan    return NULL_TREE;
3233169689Skan
3234169689Skan  if (TREE_CODE (sub) == ADDR_EXPR)
3235169689Skan    {
3236169689Skan      tree op = TREE_OPERAND (sub, 0);
3237169689Skan      tree optype = TREE_TYPE (op);
3238169689Skan      /* *&p => p */
3239169689Skan      if (lang_hooks.types_compatible_p (type, optype))
3240169689Skan        return op;
3241169689Skan      /* *(foo *)&fooarray => fooarray[0] */
3242169689Skan      else if (TREE_CODE (optype) == ARRAY_TYPE
3243169689Skan	       && lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
3244169689Skan       {
3245169689Skan         tree type_domain = TYPE_DOMAIN (optype);
3246169689Skan         tree min_val = size_zero_node;
3247169689Skan         if (type_domain && TYPE_MIN_VALUE (type_domain))
3248169689Skan           min_val = TYPE_MIN_VALUE (type_domain);
3249169689Skan         return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
3250169689Skan       }
3251169689Skan    }
3252169689Skan
3253169689Skan  /* *(foo *)fooarrptr => (*fooarrptr)[0] */
3254169689Skan  if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
3255169689Skan      && lang_hooks.types_compatible_p (type, TREE_TYPE (TREE_TYPE (subtype))))
3256169689Skan    {
3257169689Skan      tree type_domain;
3258169689Skan      tree min_val = size_zero_node;
3259169689Skan      tree osub = sub;
3260169689Skan      sub = fold_indirect_ref_rhs (sub);
3261169689Skan      if (! sub)
3262169689Skan	sub = build1 (INDIRECT_REF, TREE_TYPE (subtype), osub);
3263169689Skan      type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
3264169689Skan      if (type_domain && TYPE_MIN_VALUE (type_domain))
3265169689Skan        min_val = TYPE_MIN_VALUE (type_domain);
3266169689Skan      return build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE);
3267169689Skan    }
3268169689Skan
3269169689Skan  return NULL_TREE;
3270169689Skan}
3271169689Skan
3272169689Skan/* Subroutine of gimplify_modify_expr to do simplifications of MODIFY_EXPRs
3273169689Skan   based on the code of the RHS.  We loop for as long as something changes.  */
3274169689Skan
3275169689Skanstatic enum gimplify_status
3276169689Skangimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
3277169689Skan			  tree *post_p, bool want_value)
3278169689Skan{
3279169689Skan  enum gimplify_status ret = GS_OK;
3280169689Skan
3281169689Skan  while (ret != GS_UNHANDLED)
3282169689Skan    switch (TREE_CODE (*from_p))
3283169689Skan      {
3284169689Skan      case INDIRECT_REF:
3285169689Skan	{
3286169689Skan	  /* If we have code like
3287169689Skan
3288169689Skan	        *(const A*)(A*)&x
3289169689Skan
3290169689Skan	     where the type of "x" is a (possibly cv-qualified variant
3291169689Skan	     of "A"), treat the entire expression as identical to "x".
3292169689Skan	     This kind of code arises in C++ when an object is bound
3293169689Skan	     to a const reference, and if "x" is a TARGET_EXPR we want
3294169689Skan	     to take advantage of the optimization below.  */
3295169689Skan	  tree t = fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
3296169689Skan	  if (t)
3297169689Skan	    {
3298169689Skan	      *from_p = t;
3299169689Skan	      ret = GS_OK;
3300169689Skan	    }
3301169689Skan	  else
3302169689Skan	    ret = GS_UNHANDLED;
3303169689Skan	  break;
3304169689Skan	}
3305169689Skan
3306169689Skan      case TARGET_EXPR:
3307169689Skan	{
3308169689Skan	  /* If we are initializing something from a TARGET_EXPR, strip the
3309169689Skan	     TARGET_EXPR and initialize it directly, if possible.  This can't
3310169689Skan	     be done if the initializer is void, since that implies that the
3311169689Skan	     temporary is set in some non-trivial way.
3312169689Skan
3313169689Skan	     ??? What about code that pulls out the temp and uses it
3314169689Skan	     elsewhere? I think that such code never uses the TARGET_EXPR as
3315169689Skan	     an initializer.  If I'm wrong, we'll die because the temp won't
3316169689Skan	     have any RTL.  In that case, I guess we'll need to replace
3317169689Skan	     references somehow.  */
3318169689Skan	  tree init = TARGET_EXPR_INITIAL (*from_p);
3319169689Skan
3320169689Skan	  if (!VOID_TYPE_P (TREE_TYPE (init)))
3321169689Skan	    {
3322169689Skan	      *from_p = init;
3323169689Skan	      ret = GS_OK;
3324169689Skan	    }
3325169689Skan	  else
3326169689Skan	    ret = GS_UNHANDLED;
3327169689Skan	}
3328169689Skan	break;
3329169689Skan
3330169689Skan      case COMPOUND_EXPR:
3331169689Skan	/* Remove any COMPOUND_EXPR in the RHS so the following cases will be
3332169689Skan	   caught.  */
3333169689Skan	gimplify_compound_expr (from_p, pre_p, true);
3334169689Skan	ret = GS_OK;
3335169689Skan	break;
3336169689Skan
3337169689Skan      case CONSTRUCTOR:
3338169689Skan	/* If we're initializing from a CONSTRUCTOR, break this into
3339169689Skan	   individual MODIFY_EXPRs.  */
3340169689Skan	return gimplify_init_constructor (expr_p, pre_p, post_p, want_value);
3341169689Skan
3342169689Skan      case COND_EXPR:
3343169689Skan	/* If we're assigning to a non-register type, push the assignment
3344169689Skan	   down into the branches.  This is mandatory for ADDRESSABLE types,
3345169689Skan	   since we cannot generate temporaries for such, but it saves a
3346169689Skan	   copy in other cases as well.  */
3347169689Skan	if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
3348169689Skan	  {
3349169689Skan	    /* This code should mirror the code in gimplify_cond_expr. */
3350169689Skan	    enum tree_code code = TREE_CODE (*expr_p);
3351169689Skan	    tree cond = *from_p;
3352169689Skan	    tree result = *to_p;
3353169689Skan
3354169689Skan	    ret = gimplify_expr (&result, pre_p, post_p,
3355169689Skan				 is_gimple_min_lval, fb_lvalue);
3356169689Skan	    if (ret != GS_ERROR)
3357169689Skan	      ret = GS_OK;
3358169689Skan
3359169689Skan	    if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
3360169689Skan	      TREE_OPERAND (cond, 1)
3361169689Skan		= build2 (code, void_type_node, result,
3362169689Skan			  TREE_OPERAND (cond, 1));
3363169689Skan	    if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
3364169689Skan	      TREE_OPERAND (cond, 2)
3365169689Skan		= build2 (code, void_type_node, unshare_expr (result),
3366169689Skan			  TREE_OPERAND (cond, 2));
3367169689Skan
3368169689Skan	    TREE_TYPE (cond) = void_type_node;
3369169689Skan	    recalculate_side_effects (cond);
3370169689Skan
3371169689Skan	    if (want_value)
3372169689Skan	      {
3373169689Skan		gimplify_and_add (cond, pre_p);
3374169689Skan		*expr_p = unshare_expr (result);
3375169689Skan	      }
3376169689Skan	    else
3377169689Skan	      *expr_p = cond;
3378169689Skan	    return ret;
3379169689Skan	  }
3380169689Skan	else
3381169689Skan	  ret = GS_UNHANDLED;
3382169689Skan	break;
3383169689Skan
3384169689Skan      case CALL_EXPR:
3385169689Skan	/* For calls that return in memory, give *to_p as the CALL_EXPR's
3386169689Skan	   return slot so that we don't generate a temporary.  */
3387169689Skan	if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
3388169689Skan	    && aggregate_value_p (*from_p, *from_p))
3389169689Skan	  {
3390169689Skan	    bool use_target;
3391169689Skan
3392169689Skan	    if (!(rhs_predicate_for (*to_p))(*from_p))
3393169689Skan	      /* If we need a temporary, *to_p isn't accurate.  */
3394169689Skan	      use_target = false;
3395169689Skan	    else if (TREE_CODE (*to_p) == RESULT_DECL
3396169689Skan		     && DECL_NAME (*to_p) == NULL_TREE
3397169689Skan		     && needs_to_live_in_memory (*to_p))
3398169689Skan	      /* It's OK to use the return slot directly unless it's an NRV. */
3399169689Skan	      use_target = true;
3400169689Skan	    else if (is_gimple_reg_type (TREE_TYPE (*to_p))
3401169689Skan		     || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
3402169689Skan	      /* Don't force regs into memory.  */
3403169689Skan	      use_target = false;
3404169689Skan	    else if (TREE_CODE (*to_p) == VAR_DECL
3405169689Skan		     && DECL_GIMPLE_FORMAL_TEMP_P (*to_p))
3406169689Skan	      /* Don't use the original target if it's a formal temp; we
3407169689Skan		 don't want to take their addresses.  */
3408169689Skan	      use_target = false;
3409169689Skan	    else if (TREE_CODE (*expr_p) == INIT_EXPR)
3410169689Skan	      /* It's OK to use the target directly if it's being
3411169689Skan		 initialized. */
3412169689Skan	      use_target = true;
3413169689Skan	    else if (!is_gimple_non_addressable (*to_p))
3414169689Skan	      /* Don't use the original target if it's already addressable;
3415169689Skan		 if its address escapes, and the called function uses the
3416169689Skan		 NRV optimization, a conforming program could see *to_p
3417169689Skan		 change before the called function returns; see c++/19317.
3418169689Skan		 When optimizing, the return_slot pass marks more functions
3419169689Skan		 as safe after we have escape info.  */
3420169689Skan	      use_target = false;
3421169689Skan	    else
3422169689Skan	      use_target = true;
3423169689Skan
3424169689Skan	    if (use_target)
3425169689Skan	      {
3426169689Skan		CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
3427169689Skan		lang_hooks.mark_addressable (*to_p);
3428169689Skan	      }
3429169689Skan	  }
3430169689Skan
3431169689Skan	ret = GS_UNHANDLED;
3432169689Skan	break;
3433169689Skan
3434169689Skan	/* If we're initializing from a container, push the initialization
3435169689Skan	   inside it.  */
3436169689Skan      case CLEANUP_POINT_EXPR:
3437169689Skan      case BIND_EXPR:
3438169689Skan      case STATEMENT_LIST:
3439169689Skan	{
3440169689Skan	  tree wrap = *from_p;
3441169689Skan	  tree t;
3442169689Skan
3443169689Skan	  ret = gimplify_expr (to_p, pre_p, post_p,
3444169689Skan			       is_gimple_min_lval, fb_lvalue);
3445169689Skan	  if (ret != GS_ERROR)
3446169689Skan	    ret = GS_OK;
3447169689Skan
3448169689Skan	  t = voidify_wrapper_expr (wrap, *expr_p);
3449169689Skan	  gcc_assert (t == *expr_p);
3450169689Skan
3451169689Skan	  if (want_value)
3452169689Skan	    {
3453169689Skan	      gimplify_and_add (wrap, pre_p);
3454169689Skan	      *expr_p = unshare_expr (*to_p);
3455169689Skan	    }
3456169689Skan	  else
3457169689Skan	    *expr_p = wrap;
3458169689Skan	  return GS_OK;
3459169689Skan	}
3460169689Skan
3461169689Skan      default:
3462169689Skan	ret = GS_UNHANDLED;
3463169689Skan	break;
3464169689Skan      }
3465169689Skan
3466169689Skan  return ret;
3467169689Skan}
3468169689Skan
3469169689Skan/* Promote partial stores to COMPLEX variables to total stores.  *EXPR_P is
3470169689Skan   a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with
3471169689Skan   DECL_COMPLEX_GIMPLE_REG_P set.  */
3472169689Skan
3473169689Skanstatic enum gimplify_status
3474169689Skangimplify_modify_expr_complex_part (tree *expr_p, tree *pre_p, bool want_value)
3475169689Skan{
3476169689Skan  enum tree_code code, ocode;
3477169689Skan  tree lhs, rhs, new_rhs, other, realpart, imagpart;
3478169689Skan
3479169689Skan  lhs = TREE_OPERAND (*expr_p, 0);
3480169689Skan  rhs = TREE_OPERAND (*expr_p, 1);
3481169689Skan  code = TREE_CODE (lhs);
3482169689Skan  lhs = TREE_OPERAND (lhs, 0);
3483169689Skan
3484169689Skan  ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
3485169689Skan  other = build1 (ocode, TREE_TYPE (rhs), lhs);
3486169689Skan  other = get_formal_tmp_var (other, pre_p);
3487169689Skan
3488169689Skan  realpart = code == REALPART_EXPR ? rhs : other;
3489169689Skan  imagpart = code == REALPART_EXPR ? other : rhs;
3490169689Skan
3491169689Skan  if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
3492169689Skan    new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
3493169689Skan  else
3494169689Skan    new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
3495169689Skan
3496169689Skan  TREE_OPERAND (*expr_p, 0) = lhs;
3497169689Skan  TREE_OPERAND (*expr_p, 1) = new_rhs;
3498169689Skan
3499169689Skan  if (want_value)
3500169689Skan    {
3501169689Skan      append_to_statement_list (*expr_p, pre_p);
3502169689Skan      *expr_p = rhs;
3503169689Skan    }
3504169689Skan
3505169689Skan  return GS_ALL_DONE;
3506169689Skan}
3507169689Skan
3508169689Skan/* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
3509169689Skan
3510169689Skan      modify_expr
3511169689Skan	      : varname '=' rhs
3512169689Skan	      | '*' ID '=' rhs
3513169689Skan
3514169689Skan    PRE_P points to the list where side effects that must happen before
3515169689Skan	*EXPR_P should be stored.
3516169689Skan
3517169689Skan    POST_P points to the list where side effects that must happen after
3518169689Skan	*EXPR_P should be stored.
3519169689Skan
3520169689Skan    WANT_VALUE is nonzero iff we want to use the value of this expression
3521169689Skan	in another expression.  */
3522169689Skan
3523169689Skanstatic enum gimplify_status
3524169689Skangimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
3525169689Skan{
3526169689Skan  tree *from_p = &TREE_OPERAND (*expr_p, 1);
3527169689Skan  tree *to_p = &TREE_OPERAND (*expr_p, 0);
3528169689Skan  enum gimplify_status ret = GS_UNHANDLED;
3529169689Skan
3530169689Skan  gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
3531169689Skan	      || TREE_CODE (*expr_p) == INIT_EXPR);
3532169689Skan
3533220150Smm  /* See if any simplifications can be done based on what the RHS is.  */
3534220150Smm  ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
3535220150Smm				  want_value);
3536220150Smm  if (ret != GS_UNHANDLED)
3537220150Smm    return ret;
3538220150Smm
3539220150Smm  /* For zero sized types only gimplify the left hand side and right hand
3540220150Smm     side as statements and throw away the assignment.  Do this after
3541220150Smm     gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
3542220150Smm     types properly.  */
3543169689Skan  if (zero_sized_type (TREE_TYPE (*from_p)))
3544169689Skan    {
3545169689Skan      gimplify_stmt (from_p);
3546169689Skan      gimplify_stmt (to_p);
3547169689Skan      append_to_statement_list (*from_p, pre_p);
3548169689Skan      append_to_statement_list (*to_p, pre_p);
3549169689Skan      *expr_p = NULL_TREE;
3550169689Skan      return GS_ALL_DONE;
3551169689Skan    }
3552169689Skan
3553169689Skan  /* If the value being copied is of variable width, compute the length
3554169689Skan     of the copy into a WITH_SIZE_EXPR.   Note that we need to do this
3555169689Skan     before gimplifying any of the operands so that we can resolve any
3556169689Skan     PLACEHOLDER_EXPRs in the size.  Also note that the RTL expander uses
3557169689Skan     the size of the expression to be copied, not of the destination, so
3558169689Skan     that is what we must here.  */
3559169689Skan  maybe_with_size_expr (from_p);
3560169689Skan
3561169689Skan  ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3562169689Skan  if (ret == GS_ERROR)
3563169689Skan    return ret;
3564169689Skan
3565169689Skan  ret = gimplify_expr (from_p, pre_p, post_p,
3566169689Skan		       rhs_predicate_for (*to_p), fb_rvalue);
3567169689Skan  if (ret == GS_ERROR)
3568169689Skan    return ret;
3569169689Skan
3570169689Skan  /* Now see if the above changed *from_p to something we handle specially.  */
3571169689Skan  ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
3572169689Skan				  want_value);
3573169689Skan  if (ret != GS_UNHANDLED)
3574169689Skan    return ret;
3575169689Skan
3576169689Skan  /* If we've got a variable sized assignment between two lvalues (i.e. does
3577169689Skan     not involve a call), then we can make things a bit more straightforward
3578169689Skan     by converting the assignment to memcpy or memset.  */
3579169689Skan  if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
3580169689Skan    {
3581169689Skan      tree from = TREE_OPERAND (*from_p, 0);
3582169689Skan      tree size = TREE_OPERAND (*from_p, 1);
3583169689Skan
3584169689Skan      if (TREE_CODE (from) == CONSTRUCTOR)
3585169689Skan	return gimplify_modify_expr_to_memset (expr_p, size, want_value);
3586169689Skan      if (is_gimple_addressable (from))
3587169689Skan	{
3588169689Skan	  *from_p = from;
3589169689Skan	  return gimplify_modify_expr_to_memcpy (expr_p, size, want_value);
3590169689Skan	}
3591169689Skan    }
3592169689Skan
3593169689Skan  /* Transform partial stores to non-addressable complex variables into
3594169689Skan     total stores.  This allows us to use real instead of virtual operands
3595169689Skan     for these variables, which improves optimization.  */
3596169689Skan  if ((TREE_CODE (*to_p) == REALPART_EXPR
3597169689Skan       || TREE_CODE (*to_p) == IMAGPART_EXPR)
3598169689Skan      && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
3599169689Skan    return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
3600169689Skan
3601169689Skan  if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
3602169689Skan    {
3603169689Skan      /* If we've somehow already got an SSA_NAME on the LHS, then
3604169689Skan	 we're probably modified it twice.  Not good.  */
3605169689Skan      gcc_assert (TREE_CODE (*to_p) != SSA_NAME);
3606169689Skan      *to_p = make_ssa_name (*to_p, *expr_p);
3607169689Skan    }
3608169689Skan
3609169689Skan  if (want_value)
3610169689Skan    {
3611169689Skan      append_to_statement_list (*expr_p, pre_p);
3612169689Skan      *expr_p = *to_p;
3613169689Skan      return GS_OK;
3614169689Skan    }
3615169689Skan
3616169689Skan  return GS_ALL_DONE;
3617169689Skan}
3618169689Skan
3619169689Skan/*  Gimplify a comparison between two variable-sized objects.  Do this
3620169689Skan    with a call to BUILT_IN_MEMCMP.  */
3621169689Skan
3622169689Skanstatic enum gimplify_status
3623169689Skangimplify_variable_sized_compare (tree *expr_p)
3624169689Skan{
3625169689Skan  tree op0 = TREE_OPERAND (*expr_p, 0);
3626169689Skan  tree op1 = TREE_OPERAND (*expr_p, 1);
3627169689Skan  tree args, t, dest;
3628169689Skan
3629169689Skan  t = TYPE_SIZE_UNIT (TREE_TYPE (op0));
3630169689Skan  t = unshare_expr (t);
3631169689Skan  t = SUBSTITUTE_PLACEHOLDER_IN_EXPR (t, op0);
3632169689Skan  args = tree_cons (NULL, t, NULL);
3633169689Skan  t = build_fold_addr_expr (op1);
3634169689Skan  args = tree_cons (NULL, t, args);
3635169689Skan  dest = build_fold_addr_expr (op0);
3636169689Skan  args = tree_cons (NULL, dest, args);
3637169689Skan  t = implicit_built_in_decls[BUILT_IN_MEMCMP];
3638169689Skan  t = build_function_call_expr (t, args);
3639169689Skan  *expr_p
3640169689Skan    = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
3641169689Skan
3642169689Skan  return GS_OK;
3643169689Skan}
3644169689Skan
3645169689Skan/*  Gimplify a comparison between two aggregate objects of integral scalar
3646169689Skan    mode as a comparison between the bitwise equivalent scalar values.  */
3647169689Skan
3648169689Skanstatic enum gimplify_status
3649169689Skangimplify_scalar_mode_aggregate_compare (tree *expr_p)
3650169689Skan{
3651169689Skan  tree op0 = TREE_OPERAND (*expr_p, 0);
3652169689Skan  tree op1 = TREE_OPERAND (*expr_p, 1);
3653169689Skan
3654169689Skan  tree type = TREE_TYPE (op0);
3655169689Skan  tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
3656169689Skan
3657169689Skan  op0 = fold_build1 (VIEW_CONVERT_EXPR, scalar_type, op0);
3658169689Skan  op1 = fold_build1 (VIEW_CONVERT_EXPR, scalar_type, op1);
3659169689Skan
3660169689Skan  *expr_p
3661169689Skan    = fold_build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
3662169689Skan
3663169689Skan  return GS_OK;
3664169689Skan}
3665169689Skan
3666169689Skan/*  Gimplify TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR expressions.  EXPR_P
3667169689Skan    points to the expression to gimplify.
3668169689Skan
3669169689Skan    Expressions of the form 'a && b' are gimplified to:
3670169689Skan
3671169689Skan	a && b ? true : false
3672169689Skan
3673169689Skan    gimplify_cond_expr will do the rest.
3674169689Skan
3675169689Skan    PRE_P points to the list where side effects that must happen before
3676169689Skan	*EXPR_P should be stored.  */
3677169689Skan
3678169689Skanstatic enum gimplify_status
3679169689Skangimplify_boolean_expr (tree *expr_p)
3680169689Skan{
3681169689Skan  /* Preserve the original type of the expression.  */
3682169689Skan  tree type = TREE_TYPE (*expr_p);
3683169689Skan
3684169689Skan  *expr_p = build3 (COND_EXPR, type, *expr_p,
3685169689Skan		    fold_convert (type, boolean_true_node),
3686169689Skan		    fold_convert (type, boolean_false_node));
3687169689Skan
3688169689Skan  return GS_OK;
3689169689Skan}
3690169689Skan
3691169689Skan/* Gimplifies an expression sequence.  This function gimplifies each
3692169689Skan   expression and re-writes the original expression with the last
3693169689Skan   expression of the sequence in GIMPLE form.
3694169689Skan
3695169689Skan   PRE_P points to the list where the side effects for all the
3696169689Skan       expressions in the sequence will be emitted.
3697169689Skan
3698169689Skan   WANT_VALUE is true when the result of the last COMPOUND_EXPR is used.  */
3699169689Skan/* ??? Should rearrange to share the pre-queue with all the indirect
3700169689Skan   invocations of gimplify_expr.  Would probably save on creations
3701169689Skan   of statement_list nodes.  */
3702169689Skan
3703169689Skanstatic enum gimplify_status
3704169689Skangimplify_compound_expr (tree *expr_p, tree *pre_p, bool want_value)
3705169689Skan{
3706169689Skan  tree t = *expr_p;
3707169689Skan
3708169689Skan  do
3709169689Skan    {
3710169689Skan      tree *sub_p = &TREE_OPERAND (t, 0);
3711169689Skan
3712169689Skan      if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
3713169689Skan	gimplify_compound_expr (sub_p, pre_p, false);
3714169689Skan      else
3715169689Skan	gimplify_stmt (sub_p);
3716169689Skan      append_to_statement_list (*sub_p, pre_p);
3717169689Skan
3718169689Skan      t = TREE_OPERAND (t, 1);
3719169689Skan    }
3720169689Skan  while (TREE_CODE (t) == COMPOUND_EXPR);
3721169689Skan
3722169689Skan  *expr_p = t;
3723169689Skan  if (want_value)
3724169689Skan    return GS_OK;
3725169689Skan  else
3726169689Skan    {
3727169689Skan      gimplify_stmt (expr_p);
3728169689Skan      return GS_ALL_DONE;
3729169689Skan    }
3730169689Skan}
3731169689Skan
3732169689Skan/* Gimplifies a statement list.  These may be created either by an
3733169689Skan   enlightened front-end, or by shortcut_cond_expr.  */
3734169689Skan
3735169689Skanstatic enum gimplify_status
3736169689Skangimplify_statement_list (tree *expr_p, tree *pre_p)
3737169689Skan{
3738169689Skan  tree temp = voidify_wrapper_expr (*expr_p, NULL);
3739169689Skan
3740169689Skan  tree_stmt_iterator i = tsi_start (*expr_p);
3741169689Skan
3742169689Skan  while (!tsi_end_p (i))
3743169689Skan    {
3744169689Skan      tree t;
3745169689Skan
3746169689Skan      gimplify_stmt (tsi_stmt_ptr (i));
3747169689Skan
3748169689Skan      t = tsi_stmt (i);
3749169689Skan      if (t == NULL)
3750169689Skan	tsi_delink (&i);
3751169689Skan      else if (TREE_CODE (t) == STATEMENT_LIST)
3752169689Skan	{
3753169689Skan	  tsi_link_before (&i, t, TSI_SAME_STMT);
3754169689Skan	  tsi_delink (&i);
3755169689Skan	}
3756169689Skan      else
3757169689Skan	tsi_next (&i);
3758169689Skan    }
3759169689Skan
3760169689Skan  if (temp)
3761169689Skan    {
3762169689Skan      append_to_statement_list (*expr_p, pre_p);
3763169689Skan      *expr_p = temp;
3764169689Skan      return GS_OK;
3765169689Skan    }
3766169689Skan
3767169689Skan  return GS_ALL_DONE;
3768169689Skan}
3769169689Skan
3770169689Skan/*  Gimplify a SAVE_EXPR node.  EXPR_P points to the expression to
3771169689Skan    gimplify.  After gimplification, EXPR_P will point to a new temporary
3772169689Skan    that holds the original value of the SAVE_EXPR node.
3773169689Skan
3774169689Skan    PRE_P points to the list where side effects that must happen before
3775169689Skan	*EXPR_P should be stored.  */
3776169689Skan
3777169689Skanstatic enum gimplify_status
3778169689Skangimplify_save_expr (tree *expr_p, tree *pre_p, tree *post_p)
3779169689Skan{
3780169689Skan  enum gimplify_status ret = GS_ALL_DONE;
3781169689Skan  tree val;
3782169689Skan
3783169689Skan  gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
3784169689Skan  val = TREE_OPERAND (*expr_p, 0);
3785169689Skan
3786169689Skan  /* If the SAVE_EXPR has not been resolved, then evaluate it once.  */
3787169689Skan  if (!SAVE_EXPR_RESOLVED_P (*expr_p))
3788169689Skan    {
3789169689Skan      /* The operand may be a void-valued expression such as SAVE_EXPRs
3790169689Skan	 generated by the Java frontend for class initialization.  It is
3791169689Skan	 being executed only for its side-effects.  */
3792169689Skan      if (TREE_TYPE (val) == void_type_node)
3793169689Skan	{
3794169689Skan	  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
3795169689Skan			       is_gimple_stmt, fb_none);
3796169689Skan	  append_to_statement_list (TREE_OPERAND (*expr_p, 0), pre_p);
3797169689Skan	  val = NULL;
3798169689Skan	}
3799169689Skan      else
3800169689Skan	val = get_initialized_tmp_var (val, pre_p, post_p);
3801169689Skan
3802169689Skan      TREE_OPERAND (*expr_p, 0) = val;
3803169689Skan      SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
3804169689Skan    }
3805169689Skan
3806169689Skan  *expr_p = val;
3807169689Skan
3808169689Skan  return ret;
3809169689Skan}
3810169689Skan
3811169689Skan/*  Re-write the ADDR_EXPR node pointed to by EXPR_P
3812169689Skan
3813169689Skan      unary_expr
3814169689Skan	      : ...
3815169689Skan	      | '&' varname
3816169689Skan	      ...
3817169689Skan
3818169689Skan    PRE_P points to the list where side effects that must happen before
3819169689Skan	*EXPR_P should be stored.
3820169689Skan
3821169689Skan    POST_P points to the list where side effects that must happen after
3822169689Skan	*EXPR_P should be stored.  */
3823169689Skan
3824169689Skanstatic enum gimplify_status
3825169689Skangimplify_addr_expr (tree *expr_p, tree *pre_p, tree *post_p)
3826169689Skan{
3827169689Skan  tree expr = *expr_p;
3828169689Skan  tree op0 = TREE_OPERAND (expr, 0);
3829169689Skan  enum gimplify_status ret;
3830169689Skan
3831169689Skan  switch (TREE_CODE (op0))
3832169689Skan    {
3833169689Skan    case INDIRECT_REF:
3834169689Skan    case MISALIGNED_INDIRECT_REF:
3835169689Skan    do_indirect_ref:
3836169689Skan      /* Check if we are dealing with an expression of the form '&*ptr'.
3837169689Skan	 While the front end folds away '&*ptr' into 'ptr', these
3838169689Skan	 expressions may be generated internally by the compiler (e.g.,
3839169689Skan	 builtins like __builtin_va_end).  */
3840169689Skan      /* Caution: the silent array decomposition semantics we allow for
3841169689Skan	 ADDR_EXPR means we can't always discard the pair.  */
3842169689Skan      /* Gimplification of the ADDR_EXPR operand may drop
3843169689Skan	 cv-qualification conversions, so make sure we add them if
3844169689Skan	 needed.  */
3845169689Skan      {
3846169689Skan	tree op00 = TREE_OPERAND (op0, 0);
3847169689Skan	tree t_expr = TREE_TYPE (expr);
3848169689Skan	tree t_op00 = TREE_TYPE (op00);
3849169689Skan
3850169689Skan        if (!lang_hooks.types_compatible_p (t_expr, t_op00))
3851169689Skan	  {
3852169689Skan#ifdef ENABLE_CHECKING
3853169689Skan	    tree t_op0 = TREE_TYPE (op0);
3854169689Skan	    gcc_assert (POINTER_TYPE_P (t_expr)
3855169689Skan			&& cpt_same_type (TREE_CODE (t_op0) == ARRAY_TYPE
3856169689Skan					  ? TREE_TYPE (t_op0) : t_op0,
3857169689Skan					  TREE_TYPE (t_expr))
3858169689Skan			&& POINTER_TYPE_P (t_op00)
3859169689Skan			&& cpt_same_type (t_op0, TREE_TYPE (t_op00)));
3860169689Skan#endif
3861169689Skan	    op00 = fold_convert (TREE_TYPE (expr), op00);
3862169689Skan	  }
3863169689Skan        *expr_p = op00;
3864169689Skan        ret = GS_OK;
3865169689Skan      }
3866169689Skan      break;
3867169689Skan
3868169689Skan    case VIEW_CONVERT_EXPR:
3869169689Skan      /* Take the address of our operand and then convert it to the type of
3870169689Skan	 this ADDR_EXPR.
3871169689Skan
3872169689Skan	 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
3873169689Skan	 all clear.  The impact of this transformation is even less clear.  */
3874169689Skan
3875169689Skan      /* If the operand is a useless conversion, look through it.  Doing so
3876169689Skan	 guarantees that the ADDR_EXPR and its operand will remain of the
3877169689Skan	 same type.  */
3878169689Skan      if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
3879169689Skan	op0 = TREE_OPERAND (op0, 0);
3880169689Skan
3881169689Skan      *expr_p = fold_convert (TREE_TYPE (expr),
3882169689Skan			      build_fold_addr_expr (TREE_OPERAND (op0, 0)));
3883169689Skan      ret = GS_OK;
3884169689Skan      break;
3885169689Skan
3886169689Skan    default:
3887169689Skan      /* We use fb_either here because the C frontend sometimes takes
3888169689Skan	 the address of a call that returns a struct; see
3889169689Skan	 gcc.dg/c99-array-lval-1.c.  The gimplifier will correctly make
3890169689Skan	 the implied temporary explicit.  */
3891169689Skan      ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
3892169689Skan			   is_gimple_addressable, fb_either);
3893169689Skan      if (ret != GS_ERROR)
3894169689Skan	{
3895169689Skan	  op0 = TREE_OPERAND (expr, 0);
3896169689Skan
3897169689Skan	  /* For various reasons, the gimplification of the expression
3898169689Skan	     may have made a new INDIRECT_REF.  */
3899169689Skan	  if (TREE_CODE (op0) == INDIRECT_REF)
3900169689Skan	    goto do_indirect_ref;
3901169689Skan
3902169689Skan	  /* Make sure TREE_INVARIANT, TREE_CONSTANT, and TREE_SIDE_EFFECTS
3903169689Skan	     is set properly.  */
3904169689Skan	  recompute_tree_invariant_for_addr_expr (expr);
3905169689Skan
3906169689Skan	  /* Mark the RHS addressable.  */
3907169689Skan	  lang_hooks.mark_addressable (TREE_OPERAND (expr, 0));
3908169689Skan	}
3909169689Skan      break;
3910169689Skan    }
3911169689Skan
3912169689Skan  return ret;
3913169689Skan}
3914169689Skan
3915169689Skan/* Gimplify the operands of an ASM_EXPR.  Input operands should be a gimple
3916169689Skan   value; output operands should be a gimple lvalue.  */
3917169689Skan
3918169689Skanstatic enum gimplify_status
3919169689Skangimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p)
3920169689Skan{
3921169689Skan  tree expr = *expr_p;
3922169689Skan  int noutputs = list_length (ASM_OUTPUTS (expr));
3923169689Skan  const char **oconstraints
3924169689Skan    = (const char **) alloca ((noutputs) * sizeof (const char *));
3925169689Skan  int i;
3926169689Skan  tree link;
3927169689Skan  const char *constraint;
3928169689Skan  bool allows_mem, allows_reg, is_inout;
3929169689Skan  enum gimplify_status ret, tret;
3930169689Skan
3931169689Skan  ret = GS_ALL_DONE;
3932169689Skan  for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = TREE_CHAIN (link))
3933169689Skan    {
3934169689Skan      size_t constraint_len;
3935169689Skan      oconstraints[i] = constraint
3936169689Skan	= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
3937169689Skan      constraint_len = strlen (constraint);
3938169689Skan      if (constraint_len == 0)
3939169689Skan        continue;
3940169689Skan
3941169689Skan      parse_output_constraint (&constraint, i, 0, 0,
3942169689Skan			       &allows_mem, &allows_reg, &is_inout);
3943169689Skan
3944169689Skan      if (!allows_reg && allows_mem)
3945169689Skan	lang_hooks.mark_addressable (TREE_VALUE (link));
3946169689Skan
3947169689Skan      tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
3948169689Skan			    is_inout ? is_gimple_min_lval : is_gimple_lvalue,
3949169689Skan			    fb_lvalue | fb_mayfail);
3950169689Skan      if (tret == GS_ERROR)
3951169689Skan	{
3952169689Skan	  error ("invalid lvalue in asm output %d", i);
3953169689Skan	  ret = tret;
3954169689Skan	}
3955169689Skan
3956169689Skan      if (is_inout)
3957169689Skan	{
3958169689Skan	  /* An input/output operand.  To give the optimizers more
3959169689Skan	     flexibility, split it into separate input and output
3960169689Skan 	     operands.  */
3961169689Skan	  tree input;
3962169689Skan	  char buf[10];
3963169689Skan
3964169689Skan	  /* Turn the in/out constraint into an output constraint.  */
3965169689Skan	  char *p = xstrdup (constraint);
3966169689Skan	  p[0] = '=';
3967169689Skan	  TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
3968169689Skan
3969169689Skan	  /* And add a matching input constraint.  */
3970169689Skan	  if (allows_reg)
3971169689Skan	    {
3972169689Skan	      sprintf (buf, "%d", i);
3973169689Skan
3974169689Skan	      /* If there are multiple alternatives in the constraint,
3975169689Skan		 handle each of them individually.  Those that allow register
3976169689Skan		 will be replaced with operand number, the others will stay
3977169689Skan		 unchanged.  */
3978169689Skan	      if (strchr (p, ',') != NULL)
3979169689Skan		{
3980169689Skan		  size_t len = 0, buflen = strlen (buf);
3981169689Skan		  char *beg, *end, *str, *dst;
3982169689Skan
3983169689Skan		  for (beg = p + 1;;)
3984169689Skan		    {
3985169689Skan		      end = strchr (beg, ',');
3986169689Skan		      if (end == NULL)
3987169689Skan			end = strchr (beg, '\0');
3988169689Skan		      if ((size_t) (end - beg) < buflen)
3989169689Skan			len += buflen + 1;
3990169689Skan		      else
3991169689Skan			len += end - beg + 1;
3992169689Skan		      if (*end)
3993169689Skan			beg = end + 1;
3994169689Skan		      else
3995169689Skan			break;
3996169689Skan		    }
3997169689Skan
3998169689Skan		  str = (char *) alloca (len);
3999169689Skan		  for (beg = p + 1, dst = str;;)
4000169689Skan		    {
4001169689Skan		      const char *tem;
4002169689Skan		      bool mem_p, reg_p, inout_p;
4003169689Skan
4004169689Skan		      end = strchr (beg, ',');
4005169689Skan		      if (end)
4006169689Skan			*end = '\0';
4007169689Skan		      beg[-1] = '=';
4008169689Skan		      tem = beg - 1;
4009169689Skan		      parse_output_constraint (&tem, i, 0, 0,
4010169689Skan					       &mem_p, &reg_p, &inout_p);
4011169689Skan		      if (dst != str)
4012169689Skan			*dst++ = ',';
4013169689Skan		      if (reg_p)
4014169689Skan			{
4015169689Skan			  memcpy (dst, buf, buflen);
4016169689Skan			  dst += buflen;
4017169689Skan			}
4018169689Skan		      else
4019169689Skan			{
4020169689Skan			  if (end)
4021169689Skan			    len = end - beg;
4022169689Skan			  else
4023169689Skan			    len = strlen (beg);
4024169689Skan			  memcpy (dst, beg, len);
4025169689Skan			  dst += len;
4026169689Skan			}
4027169689Skan		      if (end)
4028169689Skan			beg = end + 1;
4029169689Skan		      else
4030169689Skan			break;
4031169689Skan		    }
4032169689Skan		  *dst = '\0';
4033169689Skan		  input = build_string (dst - str, str);
4034169689Skan		}
4035169689Skan	      else
4036169689Skan		input = build_string (strlen (buf), buf);
4037169689Skan	    }
4038169689Skan	  else
4039169689Skan	    input = build_string (constraint_len - 1, constraint + 1);
4040169689Skan
4041169689Skan	  free (p);
4042169689Skan
4043169689Skan	  input = build_tree_list (build_tree_list (NULL_TREE, input),
4044169689Skan				   unshare_expr (TREE_VALUE (link)));
4045169689Skan	  ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
4046169689Skan	}
4047169689Skan    }
4048169689Skan
4049169689Skan  for (link = ASM_INPUTS (expr); link; ++i, link = TREE_CHAIN (link))
4050169689Skan    {
4051169689Skan      constraint
4052169689Skan	= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
4053169689Skan      parse_input_constraint (&constraint, 0, 0, noutputs, 0,
4054169689Skan			      oconstraints, &allows_mem, &allows_reg);
4055169689Skan
4056171825Skan      /* If we can't make copies, we can only accept memory.  */
4057171825Skan      if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (link))))
4058171825Skan	{
4059171825Skan	  if (allows_mem)
4060171825Skan	    allows_reg = 0;
4061171825Skan	  else
4062171825Skan	    {
4063171825Skan	      error ("impossible constraint in %<asm%>");
4064171825Skan	      error ("non-memory input %d must stay in memory", i);
4065171825Skan	      return GS_ERROR;
4066171825Skan	    }
4067171825Skan	}
4068171825Skan
4069169689Skan      /* If the operand is a memory input, it should be an lvalue.  */
4070169689Skan      if (!allows_reg && allows_mem)
4071169689Skan	{
4072169689Skan	  tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
4073169689Skan				is_gimple_lvalue, fb_lvalue | fb_mayfail);
4074169689Skan	  lang_hooks.mark_addressable (TREE_VALUE (link));
4075169689Skan	  if (tret == GS_ERROR)
4076169689Skan	    {
4077169689Skan	      error ("memory input %d is not directly addressable", i);
4078169689Skan	      ret = tret;
4079169689Skan	    }
4080169689Skan	}
4081169689Skan      else
4082169689Skan	{
4083169689Skan	  tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
4084169689Skan				is_gimple_asm_val, fb_rvalue);
4085169689Skan	  if (tret == GS_ERROR)
4086169689Skan	    ret = tret;
4087169689Skan	}
4088169689Skan    }
4089169689Skan
4090169689Skan  return ret;
4091169689Skan}
4092169689Skan
4093169689Skan/* Gimplify a CLEANUP_POINT_EXPR.  Currently this works by adding
4094169689Skan   WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
4095169689Skan   gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
4096169689Skan   return to this function.
4097169689Skan
4098169689Skan   FIXME should we complexify the prequeue handling instead?  Or use flags
4099169689Skan   for all the cleanups and let the optimizer tighten them up?  The current
4100169689Skan   code seems pretty fragile; it will break on a cleanup within any
4101169689Skan   non-conditional nesting.  But any such nesting would be broken, anyway;
4102169689Skan   we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
4103169689Skan   and continues out of it.  We can do that at the RTL level, though, so
4104169689Skan   having an optimizer to tighten up try/finally regions would be a Good
4105169689Skan   Thing.  */
4106169689Skan
4107169689Skanstatic enum gimplify_status
4108169689Skangimplify_cleanup_point_expr (tree *expr_p, tree *pre_p)
4109169689Skan{
4110169689Skan  tree_stmt_iterator iter;
4111169689Skan  tree body;
4112169689Skan
4113169689Skan  tree temp = voidify_wrapper_expr (*expr_p, NULL);
4114169689Skan
4115169689Skan  /* We only care about the number of conditions between the innermost
4116169689Skan     CLEANUP_POINT_EXPR and the cleanup.  So save and reset the count and
4117169689Skan     any cleanups collected outside the CLEANUP_POINT_EXPR.  */
4118169689Skan  int old_conds = gimplify_ctxp->conditions;
4119169689Skan  tree old_cleanups = gimplify_ctxp->conditional_cleanups;
4120169689Skan  gimplify_ctxp->conditions = 0;
4121169689Skan  gimplify_ctxp->conditional_cleanups = NULL_TREE;
4122169689Skan
4123169689Skan  body = TREE_OPERAND (*expr_p, 0);
4124169689Skan  gimplify_to_stmt_list (&body);
4125169689Skan
4126169689Skan  gimplify_ctxp->conditions = old_conds;
4127169689Skan  gimplify_ctxp->conditional_cleanups = old_cleanups;
4128169689Skan
4129169689Skan  for (iter = tsi_start (body); !tsi_end_p (iter); )
4130169689Skan    {
4131169689Skan      tree *wce_p = tsi_stmt_ptr (iter);
4132169689Skan      tree wce = *wce_p;
4133169689Skan
4134169689Skan      if (TREE_CODE (wce) == WITH_CLEANUP_EXPR)
4135169689Skan	{
4136169689Skan	  if (tsi_one_before_end_p (iter))
4137169689Skan	    {
4138169689Skan	      tsi_link_before (&iter, TREE_OPERAND (wce, 0), TSI_SAME_STMT);
4139169689Skan	      tsi_delink (&iter);
4140169689Skan	      break;
4141169689Skan	    }
4142169689Skan	  else
4143169689Skan	    {
4144169689Skan	      tree sl, tfe;
4145169689Skan	      enum tree_code code;
4146169689Skan
4147169689Skan	      if (CLEANUP_EH_ONLY (wce))
4148169689Skan		code = TRY_CATCH_EXPR;
4149169689Skan	      else
4150169689Skan		code = TRY_FINALLY_EXPR;
4151169689Skan
4152169689Skan	      sl = tsi_split_statement_list_after (&iter);
4153169689Skan	      tfe = build2 (code, void_type_node, sl, NULL_TREE);
4154169689Skan	      append_to_statement_list (TREE_OPERAND (wce, 0),
4155169689Skan				        &TREE_OPERAND (tfe, 1));
4156169689Skan	      *wce_p = tfe;
4157169689Skan	      iter = tsi_start (sl);
4158169689Skan	    }
4159169689Skan	}
4160169689Skan      else
4161169689Skan	tsi_next (&iter);
4162169689Skan    }
4163169689Skan
4164169689Skan  if (temp)
4165169689Skan    {
4166169689Skan      *expr_p = temp;
4167169689Skan      append_to_statement_list (body, pre_p);
4168169689Skan      return GS_OK;
4169169689Skan    }
4170169689Skan  else
4171169689Skan    {
4172169689Skan      *expr_p = body;
4173169689Skan      return GS_ALL_DONE;
4174169689Skan    }
4175169689Skan}
4176169689Skan
4177169689Skan/* Insert a cleanup marker for gimplify_cleanup_point_expr.  CLEANUP
4178169689Skan   is the cleanup action required.  */
4179169689Skan
4180169689Skanstatic void
4181169689Skangimple_push_cleanup (tree var, tree cleanup, bool eh_only, tree *pre_p)
4182169689Skan{
4183169689Skan  tree wce;
4184169689Skan
4185169689Skan  /* Errors can result in improperly nested cleanups.  Which results in
4186169689Skan     confusion when trying to resolve the WITH_CLEANUP_EXPR.  */
4187169689Skan  if (errorcount || sorrycount)
4188169689Skan    return;
4189169689Skan
4190169689Skan  if (gimple_conditional_context ())
4191169689Skan    {
4192169689Skan      /* If we're in a conditional context, this is more complex.  We only
4193169689Skan	 want to run the cleanup if we actually ran the initialization that
4194169689Skan	 necessitates it, but we want to run it after the end of the
4195169689Skan	 conditional context.  So we wrap the try/finally around the
4196169689Skan	 condition and use a flag to determine whether or not to actually
4197169689Skan	 run the destructor.  Thus
4198169689Skan
4199169689Skan	   test ? f(A()) : 0
4200169689Skan
4201169689Skan	 becomes (approximately)
4202169689Skan
4203169689Skan	   flag = 0;
4204169689Skan	   try {
4205169689Skan	     if (test) { A::A(temp); flag = 1; val = f(temp); }
4206169689Skan	     else { val = 0; }
4207169689Skan	   } finally {
4208169689Skan	     if (flag) A::~A(temp);
4209169689Skan	   }
4210169689Skan	   val
4211169689Skan      */
4212169689Skan
4213169689Skan      tree flag = create_tmp_var (boolean_type_node, "cleanup");
4214169689Skan      tree ffalse = build2 (MODIFY_EXPR, void_type_node, flag,
4215169689Skan			    boolean_false_node);
4216169689Skan      tree ftrue = build2 (MODIFY_EXPR, void_type_node, flag,
4217169689Skan			   boolean_true_node);
4218169689Skan      cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
4219169689Skan      wce = build1 (WITH_CLEANUP_EXPR, void_type_node, cleanup);
4220169689Skan      append_to_statement_list (ffalse, &gimplify_ctxp->conditional_cleanups);
4221169689Skan      append_to_statement_list (wce, &gimplify_ctxp->conditional_cleanups);
4222169689Skan      append_to_statement_list (ftrue, pre_p);
4223169689Skan
4224169689Skan      /* Because of this manipulation, and the EH edges that jump
4225169689Skan	 threading cannot redirect, the temporary (VAR) will appear
4226169689Skan	 to be used uninitialized.  Don't warn.  */
4227169689Skan      TREE_NO_WARNING (var) = 1;
4228169689Skan    }
4229169689Skan  else
4230169689Skan    {
4231169689Skan      wce = build1 (WITH_CLEANUP_EXPR, void_type_node, cleanup);
4232169689Skan      CLEANUP_EH_ONLY (wce) = eh_only;
4233169689Skan      append_to_statement_list (wce, pre_p);
4234169689Skan    }
4235169689Skan
4236169689Skan  gimplify_stmt (&TREE_OPERAND (wce, 0));
4237169689Skan}
4238169689Skan
4239169689Skan/* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR.  */
4240169689Skan
4241169689Skanstatic enum gimplify_status
4242169689Skangimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p)
4243169689Skan{
4244169689Skan  tree targ = *expr_p;
4245169689Skan  tree temp = TARGET_EXPR_SLOT (targ);
4246169689Skan  tree init = TARGET_EXPR_INITIAL (targ);
4247169689Skan  enum gimplify_status ret;
4248169689Skan
4249169689Skan  if (init)
4250169689Skan    {
4251169689Skan      /* TARGET_EXPR temps aren't part of the enclosing block, so add it
4252169689Skan	 to the temps list.  */
4253169689Skan      gimple_add_tmp_var (temp);
4254169689Skan
4255169689Skan      /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
4256169689Skan	 expression is supposed to initialize the slot.  */
4257169689Skan      if (VOID_TYPE_P (TREE_TYPE (init)))
4258169689Skan	ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
4259169689Skan      else
4260169689Skan	{
4261169689Skan	  init = build2 (INIT_EXPR, void_type_node, temp, init);
4262169689Skan	  ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt,
4263169689Skan			       fb_none);
4264169689Skan	}
4265169689Skan      if (ret == GS_ERROR)
4266169689Skan	{
4267169689Skan	  /* PR c++/28266 Make sure this is expanded only once. */
4268169689Skan	  TARGET_EXPR_INITIAL (targ) = NULL_TREE;
4269169689Skan	  return GS_ERROR;
4270169689Skan	}
4271169689Skan      append_to_statement_list (init, pre_p);
4272169689Skan
4273169689Skan      /* If needed, push the cleanup for the temp.  */
4274169689Skan      if (TARGET_EXPR_CLEANUP (targ))
4275169689Skan	{
4276169689Skan	  gimplify_stmt (&TARGET_EXPR_CLEANUP (targ));
4277169689Skan	  gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
4278169689Skan			       CLEANUP_EH_ONLY (targ), pre_p);
4279169689Skan	}
4280169689Skan
4281169689Skan      /* Only expand this once.  */
4282169689Skan      TREE_OPERAND (targ, 3) = init;
4283169689Skan      TARGET_EXPR_INITIAL (targ) = NULL_TREE;
4284169689Skan    }
4285169689Skan  else
4286169689Skan    /* We should have expanded this before.  */
4287169689Skan    gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
4288169689Skan
4289169689Skan  *expr_p = temp;
4290169689Skan  return GS_OK;
4291169689Skan}
4292169689Skan
4293169689Skan/* Gimplification of expression trees.  */
4294169689Skan
4295169689Skan/* Gimplify an expression which appears at statement context; usually, this
4296169689Skan   means replacing it with a suitably gimple STATEMENT_LIST.  */
4297169689Skan
4298169689Skanvoid
4299169689Skangimplify_stmt (tree *stmt_p)
4300169689Skan{
4301169689Skan  gimplify_expr (stmt_p, NULL, NULL, is_gimple_stmt, fb_none);
4302169689Skan}
4303169689Skan
4304169689Skan/* Similarly, but force the result to be a STATEMENT_LIST.  */
4305169689Skan
4306169689Skanvoid
4307169689Skangimplify_to_stmt_list (tree *stmt_p)
4308169689Skan{
4309169689Skan  gimplify_stmt (stmt_p);
4310169689Skan  if (!*stmt_p)
4311169689Skan    *stmt_p = alloc_stmt_list ();
4312169689Skan  else if (TREE_CODE (*stmt_p) != STATEMENT_LIST)
4313169689Skan    {
4314169689Skan      tree t = *stmt_p;
4315169689Skan      *stmt_p = alloc_stmt_list ();
4316169689Skan      append_to_statement_list (t, stmt_p);
4317169689Skan    }
4318169689Skan}
4319169689Skan
4320169689Skan
4321169689Skan/* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
4322169689Skan   to CTX.  If entries already exist, force them to be some flavor of private.
4323169689Skan   If there is no enclosing parallel, do nothing.  */
4324169689Skan
4325169689Skanvoid
4326169689Skanomp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
4327169689Skan{
4328169689Skan  splay_tree_node n;
4329169689Skan
4330169689Skan  if (decl == NULL || !DECL_P (decl))
4331169689Skan    return;
4332169689Skan
4333169689Skan  do
4334169689Skan    {
4335169689Skan      n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
4336169689Skan      if (n != NULL)
4337169689Skan	{
4338169689Skan	  if (n->value & GOVD_SHARED)
4339169689Skan	    n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
4340169689Skan	  else
4341169689Skan	    return;
4342169689Skan	}
4343169689Skan      else if (ctx->is_parallel)
4344169689Skan	omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
4345169689Skan
4346169689Skan      ctx = ctx->outer_context;
4347169689Skan    }
4348169689Skan  while (ctx);
4349169689Skan}
4350169689Skan
4351169689Skan/* Similarly for each of the type sizes of TYPE.  */
4352169689Skan
4353169689Skanstatic void
4354169689Skanomp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
4355169689Skan{
4356169689Skan  if (type == NULL || type == error_mark_node)
4357169689Skan    return;
4358169689Skan  type = TYPE_MAIN_VARIANT (type);
4359169689Skan
4360169689Skan  if (pointer_set_insert (ctx->privatized_types, type))
4361169689Skan    return;
4362169689Skan
4363169689Skan  switch (TREE_CODE (type))
4364169689Skan    {
4365169689Skan    case INTEGER_TYPE:
4366169689Skan    case ENUMERAL_TYPE:
4367169689Skan    case BOOLEAN_TYPE:
4368169689Skan    case REAL_TYPE:
4369169689Skan      omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
4370169689Skan      omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
4371169689Skan      break;
4372169689Skan
4373169689Skan    case ARRAY_TYPE:
4374169689Skan      omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
4375169689Skan      omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
4376169689Skan      break;
4377169689Skan
4378169689Skan    case RECORD_TYPE:
4379169689Skan    case UNION_TYPE:
4380169689Skan    case QUAL_UNION_TYPE:
4381169689Skan      {
4382169689Skan	tree field;
4383169689Skan	for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
4384169689Skan	  if (TREE_CODE (field) == FIELD_DECL)
4385169689Skan	    {
4386169689Skan	      omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
4387169689Skan	      omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
4388169689Skan	    }
4389169689Skan      }
4390169689Skan      break;
4391169689Skan
4392169689Skan    case POINTER_TYPE:
4393169689Skan    case REFERENCE_TYPE:
4394169689Skan      omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
4395169689Skan      break;
4396169689Skan
4397169689Skan    default:
4398169689Skan      break;
4399169689Skan    }
4400169689Skan
4401169689Skan  omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
4402169689Skan  omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
4403169689Skan  lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
4404169689Skan}
4405169689Skan
4406169689Skan/* Add an entry for DECL in the OpenMP context CTX with FLAGS.  */
4407169689Skan
4408169689Skanstatic void
4409169689Skanomp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
4410169689Skan{
4411169689Skan  splay_tree_node n;
4412169689Skan  unsigned int nflags;
4413169689Skan  tree t;
4414169689Skan
4415169689Skan  if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node)
4416169689Skan    return;
4417169689Skan
4418169689Skan  /* Never elide decls whose type has TREE_ADDRESSABLE set.  This means
4419169689Skan     there are constructors involved somewhere.  */
4420169689Skan  if (TREE_ADDRESSABLE (TREE_TYPE (decl))
4421169689Skan      || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
4422169689Skan    flags |= GOVD_SEEN;
4423169689Skan
4424169689Skan  n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
4425169689Skan  if (n != NULL)
4426169689Skan    {
4427169689Skan      /* We shouldn't be re-adding the decl with the same data
4428169689Skan	 sharing class.  */
4429169689Skan      gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
4430169689Skan      /* The only combination of data sharing classes we should see is
4431169689Skan	 FIRSTPRIVATE and LASTPRIVATE.  */
4432169689Skan      nflags = n->value | flags;
4433169689Skan      gcc_assert ((nflags & GOVD_DATA_SHARE_CLASS)
4434169689Skan		  == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE));
4435169689Skan      n->value = nflags;
4436169689Skan      return;
4437169689Skan    }
4438169689Skan
4439169689Skan  /* When adding a variable-sized variable, we have to handle all sorts
4440169689Skan     of additional bits of data: the pointer replacement variable, and
4441169689Skan     the parameters of the type.  */
4442169689Skan  if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
4443169689Skan    {
4444169689Skan      /* Add the pointer replacement variable as PRIVATE if the variable
4445169689Skan	 replacement is private, else FIRSTPRIVATE since we'll need the
4446169689Skan	 address of the original variable either for SHARED, or for the
4447169689Skan	 copy into or out of the context.  */
4448169689Skan      if (!(flags & GOVD_LOCAL))
4449169689Skan	{
4450169689Skan	  nflags = flags & GOVD_PRIVATE ? GOVD_PRIVATE : GOVD_FIRSTPRIVATE;
4451169689Skan	  nflags |= flags & GOVD_SEEN;
4452169689Skan	  t = DECL_VALUE_EXPR (decl);
4453169689Skan	  gcc_assert (TREE_CODE (t) == INDIRECT_REF);
4454169689Skan	  t = TREE_OPERAND (t, 0);
4455169689Skan	  gcc_assert (DECL_P (t));
4456169689Skan	  omp_add_variable (ctx, t, nflags);
4457169689Skan	}
4458169689Skan
4459169689Skan      /* Add all of the variable and type parameters (which should have
4460169689Skan	 been gimplified to a formal temporary) as FIRSTPRIVATE.  */
4461169689Skan      omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
4462169689Skan      omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
4463169689Skan      omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
4464169689Skan
4465169689Skan      /* The variable-sized variable itself is never SHARED, only some form
4466169689Skan	 of PRIVATE.  The sharing would take place via the pointer variable
4467169689Skan	 which we remapped above.  */
4468169689Skan      if (flags & GOVD_SHARED)
4469169689Skan	flags = GOVD_PRIVATE | GOVD_DEBUG_PRIVATE
4470169689Skan		| (flags & (GOVD_SEEN | GOVD_EXPLICIT));
4471169689Skan
4472169689Skan      /* We're going to make use of the TYPE_SIZE_UNIT at least in the
4473169689Skan	 alloca statement we generate for the variable, so make sure it
4474169689Skan	 is available.  This isn't automatically needed for the SHARED
4475169689Skan	 case, since we won't be allocating local storage then.
4476169689Skan	 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
4477169689Skan	 in this case omp_notice_variable will be called later
4478169689Skan	 on when it is gimplified.  */
4479169689Skan      else if (! (flags & GOVD_LOCAL))
4480169689Skan	omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
4481169689Skan    }
4482169689Skan  else if (lang_hooks.decls.omp_privatize_by_reference (decl))
4483169689Skan    {
4484169689Skan      gcc_assert ((flags & GOVD_LOCAL) == 0);
4485169689Skan      omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
4486169689Skan
4487169689Skan      /* Similar to the direct variable sized case above, we'll need the
4488169689Skan	 size of references being privatized.  */
4489169689Skan      if ((flags & GOVD_SHARED) == 0)
4490169689Skan	{
4491169689Skan	  t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
4492169689Skan	  if (TREE_CODE (t) != INTEGER_CST)
4493169689Skan	    omp_notice_variable (ctx, t, true);
4494169689Skan	}
4495169689Skan    }
4496169689Skan
4497169689Skan  splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
4498169689Skan}
4499169689Skan
4500169689Skan/* Record the fact that DECL was used within the OpenMP context CTX.
4501169689Skan   IN_CODE is true when real code uses DECL, and false when we should
4502169689Skan   merely emit default(none) errors.  Return true if DECL is going to
4503169689Skan   be remapped and thus DECL shouldn't be gimplified into its
4504169689Skan   DECL_VALUE_EXPR (if any).  */
4505169689Skan
4506169689Skanstatic bool
4507169689Skanomp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
4508169689Skan{
4509169689Skan  splay_tree_node n;
4510169689Skan  unsigned flags = in_code ? GOVD_SEEN : 0;
4511169689Skan  bool ret = false, shared;
4512169689Skan
4513169689Skan  if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node)
4514169689Skan    return false;
4515169689Skan
4516169689Skan  /* Threadprivate variables are predetermined.  */
4517169689Skan  if (is_global_var (decl))
4518169689Skan    {
4519169689Skan      if (DECL_THREAD_LOCAL_P (decl))
4520169689Skan	return false;
4521169689Skan
4522169689Skan      if (DECL_HAS_VALUE_EXPR_P (decl))
4523169689Skan	{
4524169689Skan	  tree value = get_base_address (DECL_VALUE_EXPR (decl));
4525169689Skan
4526169689Skan	  if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
4527169689Skan	    return false;
4528169689Skan	}
4529169689Skan    }
4530169689Skan
4531169689Skan  n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
4532169689Skan  if (n == NULL)
4533169689Skan    {
4534169689Skan      enum omp_clause_default_kind default_kind, kind;
4535169689Skan
4536169689Skan      if (!ctx->is_parallel)
4537169689Skan	goto do_outer;
4538169689Skan
4539169689Skan      /* ??? Some compiler-generated variables (like SAVE_EXPRs) could be
4540169689Skan	 remapped firstprivate instead of shared.  To some extent this is
4541169689Skan	 addressed in omp_firstprivatize_type_sizes, but not effectively.  */
4542169689Skan      default_kind = ctx->default_kind;
4543169689Skan      kind = lang_hooks.decls.omp_predetermined_sharing (decl);
4544169689Skan      if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
4545169689Skan	default_kind = kind;
4546169689Skan
4547169689Skan      switch (default_kind)
4548169689Skan	{
4549169689Skan	case OMP_CLAUSE_DEFAULT_NONE:
4550169689Skan	  error ("%qs not specified in enclosing parallel",
4551169689Skan		 IDENTIFIER_POINTER (DECL_NAME (decl)));
4552169689Skan	  error ("%Henclosing parallel", &ctx->location);
4553169689Skan	  /* FALLTHRU */
4554169689Skan	case OMP_CLAUSE_DEFAULT_SHARED:
4555169689Skan	  flags |= GOVD_SHARED;
4556169689Skan	  break;
4557169689Skan	case OMP_CLAUSE_DEFAULT_PRIVATE:
4558169689Skan	  flags |= GOVD_PRIVATE;
4559169689Skan	  break;
4560169689Skan	default:
4561169689Skan	  gcc_unreachable ();
4562169689Skan	}
4563169689Skan
4564169689Skan      omp_add_variable (ctx, decl, flags);
4565169689Skan
4566169689Skan      shared = (flags & GOVD_SHARED) != 0;
4567169689Skan      ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
4568169689Skan      goto do_outer;
4569169689Skan    }
4570169689Skan
4571169689Skan  shared = ((flags | n->value) & GOVD_SHARED) != 0;
4572169689Skan  ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
4573169689Skan
4574169689Skan  /* If nothing changed, there's nothing left to do.  */
4575169689Skan  if ((n->value & flags) == flags)
4576169689Skan    return ret;
4577169689Skan  flags |= n->value;
4578169689Skan  n->value = flags;
4579169689Skan
4580169689Skan do_outer:
4581169689Skan  /* If the variable is private in the current context, then we don't
4582169689Skan     need to propagate anything to an outer context.  */
4583169689Skan  if (flags & GOVD_PRIVATE)
4584169689Skan    return ret;
4585169689Skan  if (ctx->outer_context
4586169689Skan      && omp_notice_variable (ctx->outer_context, decl, in_code))
4587169689Skan    return true;
4588169689Skan  return ret;
4589169689Skan}
4590169689Skan
4591169689Skan/* Verify that DECL is private within CTX.  If there's specific information
4592169689Skan   to the contrary in the innermost scope, generate an error.  */
4593169689Skan
4594169689Skanstatic bool
4595169689Skanomp_is_private (struct gimplify_omp_ctx *ctx, tree decl)
4596169689Skan{
4597169689Skan  splay_tree_node n;
4598169689Skan
4599169689Skan  n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
4600169689Skan  if (n != NULL)
4601169689Skan    {
4602169689Skan      if (n->value & GOVD_SHARED)
4603169689Skan	{
4604169689Skan	  if (ctx == gimplify_omp_ctxp)
4605169689Skan	    {
4606169689Skan	      error ("iteration variable %qs should be private",
4607169689Skan		     IDENTIFIER_POINTER (DECL_NAME (decl)));
4608169689Skan	      n->value = GOVD_PRIVATE;
4609169689Skan	      return true;
4610169689Skan	    }
4611169689Skan	  else
4612169689Skan	    return false;
4613169689Skan	}
4614169689Skan      else if ((n->value & GOVD_EXPLICIT) != 0
4615169689Skan	       && (ctx == gimplify_omp_ctxp
4616169689Skan		   || (ctx->is_combined_parallel
4617169689Skan		       && gimplify_omp_ctxp->outer_context == ctx)))
4618169689Skan	{
4619169689Skan	  if ((n->value & GOVD_FIRSTPRIVATE) != 0)
4620169689Skan	    error ("iteration variable %qs should not be firstprivate",
4621169689Skan		   IDENTIFIER_POINTER (DECL_NAME (decl)));
4622169689Skan	  else if ((n->value & GOVD_REDUCTION) != 0)
4623169689Skan	    error ("iteration variable %qs should not be reduction",
4624169689Skan		   IDENTIFIER_POINTER (DECL_NAME (decl)));
4625169689Skan	}
4626169689Skan      return true;
4627169689Skan    }
4628169689Skan
4629169689Skan  if (ctx->is_parallel)
4630169689Skan    return false;
4631169689Skan  else if (ctx->outer_context)
4632169689Skan    return omp_is_private (ctx->outer_context, decl);
4633169689Skan  else
4634169689Skan    return !is_global_var (decl);
4635169689Skan}
4636169689Skan
4637169689Skan/* Return true if DECL is private within a parallel region
4638169689Skan   that binds to the current construct's context or in parallel
4639169689Skan   region's REDUCTION clause.  */
4640169689Skan
4641169689Skanstatic bool
4642169689Skanomp_check_private (struct gimplify_omp_ctx *ctx, tree decl)
4643169689Skan{
4644169689Skan  splay_tree_node n;
4645169689Skan
4646169689Skan  do
4647169689Skan    {
4648169689Skan      ctx = ctx->outer_context;
4649169689Skan      if (ctx == NULL)
4650169689Skan	return !(is_global_var (decl)
4651169689Skan		 /* References might be private, but might be shared too.  */
4652169689Skan		 || lang_hooks.decls.omp_privatize_by_reference (decl));
4653169689Skan
4654169689Skan      n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
4655169689Skan      if (n != NULL)
4656169689Skan	return (n->value & GOVD_SHARED) == 0;
4657169689Skan    }
4658169689Skan  while (!ctx->is_parallel);
4659169689Skan  return false;
4660169689Skan}
4661169689Skan
4662169689Skan/* Scan the OpenMP clauses in *LIST_P, installing mappings into a new
4663169689Skan   and previous omp contexts.  */
4664169689Skan
4665169689Skanstatic void
4666169689Skangimplify_scan_omp_clauses (tree *list_p, tree *pre_p, bool in_parallel,
4667169689Skan			   bool in_combined_parallel)
4668169689Skan{
4669169689Skan  struct gimplify_omp_ctx *ctx, *outer_ctx;
4670169689Skan  tree c;
4671169689Skan
4672169689Skan  ctx = new_omp_context (in_parallel, in_combined_parallel);
4673169689Skan  outer_ctx = ctx->outer_context;
4674169689Skan
4675169689Skan  while ((c = *list_p) != NULL)
4676169689Skan    {
4677169689Skan      enum gimplify_status gs;
4678169689Skan      bool remove = false;
4679169689Skan      bool notice_outer = true;
4680169689Skan      const char *check_non_private = NULL;
4681169689Skan      unsigned int flags;
4682169689Skan      tree decl;
4683169689Skan
4684169689Skan      switch (OMP_CLAUSE_CODE (c))
4685169689Skan	{
4686169689Skan	case OMP_CLAUSE_PRIVATE:
4687169689Skan	  flags = GOVD_PRIVATE | GOVD_EXPLICIT;
4688169689Skan	  notice_outer = false;
4689169689Skan	  goto do_add;
4690169689Skan	case OMP_CLAUSE_SHARED:
4691169689Skan	  flags = GOVD_SHARED | GOVD_EXPLICIT;
4692169689Skan	  goto do_add;
4693169689Skan	case OMP_CLAUSE_FIRSTPRIVATE:
4694169689Skan	  flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
4695169689Skan	  check_non_private = "firstprivate";
4696169689Skan	  goto do_add;
4697169689Skan	case OMP_CLAUSE_LASTPRIVATE:
4698169689Skan	  flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
4699169689Skan	  check_non_private = "lastprivate";
4700169689Skan	  goto do_add;
4701169689Skan	case OMP_CLAUSE_REDUCTION:
4702169689Skan	  flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
4703169689Skan	  check_non_private = "reduction";
4704169689Skan	  goto do_add;
4705169689Skan
4706169689Skan	do_add:
4707169689Skan	  decl = OMP_CLAUSE_DECL (c);
4708169689Skan	  if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node)
4709169689Skan	    {
4710169689Skan	      remove = true;
4711169689Skan	      break;
4712169689Skan	    }
4713169689Skan	  omp_add_variable (ctx, decl, flags);
4714169689Skan	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
4715169689Skan	      && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
4716169689Skan	    {
4717169689Skan	      omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
4718169689Skan				GOVD_LOCAL | GOVD_SEEN);
4719169689Skan	      gimplify_omp_ctxp = ctx;
4720169689Skan	      push_gimplify_context ();
4721169689Skan	      gimplify_stmt (&OMP_CLAUSE_REDUCTION_INIT (c));
4722169689Skan	      pop_gimplify_context (OMP_CLAUSE_REDUCTION_INIT (c));
4723169689Skan	      push_gimplify_context ();
4724169689Skan	      gimplify_stmt (&OMP_CLAUSE_REDUCTION_MERGE (c));
4725169689Skan	      pop_gimplify_context (OMP_CLAUSE_REDUCTION_MERGE (c));
4726169689Skan	      gimplify_omp_ctxp = outer_ctx;
4727169689Skan	    }
4728169689Skan	  if (notice_outer)
4729169689Skan	    goto do_notice;
4730169689Skan	  break;
4731169689Skan
4732169689Skan	case OMP_CLAUSE_COPYIN:
4733169689Skan	case OMP_CLAUSE_COPYPRIVATE:
4734169689Skan	  decl = OMP_CLAUSE_DECL (c);
4735169689Skan	  if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node)
4736169689Skan	    {
4737169689Skan	      remove = true;
4738169689Skan	      break;
4739169689Skan	    }
4740169689Skan	do_notice:
4741169689Skan	  if (outer_ctx)
4742169689Skan	    omp_notice_variable (outer_ctx, decl, true);
4743169689Skan	  if (check_non_private
4744169689Skan	      && !in_parallel
4745169689Skan	      && omp_check_private (ctx, decl))
4746169689Skan	    {
4747169689Skan	      error ("%s variable %qs is private in outer context",
4748169689Skan		     check_non_private, IDENTIFIER_POINTER (DECL_NAME (decl)));
4749169689Skan	      remove = true;
4750169689Skan	    }
4751169689Skan	  break;
4752169689Skan
4753169689Skan	case OMP_CLAUSE_IF:
4754169689Skan	  OMP_CLAUSE_OPERAND (c, 0)
4755169689Skan	    = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
4756169689Skan	  /* Fall through.  */
4757169689Skan
4758169689Skan	case OMP_CLAUSE_SCHEDULE:
4759169689Skan	case OMP_CLAUSE_NUM_THREADS:
4760169689Skan	  gs = gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
4761169689Skan			      is_gimple_val, fb_rvalue);
4762169689Skan	  if (gs == GS_ERROR)
4763169689Skan	    remove = true;
4764169689Skan	  break;
4765169689Skan
4766169689Skan	case OMP_CLAUSE_NOWAIT:
4767169689Skan	case OMP_CLAUSE_ORDERED:
4768169689Skan	  break;
4769169689Skan
4770169689Skan	case OMP_CLAUSE_DEFAULT:
4771169689Skan	  ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
4772169689Skan	  break;
4773169689Skan
4774169689Skan	default:
4775169689Skan	  gcc_unreachable ();
4776169689Skan	}
4777169689Skan
4778169689Skan      if (remove)
4779169689Skan	*list_p = OMP_CLAUSE_CHAIN (c);
4780169689Skan      else
4781169689Skan	list_p = &OMP_CLAUSE_CHAIN (c);
4782169689Skan    }
4783169689Skan
4784169689Skan  gimplify_omp_ctxp = ctx;
4785169689Skan}
4786169689Skan
4787169689Skan/* For all variables that were not actually used within the context,
4788169689Skan   remove PRIVATE, SHARED, and FIRSTPRIVATE clauses.  */
4789169689Skan
4790169689Skanstatic int
4791169689Skangimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
4792169689Skan{
4793169689Skan  tree *list_p = (tree *) data;
4794169689Skan  tree decl = (tree) n->key;
4795169689Skan  unsigned flags = n->value;
4796169689Skan  enum omp_clause_code code;
4797169689Skan  tree clause;
4798169689Skan  bool private_debug;
4799169689Skan
4800169689Skan  if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
4801169689Skan    return 0;
4802169689Skan  if ((flags & GOVD_SEEN) == 0)
4803169689Skan    return 0;
4804169689Skan  if (flags & GOVD_DEBUG_PRIVATE)
4805169689Skan    {
4806169689Skan      gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_PRIVATE);
4807169689Skan      private_debug = true;
4808169689Skan    }
4809169689Skan  else
4810169689Skan    private_debug
4811169689Skan      = lang_hooks.decls.omp_private_debug_clause (decl,
4812169689Skan						   !!(flags & GOVD_SHARED));
4813169689Skan  if (private_debug)
4814169689Skan    code = OMP_CLAUSE_PRIVATE;
4815169689Skan  else if (flags & GOVD_SHARED)
4816169689Skan    {
4817169689Skan      if (is_global_var (decl))
4818171825Skan	{
4819171825Skan	  struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
4820171825Skan	  while (ctx != NULL)
4821171825Skan	    {
4822171825Skan	      splay_tree_node on
4823171825Skan		= splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
4824171825Skan	      if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
4825171825Skan				      | GOVD_PRIVATE | GOVD_REDUCTION)) != 0)
4826171825Skan		break;
4827171825Skan	      ctx = ctx->outer_context;
4828171825Skan	    }
4829171825Skan	  if (ctx == NULL)
4830171825Skan	    return 0;
4831171825Skan	}
4832169689Skan      code = OMP_CLAUSE_SHARED;
4833169689Skan    }
4834169689Skan  else if (flags & GOVD_PRIVATE)
4835169689Skan    code = OMP_CLAUSE_PRIVATE;
4836169689Skan  else if (flags & GOVD_FIRSTPRIVATE)
4837169689Skan    code = OMP_CLAUSE_FIRSTPRIVATE;
4838169689Skan  else
4839169689Skan    gcc_unreachable ();
4840169689Skan
4841169689Skan  clause = build_omp_clause (code);
4842169689Skan  OMP_CLAUSE_DECL (clause) = decl;
4843169689Skan  OMP_CLAUSE_CHAIN (clause) = *list_p;
4844169689Skan  if (private_debug)
4845169689Skan    OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
4846169689Skan  *list_p = clause;
4847169689Skan
4848169689Skan  return 0;
4849169689Skan}
4850169689Skan
4851169689Skanstatic void
4852169689Skangimplify_adjust_omp_clauses (tree *list_p)
4853169689Skan{
4854169689Skan  struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
4855169689Skan  tree c, decl;
4856169689Skan
4857169689Skan  while ((c = *list_p) != NULL)
4858169689Skan    {
4859169689Skan      splay_tree_node n;
4860169689Skan      bool remove = false;
4861169689Skan
4862169689Skan      switch (OMP_CLAUSE_CODE (c))
4863169689Skan	{
4864169689Skan	case OMP_CLAUSE_PRIVATE:
4865169689Skan	case OMP_CLAUSE_SHARED:
4866169689Skan	case OMP_CLAUSE_FIRSTPRIVATE:
4867169689Skan	  decl = OMP_CLAUSE_DECL (c);
4868169689Skan	  n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
4869169689Skan	  remove = !(n->value & GOVD_SEEN);
4870169689Skan	  if (! remove)
4871169689Skan	    {
4872169689Skan	      bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
4873169689Skan	      if ((n->value & GOVD_DEBUG_PRIVATE)
4874169689Skan		  || lang_hooks.decls.omp_private_debug_clause (decl, shared))
4875169689Skan		{
4876169689Skan		  gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
4877169689Skan			      || ((n->value & GOVD_DATA_SHARE_CLASS)
4878169689Skan				  == GOVD_PRIVATE));
4879169689Skan		  OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
4880169689Skan		  OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
4881169689Skan		}
4882169689Skan	    }
4883169689Skan	  break;
4884169689Skan
4885169689Skan	case OMP_CLAUSE_LASTPRIVATE:
4886169689Skan	  /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
4887169689Skan	     accurately reflect the presence of a FIRSTPRIVATE clause.  */
4888169689Skan	  decl = OMP_CLAUSE_DECL (c);
4889169689Skan	  n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
4890169689Skan	  OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
4891169689Skan	    = (n->value & GOVD_FIRSTPRIVATE) != 0;
4892169689Skan	  break;
4893169689Skan
4894169689Skan	case OMP_CLAUSE_REDUCTION:
4895169689Skan	case OMP_CLAUSE_COPYIN:
4896169689Skan	case OMP_CLAUSE_COPYPRIVATE:
4897169689Skan	case OMP_CLAUSE_IF:
4898169689Skan	case OMP_CLAUSE_NUM_THREADS:
4899169689Skan	case OMP_CLAUSE_SCHEDULE:
4900169689Skan	case OMP_CLAUSE_NOWAIT:
4901169689Skan	case OMP_CLAUSE_ORDERED:
4902169689Skan	case OMP_CLAUSE_DEFAULT:
4903169689Skan	  break;
4904169689Skan
4905169689Skan	default:
4906169689Skan	  gcc_unreachable ();
4907169689Skan	}
4908169689Skan
4909169689Skan      if (remove)
4910169689Skan	*list_p = OMP_CLAUSE_CHAIN (c);
4911169689Skan      else
4912169689Skan	list_p = &OMP_CLAUSE_CHAIN (c);
4913169689Skan    }
4914169689Skan
4915169689Skan  /* Add in any implicit data sharing.  */
4916169689Skan  splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, list_p);
4917169689Skan
4918169689Skan  gimplify_omp_ctxp = ctx->outer_context;
4919169689Skan  delete_omp_context (ctx);
4920169689Skan}
4921169689Skan
4922169689Skan/* Gimplify the contents of an OMP_PARALLEL statement.  This involves
4923169689Skan   gimplification of the body, as well as scanning the body for used
4924169689Skan   variables.  We need to do this scan now, because variable-sized
4925169689Skan   decls will be decomposed during gimplification.  */
4926169689Skan
4927169689Skanstatic enum gimplify_status
4928169689Skangimplify_omp_parallel (tree *expr_p, tree *pre_p)
4929169689Skan{
4930169689Skan  tree expr = *expr_p;
4931169689Skan
4932169689Skan  gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p, true,
4933169689Skan			     OMP_PARALLEL_COMBINED (expr));
4934169689Skan
4935169689Skan  push_gimplify_context ();
4936169689Skan
4937169689Skan  gimplify_stmt (&OMP_PARALLEL_BODY (expr));
4938169689Skan
4939169689Skan  if (TREE_CODE (OMP_PARALLEL_BODY (expr)) == BIND_EXPR)
4940169689Skan    pop_gimplify_context (OMP_PARALLEL_BODY (expr));
4941169689Skan  else
4942169689Skan    pop_gimplify_context (NULL_TREE);
4943169689Skan
4944169689Skan  gimplify_adjust_omp_clauses (&OMP_PARALLEL_CLAUSES (expr));
4945169689Skan
4946169689Skan  return GS_ALL_DONE;
4947169689Skan}
4948169689Skan
4949169689Skan/* Gimplify the gross structure of an OMP_FOR statement.  */
4950169689Skan
4951169689Skanstatic enum gimplify_status
4952169689Skangimplify_omp_for (tree *expr_p, tree *pre_p)
4953169689Skan{
4954169689Skan  tree for_stmt, decl, t;
4955169689Skan  enum gimplify_status ret = 0;
4956169689Skan
4957169689Skan  for_stmt = *expr_p;
4958169689Skan
4959169689Skan  gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, false, false);
4960169689Skan
4961169689Skan  t = OMP_FOR_INIT (for_stmt);
4962169689Skan  gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
4963169689Skan  decl = TREE_OPERAND (t, 0);
4964169689Skan  gcc_assert (DECL_P (decl));
4965169689Skan  gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl)));
4966169689Skan
4967169689Skan  /* Make sure the iteration variable is private.  */
4968169689Skan  if (omp_is_private (gimplify_omp_ctxp, decl))
4969169689Skan    omp_notice_variable (gimplify_omp_ctxp, decl, true);
4970169689Skan  else
4971169689Skan    omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
4972169689Skan
4973169689Skan  ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
4974169689Skan			NULL, is_gimple_val, fb_rvalue);
4975169689Skan
4976169689Skan  t = OMP_FOR_COND (for_stmt);
4977169689Skan  gcc_assert (COMPARISON_CLASS_P (t));
4978169689Skan  gcc_assert (TREE_OPERAND (t, 0) == decl);
4979169689Skan
4980169689Skan  ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
4981169689Skan			NULL, is_gimple_val, fb_rvalue);
4982169689Skan
4983169689Skan  t = OMP_FOR_INCR (for_stmt);
4984169689Skan  switch (TREE_CODE (t))
4985169689Skan    {
4986169689Skan    case PREINCREMENT_EXPR:
4987169689Skan    case POSTINCREMENT_EXPR:
4988169689Skan      t = build_int_cst (TREE_TYPE (decl), 1);
4989169689Skan      goto build_modify;
4990169689Skan    case PREDECREMENT_EXPR:
4991169689Skan    case POSTDECREMENT_EXPR:
4992169689Skan      t = build_int_cst (TREE_TYPE (decl), -1);
4993169689Skan      goto build_modify;
4994169689Skan    build_modify:
4995169689Skan      t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
4996169689Skan      t = build2 (MODIFY_EXPR, void_type_node, decl, t);
4997169689Skan      OMP_FOR_INCR (for_stmt) = t;
4998169689Skan      break;
4999169689Skan
5000169689Skan    case MODIFY_EXPR:
5001169689Skan      gcc_assert (TREE_OPERAND (t, 0) == decl);
5002169689Skan      t = TREE_OPERAND (t, 1);
5003169689Skan      switch (TREE_CODE (t))
5004169689Skan	{
5005169689Skan	case PLUS_EXPR:
5006169689Skan	  if (TREE_OPERAND (t, 1) == decl)
5007169689Skan	    {
5008169689Skan	      TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
5009169689Skan	      TREE_OPERAND (t, 0) = decl;
5010169689Skan	      break;
5011169689Skan	    }
5012169689Skan	case MINUS_EXPR:
5013169689Skan	  gcc_assert (TREE_OPERAND (t, 0) == decl);
5014169689Skan	  break;
5015169689Skan	default:
5016169689Skan	  gcc_unreachable ();
5017169689Skan	}
5018169689Skan
5019169689Skan      ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
5020169689Skan			    NULL, is_gimple_val, fb_rvalue);
5021169689Skan      break;
5022169689Skan
5023169689Skan    default:
5024169689Skan      gcc_unreachable ();
5025169689Skan    }
5026169689Skan
5027169689Skan  gimplify_to_stmt_list (&OMP_FOR_BODY (for_stmt));
5028169689Skan  gimplify_adjust_omp_clauses (&OMP_FOR_CLAUSES (for_stmt));
5029169689Skan
5030169689Skan  return ret == GS_ALL_DONE ? GS_ALL_DONE : GS_ERROR;
5031169689Skan}
5032169689Skan
5033169689Skan/* Gimplify the gross structure of other OpenMP worksharing constructs.
5034169689Skan   In particular, OMP_SECTIONS and OMP_SINGLE.  */
5035169689Skan
5036169689Skanstatic enum gimplify_status
5037169689Skangimplify_omp_workshare (tree *expr_p, tree *pre_p)
5038169689Skan{
5039169689Skan  tree stmt = *expr_p;
5040169689Skan
5041169689Skan  gimplify_scan_omp_clauses (&OMP_CLAUSES (stmt), pre_p, false, false);
5042169689Skan  gimplify_to_stmt_list (&OMP_BODY (stmt));
5043169689Skan  gimplify_adjust_omp_clauses (&OMP_CLAUSES (stmt));
5044169689Skan
5045169689Skan  return GS_ALL_DONE;
5046169689Skan}
5047169689Skan
5048169689Skan/* A subroutine of gimplify_omp_atomic.  The front end is supposed to have
5049169689Skan   stabilized the lhs of the atomic operation as *ADDR.  Return true if
5050169689Skan   EXPR is this stabilized form.  */
5051169689Skan
5052169689Skanstatic bool
5053169689Skangoa_lhs_expr_p (tree expr, tree addr)
5054169689Skan{
5055169689Skan  /* Also include casts to other type variants.  The C front end is fond
5056169689Skan     of adding these for e.g. volatile variables.  This is like
5057169689Skan     STRIP_TYPE_NOPS but includes the main variant lookup.  */
5058169689Skan  while ((TREE_CODE (expr) == NOP_EXPR
5059169689Skan          || TREE_CODE (expr) == CONVERT_EXPR
5060169689Skan          || TREE_CODE (expr) == NON_LVALUE_EXPR)
5061169689Skan         && TREE_OPERAND (expr, 0) != error_mark_node
5062169689Skan         && (TYPE_MAIN_VARIANT (TREE_TYPE (expr))
5063169689Skan             == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (expr, 0)))))
5064169689Skan    expr = TREE_OPERAND (expr, 0);
5065169689Skan
5066169689Skan  if (TREE_CODE (expr) == INDIRECT_REF && TREE_OPERAND (expr, 0) == addr)
5067169689Skan    return true;
5068169689Skan  if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
5069169689Skan    return true;
5070169689Skan  return false;
5071169689Skan}
5072169689Skan
5073169689Skan/* A subroutine of gimplify_omp_atomic.  Attempt to implement the atomic
5074169689Skan   operation as a __sync_fetch_and_op builtin.  INDEX is log2 of the
5075169689Skan   size of the data type, and thus usable to find the index of the builtin
5076169689Skan   decl.  Returns GS_UNHANDLED if the expression is not of the proper form.  */
5077169689Skan
5078169689Skanstatic enum gimplify_status
5079169689Skangimplify_omp_atomic_fetch_op (tree *expr_p, tree addr, tree rhs, int index)
5080169689Skan{
5081169689Skan  enum built_in_function base;
5082169689Skan  tree decl, args, itype;
5083169689Skan  enum insn_code *optab;
5084169689Skan
5085169689Skan  /* Check for one of the supported fetch-op operations.  */
5086169689Skan  switch (TREE_CODE (rhs))
5087169689Skan    {
5088169689Skan    case PLUS_EXPR:
5089169689Skan      base = BUILT_IN_FETCH_AND_ADD_N;
5090169689Skan      optab = sync_add_optab;
5091169689Skan      break;
5092169689Skan    case MINUS_EXPR:
5093169689Skan      base = BUILT_IN_FETCH_AND_SUB_N;
5094169689Skan      optab = sync_add_optab;
5095169689Skan      break;
5096169689Skan    case BIT_AND_EXPR:
5097169689Skan      base = BUILT_IN_FETCH_AND_AND_N;
5098169689Skan      optab = sync_and_optab;
5099169689Skan      break;
5100169689Skan    case BIT_IOR_EXPR:
5101169689Skan      base = BUILT_IN_FETCH_AND_OR_N;
5102169689Skan      optab = sync_ior_optab;
5103169689Skan      break;
5104169689Skan    case BIT_XOR_EXPR:
5105169689Skan      base = BUILT_IN_FETCH_AND_XOR_N;
5106169689Skan      optab = sync_xor_optab;
5107169689Skan      break;
5108169689Skan    default:
5109169689Skan      return GS_UNHANDLED;
5110169689Skan    }
5111169689Skan
5112169689Skan  /* Make sure the expression is of the proper form.  */
5113169689Skan  if (goa_lhs_expr_p (TREE_OPERAND (rhs, 0), addr))
5114169689Skan    rhs = TREE_OPERAND (rhs, 1);
5115169689Skan  else if (commutative_tree_code (TREE_CODE (rhs))
5116169689Skan	   && goa_lhs_expr_p (TREE_OPERAND (rhs, 1), addr))
5117169689Skan    rhs = TREE_OPERAND (rhs, 0);
5118169689Skan  else
5119169689Skan    return GS_UNHANDLED;
5120169689Skan
5121169689Skan  decl = built_in_decls[base + index + 1];
5122169689Skan  itype = TREE_TYPE (TREE_TYPE (decl));
5123169689Skan
5124169689Skan  if (optab[TYPE_MODE (itype)] == CODE_FOR_nothing)
5125169689Skan    return GS_UNHANDLED;
5126169689Skan
5127169689Skan  args = tree_cons (NULL, fold_convert (itype, rhs), NULL);
5128169689Skan  args = tree_cons (NULL, addr, args);
5129169689Skan  *expr_p = build_function_call_expr (decl, args);
5130169689Skan  return GS_OK;
5131169689Skan}
5132169689Skan
5133169689Skan/* A subroutine of gimplify_omp_atomic_pipeline.  Walk *EXPR_P and replace
5134169689Skan   appearances of *LHS_ADDR with LHS_VAR.  If an expression does not involve
5135169689Skan   the lhs, evaluate it into a temporary.  Return 1 if the lhs appeared as
5136169689Skan   a subexpression, 0 if it did not, or -1 if an error was encountered.  */
5137169689Skan
5138169689Skanstatic int
5139169689Skangoa_stabilize_expr (tree *expr_p, tree *pre_p, tree lhs_addr, tree lhs_var)
5140169689Skan{
5141169689Skan  tree expr = *expr_p;
5142169689Skan  int saw_lhs;
5143169689Skan
5144169689Skan  if (goa_lhs_expr_p (expr, lhs_addr))
5145169689Skan    {
5146169689Skan      *expr_p = lhs_var;
5147169689Skan      return 1;
5148169689Skan    }
5149169689Skan  if (is_gimple_val (expr))
5150169689Skan    return 0;
5151169689Skan
5152169689Skan  saw_lhs = 0;
5153169689Skan  switch (TREE_CODE_CLASS (TREE_CODE (expr)))
5154169689Skan    {
5155169689Skan    case tcc_binary:
5156169689Skan      saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
5157169689Skan				     lhs_addr, lhs_var);
5158169689Skan    case tcc_unary:
5159169689Skan      saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
5160169689Skan				     lhs_addr, lhs_var);
5161169689Skan      break;
5162169689Skan    default:
5163169689Skan      break;
5164169689Skan    }
5165169689Skan
5166169689Skan  if (saw_lhs == 0)
5167169689Skan    {
5168169689Skan      enum gimplify_status gs;
5169169689Skan      gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
5170169689Skan      if (gs != GS_ALL_DONE)
5171169689Skan	saw_lhs = -1;
5172169689Skan    }
5173169689Skan
5174169689Skan  return saw_lhs;
5175169689Skan}
5176169689Skan
5177169689Skan/* A subroutine of gimplify_omp_atomic.  Implement the atomic operation as:
5178169689Skan
5179169689Skan	oldval = *addr;
5180169689Skan      repeat:
5181169689Skan	newval = rhs;	// with oldval replacing *addr in rhs
5182169689Skan	oldval = __sync_val_compare_and_swap (addr, oldval, newval);
5183169689Skan	if (oldval != newval)
5184169689Skan	  goto repeat;
5185169689Skan
5186169689Skan   INDEX is log2 of the size of the data type, and thus usable to find the
5187169689Skan   index of the builtin decl.  */
5188169689Skan
5189169689Skanstatic enum gimplify_status
5190169689Skangimplify_omp_atomic_pipeline (tree *expr_p, tree *pre_p, tree addr,
5191169689Skan			      tree rhs, int index)
5192169689Skan{
5193169689Skan  tree oldval, oldival, oldival2, newval, newival, label;
5194169689Skan  tree type, itype, cmpxchg, args, x, iaddr;
5195169689Skan
5196169689Skan  cmpxchg = built_in_decls[BUILT_IN_VAL_COMPARE_AND_SWAP_N + index + 1];
5197169689Skan  type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5198169689Skan  itype = TREE_TYPE (TREE_TYPE (cmpxchg));
5199169689Skan
5200169689Skan  if (sync_compare_and_swap[TYPE_MODE (itype)] == CODE_FOR_nothing)
5201169689Skan    return GS_UNHANDLED;
5202169689Skan
5203169689Skan  oldval = create_tmp_var (type, NULL);
5204169689Skan  newval = create_tmp_var (type, NULL);
5205169689Skan
5206169689Skan  /* Precompute as much of RHS as possible.  In the same walk, replace
5207169689Skan     occurrences of the lhs value with our temporary.  */
5208169689Skan  if (goa_stabilize_expr (&rhs, pre_p, addr, oldval) < 0)
5209169689Skan    return GS_ERROR;
5210169689Skan
5211169689Skan  x = build_fold_indirect_ref (addr);
5212169689Skan  x = build2 (MODIFY_EXPR, void_type_node, oldval, x);
5213169689Skan  gimplify_and_add (x, pre_p);
5214169689Skan
5215169689Skan  /* For floating-point values, we'll need to view-convert them to integers
5216169689Skan     so that we can perform the atomic compare and swap.  Simplify the
5217169689Skan     following code by always setting up the "i"ntegral variables.  */
5218169689Skan  if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
5219169689Skan    {
5220169689Skan      oldival = oldval;
5221169689Skan      newival = newval;
5222169689Skan      iaddr = addr;
5223169689Skan    }
5224169689Skan  else
5225169689Skan    {
5226169689Skan      oldival = create_tmp_var (itype, NULL);
5227169689Skan      newival = create_tmp_var (itype, NULL);
5228169689Skan
5229169689Skan      x = build1 (VIEW_CONVERT_EXPR, itype, oldval);
5230169689Skan      x = build2 (MODIFY_EXPR, void_type_node, oldival, x);
5231169689Skan      gimplify_and_add (x, pre_p);
5232169689Skan      iaddr = fold_convert (build_pointer_type (itype), addr);
5233169689Skan    }
5234169689Skan
5235169689Skan  oldival2 = create_tmp_var (itype, NULL);
5236169689Skan
5237169689Skan  label = create_artificial_label ();
5238169689Skan  x = build1 (LABEL_EXPR, void_type_node, label);
5239169689Skan  gimplify_and_add (x, pre_p);
5240169689Skan
5241169689Skan  x = build2 (MODIFY_EXPR, void_type_node, newval, rhs);
5242169689Skan  gimplify_and_add (x, pre_p);
5243169689Skan
5244169689Skan  if (newval != newival)
5245169689Skan    {
5246169689Skan      x = build1 (VIEW_CONVERT_EXPR, itype, newval);
5247169689Skan      x = build2 (MODIFY_EXPR, void_type_node, newival, x);
5248169689Skan      gimplify_and_add (x, pre_p);
5249169689Skan    }
5250169689Skan
5251169689Skan  x = build2 (MODIFY_EXPR, void_type_node, oldival2,
5252169689Skan	      fold_convert (itype, oldival));
5253169689Skan  gimplify_and_add (x, pre_p);
5254169689Skan
5255169689Skan  args = tree_cons (NULL, fold_convert (itype, newival), NULL);
5256169689Skan  args = tree_cons (NULL, fold_convert (itype, oldival), args);
5257169689Skan  args = tree_cons (NULL, iaddr, args);
5258169689Skan  x = build_function_call_expr (cmpxchg, args);
5259169689Skan  if (oldval == oldival)
5260169689Skan    x = fold_convert (type, x);
5261169689Skan  x = build2 (MODIFY_EXPR, void_type_node, oldival, x);
5262169689Skan  gimplify_and_add (x, pre_p);
5263169689Skan
5264169689Skan  /* For floating point, be prepared for the loop backedge.  */
5265169689Skan  if (oldval != oldival)
5266169689Skan    {
5267169689Skan      x = build1 (VIEW_CONVERT_EXPR, type, oldival);
5268169689Skan      x = build2 (MODIFY_EXPR, void_type_node, oldval, x);
5269169689Skan      gimplify_and_add (x, pre_p);
5270169689Skan    }
5271169689Skan
5272169689Skan  /* Note that we always perform the comparison as an integer, even for
5273169689Skan     floating point.  This allows the atomic operation to properly
5274169689Skan     succeed even with NaNs and -0.0.  */
5275169689Skan  x = build3 (COND_EXPR, void_type_node,
5276169689Skan	      build2 (NE_EXPR, boolean_type_node, oldival, oldival2),
5277169689Skan	      build1 (GOTO_EXPR, void_type_node, label), NULL);
5278169689Skan  gimplify_and_add (x, pre_p);
5279169689Skan
5280169689Skan  *expr_p = NULL;
5281169689Skan  return GS_ALL_DONE;
5282169689Skan}
5283169689Skan
5284169689Skan/* A subroutine of gimplify_omp_atomic.  Implement the atomic operation as:
5285169689Skan
5286169689Skan	GOMP_atomic_start ();
5287169689Skan	*addr = rhs;
5288169689Skan	GOMP_atomic_end ();
5289169689Skan
5290169689Skan   The result is not globally atomic, but works so long as all parallel
5291169689Skan   references are within #pragma omp atomic directives.  According to
5292169689Skan   responses received from omp@openmp.org, appears to be within spec.
5293169689Skan   Which makes sense, since that's how several other compilers handle
5294169689Skan   this situation as well.  */
5295169689Skan
5296169689Skanstatic enum gimplify_status
5297169689Skangimplify_omp_atomic_mutex (tree *expr_p, tree *pre_p, tree addr, tree rhs)
5298169689Skan{
5299169689Skan  tree t;
5300169689Skan
5301169689Skan  t = built_in_decls[BUILT_IN_GOMP_ATOMIC_START];
5302169689Skan  t = build_function_call_expr (t, NULL);
5303169689Skan  gimplify_and_add (t, pre_p);
5304169689Skan
5305169689Skan  t = build_fold_indirect_ref (addr);
5306169689Skan  t = build2 (MODIFY_EXPR, void_type_node, t, rhs);
5307169689Skan  gimplify_and_add (t, pre_p);
5308169689Skan
5309169689Skan  t = built_in_decls[BUILT_IN_GOMP_ATOMIC_END];
5310169689Skan  t = build_function_call_expr (t, NULL);
5311169689Skan  gimplify_and_add (t, pre_p);
5312169689Skan
5313169689Skan  *expr_p = NULL;
5314169689Skan  return GS_ALL_DONE;
5315169689Skan}
5316169689Skan
5317169689Skan/* Gimplify an OMP_ATOMIC statement.  */
5318169689Skan
5319169689Skanstatic enum gimplify_status
5320169689Skangimplify_omp_atomic (tree *expr_p, tree *pre_p)
5321169689Skan{
5322169689Skan  tree addr = TREE_OPERAND (*expr_p, 0);
5323169689Skan  tree rhs = TREE_OPERAND (*expr_p, 1);
5324169689Skan  tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5325169689Skan  HOST_WIDE_INT index;
5326169689Skan
5327169689Skan  /* Make sure the type is one of the supported sizes.  */
5328169689Skan  index = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5329169689Skan  index = exact_log2 (index);
5330169689Skan  if (index >= 0 && index <= 4)
5331169689Skan    {
5332169689Skan      enum gimplify_status gs;
5333169689Skan      unsigned int align;
5334169689Skan
5335169689Skan      if (DECL_P (TREE_OPERAND (addr, 0)))
5336169689Skan	align = DECL_ALIGN_UNIT (TREE_OPERAND (addr, 0));
5337169689Skan      else if (TREE_CODE (TREE_OPERAND (addr, 0)) == COMPONENT_REF
5338169689Skan	       && TREE_CODE (TREE_OPERAND (TREE_OPERAND (addr, 0), 1))
5339169689Skan		  == FIELD_DECL)
5340169689Skan	align = DECL_ALIGN_UNIT (TREE_OPERAND (TREE_OPERAND (addr, 0), 1));
5341169689Skan      else
5342169689Skan	align = TYPE_ALIGN_UNIT (type);
5343169689Skan
5344169689Skan      /* __sync builtins require strict data alignment.  */
5345169689Skan      if (exact_log2 (align) >= index)
5346169689Skan	{
5347169689Skan	  /* When possible, use specialized atomic update functions.  */
5348169689Skan	  if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
5349169689Skan	    {
5350169689Skan	      gs = gimplify_omp_atomic_fetch_op (expr_p, addr, rhs, index);
5351169689Skan	      if (gs != GS_UNHANDLED)
5352169689Skan		return gs;
5353169689Skan	    }
5354169689Skan
5355169689Skan	  /* If we don't have specialized __sync builtins, try and implement
5356169689Skan	     as a compare and swap loop.  */
5357169689Skan	  gs = gimplify_omp_atomic_pipeline (expr_p, pre_p, addr, rhs, index);
5358169689Skan	  if (gs != GS_UNHANDLED)
5359169689Skan	    return gs;
5360169689Skan	}
5361169689Skan    }
5362169689Skan
5363169689Skan  /* The ultimate fallback is wrapping the operation in a mutex.  */
5364169689Skan  return gimplify_omp_atomic_mutex (expr_p, pre_p, addr, rhs);
5365169689Skan}
5366169689Skan
5367169689Skan/*  Gimplifies the expression tree pointed to by EXPR_P.  Return 0 if
5368169689Skan    gimplification failed.
5369169689Skan
5370169689Skan    PRE_P points to the list where side effects that must happen before
5371169689Skan	EXPR should be stored.
5372169689Skan
5373169689Skan    POST_P points to the list where side effects that must happen after
5374169689Skan	EXPR should be stored, or NULL if there is no suitable list.  In
5375169689Skan	that case, we copy the result to a temporary, emit the
5376169689Skan	post-effects, and then return the temporary.
5377169689Skan
5378169689Skan    GIMPLE_TEST_F points to a function that takes a tree T and
5379169689Skan	returns nonzero if T is in the GIMPLE form requested by the
5380169689Skan	caller.  The GIMPLE predicates are in tree-gimple.c.
5381169689Skan
5382169689Skan	This test is used twice.  Before gimplification, the test is
5383169689Skan	invoked to determine whether *EXPR_P is already gimple enough.  If
5384169689Skan	that fails, *EXPR_P is gimplified according to its code and
5385169689Skan	GIMPLE_TEST_F is called again.  If the test still fails, then a new
5386169689Skan	temporary variable is created and assigned the value of the
5387169689Skan	gimplified expression.
5388169689Skan
5389169689Skan    FALLBACK tells the function what sort of a temporary we want.  If the 1
5390169689Skan	bit is set, an rvalue is OK.  If the 2 bit is set, an lvalue is OK.
5391169689Skan	If both are set, either is OK, but an lvalue is preferable.
5392169689Skan
5393169689Skan    The return value is either GS_ERROR or GS_ALL_DONE, since this function
5394169689Skan    iterates until solution.  */
5395169689Skan
5396169689Skanenum gimplify_status
5397169689Skangimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
5398169689Skan	       bool (* gimple_test_f) (tree), fallback_t fallback)
5399169689Skan{
5400169689Skan  tree tmp;
5401169689Skan  tree internal_pre = NULL_TREE;
5402169689Skan  tree internal_post = NULL_TREE;
5403169689Skan  tree save_expr;
5404169689Skan  int is_statement = (pre_p == NULL);
5405169689Skan  location_t saved_location;
5406169689Skan  enum gimplify_status ret;
5407169689Skan
5408169689Skan  save_expr = *expr_p;
5409169689Skan  if (save_expr == NULL_TREE)
5410169689Skan    return GS_ALL_DONE;
5411169689Skan
5412169689Skan  /* We used to check the predicate here and return immediately if it
5413169689Skan     succeeds.  This is wrong; the design is for gimplification to be
5414169689Skan     idempotent, and for the predicates to only test for valid forms, not
5415169689Skan     whether they are fully simplified.  */
5416169689Skan
5417169689Skan  /* Set up our internal queues if needed.  */
5418169689Skan  if (pre_p == NULL)
5419169689Skan    pre_p = &internal_pre;
5420169689Skan  if (post_p == NULL)
5421169689Skan    post_p = &internal_post;
5422169689Skan
5423169689Skan  saved_location = input_location;
5424169689Skan  if (save_expr != error_mark_node
5425169689Skan      && EXPR_HAS_LOCATION (*expr_p))
5426169689Skan    input_location = EXPR_LOCATION (*expr_p);
5427169689Skan
5428169689Skan  /* Loop over the specific gimplifiers until the toplevel node
5429169689Skan     remains the same.  */
5430169689Skan  do
5431169689Skan    {
5432169689Skan      /* Strip away as many useless type conversions as possible
5433169689Skan	 at the toplevel.  */
5434169689Skan      STRIP_USELESS_TYPE_CONVERSION (*expr_p);
5435169689Skan
5436169689Skan      /* Remember the expr.  */
5437169689Skan      save_expr = *expr_p;
5438169689Skan
5439169689Skan      /* Die, die, die, my darling.  */
5440169689Skan      if (save_expr == error_mark_node
5441169689Skan	  || (TREE_TYPE (save_expr)
5442169689Skan	      && TREE_TYPE (save_expr) == error_mark_node))
5443169689Skan	{
5444169689Skan	  ret = GS_ERROR;
5445169689Skan	  break;
5446169689Skan	}
5447169689Skan
5448169689Skan      /* Do any language-specific gimplification.  */
5449169689Skan      ret = lang_hooks.gimplify_expr (expr_p, pre_p, post_p);
5450169689Skan      if (ret == GS_OK)
5451169689Skan	{
5452169689Skan	  if (*expr_p == NULL_TREE)
5453169689Skan	    break;
5454169689Skan	  if (*expr_p != save_expr)
5455169689Skan	    continue;
5456169689Skan	}
5457169689Skan      else if (ret != GS_UNHANDLED)
5458169689Skan	break;
5459169689Skan
5460169689Skan      ret = GS_OK;
5461169689Skan      switch (TREE_CODE (*expr_p))
5462169689Skan	{
5463169689Skan	  /* First deal with the special cases.  */
5464169689Skan
5465169689Skan	case POSTINCREMENT_EXPR:
5466169689Skan	case POSTDECREMENT_EXPR:
5467169689Skan	case PREINCREMENT_EXPR:
5468169689Skan	case PREDECREMENT_EXPR:
5469169689Skan	  ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
5470169689Skan					fallback != fb_none);
5471169689Skan	  break;
5472169689Skan
5473169689Skan	case ARRAY_REF:
5474169689Skan	case ARRAY_RANGE_REF:
5475169689Skan	case REALPART_EXPR:
5476169689Skan	case IMAGPART_EXPR:
5477169689Skan	case COMPONENT_REF:
5478169689Skan	case VIEW_CONVERT_EXPR:
5479169689Skan	  ret = gimplify_compound_lval (expr_p, pre_p, post_p,
5480169689Skan					fallback ? fallback : fb_rvalue);
5481169689Skan	  break;
5482169689Skan
5483169689Skan	case COND_EXPR:
5484169689Skan	  ret = gimplify_cond_expr (expr_p, pre_p, fallback);
5485169689Skan	  /* C99 code may assign to an array in a structure value of a
5486169689Skan	     conditional expression, and this has undefined behavior
5487169689Skan	     only on execution, so create a temporary if an lvalue is
5488169689Skan	     required.  */
5489169689Skan	  if (fallback == fb_lvalue)
5490169689Skan	    {
5491169689Skan	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
5492169689Skan	      lang_hooks.mark_addressable (*expr_p);
5493169689Skan	    }
5494169689Skan	  break;
5495169689Skan
5496169689Skan	case CALL_EXPR:
5497169689Skan	  ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
5498169689Skan	  /* C99 code may assign to an array in a structure returned
5499169689Skan	     from a function, and this has undefined behavior only on
5500169689Skan	     execution, so create a temporary if an lvalue is
5501169689Skan	     required.  */
5502169689Skan	  if (fallback == fb_lvalue)
5503169689Skan	    {
5504169689Skan	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
5505169689Skan	      lang_hooks.mark_addressable (*expr_p);
5506169689Skan	    }
5507169689Skan	  break;
5508169689Skan
5509169689Skan	case TREE_LIST:
5510169689Skan	  gcc_unreachable ();
5511169689Skan
5512169689Skan	case COMPOUND_EXPR:
5513169689Skan	  ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
5514169689Skan	  break;
5515169689Skan
5516169689Skan	case MODIFY_EXPR:
5517169689Skan	case INIT_EXPR:
5518169689Skan	  ret = gimplify_modify_expr (expr_p, pre_p, post_p,
5519169689Skan				      fallback != fb_none);
5520169689Skan
5521169689Skan	  /* The distinction between MODIFY_EXPR and INIT_EXPR is no longer
5522169689Skan	     useful.  */
5523169689Skan	  if (*expr_p && TREE_CODE (*expr_p) == INIT_EXPR)
5524169689Skan	    TREE_SET_CODE (*expr_p, MODIFY_EXPR);
5525169689Skan	  break;
5526169689Skan
5527169689Skan	case TRUTH_ANDIF_EXPR:
5528169689Skan	case TRUTH_ORIF_EXPR:
5529169689Skan	  ret = gimplify_boolean_expr (expr_p);
5530169689Skan	  break;
5531169689Skan
5532169689Skan	case TRUTH_NOT_EXPR:
5533169689Skan	  TREE_OPERAND (*expr_p, 0)
5534169689Skan	    = gimple_boolify (TREE_OPERAND (*expr_p, 0));
5535169689Skan	  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5536169689Skan			       is_gimple_val, fb_rvalue);
5537169689Skan	  recalculate_side_effects (*expr_p);
5538169689Skan	  break;
5539169689Skan
5540169689Skan	case ADDR_EXPR:
5541169689Skan	  ret = gimplify_addr_expr (expr_p, pre_p, post_p);
5542169689Skan	  break;
5543169689Skan
5544169689Skan	case VA_ARG_EXPR:
5545169689Skan	  ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
5546169689Skan	  break;
5547169689Skan
5548169689Skan	case CONVERT_EXPR:
5549169689Skan	case NOP_EXPR:
5550169689Skan	  if (IS_EMPTY_STMT (*expr_p))
5551169689Skan	    {
5552169689Skan	      ret = GS_ALL_DONE;
5553169689Skan	      break;
5554169689Skan	    }
5555169689Skan
5556169689Skan	  if (VOID_TYPE_P (TREE_TYPE (*expr_p))
5557169689Skan	      || fallback == fb_none)
5558169689Skan	    {
5559169689Skan	      /* Just strip a conversion to void (or in void context) and
5560169689Skan		 try again.  */
5561169689Skan	      *expr_p = TREE_OPERAND (*expr_p, 0);
5562169689Skan	      break;
5563169689Skan	    }
5564169689Skan
5565169689Skan	  ret = gimplify_conversion (expr_p);
5566169689Skan	  if (ret == GS_ERROR)
5567169689Skan	    break;
5568169689Skan	  if (*expr_p != save_expr)
5569169689Skan	    break;
5570169689Skan	  /* FALLTHRU */
5571169689Skan
5572169689Skan	case FIX_TRUNC_EXPR:
5573169689Skan	case FIX_CEIL_EXPR:
5574169689Skan	case FIX_FLOOR_EXPR:
5575169689Skan	case FIX_ROUND_EXPR:
5576169689Skan	  /* unary_expr: ... | '(' cast ')' val | ...  */
5577169689Skan	  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5578169689Skan			       is_gimple_val, fb_rvalue);
5579169689Skan	  recalculate_side_effects (*expr_p);
5580169689Skan	  break;
5581169689Skan
5582169689Skan	case INDIRECT_REF:
5583169689Skan	  *expr_p = fold_indirect_ref (*expr_p);
5584169689Skan	  if (*expr_p != save_expr)
5585169689Skan	    break;
5586169689Skan	  /* else fall through.  */
5587169689Skan	case ALIGN_INDIRECT_REF:
5588169689Skan	case MISALIGNED_INDIRECT_REF:
5589169689Skan	  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5590169689Skan			       is_gimple_reg, fb_rvalue);
5591169689Skan	  recalculate_side_effects (*expr_p);
5592169689Skan	  break;
5593169689Skan
5594169689Skan	  /* Constants need not be gimplified.  */
5595169689Skan	case INTEGER_CST:
5596169689Skan	case REAL_CST:
5597169689Skan	case STRING_CST:
5598169689Skan	case COMPLEX_CST:
5599169689Skan	case VECTOR_CST:
5600169689Skan	  ret = GS_ALL_DONE;
5601169689Skan	  break;
5602169689Skan
5603169689Skan	case CONST_DECL:
5604169689Skan	  /* If we require an lvalue, such as for ADDR_EXPR, retain the
5605169689Skan	     CONST_DECL node.  Otherwise the decl is replaceable by its
5606169689Skan	     value.  */
5607169689Skan	  /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either.  */
5608169689Skan	  if (fallback & fb_lvalue)
5609169689Skan	    ret = GS_ALL_DONE;
5610169689Skan	  else
5611169689Skan	    *expr_p = DECL_INITIAL (*expr_p);
5612169689Skan	  break;
5613169689Skan
5614169689Skan	case DECL_EXPR:
5615169689Skan	  ret = gimplify_decl_expr (expr_p);
5616169689Skan	  break;
5617169689Skan
5618169689Skan	case EXC_PTR_EXPR:
5619169689Skan	  /* FIXME make this a decl.  */
5620169689Skan	  ret = GS_ALL_DONE;
5621169689Skan	  break;
5622169689Skan
5623169689Skan	case BIND_EXPR:
5624169689Skan	  ret = gimplify_bind_expr (expr_p, pre_p);
5625169689Skan	  break;
5626169689Skan
5627169689Skan	case LOOP_EXPR:
5628169689Skan	  ret = gimplify_loop_expr (expr_p, pre_p);
5629169689Skan	  break;
5630169689Skan
5631169689Skan	case SWITCH_EXPR:
5632169689Skan	  ret = gimplify_switch_expr (expr_p, pre_p);
5633169689Skan	  break;
5634169689Skan
5635169689Skan	case EXIT_EXPR:
5636169689Skan	  ret = gimplify_exit_expr (expr_p);
5637169689Skan	  break;
5638169689Skan
5639169689Skan	case GOTO_EXPR:
5640169689Skan	  /* If the target is not LABEL, then it is a computed jump
5641169689Skan	     and the target needs to be gimplified.  */
5642169689Skan	  if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
5643169689Skan	    ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
5644169689Skan				 NULL, is_gimple_val, fb_rvalue);
5645169689Skan	  break;
5646169689Skan
5647169689Skan	case LABEL_EXPR:
5648169689Skan	  ret = GS_ALL_DONE;
5649169689Skan	  gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
5650169689Skan		      == current_function_decl);
5651169689Skan	  break;
5652169689Skan
5653169689Skan	case CASE_LABEL_EXPR:
5654169689Skan	  ret = gimplify_case_label_expr (expr_p);
5655169689Skan	  break;
5656169689Skan
5657169689Skan	case RETURN_EXPR:
5658169689Skan	  ret = gimplify_return_expr (*expr_p, pre_p);
5659169689Skan	  break;
5660169689Skan
5661169689Skan	case CONSTRUCTOR:
5662169689Skan	  /* Don't reduce this in place; let gimplify_init_constructor work its
5663169689Skan	     magic.  Buf if we're just elaborating this for side effects, just
5664169689Skan	     gimplify any element that has side-effects.  */
5665169689Skan	  if (fallback == fb_none)
5666169689Skan	    {
5667169689Skan	      unsigned HOST_WIDE_INT ix;
5668169689Skan	      constructor_elt *ce;
5669169689Skan	      tree temp = NULL_TREE;
5670169689Skan	      for (ix = 0;
5671169689Skan		   VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (*expr_p),
5672169689Skan				ix, ce);
5673169689Skan		   ix++)
5674169689Skan		if (TREE_SIDE_EFFECTS (ce->value))
5675169689Skan		  append_to_statement_list (ce->value, &temp);
5676169689Skan
5677169689Skan	      *expr_p = temp;
5678169689Skan	      ret = GS_OK;
5679169689Skan	    }
5680169689Skan	  /* C99 code may assign to an array in a constructed
5681169689Skan	     structure or union, and this has undefined behavior only
5682169689Skan	     on execution, so create a temporary if an lvalue is
5683169689Skan	     required.  */
5684169689Skan	  else if (fallback == fb_lvalue)
5685169689Skan	    {
5686169689Skan	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
5687169689Skan	      lang_hooks.mark_addressable (*expr_p);
5688169689Skan	    }
5689169689Skan	  else
5690169689Skan	    ret = GS_ALL_DONE;
5691169689Skan	  break;
5692169689Skan
5693169689Skan	  /* The following are special cases that are not handled by the
5694169689Skan	     original GIMPLE grammar.  */
5695169689Skan
5696169689Skan	  /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
5697169689Skan	     eliminated.  */
5698169689Skan	case SAVE_EXPR:
5699169689Skan	  ret = gimplify_save_expr (expr_p, pre_p, post_p);
5700169689Skan	  break;
5701169689Skan
5702169689Skan	case BIT_FIELD_REF:
5703169689Skan	  {
5704169689Skan	    enum gimplify_status r0, r1, r2;
5705169689Skan
5706169689Skan	    r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5707169689Skan				is_gimple_lvalue, fb_either);
5708169689Skan	    r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
5709169689Skan				is_gimple_val, fb_rvalue);
5710169689Skan	    r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p, post_p,
5711169689Skan				is_gimple_val, fb_rvalue);
5712169689Skan	    recalculate_side_effects (*expr_p);
5713169689Skan
5714169689Skan	    ret = MIN (r0, MIN (r1, r2));
5715169689Skan	  }
5716169689Skan	  break;
5717169689Skan
5718169689Skan	case NON_LVALUE_EXPR:
5719169689Skan	  /* This should have been stripped above.  */
5720169689Skan	  gcc_unreachable ();
5721169689Skan
5722169689Skan	case ASM_EXPR:
5723169689Skan	  ret = gimplify_asm_expr (expr_p, pre_p, post_p);
5724169689Skan	  break;
5725169689Skan
5726169689Skan	case TRY_FINALLY_EXPR:
5727169689Skan	case TRY_CATCH_EXPR:
5728169689Skan	  gimplify_to_stmt_list (&TREE_OPERAND (*expr_p, 0));
5729169689Skan	  gimplify_to_stmt_list (&TREE_OPERAND (*expr_p, 1));
5730169689Skan	  ret = GS_ALL_DONE;
5731169689Skan	  break;
5732169689Skan
5733169689Skan	case CLEANUP_POINT_EXPR:
5734169689Skan	  ret = gimplify_cleanup_point_expr (expr_p, pre_p);
5735169689Skan	  break;
5736169689Skan
5737169689Skan	case TARGET_EXPR:
5738169689Skan	  ret = gimplify_target_expr (expr_p, pre_p, post_p);
5739169689Skan	  break;
5740169689Skan
5741169689Skan	case CATCH_EXPR:
5742169689Skan	  gimplify_to_stmt_list (&CATCH_BODY (*expr_p));
5743169689Skan	  ret = GS_ALL_DONE;
5744169689Skan	  break;
5745169689Skan
5746169689Skan	case EH_FILTER_EXPR:
5747169689Skan	  gimplify_to_stmt_list (&EH_FILTER_FAILURE (*expr_p));
5748169689Skan	  ret = GS_ALL_DONE;
5749169689Skan	  break;
5750169689Skan
5751169689Skan	case OBJ_TYPE_REF:
5752169689Skan	  {
5753169689Skan	    enum gimplify_status r0, r1;
5754169689Skan	    r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, post_p,
5755169689Skan			        is_gimple_val, fb_rvalue);
5756169689Skan	    r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
5757169689Skan			        is_gimple_val, fb_rvalue);
5758169689Skan	    ret = MIN (r0, r1);
5759169689Skan	  }
5760169689Skan	  break;
5761169689Skan
5762169689Skan	case LABEL_DECL:
5763169689Skan	  /* We get here when taking the address of a label.  We mark
5764169689Skan	     the label as "forced"; meaning it can never be removed and
5765169689Skan	     it is a potential target for any computed goto.  */
5766169689Skan	  FORCED_LABEL (*expr_p) = 1;
5767169689Skan	  ret = GS_ALL_DONE;
5768169689Skan	  break;
5769169689Skan
5770169689Skan	case STATEMENT_LIST:
5771169689Skan	  ret = gimplify_statement_list (expr_p, pre_p);
5772169689Skan	  break;
5773169689Skan
5774169689Skan	case WITH_SIZE_EXPR:
5775169689Skan	  {
5776169689Skan	    gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
5777169689Skan			   post_p == &internal_post ? NULL : post_p,
5778169689Skan			   gimple_test_f, fallback);
5779169689Skan	    gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
5780169689Skan			   is_gimple_val, fb_rvalue);
5781169689Skan	  }
5782169689Skan	  break;
5783169689Skan
5784169689Skan	case VAR_DECL:
5785169689Skan	case PARM_DECL:
5786169689Skan	  ret = gimplify_var_or_parm_decl (expr_p);
5787169689Skan	  break;
5788169689Skan
5789169689Skan	case RESULT_DECL:
5790169689Skan	  /* When within an OpenMP context, notice uses of variables.  */
5791169689Skan	  if (gimplify_omp_ctxp)
5792169689Skan	    omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
5793169689Skan	  ret = GS_ALL_DONE;
5794169689Skan	  break;
5795169689Skan
5796169689Skan	case SSA_NAME:
5797169689Skan	  /* Allow callbacks into the gimplifier during optimization.  */
5798169689Skan	  ret = GS_ALL_DONE;
5799169689Skan	  break;
5800169689Skan
5801169689Skan	case OMP_PARALLEL:
5802169689Skan	  ret = gimplify_omp_parallel (expr_p, pre_p);
5803169689Skan	  break;
5804169689Skan
5805169689Skan	case OMP_FOR:
5806169689Skan	  ret = gimplify_omp_for (expr_p, pre_p);
5807169689Skan	  break;
5808169689Skan
5809169689Skan	case OMP_SECTIONS:
5810169689Skan	case OMP_SINGLE:
5811169689Skan	  ret = gimplify_omp_workshare (expr_p, pre_p);
5812169689Skan	  break;
5813169689Skan
5814169689Skan	case OMP_SECTION:
5815169689Skan	case OMP_MASTER:
5816169689Skan	case OMP_ORDERED:
5817169689Skan	case OMP_CRITICAL:
5818169689Skan	  gimplify_to_stmt_list (&OMP_BODY (*expr_p));
5819169689Skan	  break;
5820169689Skan
5821169689Skan	case OMP_ATOMIC:
5822169689Skan	  ret = gimplify_omp_atomic (expr_p, pre_p);
5823169689Skan	  break;
5824169689Skan
5825169689Skan	case OMP_RETURN:
5826169689Skan	case OMP_CONTINUE:
5827169689Skan	  ret = GS_ALL_DONE;
5828169689Skan	  break;
5829169689Skan
5830169689Skan	default:
5831169689Skan	  switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
5832169689Skan	    {
5833169689Skan	    case tcc_comparison:
5834169689Skan	      /* Handle comparison of objects of non scalar mode aggregates
5835169689Skan	     	 with a call to memcmp.  It would be nice to only have to do
5836169689Skan	     	 this for variable-sized objects, but then we'd have to allow
5837169689Skan	     	 the same nest of reference nodes we allow for MODIFY_EXPR and
5838169689Skan	     	 that's too complex.
5839169689Skan
5840169689Skan		 Compare scalar mode aggregates as scalar mode values.  Using
5841169689Skan		 memcmp for them would be very inefficient at best, and is
5842169689Skan		 plain wrong if bitfields are involved.  */
5843169689Skan
5844169689Skan	      {
5845169689Skan		tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
5846169689Skan
5847169689Skan		if (!AGGREGATE_TYPE_P (type))
5848169689Skan		  goto expr_2;
5849169689Skan		else if (TYPE_MODE (type) != BLKmode)
5850169689Skan		  ret = gimplify_scalar_mode_aggregate_compare (expr_p);
5851169689Skan		else
5852169689Skan		  ret = gimplify_variable_sized_compare (expr_p);
5853169689Skan
5854169689Skan		break;
5855169689Skan		}
5856169689Skan
5857169689Skan	    /* If *EXPR_P does not need to be special-cased, handle it
5858169689Skan	       according to its class.  */
5859169689Skan	    case tcc_unary:
5860169689Skan	      ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
5861169689Skan				   post_p, is_gimple_val, fb_rvalue);
5862169689Skan	      break;
5863169689Skan
5864169689Skan	    case tcc_binary:
5865169689Skan	    expr_2:
5866169689Skan	      {
5867169689Skan		enum gimplify_status r0, r1;
5868169689Skan
5869169689Skan		r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
5870169689Skan				    post_p, is_gimple_val, fb_rvalue);
5871169689Skan		r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
5872169689Skan				    post_p, is_gimple_val, fb_rvalue);
5873169689Skan
5874169689Skan		ret = MIN (r0, r1);
5875169689Skan		break;
5876169689Skan	      }
5877169689Skan
5878169689Skan	    case tcc_declaration:
5879169689Skan	    case tcc_constant:
5880169689Skan	      ret = GS_ALL_DONE;
5881169689Skan	      goto dont_recalculate;
5882169689Skan
5883169689Skan	    default:
5884169689Skan	      gcc_assert (TREE_CODE (*expr_p) == TRUTH_AND_EXPR
5885169689Skan			  || TREE_CODE (*expr_p) == TRUTH_OR_EXPR
5886169689Skan			  || TREE_CODE (*expr_p) == TRUTH_XOR_EXPR);
5887169689Skan	      goto expr_2;
5888169689Skan	    }
5889169689Skan
5890169689Skan	  recalculate_side_effects (*expr_p);
5891169689Skan	dont_recalculate:
5892169689Skan	  break;
5893169689Skan	}
5894169689Skan
5895169689Skan      /* If we replaced *expr_p, gimplify again.  */
5896169689Skan      if (ret == GS_OK && (*expr_p == NULL || *expr_p == save_expr))
5897169689Skan	ret = GS_ALL_DONE;
5898169689Skan    }
5899169689Skan  while (ret == GS_OK);
5900169689Skan
5901169689Skan  /* If we encountered an error_mark somewhere nested inside, either
5902169689Skan     stub out the statement or propagate the error back out.  */
5903169689Skan  if (ret == GS_ERROR)
5904169689Skan    {
5905169689Skan      if (is_statement)
5906169689Skan	*expr_p = NULL;
5907169689Skan      goto out;
5908169689Skan    }
5909169689Skan
5910169689Skan  /* This was only valid as a return value from the langhook, which
5911169689Skan     we handled.  Make sure it doesn't escape from any other context.  */
5912169689Skan  gcc_assert (ret != GS_UNHANDLED);
5913169689Skan
5914169689Skan  if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
5915169689Skan    {
5916169689Skan      /* We aren't looking for a value, and we don't have a valid
5917169689Skan	 statement.  If it doesn't have side-effects, throw it away.  */
5918169689Skan      if (!TREE_SIDE_EFFECTS (*expr_p))
5919169689Skan	*expr_p = NULL;
5920169689Skan      else if (!TREE_THIS_VOLATILE (*expr_p))
5921169689Skan	{
5922169689Skan	  /* This is probably a _REF that contains something nested that
5923169689Skan	     has side effects.  Recurse through the operands to find it.  */
5924169689Skan	  enum tree_code code = TREE_CODE (*expr_p);
5925169689Skan
5926169689Skan	  switch (code)
5927169689Skan	    {
5928169689Skan	    case COMPONENT_REF:
5929169689Skan	    case REALPART_EXPR:
5930169689Skan	    case IMAGPART_EXPR:
5931169689Skan	    case VIEW_CONVERT_EXPR:
5932169689Skan	      gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5933169689Skan			     gimple_test_f, fallback);
5934169689Skan	      break;
5935169689Skan
5936169689Skan	    case ARRAY_REF:
5937169689Skan	    case ARRAY_RANGE_REF:
5938169689Skan	      gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5939169689Skan			     gimple_test_f, fallback);
5940169689Skan	      gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
5941169689Skan			     gimple_test_f, fallback);
5942169689Skan	      break;
5943169689Skan
5944169689Skan	    default:
5945169689Skan	       /* Anything else with side-effects must be converted to
5946169689Skan		  a valid statement before we get here.  */
5947169689Skan	      gcc_unreachable ();
5948169689Skan	    }
5949169689Skan
5950169689Skan	  *expr_p = NULL;
5951169689Skan	}
5952169689Skan      else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
5953169689Skan	       && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode)
5954169689Skan	{
5955169689Skan	  /* Historically, the compiler has treated a bare reference
5956169689Skan	     to a non-BLKmode volatile lvalue as forcing a load.  */
5957169689Skan	  tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
5958169689Skan	  /* Normally, we do not want to create a temporary for a
5959169689Skan	     TREE_ADDRESSABLE type because such a type should not be
5960169689Skan	     copied by bitwise-assignment.  However, we make an
5961169689Skan	     exception here, as all we are doing here is ensuring that
5962169689Skan	     we read the bytes that make up the type.  We use
5963169689Skan	     create_tmp_var_raw because create_tmp_var will abort when
5964169689Skan	     given a TREE_ADDRESSABLE type.  */
5965169689Skan	  tree tmp = create_tmp_var_raw (type, "vol");
5966169689Skan	  gimple_add_tmp_var (tmp);
5967169689Skan	  *expr_p = build2 (MODIFY_EXPR, type, tmp, *expr_p);
5968169689Skan	}
5969169689Skan      else
5970169689Skan	/* We can't do anything useful with a volatile reference to
5971169689Skan	   an incomplete type, so just throw it away.  Likewise for
5972169689Skan	   a BLKmode type, since any implicit inner load should
5973169689Skan	   already have been turned into an explicit one by the
5974169689Skan	   gimplification process.  */
5975169689Skan	*expr_p = NULL;
5976169689Skan    }
5977169689Skan
5978169689Skan  /* If we are gimplifying at the statement level, we're done.  Tack
5979169689Skan     everything together and replace the original statement with the
5980169689Skan     gimplified form.  */
5981169689Skan  if (fallback == fb_none || is_statement)
5982169689Skan    {
5983169689Skan      if (internal_pre || internal_post)
5984169689Skan	{
5985169689Skan	  append_to_statement_list (*expr_p, &internal_pre);
5986169689Skan	  append_to_statement_list (internal_post, &internal_pre);
5987169689Skan	  annotate_all_with_locus (&internal_pre, input_location);
5988169689Skan	  *expr_p = internal_pre;
5989169689Skan	}
5990169689Skan      else if (!*expr_p)
5991169689Skan	;
5992169689Skan      else if (TREE_CODE (*expr_p) == STATEMENT_LIST)
5993169689Skan	annotate_all_with_locus (expr_p, input_location);
5994169689Skan      else
5995169689Skan	annotate_one_with_locus (*expr_p, input_location);
5996169689Skan      goto out;
5997169689Skan    }
5998169689Skan
5999169689Skan  /* Otherwise we're gimplifying a subexpression, so the resulting value is
6000169689Skan     interesting.  */
6001169689Skan
6002169689Skan  /* If it's sufficiently simple already, we're done.  Unless we are
6003169689Skan     handling some post-effects internally; if that's the case, we need to
6004169689Skan     copy into a temp before adding the post-effects to the tree.  */
6005169689Skan  if (!internal_post && (*gimple_test_f) (*expr_p))
6006169689Skan    goto out;
6007169689Skan
6008169689Skan  /* Otherwise, we need to create a new temporary for the gimplified
6009169689Skan     expression.  */
6010169689Skan
6011169689Skan  /* We can't return an lvalue if we have an internal postqueue.  The
6012169689Skan     object the lvalue refers to would (probably) be modified by the
6013169689Skan     postqueue; we need to copy the value out first, which means an
6014169689Skan     rvalue.  */
6015169689Skan  if ((fallback & fb_lvalue) && !internal_post
6016169689Skan      && is_gimple_addressable (*expr_p))
6017169689Skan    {
6018169689Skan      /* An lvalue will do.  Take the address of the expression, store it
6019169689Skan	 in a temporary, and replace the expression with an INDIRECT_REF of
6020169689Skan	 that temporary.  */
6021169689Skan      tmp = build_fold_addr_expr (*expr_p);
6022169689Skan      gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
6023169689Skan      *expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp);
6024169689Skan    }
6025169689Skan  else if ((fallback & fb_rvalue) && is_gimple_formal_tmp_rhs (*expr_p))
6026169689Skan    {
6027169689Skan      gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
6028169689Skan
6029169689Skan      /* An rvalue will do.  Assign the gimplified expression into a new
6030169689Skan	 temporary TMP and replace the original expression with TMP.  */
6031169689Skan
6032169689Skan      if (internal_post || (fallback & fb_lvalue))
6033169689Skan	/* The postqueue might change the value of the expression between
6034169689Skan	   the initialization and use of the temporary, so we can't use a
6035169689Skan	   formal temp.  FIXME do we care?  */
6036169689Skan	*expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
6037169689Skan      else
6038169689Skan	*expr_p = get_formal_tmp_var (*expr_p, pre_p);
6039169689Skan
6040169689Skan      if (TREE_CODE (*expr_p) != SSA_NAME)
6041169689Skan	DECL_GIMPLE_FORMAL_TEMP_P (*expr_p) = 1;
6042169689Skan    }
6043169689Skan  else
6044169689Skan    {
6045169689Skan#ifdef ENABLE_CHECKING
6046169689Skan      if (!(fallback & fb_mayfail))
6047169689Skan	{
6048169689Skan	  fprintf (stderr, "gimplification failed:\n");
6049169689Skan	  print_generic_expr (stderr, *expr_p, 0);
6050169689Skan	  debug_tree (*expr_p);
6051169689Skan	  internal_error ("gimplification failed");
6052169689Skan	}
6053169689Skan#endif
6054169689Skan      gcc_assert (fallback & fb_mayfail);
6055169689Skan      /* If this is an asm statement, and the user asked for the
6056169689Skan	 impossible, don't die.  Fail and let gimplify_asm_expr
6057169689Skan	 issue an error.  */
6058169689Skan      ret = GS_ERROR;
6059169689Skan      goto out;
6060169689Skan    }
6061169689Skan
6062169689Skan  /* Make sure the temporary matches our predicate.  */
6063169689Skan  gcc_assert ((*gimple_test_f) (*expr_p));
6064169689Skan
6065169689Skan  if (internal_post)
6066169689Skan    {
6067169689Skan      annotate_all_with_locus (&internal_post, input_location);
6068169689Skan      append_to_statement_list (internal_post, pre_p);
6069169689Skan    }
6070169689Skan
6071169689Skan out:
6072169689Skan  input_location = saved_location;
6073169689Skan  return ret;
6074169689Skan}
6075169689Skan
6076169689Skan/* Look through TYPE for variable-sized objects and gimplify each such
6077169689Skan   size that we find.  Add to LIST_P any statements generated.  */
6078169689Skan
6079169689Skanvoid
6080169689Skangimplify_type_sizes (tree type, tree *list_p)
6081169689Skan{
6082169689Skan  tree field, t;
6083169689Skan
6084169689Skan  if (type == NULL || type == error_mark_node)
6085169689Skan    return;
6086169689Skan
6087169689Skan  /* We first do the main variant, then copy into any other variants.  */
6088169689Skan  type = TYPE_MAIN_VARIANT (type);
6089169689Skan
6090169689Skan  /* Avoid infinite recursion.  */
6091169689Skan  if (TYPE_SIZES_GIMPLIFIED (type))
6092169689Skan    return;
6093169689Skan
6094169689Skan  TYPE_SIZES_GIMPLIFIED (type) = 1;
6095169689Skan
6096169689Skan  switch (TREE_CODE (type))
6097169689Skan    {
6098169689Skan    case INTEGER_TYPE:
6099169689Skan    case ENUMERAL_TYPE:
6100169689Skan    case BOOLEAN_TYPE:
6101169689Skan    case REAL_TYPE:
6102169689Skan      gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
6103169689Skan      gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
6104169689Skan
6105169689Skan      for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
6106169689Skan	{
6107169689Skan	  TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
6108169689Skan	  TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
6109169689Skan	}
6110169689Skan      break;
6111169689Skan
6112169689Skan    case ARRAY_TYPE:
6113169689Skan      /* These types may not have declarations, so handle them here.  */
6114169689Skan      gimplify_type_sizes (TREE_TYPE (type), list_p);
6115169689Skan      gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
6116169689Skan      break;
6117169689Skan
6118169689Skan    case RECORD_TYPE:
6119169689Skan    case UNION_TYPE:
6120169689Skan    case QUAL_UNION_TYPE:
6121169689Skan      for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
6122169689Skan	if (TREE_CODE (field) == FIELD_DECL)
6123169689Skan	  {
6124169689Skan	    gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
6125169689Skan	    gimplify_type_sizes (TREE_TYPE (field), list_p);
6126169689Skan	  }
6127169689Skan      break;
6128169689Skan
6129169689Skan    case POINTER_TYPE:
6130169689Skan    case REFERENCE_TYPE:
6131169689Skan	/* We used to recurse on the pointed-to type here, which turned out to
6132169689Skan	   be incorrect because its definition might refer to variables not
6133169689Skan	   yet initialized at this point if a forward declaration is involved.
6134169689Skan
6135169689Skan	   It was actually useful for anonymous pointed-to types to ensure
6136169689Skan	   that the sizes evaluation dominates every possible later use of the
6137169689Skan	   values.  Restricting to such types here would be safe since there
6138169689Skan	   is no possible forward declaration around, but would introduce an
6139169689Skan	   undesirable middle-end semantic to anonymity.  We then defer to
6140169689Skan	   front-ends the responsibility of ensuring that the sizes are
6141169689Skan	   evaluated both early and late enough, e.g. by attaching artificial
6142169689Skan	   type declarations to the tree.  */
6143169689Skan      break;
6144169689Skan
6145169689Skan    default:
6146169689Skan      break;
6147169689Skan    }
6148169689Skan
6149169689Skan  gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
6150169689Skan  gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
6151169689Skan
6152169689Skan  for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
6153169689Skan    {
6154169689Skan      TYPE_SIZE (t) = TYPE_SIZE (type);
6155169689Skan      TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
6156169689Skan      TYPE_SIZES_GIMPLIFIED (t) = 1;
6157169689Skan    }
6158169689Skan}
6159169689Skan
6160169689Skan/* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
6161169689Skan   a size or position, has had all of its SAVE_EXPRs evaluated.
6162169689Skan   We add any required statements to STMT_P.  */
6163169689Skan
6164169689Skanvoid
6165169689Skangimplify_one_sizepos (tree *expr_p, tree *stmt_p)
6166169689Skan{
6167169689Skan  tree type, expr = *expr_p;
6168169689Skan
6169169689Skan  /* We don't do anything if the value isn't there, is constant, or contains
6170169689Skan     A PLACEHOLDER_EXPR.  We also don't want to do anything if it's already
6171169689Skan     a VAR_DECL.  If it's a VAR_DECL from another function, the gimplifier
6172169689Skan     will want to replace it with a new variable, but that will cause problems
6173169689Skan     if this type is from outside the function.  It's OK to have that here.  */
6174169689Skan  if (expr == NULL_TREE || TREE_CONSTANT (expr)
6175169689Skan      || TREE_CODE (expr) == VAR_DECL
6176169689Skan      || CONTAINS_PLACEHOLDER_P (expr))
6177169689Skan    return;
6178169689Skan
6179169689Skan  type = TREE_TYPE (expr);
6180169689Skan  *expr_p = unshare_expr (expr);
6181169689Skan
6182169689Skan  gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue);
6183169689Skan  expr = *expr_p;
6184169689Skan
6185169689Skan  /* Verify that we've an exact type match with the original expression.
6186169689Skan     In particular, we do not wish to drop a "sizetype" in favour of a
6187169689Skan     type of similar dimensions.  We don't want to pollute the generic
6188169689Skan     type-stripping code with this knowledge because it doesn't matter
6189169689Skan     for the bulk of GENERIC/GIMPLE.  It only matters that TYPE_SIZE_UNIT
6190169689Skan     and friends retain their "sizetype-ness".  */
6191169689Skan  if (TREE_TYPE (expr) != type
6192169689Skan      && TREE_CODE (type) == INTEGER_TYPE
6193169689Skan      && TYPE_IS_SIZETYPE (type))
6194169689Skan    {
6195169689Skan      tree tmp;
6196169689Skan
6197169689Skan      *expr_p = create_tmp_var (type, NULL);
6198169689Skan      tmp = build1 (NOP_EXPR, type, expr);
6199169689Skan      tmp = build2 (MODIFY_EXPR, type, *expr_p, tmp);
6200169689Skan      if (EXPR_HAS_LOCATION (expr))
6201169689Skan	SET_EXPR_LOCUS (tmp, EXPR_LOCUS (expr));
6202169689Skan      else
6203169689Skan	SET_EXPR_LOCATION (tmp, input_location);
6204169689Skan
6205169689Skan      gimplify_and_add (tmp, stmt_p);
6206169689Skan    }
6207169689Skan}
6208169689Skan
6209169689Skan#ifdef ENABLE_CHECKING
6210169689Skan/* Compare types A and B for a "close enough" match.  */
6211169689Skan
6212169689Skanstatic bool
6213169689Skancpt_same_type (tree a, tree b)
6214169689Skan{
6215169689Skan  if (lang_hooks.types_compatible_p (a, b))
6216169689Skan    return true;
6217169689Skan
6218169689Skan  /* ??? The C++ FE decomposes METHOD_TYPES to FUNCTION_TYPES and doesn't
6219169689Skan     link them together.  This routine is intended to catch type errors
6220169689Skan     that will affect the optimizers, and the optimizers don't add new
6221169689Skan     dereferences of function pointers, so ignore it.  */
6222169689Skan  if ((TREE_CODE (a) == FUNCTION_TYPE || TREE_CODE (a) == METHOD_TYPE)
6223169689Skan      && (TREE_CODE (b) == FUNCTION_TYPE || TREE_CODE (b) == METHOD_TYPE))
6224169689Skan    return true;
6225169689Skan
6226169689Skan  /* ??? The C FE pushes type qualifiers after the fact into the type of
6227169689Skan     the element from the type of the array.  See build_unary_op's handling
6228169689Skan     of ADDR_EXPR.  This seems wrong -- if we were going to do this, we
6229169689Skan     should have done it when creating the variable in the first place.
6230169689Skan     Alternately, why aren't the two array types made variants?  */
6231169689Skan  if (TREE_CODE (a) == ARRAY_TYPE && TREE_CODE (b) == ARRAY_TYPE)
6232169689Skan    return cpt_same_type (TREE_TYPE (a), TREE_TYPE (b));
6233169689Skan
6234169689Skan  /* And because of those, we have to recurse down through pointers.  */
6235169689Skan  if (POINTER_TYPE_P (a) && POINTER_TYPE_P (b))
6236169689Skan    return cpt_same_type (TREE_TYPE (a), TREE_TYPE (b));
6237169689Skan
6238169689Skan  return false;
6239169689Skan}
6240169689Skan
6241169689Skan/* Check for some cases of the front end missing cast expressions.
6242169689Skan   The type of a dereference should correspond to the pointer type;
6243169689Skan   similarly the type of an address should match its object.  */
6244169689Skan
6245169689Skanstatic tree
6246169689Skancheck_pointer_types_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
6247169689Skan		       void *data ATTRIBUTE_UNUSED)
6248169689Skan{
6249169689Skan  tree t = *tp;
6250169689Skan  tree ptype, otype, dtype;
6251169689Skan
6252169689Skan  switch (TREE_CODE (t))
6253169689Skan    {
6254169689Skan    case INDIRECT_REF:
6255169689Skan    case ARRAY_REF:
6256169689Skan      otype = TREE_TYPE (t);
6257169689Skan      ptype = TREE_TYPE (TREE_OPERAND (t, 0));
6258169689Skan      dtype = TREE_TYPE (ptype);
6259169689Skan      gcc_assert (cpt_same_type (otype, dtype));
6260169689Skan      break;
6261169689Skan
6262169689Skan    case ADDR_EXPR:
6263169689Skan      ptype = TREE_TYPE (t);
6264169689Skan      otype = TREE_TYPE (TREE_OPERAND (t, 0));
6265169689Skan      dtype = TREE_TYPE (ptype);
6266169689Skan      if (!cpt_same_type (otype, dtype))
6267169689Skan	{
6268169689Skan	  /* &array is allowed to produce a pointer to the element, rather than
6269169689Skan	     a pointer to the array type.  We must allow this in order to
6270169689Skan	     properly represent assigning the address of an array in C into
6271169689Skan	     pointer to the element type.  */
6272169689Skan	  gcc_assert (TREE_CODE (otype) == ARRAY_TYPE
6273169689Skan		      && POINTER_TYPE_P (ptype)
6274169689Skan		      && cpt_same_type (TREE_TYPE (otype), dtype));
6275169689Skan	  break;
6276169689Skan	}
6277169689Skan      break;
6278169689Skan
6279169689Skan    default:
6280169689Skan      return NULL_TREE;
6281169689Skan    }
6282169689Skan
6283169689Skan
6284169689Skan  return NULL_TREE;
6285169689Skan}
6286169689Skan#endif
6287169689Skan
6288169689Skan/* Gimplify the body of statements pointed to by BODY_P.  FNDECL is the
6289169689Skan   function decl containing BODY.  */
6290169689Skan
6291169689Skanvoid
6292169689Skangimplify_body (tree *body_p, tree fndecl, bool do_parms)
6293169689Skan{
6294169689Skan  location_t saved_location = input_location;
6295169689Skan  tree body, parm_stmts;
6296169689Skan
6297169689Skan  timevar_push (TV_TREE_GIMPLIFY);
6298169689Skan
6299169689Skan  gcc_assert (gimplify_ctxp == NULL);
6300169689Skan  push_gimplify_context ();
6301169689Skan
6302169689Skan  /* Unshare most shared trees in the body and in that of any nested functions.
6303169689Skan     It would seem we don't have to do this for nested functions because
6304169689Skan     they are supposed to be output and then the outer function gimplified
6305169689Skan     first, but the g++ front end doesn't always do it that way.  */
6306169689Skan  unshare_body (body_p, fndecl);
6307169689Skan  unvisit_body (body_p, fndecl);
6308169689Skan
6309169689Skan  /* Make sure input_location isn't set to something wierd.  */
6310169689Skan  input_location = DECL_SOURCE_LOCATION (fndecl);
6311169689Skan
6312169689Skan  /* Resolve callee-copies.  This has to be done before processing
6313169689Skan     the body so that DECL_VALUE_EXPR gets processed correctly.  */
6314169689Skan  parm_stmts = do_parms ? gimplify_parameters () : NULL;
6315169689Skan
6316169689Skan  /* Gimplify the function's body.  */
6317169689Skan  gimplify_stmt (body_p);
6318169689Skan  body = *body_p;
6319169689Skan
6320169689Skan  if (!body)
6321169689Skan    body = alloc_stmt_list ();
6322169689Skan  else if (TREE_CODE (body) == STATEMENT_LIST)
6323169689Skan    {
6324169689Skan      tree t = expr_only (*body_p);
6325169689Skan      if (t)
6326169689Skan	body = t;
6327169689Skan    }
6328169689Skan
6329169689Skan  /* If there isn't an outer BIND_EXPR, add one.  */
6330169689Skan  if (TREE_CODE (body) != BIND_EXPR)
6331169689Skan    {
6332169689Skan      tree b = build3 (BIND_EXPR, void_type_node, NULL_TREE,
6333169689Skan		       NULL_TREE, NULL_TREE);
6334169689Skan      TREE_SIDE_EFFECTS (b) = 1;
6335169689Skan      append_to_statement_list_force (body, &BIND_EXPR_BODY (b));
6336169689Skan      body = b;
6337169689Skan    }
6338169689Skan
6339169689Skan  /* If we had callee-copies statements, insert them at the beginning
6340169689Skan     of the function.  */
6341169689Skan  if (parm_stmts)
6342169689Skan    {
6343169689Skan      append_to_statement_list_force (BIND_EXPR_BODY (body), &parm_stmts);
6344169689Skan      BIND_EXPR_BODY (body) = parm_stmts;
6345169689Skan    }
6346169689Skan
6347169689Skan  /* Unshare again, in case gimplification was sloppy.  */
6348169689Skan  unshare_all_trees (body);
6349169689Skan
6350169689Skan  *body_p = body;
6351169689Skan
6352169689Skan  pop_gimplify_context (body);
6353169689Skan  gcc_assert (gimplify_ctxp == NULL);
6354169689Skan
6355169689Skan#ifdef ENABLE_CHECKING
6356169689Skan  walk_tree (body_p, check_pointer_types_r, NULL, NULL);
6357169689Skan#endif
6358169689Skan
6359169689Skan  timevar_pop (TV_TREE_GIMPLIFY);
6360169689Skan  input_location = saved_location;
6361169689Skan}
6362169689Skan
6363169689Skan/* Entry point to the gimplification pass.  FNDECL is the FUNCTION_DECL
6364169689Skan   node for the function we want to gimplify.  */
6365169689Skan
6366169689Skanvoid
6367169689Skangimplify_function_tree (tree fndecl)
6368169689Skan{
6369169689Skan  tree oldfn, parm, ret;
6370169689Skan
6371169689Skan  oldfn = current_function_decl;
6372169689Skan  current_function_decl = fndecl;
6373169689Skan  cfun = DECL_STRUCT_FUNCTION (fndecl);
6374169689Skan  if (cfun == NULL)
6375169689Skan    allocate_struct_function (fndecl);
6376169689Skan
6377169689Skan  for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = TREE_CHAIN (parm))
6378169689Skan    {
6379169689Skan      /* Preliminarily mark non-addressed complex variables as eligible
6380169689Skan         for promotion to gimple registers.  We'll transform their uses
6381169689Skan         as we find them.  */
6382169689Skan      if (TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
6383169689Skan          && !TREE_THIS_VOLATILE (parm)
6384169689Skan          && !needs_to_live_in_memory (parm))
6385169689Skan        DECL_COMPLEX_GIMPLE_REG_P (parm) = 1;
6386169689Skan    }
6387169689Skan
6388169689Skan  ret = DECL_RESULT (fndecl);
6389169689Skan  if (TREE_CODE (TREE_TYPE (ret)) == COMPLEX_TYPE
6390169689Skan      && !needs_to_live_in_memory (ret))
6391169689Skan    DECL_COMPLEX_GIMPLE_REG_P (ret) = 1;
6392169689Skan
6393169689Skan  gimplify_body (&DECL_SAVED_TREE (fndecl), fndecl, true);
6394169689Skan
6395169689Skan  /* If we're instrumenting function entry/exit, then prepend the call to
6396169689Skan     the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
6397169689Skan     catch the exit hook.  */
6398169689Skan  /* ??? Add some way to ignore exceptions for this TFE.  */
6399169689Skan  if (flag_instrument_function_entry_exit
6400258501Spfg      && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
6401258501Spfg      && !flag_instrument_functions_exclude_p (fndecl))
6402169689Skan    {
6403169689Skan      tree tf, x, bind;
6404169689Skan
6405169689Skan      tf = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
6406169689Skan      TREE_SIDE_EFFECTS (tf) = 1;
6407169689Skan      x = DECL_SAVED_TREE (fndecl);
6408169689Skan      append_to_statement_list (x, &TREE_OPERAND (tf, 0));
6409169689Skan      x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_EXIT];
6410169689Skan      x = build_function_call_expr (x, NULL);
6411169689Skan      append_to_statement_list (x, &TREE_OPERAND (tf, 1));
6412169689Skan
6413169689Skan      bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
6414169689Skan      TREE_SIDE_EFFECTS (bind) = 1;
6415169689Skan      x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_ENTER];
6416169689Skan      x = build_function_call_expr (x, NULL);
6417169689Skan      append_to_statement_list (x, &BIND_EXPR_BODY (bind));
6418169689Skan      append_to_statement_list (tf, &BIND_EXPR_BODY (bind));
6419169689Skan
6420169689Skan      DECL_SAVED_TREE (fndecl) = bind;
6421169689Skan    }
6422169689Skan
6423169689Skan  current_function_decl = oldfn;
6424169689Skan  cfun = oldfn ? DECL_STRUCT_FUNCTION (oldfn) : NULL;
6425169689Skan}
6426169689Skan
6427169689Skan
6428169689Skan/* Expands EXPR to list of gimple statements STMTS.  If SIMPLE is true,
6429169689Skan   force the result to be either ssa_name or an invariant, otherwise
6430169689Skan   just force it to be a rhs expression.  If VAR is not NULL, make the
6431169689Skan   base variable of the final destination be VAR if suitable.  */
6432169689Skan
6433169689Skantree
6434169689Skanforce_gimple_operand (tree expr, tree *stmts, bool simple, tree var)
6435169689Skan{
6436169689Skan  tree t;
6437169689Skan  enum gimplify_status ret;
6438169689Skan  gimple_predicate gimple_test_f;
6439169689Skan
6440169689Skan  *stmts = NULL_TREE;
6441169689Skan
6442169689Skan  if (is_gimple_val (expr))
6443169689Skan    return expr;
6444169689Skan
6445169689Skan  gimple_test_f = simple ? is_gimple_val : is_gimple_reg_rhs;
6446169689Skan
6447169689Skan  push_gimplify_context ();
6448169689Skan  gimplify_ctxp->into_ssa = in_ssa_p;
6449169689Skan
6450169689Skan  if (var)
6451169689Skan    expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
6452169689Skan
6453169689Skan  ret = gimplify_expr (&expr, stmts, NULL,
6454169689Skan		       gimple_test_f, fb_rvalue);
6455169689Skan  gcc_assert (ret != GS_ERROR);
6456169689Skan
6457169689Skan  if (referenced_vars)
6458169689Skan    {
6459169689Skan      for (t = gimplify_ctxp->temps; t ; t = TREE_CHAIN (t))
6460169689Skan	add_referenced_var (t);
6461169689Skan    }
6462169689Skan
6463169689Skan  pop_gimplify_context (NULL);
6464169689Skan
6465169689Skan  return expr;
6466169689Skan}
6467169689Skan
6468169689Skan/* Invokes force_gimple_operand for EXPR with parameters SIMPLE_P and VAR.  If
6469169689Skan   some statements are produced, emits them before BSI.  */
6470169689Skan
6471169689Skantree
6472169689Skanforce_gimple_operand_bsi (block_stmt_iterator *bsi, tree expr,
6473169689Skan			  bool simple_p, tree var)
6474169689Skan{
6475169689Skan  tree stmts;
6476169689Skan
6477169689Skan  expr = force_gimple_operand (expr, &stmts, simple_p, var);
6478169689Skan  if (stmts)
6479169689Skan    bsi_insert_before (bsi, stmts, BSI_SAME_STMT);
6480169689Skan
6481169689Skan  return expr;
6482169689Skan}
6483169689Skan
6484169689Skan#include "gt-gimplify.h"
6485