1 /* Tree lowering pass.  This pass converts the GENERIC functions-as-trees
2    tree representation into the GIMPLE form.
3    Copyright (C) 2002-2022 Free Software Foundation, Inc.
4    Major work done by Sebastian Pop <s.pop@laposte.net>,
5    Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
6 
7 This file is part of GCC.
8 
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13 
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22 
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "backend.h"
27 #include "target.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "memmodel.h"
31 #include "tm_p.h"
32 #include "gimple.h"
33 #include "gimple-predict.h"
34 #include "tree-pass.h"                  /* FIXME: only for PROP_gimple_any */
35 #include "ssa.h"
36 #include "cgraph.h"
37 #include "tree-pretty-print.h"
38 #include "diagnostic-core.h"
39 #include "alias.h"
40 #include "fold-const.h"
41 #include "calls.h"
42 #include "varasm.h"
43 #include "stmt.h"
44 #include "expr.h"
45 #include "gimple-fold.h"
46 #include "tree-eh.h"
47 #include "gimplify.h"
48 #include "gimple-iterator.h"
49 #include "stor-layout.h"
50 #include "print-tree.h"
51 #include "tree-iterator.h"
52 #include "tree-inline.h"
53 #include "langhooks.h"
54 #include "tree-cfg.h"
55 #include "tree-ssa.h"
56 #include "tree-hash-traits.h"
57 #include "omp-general.h"
58 #include "omp-low.h"
59 #include "gimple-low.h"
60 #include "gomp-constants.h"
61 #include "splay-tree.h"
62 #include "gimple-walk.h"
63 #include "langhooks-def.h"    /* FIXME: for lhd_set_decl_assembler_name */
64 #include "builtins.h"
65 #include "stringpool.h"
66 #include "attribs.h"
67 #include "asan.h"
68 #include "dbgcnt.h"
69 #include "omp-offload.h"
70 #include "context.h"
71 #include "tree-nested.h"
72 
73 /* Hash set of poisoned variables in a bind expr.  */
74 static hash_set<tree> *asan_poisoned_variables = NULL;
75 
76 enum gimplify_omp_var_data
77 {
78   GOVD_SEEN = 0x000001,
79   GOVD_EXPLICIT = 0x000002,
80   GOVD_SHARED = 0x000004,
81   GOVD_PRIVATE = 0x000008,
82   GOVD_FIRSTPRIVATE = 0x000010,
83   GOVD_LASTPRIVATE = 0x000020,
84   GOVD_REDUCTION = 0x000040,
85   GOVD_LOCAL = 0x00080,
86   GOVD_MAP = 0x000100,
87   GOVD_DEBUG_PRIVATE = 0x000200,
88   GOVD_PRIVATE_OUTER_REF = 0x000400,
89   GOVD_LINEAR = 0x000800,
90   GOVD_ALIGNED = 0x001000,
91 
92   /* Flag for GOVD_MAP: don't copy back.  */
93   GOVD_MAP_TO_ONLY = 0x002000,
94 
95   /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference.  */
96   GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 0x004000,
97 
98   GOVD_MAP_0LEN_ARRAY = 0x008000,
99 
100   /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping.  */
101   GOVD_MAP_ALWAYS_TO = 0x010000,
102 
103   /* Flag for shared vars that are or might be stored to in the region.  */
104   GOVD_WRITTEN = 0x020000,
105 
106   /* Flag for GOVD_MAP, if it is a forced mapping.  */
107   GOVD_MAP_FORCE = 0x040000,
108 
109   /* Flag for GOVD_MAP: must be present already.  */
110   GOVD_MAP_FORCE_PRESENT = 0x080000,
111 
112   /* Flag for GOVD_MAP: only allocate.  */
113   GOVD_MAP_ALLOC_ONLY = 0x100000,
114 
115   /* Flag for GOVD_MAP: only copy back.  */
116   GOVD_MAP_FROM_ONLY = 0x200000,
117 
118   GOVD_NONTEMPORAL = 0x400000,
119 
120   /* Flag for GOVD_LASTPRIVATE: conditional modifier.  */
121   GOVD_LASTPRIVATE_CONDITIONAL = 0x800000,
122 
123   GOVD_CONDTEMP = 0x1000000,
124 
125   /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause.  */
126   GOVD_REDUCTION_INSCAN = 0x2000000,
127 
128   /* Flag for GOVD_MAP: (struct) vars that have pointer attachments for
129      fields.  */
130   GOVD_MAP_HAS_ATTACHMENTS = 0x4000000,
131 
132   /* Flag for GOVD_FIRSTPRIVATE: OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT.  */
133   GOVD_FIRSTPRIVATE_IMPLICIT = 0x8000000,
134 
135   GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
136                                  | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
137                                  | GOVD_LOCAL)
138 };
139 
140 
141 enum omp_region_type
142 {
143   ORT_WORKSHARE = 0x00,
144   ORT_TASKGROUP = 0x01,
145   ORT_SIMD          = 0x04,
146 
147   ORT_PARALLEL      = 0x08,
148   ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1,
149 
150   ORT_TASK          = 0x10,
151   ORT_UNTIED_TASK = ORT_TASK | 1,
152   ORT_TASKLOOP  = ORT_TASK | 2,
153   ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2,
154 
155   ORT_TEAMS         = 0x20,
156   ORT_COMBINED_TEAMS = ORT_TEAMS | 1,
157   ORT_HOST_TEAMS = ORT_TEAMS | 2,
158   ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2,
159 
160   /* Data region.  */
161   ORT_TARGET_DATA = 0x40,
162 
163   /* Data region with offloading.  */
164   ORT_TARGET        = 0x80,
165   ORT_COMBINED_TARGET = ORT_TARGET | 1,
166   ORT_IMPLICIT_TARGET = ORT_TARGET | 2,
167 
168   /* OpenACC variants.  */
169   ORT_ACC = 0x100,  /* A generic OpenACC region.  */
170   ORT_ACC_DATA      = ORT_ACC | ORT_TARGET_DATA, /* Data construct.  */
171   ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET,  /* Parallel construct */
172   ORT_ACC_KERNELS  = ORT_ACC | ORT_TARGET | 2,  /* Kernels construct.  */
173   ORT_ACC_SERIAL   = ORT_ACC | ORT_TARGET | 4,  /* Serial construct.  */
174   ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2,  /* Host data.  */
175 
176   /* Dummy OpenMP region, used to disable expansion of
177      DECL_VALUE_EXPRs in taskloop pre body.  */
178   ORT_NONE          = 0x200
179 };
180 
181 /* Gimplify hashtable helper.  */
182 
183 struct gimplify_hasher : free_ptr_hash <elt_t>
184 {
185   static inline hashval_t hash (const elt_t *);
186   static inline bool equal (const elt_t *, const elt_t *);
187 };
188 
189 struct gimplify_ctx
190 {
191   struct gimplify_ctx *prev_context;
192 
193   vec<gbind *> bind_expr_stack;
194   tree temps;
195   gimple_seq conditional_cleanups;
196   tree exit_label;
197   tree return_temp;
198 
199   vec<tree> case_labels;
200   hash_set<tree> *live_switch_vars;
201   /* The formal temporary table.  Should this be persistent?  */
202   hash_table<gimplify_hasher> *temp_htab;
203 
204   int conditions;
205   unsigned into_ssa : 1;
206   unsigned allow_rhs_cond_expr : 1;
207   unsigned in_cleanup_point_expr : 1;
208   unsigned keep_stack : 1;
209   unsigned save_stack : 1;
210   unsigned in_switch_expr : 1;
211 };
212 
213 enum gimplify_defaultmap_kind
214 {
215   GDMK_SCALAR,
216   GDMK_SCALAR_TARGET, /* w/ Fortran's target attr, implicit mapping, only.  */
217   GDMK_AGGREGATE,
218   GDMK_ALLOCATABLE,
219   GDMK_POINTER
220 };
221 
222 struct gimplify_omp_ctx
223 {
224   struct gimplify_omp_ctx *outer_context;
225   splay_tree variables;
226   hash_set<tree> *privatized_types;
227   tree clauses;
228   /* Iteration variables in an OMP_FOR.  */
229   vec<tree> loop_iter_var;
230   location_t location;
231   enum omp_clause_default_kind default_kind;
232   enum omp_region_type region_type;
233   enum tree_code code;
234   bool combined_loop;
235   bool distribute;
236   bool target_firstprivatize_array_bases;
237   bool add_safelen1;
238   bool order_concurrent;
239   bool has_depend;
240   bool in_for_exprs;
241   int defaultmap[5];
242 };
243 
244 static struct gimplify_ctx *gimplify_ctxp;
245 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
246 static bool in_omp_construct;
247 
248 /* Forward declaration.  */
249 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
250 static hash_map<tree, tree> *oacc_declare_returns;
251 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
252                                                      bool (*) (tree), fallback_t, bool);
253 static void prepare_gimple_addressable (tree *, gimple_seq *);
254 
255 /* Shorter alias name for the above function for use in gimplify.cc
256    only.  */
257 
258 static inline void
gimplify_seq_add_stmt(gimple_seq * seq_p,gimple * gs)259 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
260 {
261   gimple_seq_add_stmt_without_update (seq_p, gs);
262 }
263 
264 /* Append sequence SRC to the end of sequence *DST_P.  If *DST_P is
265    NULL, a new sequence is allocated.   This function is
266    similar to gimple_seq_add_seq, but does not scan the operands.
267    During gimplification, we need to manipulate statement sequences
268    before the def/use vectors have been constructed.  */
269 
270 static void
gimplify_seq_add_seq(gimple_seq * dst_p,gimple_seq src)271 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
272 {
273   gimple_stmt_iterator si;
274 
275   if (src == NULL)
276     return;
277 
278   si = gsi_last (*dst_p);
279   gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
280 }
281 
282 
283 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
284    and popping gimplify contexts.  */
285 
286 static struct gimplify_ctx *ctx_pool = NULL;
287 
288 /* Return a gimplify context struct from the pool.  */
289 
290 static inline struct gimplify_ctx *
ctx_alloc(void)291 ctx_alloc (void)
292 {
293   struct gimplify_ctx * c = ctx_pool;
294 
295   if (c)
296     ctx_pool = c->prev_context;
297   else
298     c = XNEW (struct gimplify_ctx);
299 
300   memset (c, '\0', sizeof (*c));
301   return c;
302 }
303 
304 /* Put gimplify context C back into the pool.  */
305 
306 static inline void
ctx_free(struct gimplify_ctx * c)307 ctx_free (struct gimplify_ctx *c)
308 {
309   c->prev_context = ctx_pool;
310   ctx_pool = c;
311 }
312 
313 /* Free allocated ctx stack memory.  */
314 
315 void
free_gimplify_stack(void)316 free_gimplify_stack (void)
317 {
318   struct gimplify_ctx *c;
319 
320   while ((c = ctx_pool))
321     {
322       ctx_pool = c->prev_context;
323       free (c);
324     }
325 }
326 
327 
328 /* Set up a context for the gimplifier.  */
329 
330 void
push_gimplify_context(bool in_ssa,bool rhs_cond_ok)331 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
332 {
333   struct gimplify_ctx *c = ctx_alloc ();
334 
335   c->prev_context = gimplify_ctxp;
336   gimplify_ctxp = c;
337   gimplify_ctxp->into_ssa = in_ssa;
338   gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
339 }
340 
341 /* Tear down a context for the gimplifier.  If BODY is non-null, then
342    put the temporaries into the outer BIND_EXPR.  Otherwise, put them
343    in the local_decls.
344 
345    BODY is not a sequence, but the first tuple in a sequence.  */
346 
347 void
pop_gimplify_context(gimple * body)348 pop_gimplify_context (gimple *body)
349 {
350   struct gimplify_ctx *c = gimplify_ctxp;
351 
352   gcc_assert (c
353               && (!c->bind_expr_stack.exists ()
354                       || c->bind_expr_stack.is_empty ()));
355   c->bind_expr_stack.release ();
356   gimplify_ctxp = c->prev_context;
357 
358   if (body)
359     declare_vars (c->temps, body, false);
360   else
361     record_vars (c->temps);
362 
363   delete c->temp_htab;
364   c->temp_htab = NULL;
365   ctx_free (c);
366 }
367 
368 /* Push a GIMPLE_BIND tuple onto the stack of bindings.  */
369 
370 static void
gimple_push_bind_expr(gbind * bind_stmt)371 gimple_push_bind_expr (gbind *bind_stmt)
372 {
373   gimplify_ctxp->bind_expr_stack.reserve (8);
374   gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
375 }
376 
377 /* Pop the first element off the stack of bindings.  */
378 
379 static void
gimple_pop_bind_expr(void)380 gimple_pop_bind_expr (void)
381 {
382   gimplify_ctxp->bind_expr_stack.pop ();
383 }
384 
385 /* Return the first element of the stack of bindings.  */
386 
387 gbind *
gimple_current_bind_expr(void)388 gimple_current_bind_expr (void)
389 {
390   return gimplify_ctxp->bind_expr_stack.last ();
391 }
392 
393 /* Return the stack of bindings created during gimplification.  */
394 
395 vec<gbind *>
gimple_bind_expr_stack(void)396 gimple_bind_expr_stack (void)
397 {
398   return gimplify_ctxp->bind_expr_stack;
399 }
400 
401 /* Return true iff there is a COND_EXPR between us and the innermost
402    CLEANUP_POINT_EXPR.  This info is used by gimple_push_cleanup.  */
403 
404 static bool
gimple_conditional_context(void)405 gimple_conditional_context (void)
406 {
407   return gimplify_ctxp->conditions > 0;
408 }
409 
410 /* Note that we've entered a COND_EXPR.  */
411 
412 static void
gimple_push_condition(void)413 gimple_push_condition (void)
414 {
415 #ifdef ENABLE_GIMPLE_CHECKING
416   if (gimplify_ctxp->conditions == 0)
417     gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
418 #endif
419   ++(gimplify_ctxp->conditions);
420 }
421 
422 /* Note that we've left a COND_EXPR.  If we're back at unconditional scope
423    now, add any conditional cleanups we've seen to the prequeue.  */
424 
425 static void
gimple_pop_condition(gimple_seq * pre_p)426 gimple_pop_condition (gimple_seq *pre_p)
427 {
428   int conds = --(gimplify_ctxp->conditions);
429 
430   gcc_assert (conds >= 0);
431   if (conds == 0)
432     {
433       gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
434       gimplify_ctxp->conditional_cleanups = NULL;
435     }
436 }
437 
438 /* A stable comparison routine for use with splay trees and DECLs.  */
439 
440 static int
splay_tree_compare_decl_uid(splay_tree_key xa,splay_tree_key xb)441 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
442 {
443   tree a = (tree) xa;
444   tree b = (tree) xb;
445 
446   return DECL_UID (a) - DECL_UID (b);
447 }
448 
449 /* Create a new omp construct that deals with variable remapping.  */
450 
451 static struct gimplify_omp_ctx *
new_omp_context(enum omp_region_type region_type)452 new_omp_context (enum omp_region_type region_type)
453 {
454   struct gimplify_omp_ctx *c;
455 
456   c = XCNEW (struct gimplify_omp_ctx);
457   c->outer_context = gimplify_omp_ctxp;
458   c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
459   c->privatized_types = new hash_set<tree>;
460   c->location = input_location;
461   c->region_type = region_type;
462   if ((region_type & ORT_TASK) == 0)
463     c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
464   else
465     c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
466   c->defaultmap[GDMK_SCALAR] = GOVD_MAP;
467   c->defaultmap[GDMK_SCALAR_TARGET] = GOVD_MAP;
468   c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
469   c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
470   c->defaultmap[GDMK_POINTER] = GOVD_MAP;
471 
472   return c;
473 }
474 
475 /* Destroy an omp construct that deals with variable remapping.  */
476 
477 static void
delete_omp_context(struct gimplify_omp_ctx * c)478 delete_omp_context (struct gimplify_omp_ctx *c)
479 {
480   splay_tree_delete (c->variables);
481   delete c->privatized_types;
482   c->loop_iter_var.release ();
483   XDELETE (c);
484 }
485 
486 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
487 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
488 
489 /* Both gimplify the statement T and append it to *SEQ_P.  This function
490    behaves exactly as gimplify_stmt, but you don't have to pass T as a
491    reference.  */
492 
493 void
gimplify_and_add(tree t,gimple_seq * seq_p)494 gimplify_and_add (tree t, gimple_seq *seq_p)
495 {
496   gimplify_stmt (&t, seq_p);
497 }
498 
499 /* Gimplify statement T into sequence *SEQ_P, and return the first
500    tuple in the sequence of generated tuples for this statement.
501    Return NULL if gimplifying T produced no tuples.  */
502 
503 static gimple *
gimplify_and_return_first(tree t,gimple_seq * seq_p)504 gimplify_and_return_first (tree t, gimple_seq *seq_p)
505 {
506   gimple_stmt_iterator last = gsi_last (*seq_p);
507 
508   gimplify_and_add (t, seq_p);
509 
510   if (!gsi_end_p (last))
511     {
512       gsi_next (&last);
513       return gsi_stmt (last);
514     }
515   else
516     return gimple_seq_first_stmt (*seq_p);
517 }
518 
519 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
520    LHS, or for a call argument.  */
521 
522 static bool
is_gimple_mem_rhs(tree t)523 is_gimple_mem_rhs (tree t)
524 {
525   /* If we're dealing with a renamable type, either source or dest must be
526      a renamed variable.  */
527   if (is_gimple_reg_type (TREE_TYPE (t)))
528     return is_gimple_val (t);
529   else
530     return is_gimple_val (t) || is_gimple_lvalue (t);
531 }
532 
533 /* Return true if T is a CALL_EXPR or an expression that can be
534    assigned to a temporary.  Note that this predicate should only be
535    used during gimplification.  See the rationale for this in
536    gimplify_modify_expr.  */
537 
538 static bool
is_gimple_reg_rhs_or_call(tree t)539 is_gimple_reg_rhs_or_call (tree t)
540 {
541   return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
542             || TREE_CODE (t) == CALL_EXPR);
543 }
544 
545 /* Return true if T is a valid memory RHS or a CALL_EXPR.  Note that
546    this predicate should only be used during gimplification.  See the
547    rationale for this in gimplify_modify_expr.  */
548 
549 static bool
is_gimple_mem_rhs_or_call(tree t)550 is_gimple_mem_rhs_or_call (tree t)
551 {
552   /* If we're dealing with a renamable type, either source or dest must be
553      a renamed variable.  */
554   if (is_gimple_reg_type (TREE_TYPE (t)))
555     return is_gimple_val (t);
556   else
557     return (is_gimple_val (t)
558               || is_gimple_lvalue (t)
559               || TREE_CLOBBER_P (t)
560               || TREE_CODE (t) == CALL_EXPR);
561 }
562 
563 /* Create a temporary with a name derived from VAL.  Subroutine of
564    lookup_tmp_var; nobody else should call this function.  */
565 
566 static inline tree
create_tmp_from_val(tree val)567 create_tmp_from_val (tree val)
568 {
569   /* Drop all qualifiers and address-space information from the value type.  */
570   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
571   tree var = create_tmp_var (type, get_name (val));
572   return var;
573 }
574 
575 /* Create a temporary to hold the value of VAL.  If IS_FORMAL, try to reuse
576    an existing expression temporary.  */
577 
578 static tree
lookup_tmp_var(tree val,bool is_formal)579 lookup_tmp_var (tree val, bool is_formal)
580 {
581   tree ret;
582 
583   /* If not optimizing, never really reuse a temporary.  local-alloc
584      won't allocate any variable that is used in more than one basic
585      block, which means it will go into memory, causing much extra
586      work in reload and final and poorer code generation, outweighing
587      the extra memory allocation here.  */
588   if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
589     ret = create_tmp_from_val (val);
590   else
591     {
592       elt_t elt, *elt_p;
593       elt_t **slot;
594 
595       elt.val = val;
596       if (!gimplify_ctxp->temp_htab)
597         gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
598       slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
599       if (*slot == NULL)
600           {
601             elt_p = XNEW (elt_t);
602             elt_p->val = val;
603             elt_p->temp = ret = create_tmp_from_val (val);
604             *slot = elt_p;
605           }
606       else
607           {
608             elt_p = *slot;
609           ret = elt_p->temp;
610           }
611     }
612 
613   return ret;
614 }
615 
616 /* Helper for get_formal_tmp_var and get_initialized_tmp_var.  */
617 
618 static tree
internal_get_tmp_var(tree val,gimple_seq * pre_p,gimple_seq * post_p,bool is_formal,bool allow_ssa)619 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
620                       bool is_formal, bool allow_ssa)
621 {
622   tree t, mod;
623 
624   /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
625      can create an INIT_EXPR and convert it into a GIMPLE_CALL below.  */
626   gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
627                      fb_rvalue);
628 
629   if (allow_ssa
630       && gimplify_ctxp->into_ssa
631       && is_gimple_reg_type (TREE_TYPE (val)))
632     {
633       t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
634       if (! gimple_in_ssa_p (cfun))
635           {
636             const char *name = get_name (val);
637             if (name)
638               SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
639           }
640     }
641   else
642     t = lookup_tmp_var (val, is_formal);
643 
644   mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
645 
646   SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
647 
648   /* gimplify_modify_expr might want to reduce this further.  */
649   gimplify_and_add (mod, pre_p);
650   ggc_free (mod);
651 
652   return t;
653 }
654 
655 /* Return a formal temporary variable initialized with VAL.  PRE_P is as
656    in gimplify_expr.  Only use this function if:
657 
658    1) The value of the unfactored expression represented by VAL will not
659       change between the initialization and use of the temporary, and
660    2) The temporary will not be otherwise modified.
661 
662    For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
663    and #2 means it is inappropriate for && temps.
664 
665    For other cases, use get_initialized_tmp_var instead.  */
666 
667 tree
get_formal_tmp_var(tree val,gimple_seq * pre_p)668 get_formal_tmp_var (tree val, gimple_seq *pre_p)
669 {
670   return internal_get_tmp_var (val, pre_p, NULL, true, true);
671 }
672 
673 /* Return a temporary variable initialized with VAL.  PRE_P and POST_P
674    are as in gimplify_expr.  */
675 
676 tree
get_initialized_tmp_var(tree val,gimple_seq * pre_p,gimple_seq * post_p,bool allow_ssa)677 get_initialized_tmp_var (tree val, gimple_seq *pre_p,
678                                gimple_seq *post_p /* = NULL */,
679                                bool allow_ssa /* = true */)
680 {
681   return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
682 }
683 
684 /* Declare all the variables in VARS in SCOPE.  If DEBUG_INFO is true,
685    generate debug info for them; otherwise don't.  */
686 
687 void
declare_vars(tree vars,gimple * gs,bool debug_info)688 declare_vars (tree vars, gimple *gs, bool debug_info)
689 {
690   tree last = vars;
691   if (last)
692     {
693       tree temps, block;
694 
695       gbind *scope = as_a <gbind *> (gs);
696 
697       temps = nreverse (last);
698 
699       block = gimple_bind_block (scope);
700       gcc_assert (!block || TREE_CODE (block) == BLOCK);
701       if (!block || !debug_info)
702           {
703             DECL_CHAIN (last) = gimple_bind_vars (scope);
704             gimple_bind_set_vars (scope, temps);
705           }
706       else
707           {
708             /* We need to attach the nodes both to the BIND_EXPR and to its
709                associated BLOCK for debugging purposes.  The key point here
710                is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
711                is a subchain of the BIND_EXPR_VARS of the BIND_EXPR.  */
712             if (BLOCK_VARS (block))
713               BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
714             else
715               {
716                 gimple_bind_set_vars (scope,
717                                             chainon (gimple_bind_vars (scope), temps));
718                 BLOCK_VARS (block) = temps;
719               }
720           }
721     }
722 }
723 
724 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
725    for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly.  Abort if
726    no such upper bound can be obtained.  */
727 
728 static void
force_constant_size(tree var)729 force_constant_size (tree var)
730 {
731   /* The only attempt we make is by querying the maximum size of objects
732      of the variable's type.  */
733 
734   HOST_WIDE_INT max_size;
735 
736   gcc_assert (VAR_P (var));
737 
738   max_size = max_int_size_in_bytes (TREE_TYPE (var));
739 
740   gcc_assert (max_size >= 0);
741 
742   DECL_SIZE_UNIT (var)
743     = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
744   DECL_SIZE (var)
745     = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
746 }
747 
748 /* Push the temporary variable TMP into the current binding.  */
749 
750 void
gimple_add_tmp_var_fn(struct function * fn,tree tmp)751 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
752 {
753   gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
754 
755   /* Later processing assumes that the object size is constant, which might
756      not be true at this point.  Force the use of a constant upper bound in
757      this case.  */
758   if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
759     force_constant_size (tmp);
760 
761   DECL_CONTEXT (tmp) = fn->decl;
762   DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
763 
764   record_vars_into (tmp, fn->decl);
765 }
766 
767 /* Push the temporary variable TMP into the current binding.  */
768 
769 void
gimple_add_tmp_var(tree tmp)770 gimple_add_tmp_var (tree tmp)
771 {
772   gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
773 
774   /* Later processing assumes that the object size is constant, which might
775      not be true at this point.  Force the use of a constant upper bound in
776      this case.  */
777   if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
778     force_constant_size (tmp);
779 
780   DECL_CONTEXT (tmp) = current_function_decl;
781   DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
782 
783   if (gimplify_ctxp)
784     {
785       DECL_CHAIN (tmp) = gimplify_ctxp->temps;
786       gimplify_ctxp->temps = tmp;
787 
788       /* Mark temporaries local within the nearest enclosing parallel.  */
789       if (gimplify_omp_ctxp)
790           {
791             struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
792             int flag = GOVD_LOCAL | GOVD_SEEN;
793             while (ctx
794                      && (ctx->region_type == ORT_WORKSHARE
795                          || ctx->region_type == ORT_TASKGROUP
796                          || ctx->region_type == ORT_SIMD
797                          || ctx->region_type == ORT_ACC))
798               {
799                 if (ctx->region_type == ORT_SIMD
800                       && TREE_ADDRESSABLE (tmp)
801                       && !TREE_STATIC (tmp))
802                     {
803                       if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
804                         ctx->add_safelen1 = true;
805                       else if (ctx->in_for_exprs)
806                         flag = GOVD_PRIVATE;
807                       else
808                         flag = GOVD_PRIVATE | GOVD_SEEN;
809                       break;
810                     }
811                 ctx = ctx->outer_context;
812               }
813             if (ctx)
814               omp_add_variable (ctx, tmp, flag);
815           }
816     }
817   else if (cfun)
818     record_vars (tmp);
819   else
820     {
821       gimple_seq body_seq;
822 
823       /* This case is for nested functions.  We need to expose the locals
824            they create.  */
825       body_seq = gimple_body (current_function_decl);
826       declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
827     }
828 }
829 
830 
831 
832 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
833    nodes that are referenced more than once in GENERIC functions.  This is
834    necessary because gimplification (translation into GIMPLE) is performed
835    by modifying tree nodes in-place, so gimplication of a shared node in a
836    first context could generate an invalid GIMPLE form in a second context.
837 
838    This is achieved with a simple mark/copy/unmark algorithm that walks the
839    GENERIC representation top-down, marks nodes with TREE_VISITED the first
840    time it encounters them, duplicates them if they already have TREE_VISITED
841    set, and finally removes the TREE_VISITED marks it has set.
842 
843    The algorithm works only at the function level, i.e. it generates a GENERIC
844    representation of a function with no nodes shared within the function when
845    passed a GENERIC function (except for nodes that are allowed to be shared).
846 
847    At the global level, it is also necessary to unshare tree nodes that are
848    referenced in more than one function, for the same aforementioned reason.
849    This requires some cooperation from the front-end.  There are 2 strategies:
850 
851      1. Manual unsharing.  The front-end needs to call unshare_expr on every
852         expression that might end up being shared across functions.
853 
854      2. Deep unsharing.  This is an extension of regular unsharing.  Instead
855         of calling unshare_expr on expressions that might be shared across
856         functions, the front-end pre-marks them with TREE_VISITED.  This will
857         ensure that they are unshared on the first reference within functions
858         when the regular unsharing algorithm runs.  The counterpart is that
859         this algorithm must look deeper than for manual unsharing, which is
860         specified by LANG_HOOKS_DEEP_UNSHARING.
861 
862   If there are only few specific cases of node sharing across functions, it is
863   probably easier for a front-end to unshare the expressions manually.  On the
864   contrary, if the expressions generated at the global level are as widespread
865   as expressions generated within functions, deep unsharing is very likely the
866   way to go.  */
867 
868 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
869    These nodes model computations that must be done once.  If we were to
870    unshare something like SAVE_EXPR(i++), the gimplification process would
871    create wrong code.  However, if DATA is non-null, it must hold a pointer
872    set that is used to unshare the subtrees of these nodes.  */
873 
874 static tree
mostly_copy_tree_r(tree * tp,int * walk_subtrees,void * data)875 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
876 {
877   tree t = *tp;
878   enum tree_code code = TREE_CODE (t);
879 
880   /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
881      copy their subtrees if we can make sure to do it only once.  */
882   if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
883     {
884       if (data && !((hash_set<tree> *)data)->add (t))
885           ;
886       else
887           *walk_subtrees = 0;
888     }
889 
890   /* Stop at types, decls, constants like copy_tree_r.  */
891   else if (TREE_CODE_CLASS (code) == tcc_type
892              || TREE_CODE_CLASS (code) == tcc_declaration
893              || TREE_CODE_CLASS (code) == tcc_constant)
894     *walk_subtrees = 0;
895 
896   /* Cope with the statement expression extension.  */
897   else if (code == STATEMENT_LIST)
898     ;
899 
900   /* Leave the bulk of the work to copy_tree_r itself.  */
901   else
902     copy_tree_r (tp, walk_subtrees, NULL);
903 
904   return NULL_TREE;
905 }
906 
907 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
908    If *TP has been visited already, then *TP is deeply copied by calling
909    mostly_copy_tree_r.  DATA is passed to mostly_copy_tree_r unmodified.  */
910 
911 static tree
copy_if_shared_r(tree * tp,int * walk_subtrees,void * data)912 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
913 {
914   tree t = *tp;
915   enum tree_code code = TREE_CODE (t);
916 
917   /* Skip types, decls, and constants.  But we do want to look at their
918      types and the bounds of types.  Mark them as visited so we properly
919      unmark their subtrees on the unmark pass.  If we've already seen them,
920      don't look down further.  */
921   if (TREE_CODE_CLASS (code) == tcc_type
922       || TREE_CODE_CLASS (code) == tcc_declaration
923       || TREE_CODE_CLASS (code) == tcc_constant)
924     {
925       if (TREE_VISITED (t))
926           *walk_subtrees = 0;
927       else
928           TREE_VISITED (t) = 1;
929     }
930 
931   /* If this node has been visited already, unshare it and don't look
932      any deeper.  */
933   else if (TREE_VISITED (t))
934     {
935       walk_tree (tp, mostly_copy_tree_r, data, NULL);
936       *walk_subtrees = 0;
937     }
938 
939   /* Otherwise, mark the node as visited and keep looking.  */
940   else
941     TREE_VISITED (t) = 1;
942 
943   return NULL_TREE;
944 }
945 
946 /* Unshare most of the shared trees rooted at *TP.  DATA is passed to the
947    copy_if_shared_r callback unmodified.  */
948 
949 void
copy_if_shared(tree * tp,void * data)950 copy_if_shared (tree *tp, void *data)
951 {
952   walk_tree (tp, copy_if_shared_r, data, NULL);
953 }
954 
955 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
956    any nested functions.  */
957 
958 static void
unshare_body(tree fndecl)959 unshare_body (tree fndecl)
960 {
961   struct cgraph_node *cgn = cgraph_node::get (fndecl);
962   /* If the language requires deep unsharing, we need a pointer set to make
963      sure we don't repeatedly unshare subtrees of unshareable nodes.  */
964   hash_set<tree> *visited
965     = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
966 
967   copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
968   copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
969   copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
970 
971   delete visited;
972 
973   if (cgn)
974     for (cgn = first_nested_function (cgn); cgn;
975            cgn = next_nested_function (cgn))
976       unshare_body (cgn->decl);
977 }
978 
979 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
980    Subtrees are walked until the first unvisited node is encountered.  */
981 
982 static tree
unmark_visited_r(tree * tp,int * walk_subtrees,void * data ATTRIBUTE_UNUSED)983 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
984 {
985   tree t = *tp;
986 
987   /* If this node has been visited, unmark it and keep looking.  */
988   if (TREE_VISITED (t))
989     TREE_VISITED (t) = 0;
990 
991   /* Otherwise, don't look any deeper.  */
992   else
993     *walk_subtrees = 0;
994 
995   return NULL_TREE;
996 }
997 
998 /* Unmark the visited trees rooted at *TP.  */
999 
1000 static inline void
unmark_visited(tree * tp)1001 unmark_visited (tree *tp)
1002 {
1003   walk_tree (tp, unmark_visited_r, NULL, NULL);
1004 }
1005 
1006 /* Likewise, but mark all trees as not visited.  */
1007 
1008 static void
unvisit_body(tree fndecl)1009 unvisit_body (tree fndecl)
1010 {
1011   struct cgraph_node *cgn = cgraph_node::get (fndecl);
1012 
1013   unmark_visited (&DECL_SAVED_TREE (fndecl));
1014   unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
1015   unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
1016 
1017   if (cgn)
1018     for (cgn = first_nested_function (cgn);
1019            cgn; cgn = next_nested_function (cgn))
1020       unvisit_body (cgn->decl);
1021 }
1022 
1023 /* Unconditionally make an unshared copy of EXPR.  This is used when using
1024    stored expressions which span multiple functions, such as BINFO_VTABLE,
1025    as the normal unsharing process can't tell that they're shared.  */
1026 
1027 tree
unshare_expr(tree expr)1028 unshare_expr (tree expr)
1029 {
1030   walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1031   return expr;
1032 }
1033 
1034 /* Worker for unshare_expr_without_location.  */
1035 
1036 static tree
prune_expr_location(tree * tp,int * walk_subtrees,void *)1037 prune_expr_location (tree *tp, int *walk_subtrees, void *)
1038 {
1039   if (EXPR_P (*tp))
1040     SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
1041   else
1042     *walk_subtrees = 0;
1043   return NULL_TREE;
1044 }
1045 
1046 /* Similar to unshare_expr but also prune all expression locations
1047    from EXPR.  */
1048 
1049 tree
unshare_expr_without_location(tree expr)1050 unshare_expr_without_location (tree expr)
1051 {
1052   walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
1053   if (EXPR_P (expr))
1054     walk_tree (&expr, prune_expr_location, NULL, NULL);
1055   return expr;
1056 }
1057 
1058 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
1059    one, OR_ELSE otherwise.  The location of a STATEMENT_LISTs
1060    comprising at least one DEBUG_BEGIN_STMT followed by exactly one
1061    EXPR is the location of the EXPR.  */
1062 
1063 static location_t
rexpr_location(tree expr,location_t or_else=UNKNOWN_LOCATION)1064 rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION)
1065 {
1066   if (!expr)
1067     return or_else;
1068 
1069   if (EXPR_HAS_LOCATION (expr))
1070     return EXPR_LOCATION (expr);
1071 
1072   if (TREE_CODE (expr) != STATEMENT_LIST)
1073     return or_else;
1074 
1075   tree_stmt_iterator i = tsi_start (expr);
1076 
1077   bool found = false;
1078   while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
1079     {
1080       found = true;
1081       tsi_next (&i);
1082     }
1083 
1084   if (!found || !tsi_one_before_end_p (i))
1085     return or_else;
1086 
1087   return rexpr_location (tsi_stmt (i), or_else);
1088 }
1089 
1090 /* Return TRUE iff EXPR (maybe recursively) has a location; see
1091    rexpr_location for the potential recursion.  */
1092 
1093 static inline bool
rexpr_has_location(tree expr)1094 rexpr_has_location (tree expr)
1095 {
1096   return rexpr_location (expr) != UNKNOWN_LOCATION;
1097 }
1098 
1099 
1100 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
1101    contain statements and have a value.  Assign its value to a temporary
1102    and give it void_type_node.  Return the temporary, or NULL_TREE if
1103    WRAPPER was already void.  */
1104 
1105 tree
voidify_wrapper_expr(tree wrapper,tree temp)1106 voidify_wrapper_expr (tree wrapper, tree temp)
1107 {
1108   tree type = TREE_TYPE (wrapper);
1109   if (type && !VOID_TYPE_P (type))
1110     {
1111       tree *p;
1112 
1113       /* Set p to point to the body of the wrapper.  Loop until we find
1114            something that isn't a wrapper.  */
1115       for (p = &wrapper; p && *p; )
1116           {
1117             switch (TREE_CODE (*p))
1118               {
1119               case BIND_EXPR:
1120                 TREE_SIDE_EFFECTS (*p) = 1;
1121                 TREE_TYPE (*p) = void_type_node;
1122                 /* For a BIND_EXPR, the body is operand 1.  */
1123                 p = &BIND_EXPR_BODY (*p);
1124                 break;
1125 
1126               case CLEANUP_POINT_EXPR:
1127               case TRY_FINALLY_EXPR:
1128               case TRY_CATCH_EXPR:
1129                 TREE_SIDE_EFFECTS (*p) = 1;
1130                 TREE_TYPE (*p) = void_type_node;
1131                 p = &TREE_OPERAND (*p, 0);
1132                 break;
1133 
1134               case STATEMENT_LIST:
1135                 {
1136                     tree_stmt_iterator i = tsi_last (*p);
1137                     TREE_SIDE_EFFECTS (*p) = 1;
1138                     TREE_TYPE (*p) = void_type_node;
1139                     p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
1140                 }
1141                 break;
1142 
1143               case COMPOUND_EXPR:
1144                 /* Advance to the last statement.  Set all container types to
1145                      void.  */
1146                 for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
1147                     {
1148                       TREE_SIDE_EFFECTS (*p) = 1;
1149                       TREE_TYPE (*p) = void_type_node;
1150                     }
1151                 break;
1152 
1153               case TRANSACTION_EXPR:
1154                 TREE_SIDE_EFFECTS (*p) = 1;
1155                 TREE_TYPE (*p) = void_type_node;
1156                 p = &TRANSACTION_EXPR_BODY (*p);
1157                 break;
1158 
1159               default:
1160                 /* Assume that any tree upon which voidify_wrapper_expr is
1161                      directly called is a wrapper, and that its body is op0.  */
1162                 if (p == &wrapper)
1163                     {
1164                       TREE_SIDE_EFFECTS (*p) = 1;
1165                       TREE_TYPE (*p) = void_type_node;
1166                       p = &TREE_OPERAND (*p, 0);
1167                       break;
1168                     }
1169                 goto out;
1170               }
1171           }
1172 
1173     out:
1174       if (p == NULL || IS_EMPTY_STMT (*p))
1175           temp = NULL_TREE;
1176       else if (temp)
1177           {
1178             /* The wrapper is on the RHS of an assignment that we're pushing
1179                down.  */
1180             gcc_assert (TREE_CODE (temp) == INIT_EXPR
1181                           || TREE_CODE (temp) == MODIFY_EXPR);
1182             TREE_OPERAND (temp, 1) = *p;
1183             *p = temp;
1184           }
1185       else
1186           {
1187             temp = create_tmp_var (type, "retval");
1188             *p = build2 (INIT_EXPR, type, temp, *p);
1189           }
1190 
1191       return temp;
1192     }
1193 
1194   return NULL_TREE;
1195 }
1196 
1197 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
1198    a temporary through which they communicate.  */
1199 
1200 static void
build_stack_save_restore(gcall ** save,gcall ** restore)1201 build_stack_save_restore (gcall **save, gcall **restore)
1202 {
1203   tree tmp_var;
1204 
1205   *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
1206   tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
1207   gimple_call_set_lhs (*save, tmp_var);
1208 
1209   *restore
1210     = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
1211                                1, tmp_var);
1212 }
1213 
1214 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable.  */
1215 
1216 static tree
build_asan_poison_call_expr(tree decl)1217 build_asan_poison_call_expr (tree decl)
1218 {
1219   /* Do not poison variables that have size equal to zero.  */
1220   tree unit_size = DECL_SIZE_UNIT (decl);
1221   if (zerop (unit_size))
1222     return NULL_TREE;
1223 
1224   tree base = build_fold_addr_expr (decl);
1225 
1226   return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
1227                                                void_type_node, 3,
1228                                                build_int_cst (integer_type_node,
1229                                                                   ASAN_MARK_POISON),
1230                                                base, unit_size);
1231 }
1232 
1233 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
1234    on POISON flag, shadow memory of a DECL variable.  The call will be
1235    put on location identified by IT iterator, where BEFORE flag drives
1236    position where the stmt will be put.  */
1237 
1238 static void
asan_poison_variable(tree decl,bool poison,gimple_stmt_iterator * it,bool before)1239 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
1240                           bool before)
1241 {
1242   tree unit_size = DECL_SIZE_UNIT (decl);
1243   tree base = build_fold_addr_expr (decl);
1244 
1245   /* Do not poison variables that have size equal to zero.  */
1246   if (zerop (unit_size))
1247     return;
1248 
1249   /* It's necessary to have all stack variables aligned to ASAN granularity
1250      bytes.  */
1251   gcc_assert (!hwasan_sanitize_p () || hwasan_sanitize_stack_p ());
1252   unsigned shadow_granularity
1253     = hwasan_sanitize_p () ? HWASAN_TAG_GRANULE_SIZE : ASAN_SHADOW_GRANULARITY;
1254   if (DECL_ALIGN_UNIT (decl) <= shadow_granularity)
1255     SET_DECL_ALIGN (decl, BITS_PER_UNIT * shadow_granularity);
1256 
1257   HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
1258 
1259   gimple *g
1260     = gimple_build_call_internal (IFN_ASAN_MARK, 3,
1261                                           build_int_cst (integer_type_node, flags),
1262                                           base, unit_size);
1263 
1264   if (before)
1265     gsi_insert_before (it, g, GSI_NEW_STMT);
1266   else
1267     gsi_insert_after (it, g, GSI_NEW_STMT);
1268 }
1269 
1270 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
1271    either poisons or unpoisons a DECL.  Created statement is appended
1272    to SEQ_P gimple sequence.  */
1273 
1274 static void
asan_poison_variable(tree decl,bool poison,gimple_seq * seq_p)1275 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
1276 {
1277   gimple_stmt_iterator it = gsi_last (*seq_p);
1278   bool before = false;
1279 
1280   if (gsi_end_p (it))
1281     before = true;
1282 
1283   asan_poison_variable (decl, poison, &it, before);
1284 }
1285 
1286 /* Sort pair of VAR_DECLs A and B by DECL_UID.  */
1287 
1288 static int
sort_by_decl_uid(const void * a,const void * b)1289 sort_by_decl_uid (const void *a, const void *b)
1290 {
1291   const tree *t1 = (const tree *)a;
1292   const tree *t2 = (const tree *)b;
1293 
1294   int uid1 = DECL_UID (*t1);
1295   int uid2 = DECL_UID (*t2);
1296 
1297   if (uid1 < uid2)
1298     return -1;
1299   else if (uid1 > uid2)
1300     return 1;
1301   else
1302     return 0;
1303 }
1304 
1305 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
1306    depending on POISON flag.  Created statement is appended
1307    to SEQ_P gimple sequence.  */
1308 
1309 static void
asan_poison_variables(hash_set<tree> * variables,bool poison,gimple_seq * seq_p)1310 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
1311 {
1312   unsigned c = variables->elements ();
1313   if (c == 0)
1314     return;
1315 
1316   auto_vec<tree> sorted_variables (c);
1317 
1318   for (hash_set<tree>::iterator it = variables->begin ();
1319        it != variables->end (); ++it)
1320     sorted_variables.safe_push (*it);
1321 
1322   sorted_variables.qsort (sort_by_decl_uid);
1323 
1324   unsigned i;
1325   tree var;
1326   FOR_EACH_VEC_ELT (sorted_variables, i, var)
1327     {
1328       asan_poison_variable (var, poison, seq_p);
1329 
1330       /* Add use_after_scope_memory attribute for the variable in order
1331            to prevent re-written into SSA.  */
1332       if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
1333                                    DECL_ATTRIBUTES (var)))
1334           DECL_ATTRIBUTES (var)
1335             = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
1336                            integer_one_node,
1337                            DECL_ATTRIBUTES (var));
1338     }
1339 }
1340 
1341 /* Gimplify a BIND_EXPR.  Just voidify and recurse.  */
1342 
1343 static enum gimplify_status
gimplify_bind_expr(tree * expr_p,gimple_seq * pre_p)1344 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
1345 {
1346   tree bind_expr = *expr_p;
1347   bool old_keep_stack = gimplify_ctxp->keep_stack;
1348   bool old_save_stack = gimplify_ctxp->save_stack;
1349   tree t;
1350   gbind *bind_stmt;
1351   gimple_seq body, cleanup;
1352   gcall *stack_save;
1353   location_t start_locus = 0, end_locus = 0;
1354   tree ret_clauses = NULL;
1355 
1356   tree temp = voidify_wrapper_expr (bind_expr, NULL);
1357 
1358   /* Mark variables seen in this bind expr.  */
1359   for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1360     {
1361       if (VAR_P (t))
1362           {
1363             struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
1364 
1365             /* Mark variable as local.  */
1366             if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t))
1367               {
1368                 if (! DECL_SEEN_IN_BIND_EXPR_P (t)
1369                       || splay_tree_lookup (ctx->variables,
1370                                                   (splay_tree_key) t) == NULL)
1371                     {
1372                       int flag = GOVD_LOCAL;
1373                       if (ctx->region_type == ORT_SIMD
1374                           && TREE_ADDRESSABLE (t)
1375                           && !TREE_STATIC (t))
1376                         {
1377                           if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST)
1378                               ctx->add_safelen1 = true;
1379                           else
1380                               flag = GOVD_PRIVATE;
1381                         }
1382                       omp_add_variable (ctx, t, flag | GOVD_SEEN);
1383                     }
1384                 /* Static locals inside of target construct or offloaded
1385                      routines need to be "omp declare target".  */
1386                 if (TREE_STATIC (t))
1387                     for (; ctx; ctx = ctx->outer_context)
1388                       if ((ctx->region_type & ORT_TARGET) != 0)
1389                         {
1390                           if (!lookup_attribute ("omp declare target",
1391                                                        DECL_ATTRIBUTES (t)))
1392                               {
1393                                 tree id = get_identifier ("omp declare target");
1394                                 DECL_ATTRIBUTES (t)
1395                                   = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
1396                                 varpool_node *node = varpool_node::get (t);
1397                                 if (node)
1398                                   {
1399                                     node->offloadable = 1;
1400                                     if (ENABLE_OFFLOADING && !DECL_EXTERNAL (t))
1401                                         {
1402                                           g->have_offload = true;
1403                                           if (!in_lto_p)
1404                                             vec_safe_push (offload_vars, t);
1405                                         }
1406                                   }
1407                               }
1408                           break;
1409                         }
1410               }
1411 
1412             DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
1413 
1414             if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
1415               cfun->has_local_explicit_reg_vars = true;
1416           }
1417     }
1418 
1419   bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
1420                                          BIND_EXPR_BLOCK (bind_expr));
1421   gimple_push_bind_expr (bind_stmt);
1422 
1423   gimplify_ctxp->keep_stack = false;
1424   gimplify_ctxp->save_stack = false;
1425 
1426   /* Gimplify the body into the GIMPLE_BIND tuple's body.  */
1427   body = NULL;
1428   gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
1429   gimple_bind_set_body (bind_stmt, body);
1430 
1431   /* Source location wise, the cleanup code (stack_restore and clobbers)
1432      belongs to the end of the block, so propagate what we have.  The
1433      stack_save operation belongs to the beginning of block, which we can
1434      infer from the bind_expr directly if the block has no explicit
1435      assignment.  */
1436   if (BIND_EXPR_BLOCK (bind_expr))
1437     {
1438       end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1439       start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
1440     }
1441   if (start_locus == 0)
1442     start_locus = EXPR_LOCATION (bind_expr);
1443 
1444   cleanup = NULL;
1445   stack_save = NULL;
1446 
1447   /* If the code both contains VLAs and calls alloca, then we cannot reclaim
1448      the stack space allocated to the VLAs.  */
1449   if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
1450     {
1451       gcall *stack_restore;
1452 
1453       /* Save stack on entry and restore it on exit.  Add a try_finally
1454            block to achieve this.  */
1455       build_stack_save_restore (&stack_save, &stack_restore);
1456 
1457       gimple_set_location (stack_save, start_locus);
1458       gimple_set_location (stack_restore, end_locus);
1459 
1460       gimplify_seq_add_stmt (&cleanup, stack_restore);
1461     }
1462 
1463   /* Add clobbers for all variables that go out of scope.  */
1464   for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
1465     {
1466       if (VAR_P (t)
1467             && !is_global_var (t)
1468             && DECL_CONTEXT (t) == current_function_decl)
1469           {
1470             if (!DECL_HARD_REGISTER (t)
1471                 && !TREE_THIS_VOLATILE (t)
1472                 && !DECL_HAS_VALUE_EXPR_P (t)
1473                 /* Only care for variables that have to be in memory.  Others
1474                      will be rewritten into SSA names, hence moved to the
1475                      top-level.  */
1476                 && !is_gimple_reg (t)
1477                 && flag_stack_reuse != SR_NONE)
1478               {
1479                 tree clobber = build_clobber (TREE_TYPE (t), CLOBBER_EOL);
1480                 gimple *clobber_stmt;
1481                 clobber_stmt = gimple_build_assign (t, clobber);
1482                 gimple_set_location (clobber_stmt, end_locus);
1483                 gimplify_seq_add_stmt (&cleanup, clobber_stmt);
1484               }
1485 
1486             if (flag_openacc && oacc_declare_returns != NULL)
1487               {
1488                 tree key = t;
1489                 if (DECL_HAS_VALUE_EXPR_P (key))
1490                     {
1491                       key = DECL_VALUE_EXPR (key);
1492                       if (TREE_CODE (key) == INDIRECT_REF)
1493                         key = TREE_OPERAND (key, 0);
1494                     }
1495                 tree *c = oacc_declare_returns->get (key);
1496                 if (c != NULL)
1497                     {
1498                       if (ret_clauses)
1499                         OMP_CLAUSE_CHAIN (*c) = ret_clauses;
1500 
1501                       ret_clauses = unshare_expr (*c);
1502 
1503                       oacc_declare_returns->remove (key);
1504 
1505                       if (oacc_declare_returns->is_empty ())
1506                         {
1507                           delete oacc_declare_returns;
1508                           oacc_declare_returns = NULL;
1509                         }
1510                     }
1511               }
1512           }
1513 
1514       if (asan_poisoned_variables != NULL
1515             && asan_poisoned_variables->contains (t))
1516           {
1517             asan_poisoned_variables->remove (t);
1518             asan_poison_variable (t, true, &cleanup);
1519           }
1520 
1521       if (gimplify_ctxp->live_switch_vars != NULL
1522             && gimplify_ctxp->live_switch_vars->contains (t))
1523           gimplify_ctxp->live_switch_vars->remove (t);
1524     }
1525 
1526   if (ret_clauses)
1527     {
1528       gomp_target *stmt;
1529       gimple_stmt_iterator si = gsi_start (cleanup);
1530 
1531       stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
1532                                               ret_clauses);
1533       gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
1534     }
1535 
1536   if (cleanup)
1537     {
1538       gtry *gs;
1539       gimple_seq new_body;
1540 
1541       new_body = NULL;
1542       gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
1543                                    GIMPLE_TRY_FINALLY);
1544 
1545       if (stack_save)
1546           gimplify_seq_add_stmt (&new_body, stack_save);
1547       gimplify_seq_add_stmt (&new_body, gs);
1548       gimple_bind_set_body (bind_stmt, new_body);
1549     }
1550 
1551   /* keep_stack propagates all the way up to the outermost BIND_EXPR.  */
1552   if (!gimplify_ctxp->keep_stack)
1553     gimplify_ctxp->keep_stack = old_keep_stack;
1554   gimplify_ctxp->save_stack = old_save_stack;
1555 
1556   gimple_pop_bind_expr ();
1557 
1558   gimplify_seq_add_stmt (pre_p, bind_stmt);
1559 
1560   if (temp)
1561     {
1562       *expr_p = temp;
1563       return GS_OK;
1564     }
1565 
1566   *expr_p = NULL_TREE;
1567   return GS_ALL_DONE;
1568 }
1569 
1570 /* Maybe add early return predict statement to PRE_P sequence.  */
1571 
1572 static void
maybe_add_early_return_predict_stmt(gimple_seq * pre_p)1573 maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
1574 {
1575   /* If we are not in a conditional context, add PREDICT statement.  */
1576   if (gimple_conditional_context ())
1577     {
1578       gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
1579                                                         NOT_TAKEN);
1580       gimplify_seq_add_stmt (pre_p, predict);
1581     }
1582 }
1583 
1584 /* Gimplify a RETURN_EXPR.  If the expression to be returned is not a
1585    GIMPLE value, it is assigned to a new temporary and the statement is
1586    re-written to return the temporary.
1587 
1588    PRE_P points to the sequence where side effects that must happen before
1589    STMT should be stored.  */
1590 
1591 static enum gimplify_status
gimplify_return_expr(tree stmt,gimple_seq * pre_p)1592 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
1593 {
1594   greturn *ret;
1595   tree ret_expr = TREE_OPERAND (stmt, 0);
1596   tree result_decl, result;
1597 
1598   if (ret_expr == error_mark_node)
1599     return GS_ERROR;
1600 
1601   if (!ret_expr
1602       || TREE_CODE (ret_expr) == RESULT_DECL)
1603     {
1604       maybe_add_early_return_predict_stmt (pre_p);
1605       greturn *ret = gimple_build_return (ret_expr);
1606       copy_warning (ret, stmt);
1607       gimplify_seq_add_stmt (pre_p, ret);
1608       return GS_ALL_DONE;
1609     }
1610 
1611   if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
1612     result_decl = NULL_TREE;
1613   else if (TREE_CODE (ret_expr) == COMPOUND_EXPR)
1614     {
1615       /* Used in C++ for handling EH cleanup of the return value if a local
1616            cleanup throws.  Assume the front-end knows what it's doing.  */
1617       result_decl = DECL_RESULT (current_function_decl);
1618       /* But crash if we end up trying to modify ret_expr below.  */
1619       ret_expr = NULL_TREE;
1620     }
1621   else
1622     {
1623       result_decl = TREE_OPERAND (ret_expr, 0);
1624 
1625       /* See through a return by reference.  */
1626       if (TREE_CODE (result_decl) == INDIRECT_REF)
1627           result_decl = TREE_OPERAND (result_decl, 0);
1628 
1629       gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
1630                        || TREE_CODE (ret_expr) == INIT_EXPR)
1631                       && TREE_CODE (result_decl) == RESULT_DECL);
1632     }
1633 
1634   /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
1635      Recall that aggregate_value_p is FALSE for any aggregate type that is
1636      returned in registers.  If we're returning values in registers, then
1637      we don't want to extend the lifetime of the RESULT_DECL, particularly
1638      across another call.  In addition, for those aggregates for which
1639      hard_function_value generates a PARALLEL, we'll die during normal
1640      expansion of structure assignments; there's special code in expand_return
1641      to handle this case that does not exist in expand_expr.  */
1642   if (!result_decl)
1643     result = NULL_TREE;
1644   else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
1645     {
1646       if (!poly_int_tree_p (DECL_SIZE (result_decl)))
1647           {
1648             if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
1649               gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
1650             /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
1651                should be effectively allocated by the caller, i.e. all calls to
1652                this function must be subject to the Return Slot Optimization.  */
1653             gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
1654             gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
1655           }
1656       result = result_decl;
1657     }
1658   else if (gimplify_ctxp->return_temp)
1659     result = gimplify_ctxp->return_temp;
1660   else
1661     {
1662       result = create_tmp_reg (TREE_TYPE (result_decl));
1663 
1664       /* ??? With complex control flow (usually involving abnormal edges),
1665            we can wind up warning about an uninitialized value for this.  Due
1666            to how this variable is constructed and initialized, this is never
1667            true.  Give up and never warn.  */
1668       suppress_warning (result, OPT_Wuninitialized);
1669 
1670       gimplify_ctxp->return_temp = result;
1671     }
1672 
1673   /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
1674      Then gimplify the whole thing.  */
1675   if (result != result_decl)
1676     TREE_OPERAND (ret_expr, 0) = result;
1677 
1678   gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
1679 
1680   maybe_add_early_return_predict_stmt (pre_p);
1681   ret = gimple_build_return (result);
1682   copy_warning (ret, stmt);
1683   gimplify_seq_add_stmt (pre_p, ret);
1684 
1685   return GS_ALL_DONE;
1686 }
1687 
1688 /* Gimplify a variable-length array DECL.  */
1689 
1690 static void
gimplify_vla_decl(tree decl,gimple_seq * seq_p)1691 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
1692 {
1693   /* This is a variable-sized decl.  Simplify its size and mark it
1694      for deferred expansion.  */
1695   tree t, addr, ptr_type;
1696 
1697   gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
1698   gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
1699 
1700   /* Don't mess with a DECL_VALUE_EXPR set by the front-end.  */
1701   if (DECL_HAS_VALUE_EXPR_P (decl))
1702     return;
1703 
1704   /* All occurrences of this decl in final gimplified code will be
1705      replaced by indirection.  Setting DECL_VALUE_EXPR does two
1706      things: First, it lets the rest of the gimplifier know what
1707      replacement to use.  Second, it lets the debug info know
1708      where to find the value.  */
1709   ptr_type = build_pointer_type (TREE_TYPE (decl));
1710   addr = create_tmp_var (ptr_type, get_name (decl));
1711   DECL_IGNORED_P (addr) = 0;
1712   t = build_fold_indirect_ref (addr);
1713   TREE_THIS_NOTRAP (t) = 1;
1714   SET_DECL_VALUE_EXPR (decl, t);
1715   DECL_HAS_VALUE_EXPR_P (decl) = 1;
1716 
1717   t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
1718                                     max_int_size_in_bytes (TREE_TYPE (decl)));
1719   /* The call has been built for a variable-sized object.  */
1720   CALL_ALLOCA_FOR_VAR_P (t) = 1;
1721   t = fold_convert (ptr_type, t);
1722   t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
1723 
1724   gimplify_and_add (t, seq_p);
1725 
1726   /* Record the dynamic allocation associated with DECL if requested.  */
1727   if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)
1728     record_dynamic_alloc (decl);
1729 }
1730 
1731 /* A helper function to be called via walk_tree.  Mark all labels under *TP
1732    as being forced.  To be called for DECL_INITIAL of static variables.  */
1733 
1734 static tree
force_labels_r(tree * tp,int * walk_subtrees,void * data ATTRIBUTE_UNUSED)1735 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
1736 {
1737   if (TYPE_P (*tp))
1738     *walk_subtrees = 0;
1739   if (TREE_CODE (*tp) == LABEL_DECL)
1740     {
1741       FORCED_LABEL (*tp) = 1;
1742       cfun->has_forced_label_in_static = 1;
1743     }
1744 
1745   return NULL_TREE;
1746 }
1747 
1748 /* Generate an initialization to automatic variable DECL based on INIT_TYPE.
1749    Build a call to internal const function DEFERRED_INIT:
1750    1st argument: SIZE of the DECL;
1751    2nd argument: INIT_TYPE;
1752    3rd argument: NAME of the DECL;
1753 
1754    as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, NAME of the DECL).  */
1755 
1756 static void
gimple_add_init_for_auto_var(tree decl,enum auto_init_type init_type,gimple_seq * seq_p)1757 gimple_add_init_for_auto_var (tree decl,
1758                                     enum auto_init_type init_type,
1759                                     gimple_seq *seq_p)
1760 {
1761   gcc_assert (auto_var_p (decl));
1762   gcc_assert (init_type > AUTO_INIT_UNINITIALIZED);
1763   location_t loc = EXPR_LOCATION (decl);
1764   tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl));
1765 
1766   tree init_type_node
1767     = build_int_cst (integer_type_node, (int) init_type);
1768 
1769   tree decl_name = NULL_TREE;
1770   if (DECL_NAME (decl))
1771 
1772     decl_name = build_string_literal (IDENTIFIER_LENGTH (DECL_NAME (decl)) + 1,
1773                                               IDENTIFIER_POINTER (DECL_NAME (decl)));
1774 
1775   else
1776     {
1777       char *decl_name_anonymous = xasprintf ("D.%u", DECL_UID (decl));
1778       decl_name = build_string_literal (strlen (decl_name_anonymous) + 1,
1779                                                   decl_name_anonymous);
1780       free (decl_name_anonymous);
1781     }
1782 
1783   tree call = build_call_expr_internal_loc (loc, IFN_DEFERRED_INIT,
1784                                                       TREE_TYPE (decl), 3,
1785                                                       decl_size, init_type_node,
1786                                                       decl_name);
1787 
1788   gimplify_assign (decl, call, seq_p);
1789 }
1790 
1791 /* Generate padding initialization for automatic vairable DECL.
1792    C guarantees that brace-init with fewer initializers than members
1793    aggregate will initialize the rest of the aggregate as-if it were
1794    static initialization.  In turn static initialization guarantees
1795    that padding is initialized to zero. So, we always initialize paddings
1796    to zeroes regardless INIT_TYPE.
1797    To do the padding initialization, we insert a call to
1798    __builtin_clear_padding (&decl, 0, for_auto_init = true).
1799    Note, we add an additional dummy argument for __builtin_clear_padding,
1800    'for_auto_init' to distinguish whether this call is for automatic
1801    variable initialization or not.
1802    */
1803 static void
gimple_add_padding_init_for_auto_var(tree decl,bool is_vla,gimple_seq * seq_p)1804 gimple_add_padding_init_for_auto_var (tree decl, bool is_vla,
1805                                               gimple_seq *seq_p)
1806 {
1807   tree addr_of_decl = NULL_TREE;
1808   tree fn = builtin_decl_explicit (BUILT_IN_CLEAR_PADDING);
1809 
1810   if (is_vla)
1811     {
1812       /* The temporary address variable for this vla should be
1813            created in gimplify_vla_decl.  */
1814       gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
1815       gcc_assert (TREE_CODE (DECL_VALUE_EXPR (decl)) == INDIRECT_REF);
1816       addr_of_decl = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
1817     }
1818   else
1819     {
1820       mark_addressable (decl);
1821       addr_of_decl = build_fold_addr_expr (decl);
1822     }
1823 
1824   gimple *call = gimple_build_call (fn, 2, addr_of_decl,
1825                                             build_one_cst (TREE_TYPE (addr_of_decl)));
1826   gimplify_seq_add_stmt (seq_p, call);
1827 }
1828 
1829 /* Return true if the DECL need to be automaticly initialized by the
1830    compiler.  */
1831 static bool
is_var_need_auto_init(tree decl)1832 is_var_need_auto_init (tree decl)
1833 {
1834   if (auto_var_p (decl)
1835       && (TREE_CODE (decl) != VAR_DECL
1836             || !DECL_HARD_REGISTER (decl))
1837       && (flag_auto_var_init > AUTO_INIT_UNINITIALIZED)
1838       && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl)))
1839       && !OPAQUE_TYPE_P (TREE_TYPE (decl))
1840       && !is_empty_type (TREE_TYPE (decl)))
1841     return true;
1842   return false;
1843 }
1844 
1845 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
1846    and initialization explicit.  */
1847 
1848 static enum gimplify_status
gimplify_decl_expr(tree * stmt_p,gimple_seq * seq_p)1849 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
1850 {
1851   tree stmt = *stmt_p;
1852   tree decl = DECL_EXPR_DECL (stmt);
1853 
1854   *stmt_p = NULL_TREE;
1855 
1856   if (TREE_TYPE (decl) == error_mark_node)
1857     return GS_ERROR;
1858 
1859   if ((TREE_CODE (decl) == TYPE_DECL
1860        || VAR_P (decl))
1861       && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
1862     {
1863       gimplify_type_sizes (TREE_TYPE (decl), seq_p);
1864       if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
1865           gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
1866     }
1867 
1868   /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
1869      in case its size expressions contain problematic nodes like CALL_EXPR.  */
1870   if (TREE_CODE (decl) == TYPE_DECL
1871       && DECL_ORIGINAL_TYPE (decl)
1872       && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
1873     {
1874       gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
1875       if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
1876           gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
1877     }
1878 
1879   if (VAR_P (decl) && !DECL_EXTERNAL (decl))
1880     {
1881       tree init = DECL_INITIAL (decl);
1882       bool is_vla = false;
1883       /* Check whether a decl has FE created VALUE_EXPR here BEFORE
1884            gimplify_vla_decl creates VALUE_EXPR for a vla decl.
1885            If the decl has VALUE_EXPR that was created by FE (usually
1886            C++FE), it's a proxy varaible, and FE already initialized
1887            the VALUE_EXPR of it, we should not initialize it anymore.  */
1888       bool decl_had_value_expr_p = DECL_HAS_VALUE_EXPR_P (decl);
1889 
1890       poly_uint64 size;
1891       if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
1892             || (!TREE_STATIC (decl)
1893                 && flag_stack_check == GENERIC_STACK_CHECK
1894                 && maybe_gt (size,
1895                                  (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
1896           {
1897             gimplify_vla_decl (decl, seq_p);
1898             is_vla = true;
1899           }
1900 
1901       if (asan_poisoned_variables
1902             && !is_vla
1903             && TREE_ADDRESSABLE (decl)
1904             && !TREE_STATIC (decl)
1905             && !DECL_HAS_VALUE_EXPR_P (decl)
1906             && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
1907             && dbg_cnt (asan_use_after_scope)
1908             && !gimplify_omp_ctxp
1909             /* GNAT introduces temporaries to hold return values of calls in
1910                initializers of variables defined in other units, so the
1911                declaration of the variable is discarded completely.  We do not
1912                want to issue poison calls for such dropped variables.  */
1913             && (DECL_SEEN_IN_BIND_EXPR_P (decl)
1914                 || (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)))
1915           {
1916             asan_poisoned_variables->add (decl);
1917             asan_poison_variable (decl, false, seq_p);
1918             if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
1919               gimplify_ctxp->live_switch_vars->add (decl);
1920           }
1921 
1922       /* Some front ends do not explicitly declare all anonymous
1923            artificial variables.  We compensate here by declaring the
1924            variables, though it would be better if the front ends would
1925            explicitly declare them.  */
1926       if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
1927             && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
1928           gimple_add_tmp_var (decl);
1929 
1930       if (init && init != error_mark_node)
1931           {
1932             if (!TREE_STATIC (decl))
1933               {
1934                 DECL_INITIAL (decl) = NULL_TREE;
1935                 init = build2 (INIT_EXPR, void_type_node, decl, init);
1936                 gimplify_and_add (init, seq_p);
1937                 ggc_free (init);
1938                 /* Clear TREE_READONLY if we really have an initialization.  */
1939                 if (!DECL_INITIAL (decl)
1940                       && !omp_privatize_by_reference (decl))
1941                     TREE_READONLY (decl) = 0;
1942               }
1943             else
1944               /* We must still examine initializers for static variables
1945                  as they may contain a label address.  */
1946               walk_tree (&init, force_labels_r, NULL, NULL);
1947           }
1948       /* When there is no explicit initializer, if the user requested,
1949            We should insert an artifical initializer for this automatic
1950            variable.  */
1951       else if (is_var_need_auto_init (decl)
1952                  && !decl_had_value_expr_p)
1953           {
1954             gimple_add_init_for_auto_var (decl,
1955                                                   flag_auto_var_init,
1956                                                   seq_p);
1957             /* The expanding of a call to the above .DEFERRED_INIT will apply
1958                block initialization to the whole space covered by this variable.
1959                As a result, all the paddings will be initialized to zeroes
1960                for zero initialization and 0xFE byte-repeatable patterns for
1961                pattern initialization.
1962                In order to make the paddings as zeroes for pattern init, We
1963                should add a call to __builtin_clear_padding to clear the
1964                paddings to zero in compatiple with CLANG.
1965                We cannot insert this call if the variable is a gimple register
1966                since __builtin_clear_padding will take the address of the
1967                variable.  As a result, if a long double/_Complex long double
1968                variable will spilled into stack later, its padding is 0XFE.  */
1969             if (flag_auto_var_init == AUTO_INIT_PATTERN
1970                 && !is_gimple_reg (decl)
1971                 && clear_padding_type_may_have_padding_p (TREE_TYPE (decl)))
1972               gimple_add_padding_init_for_auto_var (decl, is_vla, seq_p);
1973           }
1974     }
1975 
1976   return GS_ALL_DONE;
1977 }
1978 
1979 /* Gimplify a LOOP_EXPR.  Normally this just involves gimplifying the body
1980    and replacing the LOOP_EXPR with goto, but if the loop contains an
1981    EXIT_EXPR, we need to append a label for it to jump to.  */
1982 
1983 static enum gimplify_status
gimplify_loop_expr(tree * expr_p,gimple_seq * pre_p)1984 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
1985 {
1986   tree saved_label = gimplify_ctxp->exit_label;
1987   tree start_label = create_artificial_label (UNKNOWN_LOCATION);
1988 
1989   gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
1990 
1991   gimplify_ctxp->exit_label = NULL_TREE;
1992 
1993   gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
1994 
1995   gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
1996 
1997   if (gimplify_ctxp->exit_label)
1998     gimplify_seq_add_stmt (pre_p,
1999                                  gimple_build_label (gimplify_ctxp->exit_label));
2000 
2001   gimplify_ctxp->exit_label = saved_label;
2002 
2003   *expr_p = NULL;
2004   return GS_ALL_DONE;
2005 }
2006 
2007 /* Gimplify a statement list onto a sequence.  These may be created either
2008    by an enlightened front-end, or by shortcut_cond_expr.  */
2009 
2010 static enum gimplify_status
gimplify_statement_list(tree * expr_p,gimple_seq * pre_p)2011 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
2012 {
2013   tree temp = voidify_wrapper_expr (*expr_p, NULL);
2014 
2015   tree_stmt_iterator i = tsi_start (*expr_p);
2016 
2017   while (!tsi_end_p (i))
2018     {
2019       gimplify_stmt (tsi_stmt_ptr (i), pre_p);
2020       tsi_delink (&i);
2021     }
2022 
2023   if (temp)
2024     {
2025       *expr_p = temp;
2026       return GS_OK;
2027     }
2028 
2029   return GS_ALL_DONE;
2030 }
2031 
2032 
2033 /* Emit warning for the unreachable statment STMT if needed.
2034    Return the gimple itself when the warning is emitted, otherwise
2035    return NULL.  */
2036 static gimple *
emit_warn_switch_unreachable(gimple * stmt)2037 emit_warn_switch_unreachable (gimple *stmt)
2038 {
2039   if (gimple_code (stmt) == GIMPLE_GOTO
2040       && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
2041       && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
2042   /* Don't warn for compiler-generated gotos.  These occur
2043      in Duff's devices, for example.  */
2044     return NULL;
2045   else if ((flag_auto_var_init > AUTO_INIT_UNINITIALIZED)
2046              && ((gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
2047                     || (gimple_call_builtin_p (stmt, BUILT_IN_CLEAR_PADDING)
2048                         && (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 1)))
2049                     || (is_gimple_assign (stmt)
2050                         && gimple_assign_single_p (stmt)
2051                         && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
2052                         && gimple_call_internal_p (
2053                                SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt)),
2054                                IFN_DEFERRED_INIT))))
2055   /* Don't warn for compiler-generated initializations for
2056      -ftrivial-auto-var-init.
2057      There are 3 cases:
2058           case 1: a call to .DEFERRED_INIT;
2059           case 2: a call to __builtin_clear_padding with the 2nd argument is
2060                     present and non-zero;
2061           case 3: a gimple assign store right after the call to .DEFERRED_INIT
2062                     that has the LHS of .DEFERRED_INIT as the RHS as following:
2063                       _1 = .DEFERRED_INIT (4, 2, &"i1"[0]);
2064                       i1 = _1.  */
2065     return NULL;
2066   else
2067     warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
2068                     "statement will never be executed");
2069   return stmt;
2070 }
2071 
2072 /* Callback for walk_gimple_seq.  */
2073 
2074 static tree
warn_switch_unreachable_and_auto_init_r(gimple_stmt_iterator * gsi_p,bool * handled_ops_p,struct walk_stmt_info * wi)2075 warn_switch_unreachable_and_auto_init_r (gimple_stmt_iterator *gsi_p,
2076                                                    bool *handled_ops_p,
2077                                                    struct walk_stmt_info *wi)
2078 {
2079   gimple *stmt = gsi_stmt (*gsi_p);
2080   bool unreachable_issued = wi->info != NULL;
2081 
2082   *handled_ops_p = true;
2083   switch (gimple_code (stmt))
2084     {
2085     case GIMPLE_TRY:
2086       /* A compiler-generated cleanup or a user-written try block.
2087            If it's empty, don't dive into it--that would result in
2088            worse location info.  */
2089       if (gimple_try_eval (stmt) == NULL)
2090           {
2091             if (warn_switch_unreachable && !unreachable_issued)
2092               wi->info = emit_warn_switch_unreachable (stmt);
2093 
2094             /* Stop when auto var init warning is not on.  */
2095             if (!warn_trivial_auto_var_init)
2096               return integer_zero_node;
2097           }
2098       /* Fall through.  */
2099     case GIMPLE_BIND:
2100     case GIMPLE_CATCH:
2101     case GIMPLE_EH_FILTER:
2102     case GIMPLE_TRANSACTION:
2103       /* Walk the sub-statements.  */
2104       *handled_ops_p = false;
2105       break;
2106 
2107     case GIMPLE_DEBUG:
2108       /* Ignore these.  We may generate them before declarations that
2109            are never executed.  If there's something to warn about,
2110            there will be non-debug stmts too, and we'll catch those.  */
2111       break;
2112 
2113     case GIMPLE_LABEL:
2114       /* Stop till the first Label.  */
2115       return integer_zero_node;
2116     case GIMPLE_CALL:
2117       if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2118           {
2119             *handled_ops_p = false;
2120             break;
2121           }
2122       if (warn_trivial_auto_var_init
2123             && flag_auto_var_init > AUTO_INIT_UNINITIALIZED
2124             && gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
2125           {
2126             /* Get the variable name from the 3rd argument of call.  */
2127             tree var_name = gimple_call_arg (stmt, 2);
2128             var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0);
2129             const char *var_name_str = TREE_STRING_POINTER (var_name);
2130 
2131             warning_at (gimple_location (stmt), OPT_Wtrivial_auto_var_init,
2132                           "%qs cannot be initialized with"
2133                           "%<-ftrivial-auto-var_init%>",
2134                           var_name_str);
2135             break;
2136        }
2137 
2138       /* Fall through.  */
2139     default:
2140       /* check the first "real" statement (not a decl/lexical scope/...), issue
2141            warning if needed.  */
2142       if (warn_switch_unreachable && !unreachable_issued)
2143           wi->info = emit_warn_switch_unreachable (stmt);
2144       /* Stop when auto var init warning is not on.  */
2145       if (!warn_trivial_auto_var_init)
2146           return integer_zero_node;
2147       break;
2148     }
2149   return NULL_TREE;
2150 }
2151 
2152 
2153 /* Possibly warn about unreachable statements between switch's controlling
2154    expression and the first case.  Also warn about -ftrivial-auto-var-init
2155    cannot initialize the auto variable under such situation.
2156    SEQ is the body of a switch expression.  */
2157 
2158 static void
maybe_warn_switch_unreachable_and_auto_init(gimple_seq seq)2159 maybe_warn_switch_unreachable_and_auto_init (gimple_seq seq)
2160 {
2161   if ((!warn_switch_unreachable && !warn_trivial_auto_var_init)
2162       /* This warning doesn't play well with Fortran when optimizations
2163            are on.  */
2164       || lang_GNU_Fortran ()
2165       || seq == NULL)
2166     return;
2167 
2168   struct walk_stmt_info wi;
2169 
2170   memset (&wi, 0, sizeof (wi));
2171   walk_gimple_seq (seq, warn_switch_unreachable_and_auto_init_r, NULL, &wi);
2172 }
2173 
2174 
2175 /* A label entry that pairs label and a location.  */
2176 struct label_entry
2177 {
2178   tree label;
2179   location_t loc;
2180 };
2181 
2182 /* Find LABEL in vector of label entries VEC.  */
2183 
2184 static struct label_entry *
find_label_entry(const auto_vec<struct label_entry> * vec,tree label)2185 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
2186 {
2187   unsigned int i;
2188   struct label_entry *l;
2189 
2190   FOR_EACH_VEC_ELT (*vec, i, l)
2191     if (l->label == label)
2192       return l;
2193   return NULL;
2194 }
2195 
2196 /* Return true if LABEL, a LABEL_DECL, represents a case label
2197    in a vector of labels CASES.  */
2198 
2199 static bool
case_label_p(const vec<tree> * cases,tree label)2200 case_label_p (const vec<tree> *cases, tree label)
2201 {
2202   unsigned int i;
2203   tree l;
2204 
2205   FOR_EACH_VEC_ELT (*cases, i, l)
2206     if (CASE_LABEL (l) == label)
2207       return true;
2208   return false;
2209 }
2210 
2211 /* Find the last nondebug statement in a scope STMT.  */
2212 
2213 static gimple *
last_stmt_in_scope(gimple * stmt)2214 last_stmt_in_scope (gimple *stmt)
2215 {
2216   if (!stmt)
2217     return NULL;
2218 
2219   switch (gimple_code (stmt))
2220     {
2221     case GIMPLE_BIND:
2222       {
2223           gbind *bind = as_a <gbind *> (stmt);
2224           stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
2225           return last_stmt_in_scope (stmt);
2226       }
2227 
2228     case GIMPLE_TRY:
2229       {
2230           gtry *try_stmt = as_a <gtry *> (stmt);
2231           stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
2232           gimple *last_eval = last_stmt_in_scope (stmt);
2233           if (gimple_stmt_may_fallthru (last_eval)
2234               && (last_eval == NULL
2235                     || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
2236               && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
2237             {
2238               stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
2239               return last_stmt_in_scope (stmt);
2240             }
2241           else
2242             return last_eval;
2243       }
2244 
2245     case GIMPLE_DEBUG:
2246       gcc_unreachable ();
2247 
2248     default:
2249       return stmt;
2250     }
2251 }
2252 
2253 /* Collect labels that may fall through into LABELS and return the statement
2254    preceding another case label, or a user-defined label.  Store a location
2255    useful to give warnings at *PREVLOC (usually the location of the returned
2256    statement or of its surrounding scope).  */
2257 
2258 static gimple *
collect_fallthrough_labels(gimple_stmt_iterator * gsi_p,auto_vec<struct label_entry> * labels,location_t * prevloc)2259 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
2260                                   auto_vec <struct label_entry> *labels,
2261                                   location_t *prevloc)
2262 {
2263   gimple *prev = NULL;
2264 
2265   *prevloc = UNKNOWN_LOCATION;
2266   do
2267     {
2268       if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
2269           {
2270             /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
2271                which starts on a GIMPLE_SWITCH and ends with a break label.
2272                Handle that as a single statement that can fall through.  */
2273             gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
2274             gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
2275             gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
2276             if (last
2277                 && gimple_code (first) == GIMPLE_SWITCH
2278                 && gimple_code (last) == GIMPLE_LABEL)
2279               {
2280                 tree label = gimple_label_label (as_a <glabel *> (last));
2281                 if (SWITCH_BREAK_LABEL_P (label))
2282                     {
2283                       prev = bind;
2284                       gsi_next (gsi_p);
2285                       continue;
2286                     }
2287               }
2288           }
2289       if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
2290             || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
2291           {
2292             /* Nested scope.  Only look at the last statement of
2293                the innermost scope.  */
2294             location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
2295             gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
2296             if (last)
2297               {
2298                 prev = last;
2299                 /* It might be a label without a location.  Use the
2300                      location of the scope then.  */
2301                 if (!gimple_has_location (prev))
2302                     *prevloc = bind_loc;
2303               }
2304             gsi_next (gsi_p);
2305             continue;
2306           }
2307 
2308       /* Ifs are tricky.  */
2309       if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
2310           {
2311             gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
2312             tree false_lab = gimple_cond_false_label (cond_stmt);
2313             location_t if_loc = gimple_location (cond_stmt);
2314 
2315             /* If we have e.g.
2316                  if (i > 1) goto <D.2259>; else goto D;
2317                we can't do much with the else-branch.  */
2318             if (!DECL_ARTIFICIAL (false_lab))
2319               break;
2320 
2321             /* Go on until the false label, then one step back.  */
2322             for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
2323               {
2324                 gimple *stmt = gsi_stmt (*gsi_p);
2325                 if (gimple_code (stmt) == GIMPLE_LABEL
2326                       && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
2327                     break;
2328               }
2329 
2330             /* Not found?  Oops.  */
2331             if (gsi_end_p (*gsi_p))
2332               break;
2333 
2334             /* A dead label can't fall through.  */
2335             if (!UNUSED_LABEL_P (false_lab))
2336               {
2337                 struct label_entry l = { false_lab, if_loc };
2338                 labels->safe_push (l);
2339               }
2340 
2341             /* Go to the last statement of the then branch.  */
2342             gsi_prev (gsi_p);
2343 
2344             /* if (i != 0) goto <D.1759>; else goto <D.1760>;
2345                <D.1759>:
2346                <stmt>;
2347                goto <D.1761>;
2348                <D.1760>:
2349              */
2350             if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
2351                 && !gimple_has_location (gsi_stmt (*gsi_p)))
2352               {
2353                 /* Look at the statement before, it might be
2354                      attribute fallthrough, in which case don't warn.  */
2355                 gsi_prev (gsi_p);
2356                 bool fallthru_before_dest
2357                     = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
2358                 gsi_next (gsi_p);
2359                 tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
2360                 if (!fallthru_before_dest)
2361                     {
2362                       struct label_entry l = { goto_dest, if_loc };
2363                       labels->safe_push (l);
2364                     }
2365               }
2366             /* This case is about
2367                 if (1 != 0) goto <D.2022>; else goto <D.2023>;
2368                 <D.2022>:
2369                 n = n + 1; // #1
2370                 <D.2023>:  // #2
2371                 <D.1988>:  // #3
2372                where #2 is UNUSED_LABEL_P and we want to warn about #1 falling
2373                through to #3.  So set PREV to #1.  */
2374             else if (UNUSED_LABEL_P (false_lab))
2375               prev = gsi_stmt (*gsi_p);
2376 
2377             /* And move back.  */
2378             gsi_next (gsi_p);
2379           }
2380 
2381       /* Remember the last statement.  Skip labels that are of no interest
2382            to us.  */
2383       if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2384           {
2385             tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
2386             if (find_label_entry (labels, label))
2387               prev = gsi_stmt (*gsi_p);
2388           }
2389       else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
2390           ;
2391       else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
2392           ;
2393       else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
2394           prev = gsi_stmt (*gsi_p);
2395       gsi_next (gsi_p);
2396     }
2397   while (!gsi_end_p (*gsi_p)
2398            /* Stop if we find a case or a user-defined label.  */
2399            && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
2400                || !gimple_has_location (gsi_stmt (*gsi_p))));
2401 
2402   if (prev && gimple_has_location (prev))
2403     *prevloc = gimple_location (prev);
2404   return prev;
2405 }
2406 
2407 /* Return true if the switch fallthough warning should occur.  LABEL is
2408    the label statement that we're falling through to.  */
2409 
2410 static bool
should_warn_for_implicit_fallthrough(gimple_stmt_iterator * gsi_p,tree label)2411 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
2412 {
2413   gimple_stmt_iterator gsi = *gsi_p;
2414 
2415   /* Don't warn if the label is marked with a "falls through" comment.  */
2416   if (FALLTHROUGH_LABEL_P (label))
2417     return false;
2418 
2419   /* Don't warn for non-case labels followed by a statement:
2420        case 0:
2421            foo ();
2422        label:
2423            bar ();
2424      as these are likely intentional.  */
2425   if (!case_label_p (&gimplify_ctxp->case_labels, label))
2426     {
2427       tree l;
2428       while (!gsi_end_p (gsi)
2429                && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2430                && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
2431                && !case_label_p (&gimplify_ctxp->case_labels, l))
2432           gsi_next_nondebug (&gsi);
2433       if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
2434           return false;
2435     }
2436 
2437   /* Don't warn for terminated branches, i.e. when the subsequent case labels
2438      immediately breaks.  */
2439   gsi = *gsi_p;
2440 
2441   /* Skip all immediately following labels.  */
2442   while (!gsi_end_p (gsi)
2443            && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
2444                || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
2445     gsi_next_nondebug (&gsi);
2446 
2447   /* { ... something; default:; } */
2448   if (gsi_end_p (gsi)
2449       /* { ... something; default: break; } or
2450            { ... something; default: goto L; } */
2451       || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
2452       /* { ... something; default: return; } */
2453       || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
2454     return false;
2455 
2456   return true;
2457 }
2458 
2459 /* Callback for walk_gimple_seq.  */
2460 
2461 static tree
warn_implicit_fallthrough_r(gimple_stmt_iterator * gsi_p,bool * handled_ops_p,struct walk_stmt_info *)2462 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2463                                    struct walk_stmt_info *)
2464 {
2465   gimple *stmt = gsi_stmt (*gsi_p);
2466 
2467   *handled_ops_p = true;
2468   switch (gimple_code (stmt))
2469     {
2470     case GIMPLE_TRY:
2471     case GIMPLE_BIND:
2472     case GIMPLE_CATCH:
2473     case GIMPLE_EH_FILTER:
2474     case GIMPLE_TRANSACTION:
2475       /* Walk the sub-statements.  */
2476       *handled_ops_p = false;
2477       break;
2478 
2479     /* Find a sequence of form:
2480 
2481        GIMPLE_LABEL
2482        [...]
2483        <may fallthru stmt>
2484        GIMPLE_LABEL
2485 
2486        and possibly warn.  */
2487     case GIMPLE_LABEL:
2488       {
2489           /* Found a label.  Skip all immediately following labels.  */
2490           while (!gsi_end_p (*gsi_p)
2491                  && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
2492             gsi_next_nondebug (gsi_p);
2493 
2494           /* There might be no more statements.  */
2495           if (gsi_end_p (*gsi_p))
2496             return integer_zero_node;
2497 
2498           /* Vector of labels that fall through.  */
2499           auto_vec <struct label_entry> labels;
2500           location_t prevloc;
2501           gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
2502 
2503           /* There might be no more statements.  */
2504           if (gsi_end_p (*gsi_p))
2505             return integer_zero_node;
2506 
2507           gimple *next = gsi_stmt (*gsi_p);
2508           tree label;
2509           /* If what follows is a label, then we may have a fallthrough.  */
2510           if (gimple_code (next) == GIMPLE_LABEL
2511               && gimple_has_location (next)
2512               && (label = gimple_label_label (as_a <glabel *> (next)))
2513               && prev != NULL)
2514             {
2515               struct label_entry *l;
2516               bool warned_p = false;
2517               auto_diagnostic_group d;
2518               if (!should_warn_for_implicit_fallthrough (gsi_p, label))
2519                 /* Quiet.  */;
2520               else if (gimple_code (prev) == GIMPLE_LABEL
2521                          && (label = gimple_label_label (as_a <glabel *> (prev)))
2522                          && (l = find_label_entry (&labels, label)))
2523                 warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
2524                                              "this statement may fall through");
2525               else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
2526                          /* Try to be clever and don't warn when the statement
2527                               can't actually fall through.  */
2528                          && gimple_stmt_may_fallthru (prev)
2529                          && prevloc != UNKNOWN_LOCATION)
2530                 warned_p = warning_at (prevloc,
2531                                              OPT_Wimplicit_fallthrough_,
2532                                              "this statement may fall through");
2533               if (warned_p)
2534                 inform (gimple_location (next), "here");
2535 
2536               /* Mark this label as processed so as to prevent multiple
2537                  warnings in nested switches.  */
2538               FALLTHROUGH_LABEL_P (label) = true;
2539 
2540               /* So that next warn_implicit_fallthrough_r will start looking for
2541                  a new sequence starting with this label.  */
2542               gsi_prev (gsi_p);
2543             }
2544       }
2545       break;
2546    default:
2547       break;
2548     }
2549   return NULL_TREE;
2550 }
2551 
2552 /* Warn when a switch case falls through.  */
2553 
2554 static void
maybe_warn_implicit_fallthrough(gimple_seq seq)2555 maybe_warn_implicit_fallthrough (gimple_seq seq)
2556 {
2557   if (!warn_implicit_fallthrough)
2558     return;
2559 
2560   /* This warning is meant for C/C++/ObjC/ObjC++ only.  */
2561   if (!(lang_GNU_C ()
2562           || lang_GNU_CXX ()
2563           || lang_GNU_OBJC ()))
2564     return;
2565 
2566   struct walk_stmt_info wi;
2567   memset (&wi, 0, sizeof (wi));
2568   walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
2569 }
2570 
2571 /* Callback for walk_gimple_seq.  */
2572 
2573 static tree
expand_FALLTHROUGH_r(gimple_stmt_iterator * gsi_p,bool * handled_ops_p,struct walk_stmt_info * wi)2574 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
2575                           struct walk_stmt_info *wi)
2576 {
2577   gimple *stmt = gsi_stmt (*gsi_p);
2578 
2579   *handled_ops_p = true;
2580   switch (gimple_code (stmt))
2581     {
2582     case GIMPLE_TRY:
2583     case GIMPLE_BIND:
2584     case GIMPLE_CATCH:
2585     case GIMPLE_EH_FILTER:
2586     case GIMPLE_TRANSACTION:
2587       /* Walk the sub-statements.  */
2588       *handled_ops_p = false;
2589       break;
2590     case GIMPLE_CALL:
2591       if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
2592           {
2593             gsi_remove (gsi_p, true);
2594             if (gsi_end_p (*gsi_p))
2595               {
2596                 *static_cast<location_t *>(wi->info) = gimple_location (stmt);
2597                 return integer_zero_node;
2598               }
2599 
2600             bool found = false;
2601             location_t loc = gimple_location (stmt);
2602 
2603             gimple_stmt_iterator gsi2 = *gsi_p;
2604             stmt = gsi_stmt (gsi2);
2605             if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
2606               {
2607                 /* Go on until the artificial label.  */
2608                 tree goto_dest = gimple_goto_dest (stmt);
2609                 for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
2610                     {
2611                       if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
2612                           && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
2613                                  == goto_dest)
2614                         break;
2615                     }
2616 
2617                 /* Not found?  Stop.  */
2618                 if (gsi_end_p (gsi2))
2619                     break;
2620 
2621                 /* Look one past it.  */
2622                 gsi_next (&gsi2);
2623               }
2624 
2625             /* We're looking for a case label or default label here.  */
2626             while (!gsi_end_p (gsi2))
2627               {
2628                 stmt = gsi_stmt (gsi2);
2629                 if (gimple_code (stmt) == GIMPLE_LABEL)
2630                     {
2631                       tree label = gimple_label_label (as_a <glabel *> (stmt));
2632                       if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
2633                         {
2634                           found = true;
2635                           break;
2636                         }
2637                     }
2638                 else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
2639                     ;
2640                 else if (!is_gimple_debug (stmt))
2641                     /* Anything else is not expected.  */
2642                     break;
2643                 gsi_next (&gsi2);
2644               }
2645             if (!found)
2646               pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2647                          "a case label or default label");
2648           }
2649       break;
2650     default:
2651       break;
2652     }
2653   return NULL_TREE;
2654 }
2655 
2656 /* Expand all FALLTHROUGH () calls in SEQ.  */
2657 
2658 static void
expand_FALLTHROUGH(gimple_seq * seq_p)2659 expand_FALLTHROUGH (gimple_seq *seq_p)
2660 {
2661   struct walk_stmt_info wi;
2662   location_t loc;
2663   memset (&wi, 0, sizeof (wi));
2664   wi.info = (void *) &loc;
2665   walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
2666   if (wi.callback_result == integer_zero_node)
2667     /* We've found [[fallthrough]]; at the end of a switch, which the C++
2668        standard says is ill-formed; see [dcl.attr.fallthrough].  */
2669     pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
2670                "a case label or default label");
2671 }
2672 
2673 
2674 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
2675    branch to.  */
2676 
2677 static enum gimplify_status
gimplify_switch_expr(tree * expr_p,gimple_seq * pre_p)2678 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
2679 {
2680   tree switch_expr = *expr_p;
2681   gimple_seq switch_body_seq = NULL;
2682   enum gimplify_status ret;
2683   tree index_type = TREE_TYPE (switch_expr);
2684   if (index_type == NULL_TREE)
2685     index_type = TREE_TYPE (SWITCH_COND (switch_expr));
2686 
2687   ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
2688                        fb_rvalue);
2689   if (ret == GS_ERROR || ret == GS_UNHANDLED)
2690     return ret;
2691 
2692   if (SWITCH_BODY (switch_expr))
2693     {
2694       vec<tree> labels;
2695       vec<tree> saved_labels;
2696       hash_set<tree> *saved_live_switch_vars = NULL;
2697       tree default_case = NULL_TREE;
2698       gswitch *switch_stmt;
2699 
2700       /* Save old labels, get new ones from body, then restore the old
2701          labels.  Save all the things from the switch body to append after.  */
2702       saved_labels = gimplify_ctxp->case_labels;
2703       gimplify_ctxp->case_labels.create (8);
2704 
2705       /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR.  */
2706       saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
2707       tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
2708       if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
2709           gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
2710       else
2711           gimplify_ctxp->live_switch_vars = NULL;
2712 
2713       bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
2714       gimplify_ctxp->in_switch_expr = true;
2715 
2716       gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
2717 
2718       gimplify_ctxp->in_switch_expr = old_in_switch_expr;
2719       maybe_warn_switch_unreachable_and_auto_init (switch_body_seq);
2720       maybe_warn_implicit_fallthrough (switch_body_seq);
2721       /* Only do this for the outermost GIMPLE_SWITCH.  */
2722       if (!gimplify_ctxp->in_switch_expr)
2723           expand_FALLTHROUGH (&switch_body_seq);
2724 
2725       labels = gimplify_ctxp->case_labels;
2726       gimplify_ctxp->case_labels = saved_labels;
2727 
2728       if (gimplify_ctxp->live_switch_vars)
2729           {
2730             gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
2731             delete gimplify_ctxp->live_switch_vars;
2732           }
2733       gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
2734 
2735       preprocess_case_label_vec_for_gimple (labels, index_type,
2736                                                       &default_case);
2737 
2738       bool add_bind = false;
2739       if (!default_case)
2740           {
2741             glabel *new_default;
2742 
2743             default_case
2744               = build_case_label (NULL_TREE, NULL_TREE,
2745                                         create_artificial_label (UNKNOWN_LOCATION));
2746             if (old_in_switch_expr)
2747               {
2748                 SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
2749                 add_bind = true;
2750               }
2751             new_default = gimple_build_label (CASE_LABEL (default_case));
2752             gimplify_seq_add_stmt (&switch_body_seq, new_default);
2753           }
2754       else if (old_in_switch_expr)
2755           {
2756             gimple *last = gimple_seq_last_stmt (switch_body_seq);
2757             if (last && gimple_code (last) == GIMPLE_LABEL)
2758               {
2759                 tree label = gimple_label_label (as_a <glabel *> (last));
2760                 if (SWITCH_BREAK_LABEL_P (label))
2761                     add_bind = true;
2762               }
2763           }
2764 
2765       switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
2766                                                    default_case, labels);
2767       gimple_set_location (switch_stmt, EXPR_LOCATION (switch_expr));
2768       /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
2769            ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
2770            wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
2771            so that we can easily find the start and end of the switch
2772            statement.  */
2773       if (add_bind)
2774           {
2775             gimple_seq bind_body = NULL;
2776             gimplify_seq_add_stmt (&bind_body, switch_stmt);
2777             gimple_seq_add_seq (&bind_body, switch_body_seq);
2778             gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
2779             gimple_set_location (bind, EXPR_LOCATION (switch_expr));
2780             gimplify_seq_add_stmt (pre_p, bind);
2781           }
2782       else
2783           {
2784             gimplify_seq_add_stmt (pre_p, switch_stmt);
2785             gimplify_seq_add_seq (pre_p, switch_body_seq);
2786           }
2787       labels.release ();
2788     }
2789   else
2790     gcc_unreachable ();
2791 
2792   return GS_ALL_DONE;
2793 }
2794 
2795 /* Gimplify the LABEL_EXPR pointed to by EXPR_P.  */
2796 
2797 static enum gimplify_status
gimplify_label_expr(tree * expr_p,gimple_seq * pre_p)2798 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
2799 {
2800   gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
2801                 == current_function_decl);
2802 
2803   tree label = LABEL_EXPR_LABEL (*expr_p);
2804   glabel *label_stmt = gimple_build_label (label);
2805   gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2806   gimplify_seq_add_stmt (pre_p, label_stmt);
2807 
2808   if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2809     gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2810                                                                   NOT_TAKEN));
2811   else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2812     gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2813                                                                   TAKEN));
2814 
2815   return GS_ALL_DONE;
2816 }
2817 
2818 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P.  */
2819 
2820 static enum gimplify_status
gimplify_case_label_expr(tree * expr_p,gimple_seq * pre_p)2821 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
2822 {
2823   struct gimplify_ctx *ctxp;
2824   glabel *label_stmt;
2825 
2826   /* Invalid programs can play Duff's Device type games with, for example,
2827      #pragma omp parallel.  At least in the C front end, we don't
2828      detect such invalid branches until after gimplification, in the
2829      diagnose_omp_blocks pass.  */
2830   for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
2831     if (ctxp->case_labels.exists ())
2832       break;
2833 
2834   tree label = CASE_LABEL (*expr_p);
2835   label_stmt = gimple_build_label (label);
2836   gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
2837   ctxp->case_labels.safe_push (*expr_p);
2838   gimplify_seq_add_stmt (pre_p, label_stmt);
2839 
2840   if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
2841     gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
2842                                                                   NOT_TAKEN));
2843   else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
2844     gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
2845                                                                   TAKEN));
2846 
2847   return GS_ALL_DONE;
2848 }
2849 
2850 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
2851    if necessary.  */
2852 
2853 tree
build_and_jump(tree * label_p)2854 build_and_jump (tree *label_p)
2855 {
2856   if (label_p == NULL)
2857     /* If there's nowhere to jump, just fall through.  */
2858     return NULL_TREE;
2859 
2860   if (*label_p == NULL_TREE)
2861     {
2862       tree label = create_artificial_label (UNKNOWN_LOCATION);
2863       *label_p = label;
2864     }
2865 
2866   return build1 (GOTO_EXPR, void_type_node, *label_p);
2867 }
2868 
2869 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
2870    This also involves building a label to jump to and communicating it to
2871    gimplify_loop_expr through gimplify_ctxp->exit_label.  */
2872 
2873 static enum gimplify_status
gimplify_exit_expr(tree * expr_p)2874 gimplify_exit_expr (tree *expr_p)
2875 {
2876   tree cond = TREE_OPERAND (*expr_p, 0);
2877   tree expr;
2878 
2879   expr = build_and_jump (&gimplify_ctxp->exit_label);
2880   expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
2881   *expr_p = expr;
2882 
2883   return GS_OK;
2884 }
2885 
2886 /* *EXPR_P is a COMPONENT_REF being used as an rvalue.  If its type is
2887    different from its canonical type, wrap the whole thing inside a
2888    NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
2889    type.
2890 
2891    The canonical type of a COMPONENT_REF is the type of the field being
2892    referenced--unless the field is a bit-field which can be read directly
2893    in a smaller mode, in which case the canonical type is the
2894    sign-appropriate type corresponding to that mode.  */
2895 
2896 static void
canonicalize_component_ref(tree * expr_p)2897 canonicalize_component_ref (tree *expr_p)
2898 {
2899   tree expr = *expr_p;
2900   tree type;
2901 
2902   gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
2903 
2904   if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
2905     type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
2906   else
2907     type = TREE_TYPE (TREE_OPERAND (expr, 1));
2908 
2909   /* One could argue that all the stuff below is not necessary for
2910      the non-bitfield case and declare it a FE error if type
2911      adjustment would be needed.  */
2912   if (TREE_TYPE (expr) != type)
2913     {
2914 #ifdef ENABLE_TYPES_CHECKING
2915       tree old_type = TREE_TYPE (expr);
2916 #endif
2917       int type_quals;
2918 
2919       /* We need to preserve qualifiers and propagate them from
2920            operand 0.  */
2921       type_quals = TYPE_QUALS (type)
2922           | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
2923       if (TYPE_QUALS (type) != type_quals)
2924           type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
2925 
2926       /* Set the type of the COMPONENT_REF to the underlying type.  */
2927       TREE_TYPE (expr) = type;
2928 
2929 #ifdef ENABLE_TYPES_CHECKING
2930       /* It is now a FE error, if the conversion from the canonical
2931            type to the original expression type is not useless.  */
2932       gcc_assert (useless_type_conversion_p (old_type, type));
2933 #endif
2934     }
2935 }
2936 
2937 /* If a NOP conversion is changing a pointer to array of foo to a pointer
2938    to foo, embed that change in the ADDR_EXPR by converting
2939       T array[U];
2940       (T *)&array
2941    ==>
2942       &array[L]
2943    where L is the lower bound.  For simplicity, only do this for constant
2944    lower bound.
2945    The constraint is that the type of &array[L] is trivially convertible
2946    to T *.  */
2947 
2948 static void
canonicalize_addr_expr(tree * expr_p)2949 canonicalize_addr_expr (tree *expr_p)
2950 {
2951   tree expr = *expr_p;
2952   tree addr_expr = TREE_OPERAND (expr, 0);
2953   tree datype, ddatype, pddatype;
2954 
2955   /* We simplify only conversions from an ADDR_EXPR to a pointer type.  */
2956   if (!POINTER_TYPE_P (TREE_TYPE (expr))
2957       || TREE_CODE (addr_expr) != ADDR_EXPR)
2958     return;
2959 
2960   /* The addr_expr type should be a pointer to an array.  */
2961   datype = TREE_TYPE (TREE_TYPE (addr_expr));
2962   if (TREE_CODE (datype) != ARRAY_TYPE)
2963     return;
2964 
2965   /* The pointer to element type shall be trivially convertible to
2966      the expression pointer type.  */
2967   ddatype = TREE_TYPE (datype);
2968   pddatype = build_pointer_type (ddatype);
2969   if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
2970                                           pddatype))
2971     return;
2972 
2973   /* The lower bound and element sizes must be constant.  */
2974   if (!TYPE_SIZE_UNIT (ddatype)
2975       || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
2976       || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
2977       || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
2978     return;
2979 
2980   /* All checks succeeded.  Build a new node to merge the cast.  */
2981   *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
2982                         TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
2983                         NULL_TREE, NULL_TREE);
2984   *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
2985 
2986   /* We can have stripped a required restrict qualifier above.  */
2987   if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
2988     *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
2989 }
2990 
2991 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR.  Remove it and/or other conversions
2992    underneath as appropriate.  */
2993 
2994 static enum gimplify_status
gimplify_conversion(tree * expr_p)2995 gimplify_conversion (tree *expr_p)
2996 {
2997   location_t loc = EXPR_LOCATION (*expr_p);
2998   gcc_assert (CONVERT_EXPR_P (*expr_p));
2999 
3000   /* Then strip away all but the outermost conversion.  */
3001   STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
3002 
3003   /* And remove the outermost conversion if it's useless.  */
3004   if (tree_ssa_useless_type_conversion (*expr_p))
3005     *expr_p = TREE_OPERAND (*expr_p, 0);
3006 
3007   /* If we still have a conversion at the toplevel,
3008      then canonicalize some constructs.  */
3009   if (CONVERT_EXPR_P (*expr_p))
3010     {
3011       tree sub = TREE_OPERAND (*expr_p, 0);
3012 
3013       /* If a NOP conversion is changing the type of a COMPONENT_REF
3014            expression, then canonicalize its type now in order to expose more
3015            redundant conversions.  */
3016       if (TREE_CODE (sub) == COMPONENT_REF)
3017           canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
3018 
3019       /* If a NOP conversion is changing a pointer to array of foo
3020            to a pointer to foo, embed that change in the ADDR_EXPR.  */
3021       else if (TREE_CODE (sub) == ADDR_EXPR)
3022           canonicalize_addr_expr (expr_p);
3023     }
3024 
3025   /* If we have a conversion to a non-register type force the
3026      use of a VIEW_CONVERT_EXPR instead.  */
3027   if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
3028     *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
3029                                      TREE_OPERAND (*expr_p, 0));
3030 
3031   /* Canonicalize CONVERT_EXPR to NOP_EXPR.  */
3032   if (TREE_CODE (*expr_p) == CONVERT_EXPR)
3033     TREE_SET_CODE (*expr_p, NOP_EXPR);
3034 
3035   return GS_OK;
3036 }
3037 
3038 /* Gimplify a VAR_DECL or PARM_DECL.  Return GS_OK if we expanded a
3039    DECL_VALUE_EXPR, and it's worth re-examining things.  */
3040 
3041 static enum gimplify_status
gimplify_var_or_parm_decl(tree * expr_p)3042 gimplify_var_or_parm_decl (tree *expr_p)
3043 {
3044   tree decl = *expr_p;
3045 
3046   /* ??? If this is a local variable, and it has not been seen in any
3047      outer BIND_EXPR, then it's probably the result of a duplicate
3048      declaration, for which we've already issued an error.  It would
3049      be really nice if the front end wouldn't leak these at all.
3050      Currently the only known culprit is C++ destructors, as seen
3051      in g++.old-deja/g++.jason/binding.C.
3052      Another possible culpit are size expressions for variably modified
3053      types which are lost in the FE or not gimplified correctly.  */
3054   if (VAR_P (decl)
3055       && !DECL_SEEN_IN_BIND_EXPR_P (decl)
3056       && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
3057       && decl_function_context (decl) == current_function_decl)
3058     {
3059       gcc_assert (seen_error ());
3060       return GS_ERROR;
3061     }
3062 
3063   /* When within an OMP context, notice uses of variables.  */
3064   if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
3065     return GS_ALL_DONE;
3066 
3067   /* If the decl is an alias for another expression, substitute it now.  */
3068   if (DECL_HAS_VALUE_EXPR_P (decl))
3069     {
3070       *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
3071       return GS_OK;
3072     }
3073 
3074   return GS_ALL_DONE;
3075 }
3076 
3077 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T.  */
3078 
3079 static void
recalculate_side_effects(tree t)3080 recalculate_side_effects (tree t)
3081 {
3082   enum tree_code code = TREE_CODE (t);
3083   int len = TREE_OPERAND_LENGTH (t);
3084   int i;
3085 
3086   switch (TREE_CODE_CLASS (code))
3087     {
3088     case tcc_expression:
3089       switch (code)
3090           {
3091           case INIT_EXPR:
3092           case MODIFY_EXPR:
3093           case VA_ARG_EXPR:
3094           case PREDECREMENT_EXPR:
3095           case PREINCREMENT_EXPR:
3096           case POSTDECREMENT_EXPR:
3097           case POSTINCREMENT_EXPR:
3098             /* All of these have side-effects, no matter what their
3099                operands are.  */
3100             return;
3101 
3102           default:
3103             break;
3104           }
3105       /* Fall through.  */
3106 
3107     case tcc_comparison:  /* a comparison expression */
3108     case tcc_unary:       /* a unary arithmetic expression */
3109     case tcc_binary:      /* a binary arithmetic expression */
3110     case tcc_reference:   /* a reference */
3111     case tcc_vl_exp:        /* a function call */
3112       TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
3113       for (i = 0; i < len; ++i)
3114           {
3115             tree op = TREE_OPERAND (t, i);
3116             if (op && TREE_SIDE_EFFECTS (op))
3117               TREE_SIDE_EFFECTS (t) = 1;
3118           }
3119       break;
3120 
3121     case tcc_constant:
3122       /* No side-effects.  */
3123       return;
3124 
3125     default:
3126       gcc_unreachable ();
3127    }
3128 }
3129 
3130 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
3131    node *EXPR_P.
3132 
3133       compound_lval
3134                 : min_lval '[' val ']'
3135                 | min_lval '.' ID
3136                 | compound_lval '[' val ']'
3137                 | compound_lval '.' ID
3138 
3139    This is not part of the original SIMPLE definition, which separates
3140    array and member references, but it seems reasonable to handle them
3141    together.  Also, this way we don't run into problems with union
3142    aliasing; gcc requires that for accesses through a union to alias, the
3143    union reference must be explicit, which was not always the case when we
3144    were splitting up array and member refs.
3145 
3146    PRE_P points to the sequence where side effects that must happen before
3147      *EXPR_P should be stored.
3148 
3149    POST_P points to the sequence where side effects that must happen after
3150      *EXPR_P should be stored.  */
3151 
3152 static enum gimplify_status
gimplify_compound_lval(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p,fallback_t fallback)3153 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3154                               fallback_t fallback)
3155 {
3156   tree *p;
3157   enum gimplify_status ret = GS_ALL_DONE, tret;
3158   int i;
3159   location_t loc = EXPR_LOCATION (*expr_p);
3160   tree expr = *expr_p;
3161 
3162   /* Create a stack of the subexpressions so later we can walk them in
3163      order from inner to outer.  */
3164   auto_vec<tree, 10> expr_stack;
3165 
3166   /* We can handle anything that get_inner_reference can deal with.  */
3167   for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
3168     {
3169     restart:
3170       /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs.  */
3171       if (TREE_CODE (*p) == INDIRECT_REF)
3172           *p = fold_indirect_ref_loc (loc, *p);
3173 
3174       if (handled_component_p (*p))
3175           ;
3176       /* Expand DECL_VALUE_EXPR now.  In some cases that may expose
3177            additional COMPONENT_REFs.  */
3178       else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
3179                  && gimplify_var_or_parm_decl (p) == GS_OK)
3180           goto restart;
3181       else
3182           break;
3183 
3184       expr_stack.safe_push (*p);
3185     }
3186 
3187   gcc_assert (expr_stack.length ());
3188 
3189   /* Now EXPR_STACK is a stack of pointers to all the refs we've
3190      walked through and P points to the innermost expression.
3191 
3192      Java requires that we elaborated nodes in source order.  That
3193      means we must gimplify the inner expression followed by each of
3194      the indices, in order.  But we can't gimplify the inner
3195      expression until we deal with any variable bounds, sizes, or
3196      positions in order to deal with PLACEHOLDER_EXPRs.
3197 
3198      The base expression may contain a statement expression that
3199      has declarations used in size expressions, so has to be
3200      gimplified before gimplifying the size expressions.
3201 
3202      So we do this in three steps.  First we deal with variable
3203      bounds, sizes, and positions, then we gimplify the base and
3204      ensure it is memory if needed, then we deal with the annotations
3205      for any variables in the components and any indices, from left
3206      to right.  */
3207 
3208   bool need_non_reg = false;
3209   for (i = expr_stack.length () - 1; i >= 0; i--)
3210     {
3211       tree t = expr_stack[i];
3212 
3213       if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3214           {
3215             /* Deal with the low bound and element type size and put them into
3216                the ARRAY_REF.  If these values are set, they have already been
3217                gimplified.  */
3218             if (TREE_OPERAND (t, 2) == NULL_TREE)
3219               {
3220                 tree low = unshare_expr (array_ref_low_bound (t));
3221                 if (!is_gimple_min_invariant (low))
3222                     {
3223                       TREE_OPERAND (t, 2) = low;
3224                     }
3225               }
3226 
3227             if (TREE_OPERAND (t, 3) == NULL_TREE)
3228               {
3229                 tree elmt_size = array_ref_element_size (t);
3230                 if (!is_gimple_min_invariant (elmt_size))
3231                     {
3232                       elmt_size = unshare_expr (elmt_size);
3233                       tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
3234                       tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
3235 
3236                       /* Divide the element size by the alignment of the element
3237                          type (above).  */
3238                       elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR,
3239                                                         elmt_size, factor);
3240 
3241                       TREE_OPERAND (t, 3) = elmt_size;
3242                     }
3243               }
3244             need_non_reg = true;
3245           }
3246       else if (TREE_CODE (t) == COMPONENT_REF)
3247           {
3248             /* Set the field offset into T and gimplify it.  */
3249             if (TREE_OPERAND (t, 2) == NULL_TREE)
3250               {
3251                 tree offset = component_ref_field_offset (t);
3252                 if (!is_gimple_min_invariant (offset))
3253                     {
3254                       offset = unshare_expr (offset);
3255                       tree field = TREE_OPERAND (t, 1);
3256                       tree factor
3257                         = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
3258 
3259                       /* Divide the offset by its alignment.  */
3260                       offset = size_binop_loc (loc, EXACT_DIV_EXPR,
3261                                                      offset, factor);
3262 
3263                       TREE_OPERAND (t, 2) = offset;
3264                     }
3265               }
3266             need_non_reg = true;
3267           }
3268     }
3269 
3270   /* Step 2 is to gimplify the base expression.  Make sure lvalue is set
3271      so as to match the min_lval predicate.  Failure to do so may result
3272      in the creation of large aggregate temporaries.  */
3273   tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
3274                               fallback | fb_lvalue);
3275   ret = MIN (ret, tret);
3276 
3277   /* Step 2a: if we have component references we do not support on
3278      registers then make sure the base isn't a register.  Of course
3279      we can only do so if an rvalue is OK.  */
3280   if (need_non_reg && (fallback & fb_rvalue))
3281     prepare_gimple_addressable (p, pre_p);
3282 
3283   /* Step 3: gimplify size expressions and the indices and operands of
3284      ARRAY_REF.  During this loop we also remove any useless conversions.  */
3285 
3286   for (; expr_stack.length () > 0; )
3287     {
3288       tree t = expr_stack.pop ();
3289 
3290       if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
3291           {
3292             /* Gimplify the low bound and element type size. */
3293             tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3294                                         is_gimple_reg, fb_rvalue);
3295             ret = MIN (ret, tret);
3296 
3297             tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
3298                                         is_gimple_reg, fb_rvalue);
3299             ret = MIN (ret, tret);
3300 
3301             /* Gimplify the dimension.  */
3302             tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
3303                                         is_gimple_val, fb_rvalue);
3304             ret = MIN (ret, tret);
3305           }
3306       else if (TREE_CODE (t) == COMPONENT_REF)
3307           {
3308             tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
3309                                         is_gimple_reg, fb_rvalue);
3310             ret = MIN (ret, tret);
3311           }
3312 
3313       STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
3314 
3315       /* The innermost expression P may have originally had
3316            TREE_SIDE_EFFECTS set which would have caused all the outer
3317            expressions in *EXPR_P leading to P to also have had
3318            TREE_SIDE_EFFECTS set.  */
3319       recalculate_side_effects (t);
3320     }
3321 
3322   /* If the outermost expression is a COMPONENT_REF, canonicalize its type.  */
3323   if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
3324     {
3325       canonicalize_component_ref (expr_p);
3326     }
3327 
3328   expr_stack.release ();
3329 
3330   gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
3331 
3332   return ret;
3333 }
3334 
3335 /*  Gimplify the self modifying expression pointed to by EXPR_P
3336     (++, --, +=, -=).
3337 
3338     PRE_P points to the list where side effects that must happen before
3339           *EXPR_P should be stored.
3340 
3341     POST_P points to the list where side effects that must happen after
3342           *EXPR_P should be stored.
3343 
3344     WANT_VALUE is nonzero iff we want to use the value of this expression
3345           in another expression.
3346 
3347     ARITH_TYPE is the type the computation should be performed in.  */
3348 
3349 enum gimplify_status
gimplify_self_mod_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p,bool want_value,tree arith_type)3350 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
3351                               bool want_value, tree arith_type)
3352 {
3353   enum tree_code code;
3354   tree lhs, lvalue, rhs, t1;
3355   gimple_seq post = NULL, *orig_post_p = post_p;
3356   bool postfix;
3357   enum tree_code arith_code;
3358   enum gimplify_status ret;
3359   location_t loc = EXPR_LOCATION (*expr_p);
3360 
3361   code = TREE_CODE (*expr_p);
3362 
3363   gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
3364                 || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
3365 
3366   /* Prefix or postfix?  */
3367   if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
3368     /* Faster to treat as prefix if result is not used.  */
3369     postfix = want_value;
3370   else
3371     postfix = false;
3372 
3373   /* For postfix, make sure the inner expression's post side effects
3374      are executed after side effects from this expression.  */
3375   if (postfix)
3376     post_p = &post;
3377 
3378   /* Add or subtract?  */
3379   if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
3380     arith_code = PLUS_EXPR;
3381   else
3382     arith_code = MINUS_EXPR;
3383 
3384   /* Gimplify the LHS into a GIMPLE lvalue.  */
3385   lvalue = TREE_OPERAND (*expr_p, 0);
3386   ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
3387   if (ret == GS_ERROR)
3388     return ret;
3389 
3390   /* Extract the operands to the arithmetic operation.  */
3391   lhs = lvalue;
3392   rhs = TREE_OPERAND (*expr_p, 1);
3393 
3394   /* For postfix operator, we evaluate the LHS to an rvalue and then use
3395      that as the result value and in the postqueue operation.  */
3396   if (postfix)
3397     {
3398       ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
3399       if (ret == GS_ERROR)
3400           return ret;
3401 
3402       lhs = get_initialized_tmp_var (lhs, pre_p);
3403     }
3404 
3405   /* For POINTERs increment, use POINTER_PLUS_EXPR.  */
3406   if (POINTER_TYPE_P (TREE_TYPE (lhs)))
3407     {
3408       rhs = convert_to_ptrofftype_loc (loc, rhs);
3409       if (arith_code == MINUS_EXPR)
3410           rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
3411       t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
3412     }
3413   else
3414     t1 = fold_convert (TREE_TYPE (*expr_p),
3415                            fold_build2 (arith_code, arith_type,
3416                                             fold_convert (arith_type, lhs),
3417                                             fold_convert (arith_type, rhs)));
3418 
3419   if (postfix)
3420     {
3421       gimplify_assign (lvalue, t1, pre_p);
3422       gimplify_seq_add_seq (orig_post_p, post);
3423       *expr_p = lhs;
3424       return GS_ALL_DONE;
3425     }
3426   else
3427     {
3428       *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
3429       return GS_OK;
3430     }
3431 }
3432 
3433 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR.  */
3434 
3435 static void
maybe_with_size_expr(tree * expr_p)3436 maybe_with_size_expr (tree *expr_p)
3437 {
3438   tree expr = *expr_p;
3439   tree type = TREE_TYPE (expr);
3440   tree size;
3441 
3442   /* If we've already wrapped this or the type is error_mark_node, we can't do
3443      anything.  */
3444   if (TREE_CODE (expr) == WITH_SIZE_EXPR
3445       || type == error_mark_node)
3446     return;
3447 
3448   /* If the size isn't known or is a constant, we have nothing to do.  */
3449   size = TYPE_SIZE_UNIT (type);
3450   if (!size || poly_int_tree_p (size))
3451     return;
3452 
3453   /* Otherwise, make a WITH_SIZE_EXPR.  */
3454   size = unshare_expr (size);
3455   size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
3456   *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
3457 }
3458 
3459 /* Helper for gimplify_call_expr.  Gimplify a single argument *ARG_P
3460    Store any side-effects in PRE_P.  CALL_LOCATION is the location of
3461    the CALL_EXPR.  If ALLOW_SSA is set the actual parameter may be
3462    gimplified to an SSA name.  */
3463 
3464 enum gimplify_status
gimplify_arg(tree * arg_p,gimple_seq * pre_p,location_t call_location,bool allow_ssa)3465 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
3466                 bool allow_ssa)
3467 {
3468   bool (*test) (tree);
3469   fallback_t fb;
3470 
3471   /* In general, we allow lvalues for function arguments to avoid
3472      extra overhead of copying large aggregates out of even larger
3473      aggregates into temporaries only to copy the temporaries to
3474      the argument list.  Make optimizers happy by pulling out to
3475      temporaries those types that fit in registers.  */
3476   if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
3477     test = is_gimple_val, fb = fb_rvalue;
3478   else
3479     {
3480       test = is_gimple_lvalue, fb = fb_either;
3481       /* Also strip a TARGET_EXPR that would force an extra copy.  */
3482       if (TREE_CODE (*arg_p) == TARGET_EXPR)
3483           {
3484             tree init = TARGET_EXPR_INITIAL (*arg_p);
3485             if (init
3486                 && !VOID_TYPE_P (TREE_TYPE (init)))
3487               *arg_p = init;
3488           }
3489     }
3490 
3491   /* If this is a variable sized type, we must remember the size.  */
3492   maybe_with_size_expr (arg_p);
3493 
3494   /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c.  */
3495   /* Make sure arguments have the same location as the function call
3496      itself.  */
3497   protected_set_expr_location (*arg_p, call_location);
3498 
3499   /* There is a sequence point before a function call.  Side effects in
3500      the argument list must occur before the actual call. So, when
3501      gimplifying arguments, force gimplify_expr to use an internal
3502      post queue which is then appended to the end of PRE_P.  */
3503   return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
3504 }
3505 
3506 /* Don't fold inside offloading or taskreg regions: it can break code by
3507    adding decl references that weren't in the source.  We'll do it during
3508    omplower pass instead.  */
3509 
3510 static bool
maybe_fold_stmt(gimple_stmt_iterator * gsi)3511 maybe_fold_stmt (gimple_stmt_iterator *gsi)
3512 {
3513   struct gimplify_omp_ctx *ctx;
3514   for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
3515     if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
3516       return false;
3517     else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
3518       return false;
3519   /* Delay folding of builtins until the IL is in consistent state
3520      so the diagnostic machinery can do a better job.  */
3521   if (gimple_call_builtin_p (gsi_stmt (*gsi)))
3522     return false;
3523   return fold_stmt (gsi);
3524 }
3525 
3526 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
3527    WANT_VALUE is true if the result of the call is desired.  */
3528 
3529 static enum gimplify_status
gimplify_call_expr(tree * expr_p,gimple_seq * pre_p,bool want_value)3530 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
3531 {
3532   tree fndecl, parms, p, fnptrtype;
3533   enum gimplify_status ret;
3534   int i, nargs;
3535   gcall *call;
3536   bool builtin_va_start_p = false;
3537   location_t loc = EXPR_LOCATION (*expr_p);
3538 
3539   gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
3540 
3541   /* For reliable diagnostics during inlining, it is necessary that
3542      every call_expr be annotated with file and line.  */
3543   if (! EXPR_HAS_LOCATION (*expr_p))
3544     SET_EXPR_LOCATION (*expr_p, input_location);
3545 
3546   /* Gimplify internal functions created in the FEs.  */
3547   if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
3548     {
3549       if (want_value)
3550           return GS_ALL_DONE;
3551 
3552       nargs = call_expr_nargs (*expr_p);
3553       enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
3554       auto_vec<tree> vargs (nargs);
3555 
3556       for (i = 0; i < nargs; i++)
3557           {
3558             gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3559                               EXPR_LOCATION (*expr_p));
3560             vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
3561           }
3562 
3563       gcall *call = gimple_build_call_internal_vec (ifn, vargs);
3564       gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
3565       gimplify_seq_add_stmt (pre_p, call);
3566       return GS_ALL_DONE;
3567     }
3568 
3569   /* This may be a call to a builtin function.
3570 
3571      Builtin function calls may be transformed into different
3572      (and more efficient) builtin function calls under certain
3573      circumstances.  Unfortunately, gimplification can muck things
3574      up enough that the builtin expanders are not aware that certain
3575      transformations are still valid.
3576 
3577      So we attempt transformation/gimplification of the call before
3578      we gimplify the CALL_EXPR.  At this time we do not manage to
3579      transform all calls in the same manner as the expanders do, but
3580      we do transform most of them.  */
3581   fndecl = get_callee_fndecl (*expr_p);
3582   if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
3583     switch (DECL_FUNCTION_CODE (fndecl))
3584       {
3585       CASE_BUILT_IN_ALLOCA:
3586           /* If the call has been built for a variable-sized object, then we
3587              want to restore the stack level when the enclosing BIND_EXPR is
3588              exited to reclaim the allocated space; otherwise, we precisely
3589              need to do the opposite and preserve the latest stack level.  */
3590           if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
3591             gimplify_ctxp->save_stack = true;
3592           else
3593             gimplify_ctxp->keep_stack = true;
3594           break;
3595 
3596       case BUILT_IN_VA_START:
3597         {
3598             builtin_va_start_p = TRUE;
3599             if (call_expr_nargs (*expr_p) < 2)
3600               {
3601                 error ("too few arguments to function %<va_start%>");
3602                 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3603                 return GS_OK;
3604               }
3605 
3606             if (fold_builtin_next_arg (*expr_p, true))
3607               {
3608                 *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
3609                 return GS_OK;
3610               }
3611             break;
3612           }
3613 
3614       case BUILT_IN_EH_RETURN:
3615           cfun->calls_eh_return = true;
3616           break;
3617 
3618       case BUILT_IN_CLEAR_PADDING:
3619           if (call_expr_nargs (*expr_p) == 1)
3620             {
3621               /* Remember the original type of the argument in an internal
3622                  dummy second argument, as in GIMPLE pointer conversions are
3623                  useless.  Also mark this call as not for automatic
3624                  initialization in the internal dummy third argument.  */
3625               p = CALL_EXPR_ARG (*expr_p, 0);
3626               *expr_p
3627                 = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p,
3628                                              build_zero_cst (TREE_TYPE (p)));
3629               return GS_OK;
3630             }
3631           break;
3632 
3633       default:
3634         ;
3635       }
3636   if (fndecl && fndecl_built_in_p (fndecl))
3637     {
3638       tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3639       if (new_tree && new_tree != *expr_p)
3640           {
3641             /* There was a transformation of this call which computes the
3642                same value, but in a more efficient way.  Return and try
3643                again.  */
3644             *expr_p = new_tree;
3645             return GS_OK;
3646           }
3647     }
3648 
3649   /* Remember the original function pointer type.  */
3650   fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
3651 
3652   if (flag_openmp
3653       && fndecl
3654       && cfun
3655       && (cfun->curr_properties & PROP_gimple_any) == 0)
3656     {
3657       tree variant = omp_resolve_declare_variant (fndecl);
3658       if (variant != fndecl)
3659           CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
3660     }
3661 
3662   /* There is a sequence point before the call, so any side effects in
3663      the calling expression must occur before the actual call.  Force
3664      gimplify_expr to use an internal post queue.  */
3665   ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
3666                            is_gimple_call_addr, fb_rvalue);
3667 
3668   nargs = call_expr_nargs (*expr_p);
3669 
3670   /* Get argument types for verification.  */
3671   fndecl = get_callee_fndecl (*expr_p);
3672   parms = NULL_TREE;
3673   if (fndecl)
3674     parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
3675   else
3676     parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
3677 
3678   if (fndecl && DECL_ARGUMENTS (fndecl))
3679     p = DECL_ARGUMENTS (fndecl);
3680   else if (parms)
3681     p = parms;
3682   else
3683     p = NULL_TREE;
3684   for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
3685     ;
3686 
3687   /* If the last argument is __builtin_va_arg_pack () and it is not
3688      passed as a named argument, decrease the number of CALL_EXPR
3689      arguments and set instead the CALL_EXPR_VA_ARG_PACK flag.  */
3690   if (!p
3691       && i < nargs
3692       && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
3693     {
3694       tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
3695       tree last_arg_fndecl = get_callee_fndecl (last_arg);
3696 
3697       if (last_arg_fndecl
3698             && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
3699           {
3700             tree call = *expr_p;
3701 
3702             --nargs;
3703             *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
3704                                                     CALL_EXPR_FN (call),
3705                                                     nargs, CALL_EXPR_ARGP (call));
3706 
3707             /* Copy all CALL_EXPR flags, location and block, except
3708                CALL_EXPR_VA_ARG_PACK flag.  */
3709             CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
3710             CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
3711             CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
3712               = CALL_EXPR_RETURN_SLOT_OPT (call);
3713             CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
3714             SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
3715 
3716             /* Set CALL_EXPR_VA_ARG_PACK.  */
3717             CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
3718           }
3719     }
3720 
3721   /* If the call returns twice then after building the CFG the call
3722      argument computations will no longer dominate the call because
3723      we add an abnormal incoming edge to the call.  So do not use SSA
3724      vars there.  */
3725   bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
3726 
3727   /* Gimplify the function arguments.  */
3728   if (nargs > 0)
3729     {
3730       for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
3731            PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
3732            PUSH_ARGS_REVERSED ? i-- : i++)
3733         {
3734           enum gimplify_status t;
3735 
3736           /* Avoid gimplifying the second argument to va_start, which needs to
3737              be the plain PARM_DECL.  */
3738           if ((i != 1) || !builtin_va_start_p)
3739             {
3740               t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
3741                                         EXPR_LOCATION (*expr_p), ! returns_twice);
3742 
3743               if (t == GS_ERROR)
3744                 ret = GS_ERROR;
3745             }
3746         }
3747     }
3748 
3749   /* Gimplify the static chain.  */
3750   if (CALL_EXPR_STATIC_CHAIN (*expr_p))
3751     {
3752       if (fndecl && !DECL_STATIC_CHAIN (fndecl))
3753           CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
3754       else
3755           {
3756             enum gimplify_status t;
3757             t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
3758                                   EXPR_LOCATION (*expr_p), ! returns_twice);
3759             if (t == GS_ERROR)
3760               ret = GS_ERROR;
3761           }
3762     }
3763 
3764   /* Verify the function result.  */
3765   if (want_value && fndecl
3766       && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
3767     {
3768       error_at (loc, "using result of function returning %<void%>");
3769       ret = GS_ERROR;
3770     }
3771 
3772   /* Try this again in case gimplification exposed something.  */
3773   if (ret != GS_ERROR)
3774     {
3775       tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
3776 
3777       if (new_tree && new_tree != *expr_p)
3778           {
3779             /* There was a transformation of this call which computes the
3780                same value, but in a more efficient way.  Return and try
3781                again.  */
3782             *expr_p = new_tree;
3783             return GS_OK;
3784           }
3785     }
3786   else
3787     {
3788       *expr_p = error_mark_node;
3789       return GS_ERROR;
3790     }
3791 
3792   /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
3793      decl.  This allows us to eliminate redundant or useless
3794      calls to "const" functions.  */
3795   if (TREE_CODE (*expr_p) == CALL_EXPR)
3796     {
3797       int flags = call_expr_flags (*expr_p);
3798       if (flags & (ECF_CONST | ECF_PURE)
3799             /* An infinite loop is considered a side effect.  */
3800             && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
3801           TREE_SIDE_EFFECTS (*expr_p) = 0;
3802     }
3803 
3804   /* If the value is not needed by the caller, emit a new GIMPLE_CALL
3805      and clear *EXPR_P.  Otherwise, leave *EXPR_P in its gimplified
3806      form and delegate the creation of a GIMPLE_CALL to
3807      gimplify_modify_expr.  This is always possible because when
3808      WANT_VALUE is true, the caller wants the result of this call into
3809      a temporary, which means that we will emit an INIT_EXPR in
3810      internal_get_tmp_var which will then be handled by
3811      gimplify_modify_expr.  */
3812   if (!want_value)
3813     {
3814       /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
3815            have to do is replicate it as a GIMPLE_CALL tuple.  */
3816       gimple_stmt_iterator gsi;
3817       call = gimple_build_call_from_tree (*expr_p, fnptrtype);
3818       notice_special_calls (call);
3819       gimplify_seq_add_stmt (pre_p, call);
3820       gsi = gsi_last (*pre_p);
3821       maybe_fold_stmt (&gsi);
3822       *expr_p = NULL_TREE;
3823     }
3824   else
3825     /* Remember the original function type.  */
3826     CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
3827                                              CALL_EXPR_FN (*expr_p));
3828 
3829   return ret;
3830 }
3831 
3832 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
3833    rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
3834 
3835    TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
3836    condition is true or false, respectively.  If null, we should generate
3837    our own to skip over the evaluation of this specific expression.
3838 
3839    LOCUS is the source location of the COND_EXPR.
3840 
3841    This function is the tree equivalent of do_jump.
3842 
3843    shortcut_cond_r should only be called by shortcut_cond_expr.  */
3844 
3845 static tree
shortcut_cond_r(tree pred,tree * true_label_p,tree * false_label_p,location_t locus)3846 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
3847                      location_t locus)
3848 {
3849   tree local_label = NULL_TREE;
3850   tree t, expr = NULL;
3851 
3852   /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
3853      retain the shortcut semantics.  Just insert the gotos here;
3854      shortcut_cond_expr will append the real blocks later.  */
3855   if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
3856     {
3857       location_t new_locus;
3858 
3859       /* Turn if (a && b) into
3860 
3861            if (a); else goto no;
3862            if (b) goto yes; else goto no;
3863            (no:) */
3864 
3865       if (false_label_p == NULL)
3866           false_label_p = &local_label;
3867 
3868       /* Keep the original source location on the first 'if'.  */
3869       t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus);
3870       append_to_statement_list (t, &expr);
3871 
3872       /* Set the source location of the && on the second 'if'.  */
3873       new_locus = rexpr_location (pred, locus);
3874       t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3875                                  new_locus);
3876       append_to_statement_list (t, &expr);
3877     }
3878   else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
3879     {
3880       location_t new_locus;
3881 
3882       /* Turn if (a || b) into
3883 
3884            if (a) goto yes;
3885            if (b) goto yes; else goto no;
3886            (yes:) */
3887 
3888       if (true_label_p == NULL)
3889           true_label_p = &local_label;
3890 
3891       /* Keep the original source location on the first 'if'.  */
3892       t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus);
3893       append_to_statement_list (t, &expr);
3894 
3895       /* Set the source location of the || on the second 'if'.  */
3896       new_locus = rexpr_location (pred, locus);
3897       t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
3898                                  new_locus);
3899       append_to_statement_list (t, &expr);
3900     }
3901   else if (TREE_CODE (pred) == COND_EXPR
3902              && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
3903              && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
3904     {
3905       location_t new_locus;
3906 
3907       /* As long as we're messing with gotos, turn if (a ? b : c) into
3908            if (a)
3909              if (b) goto yes; else goto no;
3910            else
3911              if (c) goto yes; else goto no;
3912 
3913            Don't do this if one of the arms has void type, which can happen
3914            in C++ when the arm is throw.  */
3915 
3916       /* Keep the original source location on the first 'if'.  Set the source
3917            location of the ? on the second 'if'.  */
3918       new_locus = rexpr_location (pred, locus);
3919       expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
3920                          shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
3921                                               false_label_p, locus),
3922                          shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
3923                                               false_label_p, new_locus));
3924     }
3925   else
3926     {
3927       expr = build3 (COND_EXPR, void_type_node, pred,
3928                          build_and_jump (true_label_p),
3929                          build_and_jump (false_label_p));
3930       SET_EXPR_LOCATION (expr, locus);
3931     }
3932 
3933   if (local_label)
3934     {
3935       t = build1 (LABEL_EXPR, void_type_node, local_label);
3936       append_to_statement_list (t, &expr);
3937     }
3938 
3939   return expr;
3940 }
3941 
3942 /* If EXPR is a GOTO_EXPR, return it.  If it is a STATEMENT_LIST, skip
3943    any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
3944    statement, if it is the last one.  Otherwise, return NULL.  */
3945 
3946 static tree
find_goto(tree expr)3947 find_goto (tree expr)
3948 {
3949   if (!expr)
3950     return NULL_TREE;
3951 
3952   if (TREE_CODE (expr) == GOTO_EXPR)
3953     return expr;
3954 
3955   if (TREE_CODE (expr) != STATEMENT_LIST)
3956     return NULL_TREE;
3957 
3958   tree_stmt_iterator i = tsi_start (expr);
3959 
3960   while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
3961     tsi_next (&i);
3962 
3963   if (!tsi_one_before_end_p (i))
3964     return NULL_TREE;
3965 
3966   return find_goto (tsi_stmt (i));
3967 }
3968 
3969 /* Same as find_goto, except that it returns NULL if the destination
3970    is not a LABEL_DECL.  */
3971 
3972 static inline tree
find_goto_label(tree expr)3973 find_goto_label (tree expr)
3974 {
3975   tree dest = find_goto (expr);
3976   if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
3977     return dest;
3978   return NULL_TREE;
3979 }
3980 
3981 /* Given a conditional expression EXPR with short-circuit boolean
3982    predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
3983    predicate apart into the equivalent sequence of conditionals.  */
3984 
3985 static tree
shortcut_cond_expr(tree expr)3986 shortcut_cond_expr (tree expr)
3987 {
3988   tree pred = TREE_OPERAND (expr, 0);
3989   tree then_ = TREE_OPERAND (expr, 1);
3990   tree else_ = TREE_OPERAND (expr, 2);
3991   tree true_label, false_label, end_label, t;
3992   tree *true_label_p;
3993   tree *false_label_p;
3994   bool emit_end, emit_false, jump_over_else;
3995   bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
3996   bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
3997 
3998   /* First do simple transformations.  */
3999   if (!else_se)
4000     {
4001       /* If there is no 'else', turn
4002              if (a && b) then c
4003            into
4004              if (a) if (b) then c.  */
4005       while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
4006           {
4007             /* Keep the original source location on the first 'if'.  */
4008             location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
4009             TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
4010             /* Set the source location of the && on the second 'if'.  */
4011             if (rexpr_has_location (pred))
4012               SET_EXPR_LOCATION (expr, rexpr_location (pred));
4013             then_ = shortcut_cond_expr (expr);
4014             then_se = then_ && TREE_SIDE_EFFECTS (then_);
4015             pred = TREE_OPERAND (pred, 0);
4016             expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
4017             SET_EXPR_LOCATION (expr, locus);
4018           }
4019     }
4020 
4021   if (!then_se)
4022     {
4023       /* If there is no 'then', turn
4024              if (a || b); else d
4025            into
4026              if (a); else if (b); else d.  */
4027       while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
4028           {
4029             /* Keep the original source location on the first 'if'.  */
4030             location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
4031             TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
4032             /* Set the source location of the || on the second 'if'.  */
4033             if (rexpr_has_location (pred))
4034               SET_EXPR_LOCATION (expr, rexpr_location (pred));
4035             else_ = shortcut_cond_expr (expr);
4036             else_se = else_ && TREE_SIDE_EFFECTS (else_);
4037             pred = TREE_OPERAND (pred, 0);
4038             expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
4039             SET_EXPR_LOCATION (expr, locus);
4040           }
4041     }
4042 
4043   /* If we're done, great.  */
4044   if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
4045       && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
4046     return expr;
4047 
4048   /* Otherwise we need to mess with gotos.  Change
4049        if (a) c; else d;
4050      to
4051        if (a); else goto no;
4052        c; goto end;
4053        no: d; end:
4054      and recursively gimplify the condition.  */
4055 
4056   true_label = false_label = end_label = NULL_TREE;
4057 
4058   /* If our arms just jump somewhere, hijack those labels so we don't
4059      generate jumps to jumps.  */
4060 
4061   if (tree then_goto = find_goto_label (then_))
4062     {
4063       true_label = GOTO_DESTINATION (then_goto);
4064       then_ = NULL;
4065       then_se = false;
4066     }
4067 
4068   if (tree else_goto = find_goto_label (else_))
4069     {
4070       false_label = GOTO_DESTINATION (else_goto);
4071       else_ = NULL;
4072       else_se = false;
4073     }
4074 
4075   /* If we aren't hijacking a label for the 'then' branch, it falls through.  */
4076   if (true_label)
4077     true_label_p = &true_label;
4078   else
4079     true_label_p = NULL;
4080 
4081   /* The 'else' branch also needs a label if it contains interesting code.  */
4082   if (false_label || else_se)
4083     false_label_p = &false_label;
4084   else
4085     false_label_p = NULL;
4086 
4087   /* If there was nothing else in our arms, just forward the label(s).  */
4088   if (!then_se && !else_se)
4089     return shortcut_cond_r (pred, true_label_p, false_label_p,
4090                                   EXPR_LOC_OR_LOC (expr, input_location));
4091 
4092   /* If our last subexpression already has a terminal label, reuse it.  */
4093   if (else_se)
4094     t = expr_last (else_);
4095   else if (then_se)
4096     t = expr_last (then_);
4097   else
4098     t = NULL;
4099   if (t && TREE_CODE (t) == LABEL_EXPR)
4100     end_label = LABEL_EXPR_LABEL (t);
4101 
4102   /* If we don't care about jumping to the 'else' branch, jump to the end
4103      if the condition is false.  */
4104   if (!false_label_p)
4105     false_label_p = &end_label;
4106 
4107   /* We only want to emit these labels if we aren't hijacking them.  */
4108   emit_end = (end_label == NULL_TREE);
4109   emit_false = (false_label == NULL_TREE);
4110 
4111   /* We only emit the jump over the else clause if we have to--if the
4112      then clause may fall through.  Otherwise we can wind up with a
4113      useless jump and a useless label at the end of gimplified code,
4114      which will cause us to think that this conditional as a whole
4115      falls through even if it doesn't.  If we then inline a function
4116      which ends with such a condition, that can cause us to issue an
4117      inappropriate warning about control reaching the end of a
4118      non-void function.  */
4119   jump_over_else = block_may_fallthru (then_);
4120 
4121   pred = shortcut_cond_r (pred, true_label_p, false_label_p,
4122                                 EXPR_LOC_OR_LOC (expr, input_location));
4123 
4124   expr = NULL;
4125   append_to_statement_list (pred, &expr);
4126 
4127   append_to_statement_list (then_, &expr);
4128   if (else_se)
4129     {
4130       if (jump_over_else)
4131           {
4132             tree last = expr_last (expr);
4133             t = build_and_jump (&end_label);
4134             if (rexpr_has_location (last))
4135               SET_EXPR_LOCATION (t, rexpr_location (last));
4136             append_to_statement_list (t, &expr);
4137           }
4138       if (emit_false)
4139           {
4140             t = build1 (LABEL_EXPR, void_type_node, false_label);
4141             append_to_statement_list (t, &expr);
4142           }
4143       append_to_statement_list (else_, &expr);
4144     }
4145   if (emit_end && end_label)
4146     {
4147       t = build1 (LABEL_EXPR, void_type_node, end_label);
4148       append_to_statement_list (t, &expr);
4149     }
4150 
4151   return expr;
4152 }
4153 
4154 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE.  */
4155 
4156 tree
gimple_boolify(tree expr)4157 gimple_boolify (tree expr)
4158 {
4159   tree type = TREE_TYPE (expr);
4160   location_t loc = EXPR_LOCATION (expr);
4161 
4162   if (TREE_CODE (expr) == NE_EXPR
4163       && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
4164       && integer_zerop (TREE_OPERAND (expr, 1)))
4165     {
4166       tree call = TREE_OPERAND (expr, 0);
4167       tree fn = get_callee_fndecl (call);
4168 
4169       /* For __builtin_expect ((long) (x), y) recurse into x as well
4170            if x is truth_value_p.  */
4171       if (fn
4172             && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
4173             && call_expr_nargs (call) == 2)
4174           {
4175             tree arg = CALL_EXPR_ARG (call, 0);
4176             if (arg)
4177               {
4178                 if (TREE_CODE (arg) == NOP_EXPR
4179                       && TREE_TYPE (arg) == TREE_TYPE (call))
4180                     arg = TREE_OPERAND (arg, 0);
4181                 if (truth_value_p (TREE_CODE (arg)))
4182                     {
4183                       arg = gimple_boolify (arg);
4184                       CALL_EXPR_ARG (call, 0)
4185                         = fold_convert_loc (loc, TREE_TYPE (call), arg);
4186                     }
4187               }
4188           }
4189     }
4190 
4191   switch (TREE_CODE (expr))
4192     {
4193     case TRUTH_AND_EXPR:
4194     case TRUTH_OR_EXPR:
4195     case TRUTH_XOR_EXPR:
4196     case TRUTH_ANDIF_EXPR:
4197     case TRUTH_ORIF_EXPR:
4198       /* Also boolify the arguments of truth exprs.  */
4199       TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
4200       /* FALLTHRU */
4201 
4202     case TRUTH_NOT_EXPR:
4203       TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4204 
4205       /* These expressions always produce boolean results.  */
4206       if (TREE_CODE (type) != BOOLEAN_TYPE)
4207           TREE_TYPE (expr) = boolean_type_node;
4208       return expr;
4209 
4210     case ANNOTATE_EXPR:
4211       switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
4212           {
4213           case annot_expr_ivdep_kind:
4214           case annot_expr_unroll_kind:
4215           case annot_expr_no_vector_kind:
4216           case annot_expr_vector_kind:
4217           case annot_expr_parallel_kind:
4218             TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4219             if (TREE_CODE (type) != BOOLEAN_TYPE)
4220               TREE_TYPE (expr) = boolean_type_node;
4221             return expr;
4222           default:
4223             gcc_unreachable ();
4224           }
4225 
4226     default:
4227       if (COMPARISON_CLASS_P (expr))
4228           {
4229             /* There expressions always prduce boolean results.  */
4230             if (TREE_CODE (type) != BOOLEAN_TYPE)
4231               TREE_TYPE (expr) = boolean_type_node;
4232             return expr;
4233           }
4234       /* Other expressions that get here must have boolean values, but
4235            might need to be converted to the appropriate mode.  */
4236       if (TREE_CODE (type) == BOOLEAN_TYPE)
4237           return expr;
4238       return fold_convert_loc (loc, boolean_type_node, expr);
4239     }
4240 }
4241 
4242 /* Given a conditional expression *EXPR_P without side effects, gimplify
4243    its operands.  New statements are inserted to PRE_P.  */
4244 
4245 static enum gimplify_status
gimplify_pure_cond_expr(tree * expr_p,gimple_seq * pre_p)4246 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
4247 {
4248   tree expr = *expr_p, cond;
4249   enum gimplify_status ret, tret;
4250   enum tree_code code;
4251 
4252   cond = gimple_boolify (COND_EXPR_COND (expr));
4253 
4254   /* We need to handle && and || specially, as their gimplification
4255      creates pure cond_expr, thus leading to an infinite cycle otherwise.  */
4256   code = TREE_CODE (cond);
4257   if (code == TRUTH_ANDIF_EXPR)
4258     TREE_SET_CODE (cond, TRUTH_AND_EXPR);
4259   else if (code == TRUTH_ORIF_EXPR)
4260     TREE_SET_CODE (cond, TRUTH_OR_EXPR);
4261   ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
4262   COND_EXPR_COND (*expr_p) = cond;
4263 
4264   tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
4265                                            is_gimple_val, fb_rvalue);
4266   ret = MIN (ret, tret);
4267   tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
4268                                            is_gimple_val, fb_rvalue);
4269 
4270   return MIN (ret, tret);
4271 }
4272 
4273 /* Return true if evaluating EXPR could trap.
4274    EXPR is GENERIC, while tree_could_trap_p can be called
4275    only on GIMPLE.  */
4276 
4277 bool
generic_expr_could_trap_p(tree expr)4278 generic_expr_could_trap_p (tree expr)
4279 {
4280   unsigned i, n;
4281 
4282   if (!expr || is_gimple_val (expr))
4283     return false;
4284 
4285   if (!EXPR_P (expr) || tree_could_trap_p (expr))
4286     return true;
4287 
4288   n = TREE_OPERAND_LENGTH (expr);
4289   for (i = 0; i < n; i++)
4290     if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
4291       return true;
4292 
4293   return false;
4294 }
4295 
4296 /*  Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
4297     into
4298 
4299     if (p)                              if (p)
4300       t1 = a;                             a;
4301     else            or        else
4302       t1 = b;                             b;
4303     t1;
4304 
4305     The second form is used when *EXPR_P is of type void.
4306 
4307     PRE_P points to the list where side effects that must happen before
4308       *EXPR_P should be stored.  */
4309 
4310 static enum gimplify_status
gimplify_cond_expr(tree * expr_p,gimple_seq * pre_p,fallback_t fallback)4311 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
4312 {
4313   tree expr = *expr_p;
4314   tree type = TREE_TYPE (expr);
4315   location_t loc = EXPR_LOCATION (expr);
4316   tree tmp, arm1, arm2;
4317   enum gimplify_status ret;
4318   tree label_true, label_false, label_cont;
4319   bool have_then_clause_p, have_else_clause_p;
4320   gcond *cond_stmt;
4321   enum tree_code pred_code;
4322   gimple_seq seq = NULL;
4323 
4324   /* If this COND_EXPR has a value, copy the values into a temporary within
4325      the arms.  */
4326   if (!VOID_TYPE_P (type))
4327     {
4328       tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
4329       tree result;
4330 
4331       /* If either an rvalue is ok or we do not require an lvalue, create the
4332            temporary.  But we cannot do that if the type is addressable.  */
4333       if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
4334             && !TREE_ADDRESSABLE (type))
4335           {
4336             if (gimplify_ctxp->allow_rhs_cond_expr
4337                 /* If either branch has side effects or could trap, it can't be
4338                      evaluated unconditionally.  */
4339                 && !TREE_SIDE_EFFECTS (then_)
4340                 && !generic_expr_could_trap_p (then_)
4341                 && !TREE_SIDE_EFFECTS (else_)
4342                 && !generic_expr_could_trap_p (else_))
4343               return gimplify_pure_cond_expr (expr_p, pre_p);
4344 
4345             tmp = create_tmp_var (type, "iftmp");
4346             result = tmp;
4347           }
4348 
4349       /* Otherwise, only create and copy references to the values.  */
4350       else
4351           {
4352             type = build_pointer_type (type);
4353 
4354             if (!VOID_TYPE_P (TREE_TYPE (then_)))
4355               then_ = build_fold_addr_expr_loc (loc, then_);
4356 
4357             if (!VOID_TYPE_P (TREE_TYPE (else_)))
4358               else_ = build_fold_addr_expr_loc (loc, else_);
4359 
4360             expr
4361               = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
4362 
4363             tmp = create_tmp_var (type, "iftmp");
4364             result = build_simple_mem_ref_loc (loc, tmp);
4365           }
4366 
4367       /* Build the new then clause, `tmp = then_;'.  But don't build the
4368            assignment if the value is void; in C++ it can be if it's a throw.  */
4369       if (!VOID_TYPE_P (TREE_TYPE (then_)))
4370           TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
4371 
4372       /* Similarly, build the new else clause, `tmp = else_;'.  */
4373       if (!VOID_TYPE_P (TREE_TYPE (else_)))
4374           TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
4375 
4376       TREE_TYPE (expr) = void_type_node;
4377       recalculate_side_effects (expr);
4378 
4379       /* Move the COND_EXPR to the prequeue.  */
4380       gimplify_stmt (&expr, pre_p);
4381 
4382       *expr_p = result;
4383       return GS_ALL_DONE;
4384     }
4385 
4386   /* Remove any COMPOUND_EXPR so the following cases will be caught.  */
4387   STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
4388   if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
4389     gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
4390 
4391   /* Make sure the condition has BOOLEAN_TYPE.  */
4392   TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
4393 
4394   /* Break apart && and || conditions.  */
4395   if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
4396       || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
4397     {
4398       expr = shortcut_cond_expr (expr);
4399 
4400       if (expr != *expr_p)
4401           {
4402             *expr_p = expr;
4403 
4404             /* We can't rely on gimplify_expr to re-gimplify the expanded
4405                form properly, as cleanups might cause the target labels to be
4406                wrapped in a TRY_FINALLY_EXPR.  To prevent that, we need to
4407                set up a conditional context.  */
4408             gimple_push_condition ();
4409             gimplify_stmt (expr_p, &seq);
4410             gimple_pop_condition (pre_p);
4411             gimple_seq_add_seq (pre_p, seq);
4412 
4413             return GS_ALL_DONE;
4414           }
4415     }
4416 
4417   /* Now do the normal gimplification.  */
4418 
4419   /* Gimplify condition.  */
4420   ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
4421                            is_gimple_condexpr_for_cond, fb_rvalue);
4422   if (ret == GS_ERROR)
4423     return GS_ERROR;
4424   gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
4425 
4426   gimple_push_condition ();
4427 
4428   have_then_clause_p = have_else_clause_p = false;
4429   label_true = find_goto_label (TREE_OPERAND (expr, 1));
4430   if (label_true
4431       && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
4432       /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4433            have different locations, otherwise we end up with incorrect
4434            location information on the branches.  */
4435       && (optimize
4436             || !EXPR_HAS_LOCATION (expr)
4437             || !rexpr_has_location (label_true)
4438             || EXPR_LOCATION (expr) == rexpr_location (label_true)))
4439     {
4440       have_then_clause_p = true;
4441       label_true = GOTO_DESTINATION (label_true);
4442     }
4443   else
4444     label_true = create_artificial_label (UNKNOWN_LOCATION);
4445   label_false = find_goto_label (TREE_OPERAND (expr, 2));
4446   if (label_false
4447       && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
4448       /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
4449            have different locations, otherwise we end up with incorrect
4450            location information on the branches.  */
4451       && (optimize
4452             || !EXPR_HAS_LOCATION (expr)
4453             || !rexpr_has_location (label_false)
4454             || EXPR_LOCATION (expr) == rexpr_location (label_false)))
4455     {
4456       have_else_clause_p = true;
4457       label_false = GOTO_DESTINATION (label_false);
4458     }
4459   else
4460     label_false = create_artificial_label (UNKNOWN_LOCATION);
4461 
4462   gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
4463                                          &arm2);
4464   cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
4465                                          label_false);
4466   gimple_set_location (cond_stmt, EXPR_LOCATION (expr));
4467   copy_warning (cond_stmt, COND_EXPR_COND (expr));
4468   gimplify_seq_add_stmt (&seq, cond_stmt);
4469   gimple_stmt_iterator gsi = gsi_last (seq);
4470   maybe_fold_stmt (&gsi);
4471 
4472   label_cont = NULL_TREE;
4473   if (!have_then_clause_p)
4474     {
4475       /* For if (...) {} else { code; } put label_true after
4476            the else block.  */
4477       if (TREE_OPERAND (expr, 1) == NULL_TREE
4478             && !have_else_clause_p
4479             && TREE_OPERAND (expr, 2) != NULL_TREE)
4480           {
4481             /* For if (0) {} else { code; } tell -Wimplicit-fallthrough
4482                handling that label_cont == label_true can be only reached
4483                through fallthrough from { code; }.  */
4484             if (integer_zerop (COND_EXPR_COND (expr)))
4485               UNUSED_LABEL_P (label_true) = 1;
4486             label_cont = label_true;
4487           }
4488       else
4489           {
4490             bool then_side_effects
4491               = (TREE_OPERAND (expr, 1)
4492                  && TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)));
4493             gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
4494             have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
4495             /* For if (...) { code; } else {} or
4496                if (...) { code; } else goto label; or
4497                if (...) { code; return; } else { ... }
4498                label_cont isn't needed.  */
4499             if (!have_else_clause_p
4500                 && TREE_OPERAND (expr, 2) != NULL_TREE
4501                 && gimple_seq_may_fallthru (seq))
4502               {
4503                 gimple *g;
4504                 label_cont = create_artificial_label (UNKNOWN_LOCATION);
4505 
4506                 /* For if (0) { non-side-effect-code } else { code }
4507                      tell -Wimplicit-fallthrough handling that label_cont can
4508                      be only reached through fallthrough from { code }.  */
4509                 if (integer_zerop (COND_EXPR_COND (expr)))
4510                     {
4511                       UNUSED_LABEL_P (label_true) = 1;
4512                       if (!then_side_effects)
4513                         UNUSED_LABEL_P (label_cont) = 1;
4514                     }
4515 
4516                 g = gimple_build_goto (label_cont);
4517 
4518                 /* GIMPLE_COND's are very low level; they have embedded
4519                      gotos.  This particular embedded goto should not be marked
4520                      with the location of the original COND_EXPR, as it would
4521                      correspond to the COND_EXPR's condition, not the ELSE or the
4522                      THEN arms.  To avoid marking it with the wrong location, flag
4523                      it as "no location".  */
4524                 gimple_set_do_not_emit_location (g);
4525 
4526                 gimplify_seq_add_stmt (&seq, g);
4527               }
4528           }
4529     }
4530   if (!have_else_clause_p)
4531     {
4532       /* For if (1) { code } or if (1) { code } else { non-side-effect-code }
4533            tell -Wimplicit-fallthrough handling that label_false can be only
4534            reached through fallthrough from { code }.  */
4535       if (integer_nonzerop (COND_EXPR_COND (expr))
4536             && (TREE_OPERAND (expr, 2) == NULL_TREE
4537                 || !TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2))))
4538           UNUSED_LABEL_P (label_false) = 1;
4539       gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
4540       have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
4541     }
4542   if (label_cont)
4543     gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
4544 
4545   gimple_pop_condition (pre_p);
4546   gimple_seq_add_seq (pre_p, seq);
4547 
4548   if (ret == GS_ERROR)
4549     ; /* Do nothing.  */
4550   else if (have_then_clause_p || have_else_clause_p)
4551     ret = GS_ALL_DONE;
4552   else
4553     {
4554       /* Both arms are empty; replace the COND_EXPR with its predicate.  */
4555       expr = TREE_OPERAND (expr, 0);
4556       gimplify_stmt (&expr, pre_p);
4557     }
4558 
4559   *expr_p = NULL;
4560   return ret;
4561 }
4562 
4563 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
4564    to be marked addressable.
4565 
4566    We cannot rely on such an expression being directly markable if a temporary
4567    has been created by the gimplification.  In this case, we create another
4568    temporary and initialize it with a copy, which will become a store after we
4569    mark it addressable.  This can happen if the front-end passed us something
4570    that it could not mark addressable yet, like a Fortran pass-by-reference
4571    parameter (int) floatvar.  */
4572 
4573 static void
prepare_gimple_addressable(tree * expr_p,gimple_seq * seq_p)4574 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
4575 {
4576   while (handled_component_p (*expr_p))
4577     expr_p = &TREE_OPERAND (*expr_p, 0);
4578   if (is_gimple_reg (*expr_p))
4579     {
4580       /* Do not allow an SSA name as the temporary.  */
4581       tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
4582       DECL_NOT_GIMPLE_REG_P (var) = 1;
4583       *expr_p = var;
4584     }
4585 }
4586 
4587 /* A subroutine of gimplify_modify_expr.  Replace a MODIFY_EXPR with
4588    a call to __builtin_memcpy.  */
4589 
4590 static enum gimplify_status
gimplify_modify_expr_to_memcpy(tree * expr_p,tree size,bool want_value,gimple_seq * seq_p)4591 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
4592                                         gimple_seq *seq_p)
4593 {
4594   tree t, to, to_ptr, from, from_ptr;
4595   gcall *gs;
4596   location_t loc = EXPR_LOCATION (*expr_p);
4597 
4598   to = TREE_OPERAND (*expr_p, 0);
4599   from = TREE_OPERAND (*expr_p, 1);
4600 
4601   /* Mark the RHS addressable.  Beware that it may not be possible to do so
4602      directly if a temporary has been created by the gimplification.  */
4603   prepare_gimple_addressable (&from, seq_p);
4604 
4605   mark_addressable (from);
4606   from_ptr = build_fold_addr_expr_loc (loc, from);
4607   gimplify_arg (&from_ptr, seq_p, loc);
4608 
4609   mark_addressable (to);
4610   to_ptr = build_fold_addr_expr_loc (loc, to);
4611   gimplify_arg (&to_ptr, seq_p, loc);
4612 
4613   t = builtin_decl_implicit (BUILT_IN_MEMCPY);
4614 
4615   gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
4616   gimple_call_set_alloca_for_var (gs, true);
4617 
4618   if (want_value)
4619     {
4620       /* tmp = memcpy() */
4621       t = create_tmp_var (TREE_TYPE (to_ptr));
4622       gimple_call_set_lhs (gs, t);
4623       gimplify_seq_add_stmt (seq_p, gs);
4624 
4625       *expr_p = build_simple_mem_ref (t);
4626       return GS_ALL_DONE;
4627     }
4628 
4629   gimplify_seq_add_stmt (seq_p, gs);
4630   *expr_p = NULL;
4631   return GS_ALL_DONE;
4632 }
4633 
4634 /* A subroutine of gimplify_modify_expr.  Replace a MODIFY_EXPR with
4635    a call to __builtin_memset.  In this case we know that the RHS is
4636    a CONSTRUCTOR with an empty element list.  */
4637 
4638 static enum gimplify_status
gimplify_modify_expr_to_memset(tree * expr_p,tree size,bool want_value,gimple_seq * seq_p)4639 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
4640                                         gimple_seq *seq_p)
4641 {
4642   tree t, from, to, to_ptr;
4643   gcall *gs;
4644   location_t loc = EXPR_LOCATION (*expr_p);
4645 
4646   /* Assert our assumptions, to abort instead of producing wrong code
4647      silently if they are not met.  Beware that the RHS CONSTRUCTOR might
4648      not be immediately exposed.  */
4649   from = TREE_OPERAND (*expr_p, 1);
4650   if (TREE_CODE (from) == WITH_SIZE_EXPR)
4651     from = TREE_OPERAND (from, 0);
4652 
4653   gcc_assert (TREE_CODE (from) == CONSTRUCTOR
4654                 && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
4655 
4656   /* Now proceed.  */
4657   to = TREE_OPERAND (*expr_p, 0);
4658 
4659   to_ptr = build_fold_addr_expr_loc (loc, to);
4660   gimplify_arg (&to_ptr, seq_p, loc);
4661   t = builtin_decl_implicit (BUILT_IN_MEMSET);
4662 
4663   gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
4664 
4665   if (want_value)
4666     {
4667       /* tmp = memset() */
4668       t = create_tmp_var (TREE_TYPE (to_ptr));
4669       gimple_call_set_lhs (gs, t);
4670       gimplify_seq_add_stmt (seq_p, gs);
4671 
4672       *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
4673       return GS_ALL_DONE;
4674     }
4675 
4676   gimplify_seq_add_stmt (seq_p, gs);
4677   *expr_p = NULL;
4678   return GS_ALL_DONE;
4679 }
4680 
4681 /* A subroutine of gimplify_init_ctor_preeval.  Called via walk_tree,
4682    determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
4683    assignment.  Return non-null if we detect a potential overlap.  */
4684 
4685 struct gimplify_init_ctor_preeval_data
4686 {
4687   /* The base decl of the lhs object.  May be NULL, in which case we
4688      have to assume the lhs is indirect.  */
4689   tree lhs_base_decl;
4690 
4691   /* The alias set of the lhs object.  */
4692   alias_set_type lhs_alias_set;
4693 };
4694 
4695 static tree
gimplify_init_ctor_preeval_1(tree * tp,int * walk_subtrees,void * xdata)4696 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
4697 {
4698   struct gimplify_init_ctor_preeval_data *data
4699     = (struct gimplify_init_ctor_preeval_data *) xdata;
4700   tree t = *tp;
4701 
4702   /* If we find the base object, obviously we have overlap.  */
4703   if (data->lhs_base_decl == t)
4704     return t;
4705 
4706   /* If the constructor component is indirect, determine if we have a
4707      potential overlap with the lhs.  The only bits of information we
4708      have to go on at this point are addressability and alias sets.  */
4709   if ((INDIRECT_REF_P (t)
4710        || TREE_CODE (t) == MEM_REF)
4711       && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4712       && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
4713     return t;
4714 
4715   /* If the constructor component is a call, determine if it can hide a
4716      potential overlap with the lhs through an INDIRECT_REF like above.
4717      ??? Ugh - this is completely broken.  In fact this whole analysis
4718      doesn't look conservative.  */
4719   if (TREE_CODE (t) == CALL_EXPR)
4720     {
4721       tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
4722 
4723       for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
4724           if (POINTER_TYPE_P (TREE_VALUE (type))
4725               && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
4726               && alias_sets_conflict_p (data->lhs_alias_set,
4727                                               get_alias_set
4728                                                 (TREE_TYPE (TREE_VALUE (type)))))
4729             return t;
4730     }
4731 
4732   if (IS_TYPE_OR_DECL_P (t))
4733     *walk_subtrees = 0;
4734   return NULL;
4735 }
4736 
4737 /* A subroutine of gimplify_init_constructor.  Pre-evaluate EXPR,
4738    force values that overlap with the lhs (as described by *DATA)
4739    into temporaries.  */
4740 
4741 static void
gimplify_init_ctor_preeval(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p,struct gimplify_init_ctor_preeval_data * data)4742 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
4743                                   struct gimplify_init_ctor_preeval_data *data)
4744 {
4745   enum gimplify_status one;
4746 
4747   /* If the value is constant, then there's nothing to pre-evaluate.  */
4748   if (TREE_CONSTANT (*expr_p))
4749     {
4750       /* Ensure it does not have side effects, it might contain a reference to
4751            the object we're initializing.  */
4752       gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
4753       return;
4754     }
4755 
4756   /* If the type has non-trivial constructors, we can't pre-evaluate.  */
4757   if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
4758     return;
4759 
4760   /* Recurse for nested constructors.  */
4761   if (TREE_CODE (*expr_p) == CONSTRUCTOR)
4762     {
4763       unsigned HOST_WIDE_INT ix;
4764       constructor_elt *ce;
4765       vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
4766 
4767       FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
4768           gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
4769 
4770       return;
4771     }
4772 
4773   /* If this is a variable sized type, we must remember the size.  */
4774   maybe_with_size_expr (expr_p);
4775 
4776   /* Gimplify the constructor element to something appropriate for the rhs
4777      of a MODIFY_EXPR.  Given that we know the LHS is an aggregate, we know
4778      the gimplifier will consider this a store to memory.  Doing this
4779      gimplification now means that we won't have to deal with complicated
4780      language-specific trees, nor trees like SAVE_EXPR that can induce
4781      exponential search behavior.  */
4782   one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
4783   if (one == GS_ERROR)
4784     {
4785       *expr_p = NULL;
4786       return;
4787     }
4788 
4789   /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
4790      with the lhs, since "a = { .x=a }" doesn't make sense.  This will
4791      always be true for all scalars, since is_gimple_mem_rhs insists on a
4792      temporary variable for them.  */
4793   if (DECL_P (*expr_p))
4794     return;
4795 
4796   /* If this is of variable size, we have no choice but to assume it doesn't
4797      overlap since we can't make a temporary for it.  */
4798   if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
4799     return;
4800 
4801   /* Otherwise, we must search for overlap ...  */
4802   if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
4803     return;
4804 
4805   /* ... and if found, force the value into a temporary.  */
4806   *expr_p = get_formal_tmp_var (*expr_p, pre_p);
4807 }
4808 
4809 /* A subroutine of gimplify_init_ctor_eval.  Create a loop for
4810    a RANGE_EXPR in a CONSTRUCTOR for an array.
4811 
4812       var = lower;
4813     loop_entry:
4814       object[var] = value;
4815       if (var == upper)
4816           goto loop_exit;
4817       var = var + 1;
4818       goto loop_entry;
4819     loop_exit:
4820 
4821    We increment var _after_ the loop exit check because we might otherwise
4822    fail if upper == TYPE_MAX_VALUE (type for upper).
4823 
4824    Note that we never have to deal with SAVE_EXPRs here, because this has
4825    already been taken care of for us, in gimplify_init_ctor_preeval().  */
4826 
4827 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
4828                                              gimple_seq *, bool);
4829 
4830 static void
gimplify_init_ctor_eval_range(tree object,tree lower,tree upper,tree value,tree array_elt_type,gimple_seq * pre_p,bool cleared)4831 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
4832                                      tree value, tree array_elt_type,
4833                                      gimple_seq *pre_p, bool cleared)
4834 {
4835   tree loop_entry_label, loop_exit_label, fall_thru_label;
4836   tree var, var_type, cref, tmp;
4837 
4838   loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
4839   loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
4840   fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
4841 
4842   /* Create and initialize the index variable.  */
4843   var_type = TREE_TYPE (upper);
4844   var = create_tmp_var (var_type);
4845   gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
4846 
4847   /* Add the loop entry label.  */
4848   gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
4849 
4850   /* Build the reference.  */
4851   cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4852                      var, NULL_TREE, NULL_TREE);
4853 
4854   /* If we are a constructor, just call gimplify_init_ctor_eval to do
4855      the store.  Otherwise just assign value to the reference.  */
4856 
4857   if (TREE_CODE (value) == CONSTRUCTOR)
4858     /* NB we might have to call ourself recursively through
4859        gimplify_init_ctor_eval if the value is a constructor.  */
4860     gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4861                                    pre_p, cleared);
4862   else
4863     {
4864       if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue)
4865             != GS_ERROR)
4866           gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
4867     }
4868 
4869   /* We exit the loop when the index var is equal to the upper bound.  */
4870   gimplify_seq_add_stmt (pre_p,
4871                                gimple_build_cond (EQ_EXPR, var, upper,
4872                                                       loop_exit_label, fall_thru_label));
4873 
4874   gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
4875 
4876   /* Otherwise, increment the index var...  */
4877   tmp = build2 (PLUS_EXPR, var_type, var,
4878                     fold_convert (var_type, integer_one_node));
4879   gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
4880 
4881   /* ...and jump back to the loop entry.  */
4882   gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
4883 
4884   /* Add the loop exit label.  */
4885   gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
4886 }
4887 
4888 /* A subroutine of gimplify_init_constructor.  Generate individual
4889    MODIFY_EXPRs for a CONSTRUCTOR.  OBJECT is the LHS against which the
4890    assignments should happen.  ELTS is the CONSTRUCTOR_ELTS of the
4891    CONSTRUCTOR.  CLEARED is true if the entire LHS object has been
4892    zeroed first.  */
4893 
4894 static void
gimplify_init_ctor_eval(tree object,vec<constructor_elt,va_gc> * elts,gimple_seq * pre_p,bool cleared)4895 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
4896                                gimple_seq *pre_p, bool cleared)
4897 {
4898   tree array_elt_type = NULL;
4899   unsigned HOST_WIDE_INT ix;
4900   tree purpose, value;
4901 
4902   if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
4903     array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
4904 
4905   FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
4906     {
4907       tree cref;
4908 
4909       /* NULL values are created above for gimplification errors.  */
4910       if (value == NULL)
4911           continue;
4912 
4913       if (cleared && initializer_zerop (value))
4914           continue;
4915 
4916       /* ??? Here's to hoping the front end fills in all of the indices,
4917            so we don't have to figure out what's missing ourselves.  */
4918       gcc_assert (purpose);
4919 
4920       /* Skip zero-sized fields, unless value has side-effects.  This can
4921            happen with calls to functions returning a empty type, which
4922            we shouldn't discard.  As a number of downstream passes don't
4923            expect sets of empty type fields, we rely on the gimplification of
4924            the MODIFY_EXPR we make below to drop the assignment statement.  */
4925       if (!TREE_SIDE_EFFECTS (value)
4926             && TREE_CODE (purpose) == FIELD_DECL
4927             && is_empty_type (TREE_TYPE (purpose)))
4928           continue;
4929 
4930       /* If we have a RANGE_EXPR, we have to build a loop to assign the
4931            whole range.  */
4932       if (TREE_CODE (purpose) == RANGE_EXPR)
4933           {
4934             tree lower = TREE_OPERAND (purpose, 0);
4935             tree upper = TREE_OPERAND (purpose, 1);
4936 
4937             /* If the lower bound is equal to upper, just treat it as if
4938                upper was the index.  */
4939             if (simple_cst_equal (lower, upper))
4940               purpose = upper;
4941             else
4942               {
4943                 gimplify_init_ctor_eval_range (object, lower, upper, value,
4944                                                        array_elt_type, pre_p, cleared);
4945                 continue;
4946               }
4947           }
4948 
4949       if (array_elt_type)
4950           {
4951             /* Do not use bitsizetype for ARRAY_REF indices.  */
4952             if (TYPE_DOMAIN (TREE_TYPE (object)))
4953               purpose
4954                 = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
4955                                     purpose);
4956             cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
4957                                purpose, NULL_TREE, NULL_TREE);
4958           }
4959       else
4960           {
4961             gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
4962             cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
4963                                unshare_expr (object), purpose, NULL_TREE);
4964           }
4965 
4966       if (TREE_CODE (value) == CONSTRUCTOR
4967             && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
4968           gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
4969                                          pre_p, cleared);
4970       else
4971           {
4972             tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
4973             gimplify_and_add (init, pre_p);
4974             ggc_free (init);
4975           }
4976     }
4977 }
4978 
4979 /* Return the appropriate RHS predicate for this LHS.  */
4980 
4981 gimple_predicate
rhs_predicate_for(tree lhs)4982 rhs_predicate_for (tree lhs)
4983 {
4984   if (is_gimple_reg (lhs))
4985     return is_gimple_reg_rhs_or_call;
4986   else
4987     return is_gimple_mem_rhs_or_call;
4988 }
4989 
4990 /* Return the initial guess for an appropriate RHS predicate for this LHS,
4991    before the LHS has been gimplified.  */
4992 
4993 static gimple_predicate
initial_rhs_predicate_for(tree lhs)4994 initial_rhs_predicate_for (tree lhs)
4995 {
4996   if (is_gimple_reg_type (TREE_TYPE (lhs)))
4997     return is_gimple_reg_rhs_or_call;
4998   else
4999     return is_gimple_mem_rhs_or_call;
5000 }
5001 
5002 /* Gimplify a C99 compound literal expression.  This just means adding
5003    the DECL_EXPR before the current statement and using its anonymous
5004    decl instead.  */
5005 
5006 static enum gimplify_status
gimplify_compound_literal_expr(tree * expr_p,gimple_seq * pre_p,bool (* gimple_test_f)(tree),fallback_t fallback)5007 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
5008                                         bool (*gimple_test_f) (tree),
5009                                         fallback_t fallback)
5010 {
5011   tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
5012   tree decl = DECL_EXPR_DECL (decl_s);
5013   tree init = DECL_INITIAL (decl);
5014   /* Mark the decl as addressable if the compound literal
5015      expression is addressable now, otherwise it is marked too late
5016      after we gimplify the initialization expression.  */
5017   if (TREE_ADDRESSABLE (*expr_p))
5018     TREE_ADDRESSABLE (decl) = 1;
5019   /* Otherwise, if we don't need an lvalue and have a literal directly
5020      substitute it.  Check if it matches the gimple predicate, as
5021      otherwise we'd generate a new temporary, and we can as well just
5022      use the decl we already have.  */
5023   else if (!TREE_ADDRESSABLE (decl)
5024              && !TREE_THIS_VOLATILE (decl)
5025              && init
5026              && (fallback & fb_lvalue) == 0
5027              && gimple_test_f (init))
5028     {
5029       *expr_p = init;
5030       return GS_OK;
5031     }
5032 
5033   /* If the decl is not addressable, then it is being used in some
5034      expression or on the right hand side of a statement, and it can
5035      be put into a readonly data section.  */
5036   if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
5037     TREE_READONLY (decl) = 1;
5038 
5039   /* This decl isn't mentioned in the enclosing block, so add it to the
5040      list of temps.  FIXME it seems a bit of a kludge to say that
5041      anonymous artificial vars aren't pushed, but everything else is.  */
5042   if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
5043     gimple_add_tmp_var (decl);
5044 
5045   gimplify_and_add (decl_s, pre_p);
5046   *expr_p = decl;
5047   return GS_OK;
5048 }
5049 
5050 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
5051    return a new CONSTRUCTOR if something changed.  */
5052 
5053 static tree
optimize_compound_literals_in_ctor(tree orig_ctor)5054 optimize_compound_literals_in_ctor (tree orig_ctor)
5055 {
5056   tree ctor = orig_ctor;
5057   vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
5058   unsigned int idx, num = vec_safe_length (elts);
5059 
5060   for (idx = 0; idx < num; idx++)
5061     {
5062       tree value = (*elts)[idx].value;
5063       tree newval = value;
5064       if (TREE_CODE (value) == CONSTRUCTOR)
5065           newval = optimize_compound_literals_in_ctor (value);
5066       else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
5067           {
5068             tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
5069             tree decl = DECL_EXPR_DECL (decl_s);
5070             tree init = DECL_INITIAL (decl);
5071 
5072             if (!TREE_ADDRESSABLE (value)
5073                 && !TREE_ADDRESSABLE (decl)
5074                 && init
5075                 && TREE_CODE (init) == CONSTRUCTOR)
5076               newval = optimize_compound_literals_in_ctor (init);
5077           }
5078       if (newval == value)
5079           continue;
5080 
5081       if (ctor == orig_ctor)
5082           {
5083             ctor = copy_node (orig_ctor);
5084             CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
5085             elts = CONSTRUCTOR_ELTS (ctor);
5086           }
5087       (*elts)[idx].value = newval;
5088     }
5089   return ctor;
5090 }
5091 
5092 /* A subroutine of gimplify_modify_expr.  Break out elements of a
5093    CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
5094 
5095    Note that we still need to clear any elements that don't have explicit
5096    initializers, so if not all elements are initialized we keep the
5097    original MODIFY_EXPR, we just remove all of the constructor elements.
5098 
5099    If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
5100    GS_ERROR if we would have to create a temporary when gimplifying
5101    this constructor.  Otherwise, return GS_OK.
5102 
5103    If NOTIFY_TEMP_CREATION is false, just do the gimplification.  */
5104 
5105 static enum gimplify_status
gimplify_init_constructor(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p,bool want_value,bool notify_temp_creation)5106 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5107                                  bool want_value, bool notify_temp_creation)
5108 {
5109   tree object, ctor, type;
5110   enum gimplify_status ret;
5111   vec<constructor_elt, va_gc> *elts;
5112   bool cleared = false;
5113   bool is_empty_ctor = false;
5114   bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR);
5115 
5116   gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
5117 
5118   if (!notify_temp_creation)
5119     {
5120       ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
5121                                  is_gimple_lvalue, fb_lvalue);
5122       if (ret == GS_ERROR)
5123           return ret;
5124     }
5125 
5126   object = TREE_OPERAND (*expr_p, 0);
5127   ctor = TREE_OPERAND (*expr_p, 1)
5128     = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
5129   type = TREE_TYPE (ctor);
5130   elts = CONSTRUCTOR_ELTS (ctor);
5131   ret = GS_ALL_DONE;
5132 
5133   switch (TREE_CODE (type))
5134     {
5135     case RECORD_TYPE:
5136     case UNION_TYPE:
5137     case QUAL_UNION_TYPE:
5138     case ARRAY_TYPE:
5139       {
5140           /* Use readonly data for initializers of this or smaller size
5141              regardless of the num_nonzero_elements / num_unique_nonzero_elements
5142              ratio.  */
5143           const HOST_WIDE_INT min_unique_size = 64;
5144           /* If num_nonzero_elements / num_unique_nonzero_elements ratio
5145              is smaller than this, use readonly data.  */
5146           const int unique_nonzero_ratio = 8;
5147           /* True if a single access of the object must be ensured.  This is the
5148              case if the target is volatile, the type is non-addressable and more
5149              than one field need to be assigned.  */
5150           const bool ensure_single_access
5151             = TREE_THIS_VOLATILE (object)
5152               && !TREE_ADDRESSABLE (type)
5153               && vec_safe_length (elts) > 1;
5154           struct gimplify_init_ctor_preeval_data preeval_data;
5155           HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
5156           HOST_WIDE_INT num_unique_nonzero_elements;
5157           bool complete_p, valid_const_initializer;
5158 
5159           /* Aggregate types must lower constructors to initialization of
5160              individual elements.  The exception is that a CONSTRUCTOR node
5161              with no elements indicates zero-initialization of the whole.  */
5162           if (vec_safe_is_empty (elts))
5163             {
5164               if (notify_temp_creation)
5165                 return GS_OK;
5166 
5167               /* The var will be initialized and so appear on lhs of
5168                  assignment, it can't be TREE_READONLY anymore.  */
5169               if (VAR_P (object))
5170                 TREE_READONLY (object) = 0;
5171 
5172               is_empty_ctor = true;
5173               break;
5174             }
5175 
5176           /* Fetch information about the constructor to direct later processing.
5177              We might want to make static versions of it in various cases, and
5178              can only do so if it known to be a valid constant initializer.  */
5179           valid_const_initializer
5180             = categorize_ctor_elements (ctor, &num_nonzero_elements,
5181                                               &num_unique_nonzero_elements,
5182                                               &num_ctor_elements, &complete_p);
5183 
5184           /* If a const aggregate variable is being initialized, then it
5185              should never be a lose to promote the variable to be static.  */
5186           if (valid_const_initializer
5187               && num_nonzero_elements > 1
5188               && TREE_READONLY (object)
5189               && VAR_P (object)
5190               && !DECL_REGISTER (object)
5191               && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))
5192               /* For ctors that have many repeated nonzero elements
5193                  represented through RANGE_EXPRs, prefer initializing
5194                  those through runtime loops over copies of large amounts
5195                  of data from readonly data section.  */
5196               && (num_unique_nonzero_elements
5197                     > num_nonzero_elements / unique_nonzero_ratio
5198                     || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
5199                         <= (unsigned HOST_WIDE_INT) min_unique_size)))
5200             {
5201               if (notify_temp_creation)
5202                 return GS_ERROR;
5203 
5204               DECL_INITIAL (object) = ctor;
5205               TREE_STATIC (object) = 1;
5206               if (!DECL_NAME (object))
5207                 DECL_NAME (object) = create_tmp_var_name ("C");
5208               walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
5209 
5210               /* ??? C++ doesn't automatically append a .<number> to the
5211                  assembler name, and even when it does, it looks at FE private
5212                  data structures to figure out what that number should be,
5213                  which are not set for this variable.  I suppose this is
5214                  important for local statics for inline functions, which aren't
5215                  "local" in the object file sense.  So in order to get a unique
5216                  TU-local symbol, we must invoke the lhd version now.  */
5217               lhd_set_decl_assembler_name (object);
5218 
5219               *expr_p = NULL_TREE;
5220               break;
5221             }
5222 
5223           /* The var will be initialized and so appear on lhs of
5224              assignment, it can't be TREE_READONLY anymore.  */
5225           if (VAR_P (object) && !notify_temp_creation)
5226             TREE_READONLY (object) = 0;
5227 
5228           /* If there are "lots" of initialized elements, even discounting
5229              those that are not address constants (and thus *must* be
5230              computed at runtime), then partition the constructor into
5231              constant and non-constant parts.  Block copy the constant
5232              parts in, then generate code for the non-constant parts.  */
5233           /* TODO.  There's code in cp/typeck.cc to do this.  */
5234 
5235           if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
5236             /* store_constructor will ignore the clearing of variable-sized
5237                objects.  Initializers for such objects must explicitly set
5238                every field that needs to be set.  */
5239             cleared = false;
5240           else if (!complete_p)
5241             /* If the constructor isn't complete, clear the whole object
5242                beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
5243 
5244                ??? This ought not to be needed.  For any element not present
5245                in the initializer, we should simply set them to zero.  Except
5246                we'd need to *find* the elements that are not present, and that
5247                requires trickery to avoid quadratic compile-time behavior in
5248                large cases or excessive memory use in small cases.  */
5249             cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
5250           else if (num_ctor_elements - num_nonzero_elements
5251                      > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
5252                      && num_nonzero_elements < num_ctor_elements / 4)
5253             /* If there are "lots" of zeros, it's more efficient to clear
5254                the memory and then set the nonzero elements.  */
5255             cleared = true;
5256           else if (ensure_single_access && num_nonzero_elements == 0)
5257             /* If a single access to the target must be ensured and all elements
5258                are zero, then it's optimal to clear whatever their number.  */
5259             cleared = true;
5260           else
5261             cleared = false;
5262 
5263           /* If there are "lots" of initialized elements, and all of them
5264              are valid address constants, then the entire initializer can
5265              be dropped to memory, and then memcpy'd out.  Don't do this
5266              for sparse arrays, though, as it's more efficient to follow
5267              the standard CONSTRUCTOR behavior of memset followed by
5268              individual element initialization.  Also don't do this for small
5269              all-zero initializers (which aren't big enough to merit
5270              clearing), and don't try to make bitwise copies of
5271              TREE_ADDRESSABLE types.  */
5272           if (valid_const_initializer
5273               && complete_p
5274               && !(cleared || num_nonzero_elements == 0)
5275               && !TREE_ADDRESSABLE (type))
5276             {
5277               HOST_WIDE_INT size = int_size_in_bytes (type);
5278               unsigned int align;
5279 
5280               /* ??? We can still get unbounded array types, at least
5281                  from the C++ front end.  This seems wrong, but attempt
5282                  to work around it for now.  */
5283               if (size < 0)
5284                 {
5285                     size = int_size_in_bytes (TREE_TYPE (object));
5286                     if (size >= 0)
5287                       TREE_TYPE (ctor) = type = TREE_TYPE (object);
5288                 }
5289 
5290               /* Find the maximum alignment we can assume for the object.  */
5291               /* ??? Make use of DECL_OFFSET_ALIGN.  */
5292               if (DECL_P (object))
5293                 align = DECL_ALIGN (object);
5294               else
5295                 align = TYPE_ALIGN (type);
5296 
5297               /* Do a block move either if the size is so small as to make
5298                  each individual move a sub-unit move on average, or if it
5299                  is so large as to make individual moves inefficient.  */
5300               if (size > 0
5301                     && num_nonzero_elements > 1
5302                     /* For ctors that have many repeated nonzero elements
5303                        represented through RANGE_EXPRs, prefer initializing
5304                        those through runtime loops over copies of large amounts
5305                        of data from readonly data section.  */
5306                     && (num_unique_nonzero_elements
5307                         > num_nonzero_elements / unique_nonzero_ratio
5308                         || size <= min_unique_size)
5309                     && (size < num_nonzero_elements
5310                         || !can_move_by_pieces (size, align)))
5311                 {
5312                     if (notify_temp_creation)
5313                       return GS_ERROR;
5314 
5315                     walk_tree (&ctor, force_labels_r, NULL, NULL);
5316                     ctor = tree_output_constant_def (ctor);
5317                     if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
5318                       ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
5319                     TREE_OPERAND (*expr_p, 1) = ctor;
5320 
5321                     /* This is no longer an assignment of a CONSTRUCTOR, but
5322                        we still may have processing to do on the LHS.  So
5323                        pretend we didn't do anything here to let that happen.  */
5324                     return GS_UNHANDLED;
5325                 }
5326             }
5327 
5328           /* If a single access to the target must be ensured and there are
5329              nonzero elements or the zero elements are not assigned en masse,
5330              initialize the target from a temporary.  */
5331           if (ensure_single_access && (num_nonzero_elements > 0 || !cleared))
5332             {
5333               if (notify_temp_creation)
5334                 return GS_ERROR;
5335 
5336               tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
5337               TREE_OPERAND (*expr_p, 0) = temp;
5338               *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
5339                                     *expr_p,
5340                                     build2 (MODIFY_EXPR, void_type_node,
5341                                               object, temp));
5342               return GS_OK;
5343             }
5344 
5345           if (notify_temp_creation)
5346             return GS_OK;
5347 
5348           /* If there are nonzero elements and if needed, pre-evaluate to capture
5349              elements overlapping with the lhs into temporaries.  We must do this
5350              before clearing to fetch the values before they are zeroed-out.  */
5351           if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
5352             {
5353               preeval_data.lhs_base_decl = get_base_address (object);
5354               if (!DECL_P (preeval_data.lhs_base_decl))
5355                 preeval_data.lhs_base_decl = NULL;
5356               preeval_data.lhs_alias_set = get_alias_set (object);
5357 
5358               gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
5359                                                   pre_p, post_p, &preeval_data);
5360             }
5361 
5362           bool ctor_has_side_effects_p
5363             = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
5364 
5365           if (cleared)
5366             {
5367               /* Zap the CONSTRUCTOR element list, which simplifies this case.
5368                  Note that we still have to gimplify, in order to handle the
5369                  case of variable sized types.  Avoid shared tree structures.  */
5370               CONSTRUCTOR_ELTS (ctor) = NULL;
5371               TREE_SIDE_EFFECTS (ctor) = 0;
5372               object = unshare_expr (object);
5373               gimplify_stmt (expr_p, pre_p);
5374             }
5375 
5376           /* If we have not block cleared the object, or if there are nonzero
5377              elements in the constructor, or if the constructor has side effects,
5378              add assignments to the individual scalar fields of the object.  */
5379           if (!cleared
5380               || num_nonzero_elements > 0
5381               || ctor_has_side_effects_p)
5382             gimplify_init_ctor_eval (object, elts, pre_p, cleared);
5383 
5384           *expr_p = NULL_TREE;
5385       }
5386       break;
5387 
5388     case COMPLEX_TYPE:
5389       {
5390           tree r, i;
5391 
5392           if (notify_temp_creation)
5393             return GS_OK;
5394 
5395           /* Extract the real and imaginary parts out of the ctor.  */
5396           gcc_assert (elts->length () == 2);
5397           r = (*elts)[0].value;
5398           i = (*elts)[1].value;
5399           if (r == NULL || i == NULL)
5400             {
5401               tree zero = build_zero_cst (TREE_TYPE (type));
5402               if (r == NULL)
5403                 r = zero;
5404               if (i == NULL)
5405                 i = zero;
5406             }
5407 
5408           /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
5409              represent creation of a complex value.  */
5410           if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
5411             {
5412               ctor = build_complex (type, r, i);
5413               TREE_OPERAND (*expr_p, 1) = ctor;
5414             }
5415           else
5416             {
5417               ctor = build2 (COMPLEX_EXPR, type, r, i);
5418               TREE_OPERAND (*expr_p, 1) = ctor;
5419               ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
5420                                          pre_p,
5421                                          post_p,
5422                                          rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
5423                                          fb_rvalue);
5424             }
5425       }
5426       break;
5427 
5428     case VECTOR_TYPE:
5429       {
5430           unsigned HOST_WIDE_INT ix;
5431           constructor_elt *ce;
5432 
5433           if (notify_temp_creation)
5434             return GS_OK;
5435 
5436           /* Go ahead and simplify constant constructors to VECTOR_CST.  */
5437           if (TREE_CONSTANT (ctor))
5438             {
5439               bool constant_p = true;
5440               tree value;
5441 
5442               /* Even when ctor is constant, it might contain non-*_CST
5443                  elements, such as addresses or trapping values like
5444                  1.0/0.0 - 1.0/0.0.  Such expressions don't belong
5445                  in VECTOR_CST nodes.  */
5446               FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
5447                 if (!CONSTANT_CLASS_P (value))
5448                     {
5449                       constant_p = false;
5450                       break;
5451                     }
5452 
5453               if (constant_p)
5454                 {
5455                     TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
5456                     break;
5457                 }
5458 
5459               TREE_CONSTANT (ctor) = 0;
5460             }
5461 
5462           /* Vector types use CONSTRUCTOR all the way through gimple
5463              compilation as a general initializer.  */
5464           FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
5465             {
5466               enum gimplify_status tret;
5467               tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
5468                                           fb_rvalue);
5469               if (tret == GS_ERROR)
5470                 ret = GS_ERROR;
5471               else if (TREE_STATIC (ctor)
5472                          && !initializer_constant_valid_p (ce->value,
5473                                                                    TREE_TYPE (ce->value)))
5474                 TREE_STATIC (ctor) = 0;
5475             }
5476           recompute_constructor_flags (ctor);
5477           if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
5478             TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
5479       }
5480       break;
5481 
5482     default:
5483       /* So how did we get a CONSTRUCTOR for a scalar type?  */
5484       gcc_unreachable ();
5485     }
5486 
5487   if (ret == GS_ERROR)
5488     return GS_ERROR;
5489   /* If we have gimplified both sides of the initializer but have
5490      not emitted an assignment, do so now.  */
5491   if (*expr_p)
5492     {
5493       tree lhs = TREE_OPERAND (*expr_p, 0);
5494       tree rhs = TREE_OPERAND (*expr_p, 1);
5495       if (want_value && object == lhs)
5496           lhs = unshare_expr (lhs);
5497       gassign *init = gimple_build_assign (lhs, rhs);
5498       gimplify_seq_add_stmt (pre_p, init);
5499     }
5500   if (want_value)
5501     {
5502       *expr_p = object;
5503       ret = GS_OK;
5504     }
5505   else
5506     {
5507       *expr_p = NULL;
5508       ret = GS_ALL_DONE;
5509     }
5510 
5511   /* If the user requests to initialize automatic variables, we
5512      should initialize paddings inside the variable.  Add a call to
5513      __builtin_clear_pading (&object, 0, for_auto_init = true) to
5514      initialize paddings of object always to zero regardless of
5515      INIT_TYPE.  Note, we will not insert this call if the aggregate
5516      variable has be completely cleared already or it's initialized
5517      with an empty constructor.  We cannot insert this call if the
5518      variable is a gimple register since __builtin_clear_padding will take
5519      the address of the variable.  As a result, if a long double/_Complex long
5520      double variable will be spilled into stack later, its padding cannot
5521      be cleared with __builtin_clear_padding.  We should clear its padding
5522      when it is spilled into memory.  */
5523   if (is_init_expr
5524       && !is_gimple_reg (object)
5525       && clear_padding_type_may_have_padding_p (type)
5526       && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor)
5527             || !AGGREGATE_TYPE_P (type))
5528       && is_var_need_auto_init (object))
5529     gimple_add_padding_init_for_auto_var (object, false, pre_p);
5530 
5531   return ret;
5532 }
5533 
5534 /* Given a pointer value OP0, return a simplified version of an
5535    indirection through OP0, or NULL_TREE if no simplification is
5536    possible.  This may only be applied to a rhs of an expression.
5537    Note that the resulting type may be different from the type pointed
5538    to in the sense that it is still compatible from the langhooks
5539    point of view. */
5540 
5541 static tree
gimple_fold_indirect_ref_rhs(tree t)5542 gimple_fold_indirect_ref_rhs (tree t)
5543 {
5544   return gimple_fold_indirect_ref (t);
5545 }
5546 
5547 /* Subroutine of gimplify_modify_expr to do simplifications of
5548    MODIFY_EXPRs based on the code of the RHS.  We loop for as long as
5549    something changes.  */
5550 
5551 static enum gimplify_status
gimplify_modify_expr_rhs(tree * expr_p,tree * from_p,tree * to_p,gimple_seq * pre_p,gimple_seq * post_p,bool want_value)5552 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
5553                                 gimple_seq *pre_p, gimple_seq *post_p,
5554                                 bool want_value)
5555 {
5556   enum gimplify_status ret = GS_UNHANDLED;
5557   bool changed;
5558 
5559   do
5560     {
5561       changed = false;
5562       switch (TREE_CODE (*from_p))
5563           {
5564           case VAR_DECL:
5565             /* If we're assigning from a read-only variable initialized with
5566                a constructor and not volatile, do the direct assignment from
5567                the constructor, but only if the target is not volatile either
5568                since this latter assignment might end up being done on a per
5569                field basis.  However, if the target is volatile and the type
5570                is aggregate and non-addressable, gimplify_init_constructor
5571                knows that it needs to ensure a single access to the target
5572                and it will return GS_OK only in this case.  */
5573             if (TREE_READONLY (*from_p)
5574                 && DECL_INITIAL (*from_p)
5575                 && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR
5576                 && !TREE_THIS_VOLATILE (*from_p)
5577                 && (!TREE_THIS_VOLATILE (*to_p)
5578                       || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p))
5579                           && !TREE_ADDRESSABLE (TREE_TYPE (*to_p)))))
5580               {
5581                 tree old_from = *from_p;
5582                 enum gimplify_status subret;
5583 
5584                 /* Move the constructor into the RHS.  */
5585                 *from_p = unshare_expr (DECL_INITIAL (*from_p));
5586 
5587                 /* Let's see if gimplify_init_constructor will need to put
5588                      it in memory.  */
5589                 subret = gimplify_init_constructor (expr_p, NULL, NULL,
5590                                                               false, true);
5591                 if (subret == GS_ERROR)
5592                     {
5593                       /* If so, revert the change.  */
5594                       *from_p = old_from;
5595                     }
5596                 else
5597                     {
5598                       ret = GS_OK;
5599                       changed = true;
5600                     }
5601               }
5602             break;
5603           case INDIRECT_REF:
5604             {
5605               /* If we have code like
5606 
5607                *(const A*)(A*)&x
5608 
5609                where the type of "x" is a (possibly cv-qualified variant
5610                of "A"), treat the entire expression as identical to "x".
5611                This kind of code arises in C++ when an object is bound
5612                to a const reference, and if "x" is a TARGET_EXPR we want
5613                to take advantage of the optimization below.  */
5614               bool volatile_p = TREE_THIS_VOLATILE (*from_p);
5615               tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
5616               if (t)
5617                 {
5618                     if (TREE_THIS_VOLATILE (t) != volatile_p)
5619                       {
5620                         if (DECL_P (t))
5621                           t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
5622                                                                 build_fold_addr_expr (t));
5623                         if (REFERENCE_CLASS_P (t))
5624                           TREE_THIS_VOLATILE (t) = volatile_p;
5625                       }
5626                     *from_p = t;
5627                     ret = GS_OK;
5628                     changed = true;
5629                 }
5630               break;
5631             }
5632 
5633           case TARGET_EXPR:
5634             {
5635               /* If we are initializing something from a TARGET_EXPR, strip the
5636                  TARGET_EXPR and initialize it directly, if possible.  This can't
5637                  be done if the initializer is void, since that implies that the
5638                  temporary is set in some non-trivial way.
5639 
5640                  ??? What about code that pulls out the temp and uses it
5641                  elsewhere? I think that such code never uses the TARGET_EXPR as
5642                  an initializer.  If I'm wrong, we'll die because the temp won't
5643                  have any RTL.  In that case, I guess we'll need to replace
5644                  references somehow.  */
5645               tree init = TARGET_EXPR_INITIAL (*from_p);
5646 
5647               if (init
5648                     && (TREE_CODE (*expr_p) != MODIFY_EXPR
5649                         || !TARGET_EXPR_NO_ELIDE (*from_p))
5650                     && !VOID_TYPE_P (TREE_TYPE (init)))
5651                 {
5652                     *from_p = init;
5653                     ret = GS_OK;
5654                     changed = true;
5655                 }
5656             }
5657             break;
5658 
5659           case COMPOUND_EXPR:
5660             /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
5661                caught.  */
5662             gimplify_compound_expr (from_p, pre_p, true);
5663             ret = GS_OK;
5664             changed = true;
5665             break;
5666 
5667           case CONSTRUCTOR:
5668             /* If we already made some changes, let the front end have a
5669                crack at this before we break it down.  */
5670             if (ret != GS_UNHANDLED)
5671               break;
5672 
5673             /* If we're initializing from a CONSTRUCTOR, break this into
5674                individual MODIFY_EXPRs.  */
5675             ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
5676                                                      false);
5677             return ret;
5678 
5679           case COND_EXPR:
5680             /* If we're assigning to a non-register type, push the assignment
5681                down into the branches.  This is mandatory for ADDRESSABLE types,
5682                since we cannot generate temporaries for such, but it saves a
5683                copy in other cases as well.  */
5684             if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
5685               {
5686                 /* This code should mirror the code in gimplify_cond_expr. */
5687                 enum tree_code code = TREE_CODE (*expr_p);
5688                 tree cond = *from_p;
5689                 tree result = *to_p;
5690 
5691                 ret = gimplify_expr (&result, pre_p, post_p,
5692                                            is_gimple_lvalue, fb_lvalue);
5693                 if (ret != GS_ERROR)
5694                     ret = GS_OK;
5695 
5696                 /* If we are going to write RESULT more than once, clear
5697                      TREE_READONLY flag, otherwise we might incorrectly promote
5698                      the variable to static const and initialize it at compile
5699                      time in one of the branches.  */
5700                 if (VAR_P (result)
5701                       && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
5702                       && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5703                     TREE_READONLY (result) = 0;
5704                 if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
5705                     TREE_OPERAND (cond, 1)
5706                       = build2 (code, void_type_node, result,
5707                                   TREE_OPERAND (cond, 1));
5708                 if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
5709                     TREE_OPERAND (cond, 2)
5710                       = build2 (code, void_type_node, unshare_expr (result),
5711                                   TREE_OPERAND (cond, 2));
5712 
5713                 TREE_TYPE (cond) = void_type_node;
5714                 recalculate_side_effects (cond);
5715 
5716                 if (want_value)
5717                     {
5718                       gimplify_and_add (cond, pre_p);
5719                       *expr_p = unshare_expr (result);
5720                     }
5721                 else
5722                     *expr_p = cond;
5723                 return ret;
5724               }
5725             break;
5726 
5727           case CALL_EXPR:
5728             /* For calls that return in memory, give *to_p as the CALL_EXPR's
5729                return slot so that we don't generate a temporary.  */
5730             if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
5731                 && aggregate_value_p (*from_p, *from_p))
5732               {
5733                 bool use_target;
5734 
5735                 if (!(rhs_predicate_for (*to_p))(*from_p))
5736                     /* If we need a temporary, *to_p isn't accurate.  */
5737                     use_target = false;
5738                 /* It's OK to use the return slot directly unless it's an NRV. */
5739                 else if (TREE_CODE (*to_p) == RESULT_DECL
5740                            && DECL_NAME (*to_p) == NULL_TREE
5741                            && needs_to_live_in_memory (*to_p))
5742                     use_target = true;
5743                 else if (is_gimple_reg_type (TREE_TYPE (*to_p))
5744                            || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
5745                     /* Don't force regs into memory.  */
5746                     use_target = false;
5747                 else if (TREE_CODE (*expr_p) == INIT_EXPR)
5748                     /* It's OK to use the target directly if it's being
5749                        initialized. */
5750                     use_target = true;
5751                 else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
5752                            != INTEGER_CST)
5753                     /* Always use the target and thus RSO for variable-sized types.
5754                        GIMPLE cannot deal with a variable-sized assignment
5755                        embedded in a call statement.  */
5756                     use_target = true;
5757                 else if (TREE_CODE (*to_p) != SSA_NAME
5758                           && (!is_gimple_variable (*to_p)
5759                                 || needs_to_live_in_memory (*to_p)))
5760                     /* Don't use the original target if it's already addressable;
5761                        if its address escapes, and the called function uses the
5762                        NRV optimization, a conforming program could see *to_p
5763                        change before the called function returns; see c++/19317.
5764                        When optimizing, the return_slot pass marks more functions
5765                        as safe after we have escape info.  */
5766                     use_target = false;
5767                 else
5768                     use_target = true;
5769 
5770                 if (use_target)
5771                     {
5772                       CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
5773                       mark_addressable (*to_p);
5774                     }
5775               }
5776             break;
5777 
5778           case WITH_SIZE_EXPR:
5779             /* Likewise for calls that return an aggregate of non-constant size,
5780                since we would not be able to generate a temporary at all.  */
5781             if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
5782               {
5783                 *from_p = TREE_OPERAND (*from_p, 0);
5784                 /* We don't change ret in this case because the
5785                      WITH_SIZE_EXPR might have been added in
5786                      gimplify_modify_expr, so returning GS_OK would lead to an
5787                      infinite loop.  */
5788                 changed = true;
5789               }
5790             break;
5791 
5792             /* If we're initializing from a container, push the initialization
5793                inside it.  */
5794           case CLEANUP_POINT_EXPR:
5795           case BIND_EXPR:
5796           case STATEMENT_LIST:
5797             {
5798               tree wrap = *from_p;
5799               tree t;
5800 
5801               ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
5802                                          fb_lvalue);
5803               if (ret != GS_ERROR)
5804                 ret = GS_OK;
5805 
5806               t = voidify_wrapper_expr (wrap, *expr_p);
5807               gcc_assert (t == *expr_p);
5808 
5809               if (want_value)
5810                 {
5811                     gimplify_and_add (wrap, pre_p);
5812                     *expr_p = unshare_expr (*to_p);
5813                 }
5814               else
5815                 *expr_p = wrap;
5816               return GS_OK;
5817             }
5818 
5819           case NOP_EXPR:
5820             /* Pull out compound literal expressions from a NOP_EXPR.
5821                Those are created in the C FE to drop qualifiers during
5822                lvalue conversion.  */
5823             if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
5824                 && tree_ssa_useless_type_conversion (*from_p))
5825               {
5826                 *from_p = TREE_OPERAND (*from_p, 0);
5827                 ret = GS_OK;
5828                 changed = true;
5829               }
5830             break;
5831 
5832           case COMPOUND_LITERAL_EXPR:
5833             {
5834               tree complit = TREE_OPERAND (*expr_p, 1);
5835               tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
5836               tree decl = DECL_EXPR_DECL (decl_s);
5837               tree init = DECL_INITIAL (decl);
5838 
5839               /* struct T x = (struct T) { 0, 1, 2 } can be optimized
5840                  into struct T x = { 0, 1, 2 } if the address of the
5841                  compound literal has never been taken.  */
5842               if (!TREE_ADDRESSABLE (complit)
5843                     && !TREE_ADDRESSABLE (decl)
5844                     && init)
5845                 {
5846                     *expr_p = copy_node (*expr_p);
5847                     TREE_OPERAND (*expr_p, 1) = init;
5848                     return GS_OK;
5849                 }
5850             }
5851 
5852           default:
5853             break;
5854           }
5855     }
5856   while (changed);
5857 
5858   return ret;
5859 }
5860 
5861 
5862 /* Return true if T looks like a valid GIMPLE statement.  */
5863 
5864 static bool
is_gimple_stmt(tree t)5865 is_gimple_stmt (tree t)
5866 {
5867   const enum tree_code code = TREE_CODE (t);
5868 
5869   switch (code)
5870     {
5871     case NOP_EXPR:
5872       /* The only valid NOP_EXPR is the empty statement.  */
5873       return IS_EMPTY_STMT (t);
5874 
5875     case BIND_EXPR:
5876     case COND_EXPR:
5877       /* These are only valid if they're void.  */
5878       return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
5879 
5880     case SWITCH_EXPR:
5881     case GOTO_EXPR:
5882     case RETURN_EXPR:
5883     case LABEL_EXPR:
5884     case CASE_LABEL_EXPR:
5885     case TRY_CATCH_EXPR:
5886     case TRY_FINALLY_EXPR:
5887     case EH_FILTER_EXPR:
5888     case CATCH_EXPR:
5889     case ASM_EXPR:
5890     case STATEMENT_LIST:
5891     case OACC_PARALLEL:
5892     case OACC_KERNELS:
5893     case OACC_SERIAL:
5894     case OACC_DATA:
5895     case OACC_HOST_DATA:
5896     case OACC_DECLARE:
5897     case OACC_UPDATE:
5898     case OACC_ENTER_DATA:
5899     case OACC_EXIT_DATA:
5900     case OACC_CACHE:
5901     case OMP_PARALLEL:
5902     case OMP_FOR:
5903     case OMP_SIMD:
5904     case OMP_DISTRIBUTE:
5905     case OMP_LOOP:
5906     case OACC_LOOP:
5907     case OMP_SCAN:
5908     case OMP_SCOPE:
5909     case OMP_SECTIONS:
5910     case OMP_SECTION:
5911     case OMP_SINGLE:
5912     case OMP_MASTER:
5913     case OMP_MASKED:
5914     case OMP_TASKGROUP:
5915     case OMP_ORDERED:
5916     case OMP_CRITICAL:
5917     case OMP_TASK:
5918     case OMP_TARGET:
5919     case OMP_TARGET_DATA:
5920     case OMP_TARGET_UPDATE:
5921     case OMP_TARGET_ENTER_DATA:
5922     case OMP_TARGET_EXIT_DATA:
5923     case OMP_TASKLOOP:
5924     case OMP_TEAMS:
5925       /* These are always void.  */
5926       return true;
5927 
5928     case CALL_EXPR:
5929     case MODIFY_EXPR:
5930     case PREDICT_EXPR:
5931       /* These are valid regardless of their type.  */
5932       return true;
5933 
5934     default:
5935       return false;
5936     }
5937 }
5938 
5939 
5940 /* Promote partial stores to COMPLEX variables to total stores.  *EXPR_P is
5941    a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
5942 
5943    IMPORTANT NOTE: This promotion is performed by introducing a load of the
5944    other, unmodified part of the complex object just before the total store.
5945    As a consequence, if the object is still uninitialized, an undefined value
5946    will be loaded into a register, which may result in a spurious exception
5947    if the register is floating-point and the value happens to be a signaling
5948    NaN for example.  Then the fully-fledged complex operations lowering pass
5949    followed by a DCE pass are necessary in order to fix things up.  */
5950 
5951 static enum gimplify_status
gimplify_modify_expr_complex_part(tree * expr_p,gimple_seq * pre_p,bool want_value)5952 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
5953                                    bool want_value)
5954 {
5955   enum tree_code code, ocode;
5956   tree lhs, rhs, new_rhs, other, realpart, imagpart;
5957 
5958   lhs = TREE_OPERAND (*expr_p, 0);
5959   rhs = TREE_OPERAND (*expr_p, 1);
5960   code = TREE_CODE (lhs);
5961   lhs = TREE_OPERAND (lhs, 0);
5962 
5963   ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
5964   other = build1 (ocode, TREE_TYPE (rhs), lhs);
5965   suppress_warning (other);
5966   other = get_formal_tmp_var (other, pre_p);
5967 
5968   realpart = code == REALPART_EXPR ? rhs : other;
5969   imagpart = code == REALPART_EXPR ? other : rhs;
5970 
5971   if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
5972     new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
5973   else
5974     new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
5975 
5976   gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
5977   *expr_p = (want_value) ? rhs : NULL_TREE;
5978 
5979   return GS_ALL_DONE;
5980 }
5981 
5982 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
5983 
5984       modify_expr
5985                 : varname '=' rhs
5986                 | '*' ID '=' rhs
5987 
5988     PRE_P points to the list where side effects that must happen before
5989           *EXPR_P should be stored.
5990 
5991     POST_P points to the list where side effects that must happen after
5992           *EXPR_P should be stored.
5993 
5994     WANT_VALUE is nonzero iff we want to use the value of this expression
5995           in another expression.  */
5996 
5997 static enum gimplify_status
gimplify_modify_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p,bool want_value)5998 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
5999                           bool want_value)
6000 {
6001   tree *from_p = &TREE_OPERAND (*expr_p, 1);
6002   tree *to_p = &TREE_OPERAND (*expr_p, 0);
6003   enum gimplify_status ret = GS_UNHANDLED;
6004   gimple *assign;
6005   location_t loc = EXPR_LOCATION (*expr_p);
6006   gimple_stmt_iterator gsi;
6007 
6008   gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
6009                 || TREE_CODE (*expr_p) == INIT_EXPR);
6010 
6011   /* Trying to simplify a clobber using normal logic doesn't work,
6012      so handle it here.  */
6013   if (TREE_CLOBBER_P (*from_p))
6014     {
6015       ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
6016       if (ret == GS_ERROR)
6017           return ret;
6018       gcc_assert (!want_value);
6019       if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
6020           {
6021             tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
6022                                                          pre_p, post_p);
6023             *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
6024           }
6025       gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
6026       *expr_p = NULL;
6027       return GS_ALL_DONE;
6028     }
6029 
6030   /* Insert pointer conversions required by the middle-end that are not
6031      required by the frontend.  This fixes middle-end type checking for
6032      for example gcc.dg/redecl-6.c.  */
6033   if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
6034     {
6035       STRIP_USELESS_TYPE_CONVERSION (*from_p);
6036       if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
6037           *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
6038     }
6039 
6040   /* See if any simplifications can be done based on what the RHS is.  */
6041   ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
6042                                           want_value);
6043   if (ret != GS_UNHANDLED)
6044     return ret;
6045 
6046   /* For empty types only gimplify the left hand side and right hand
6047      side as statements and throw away the assignment.  Do this after
6048      gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
6049      types properly.  */
6050   if (is_empty_type (TREE_TYPE (*from_p))
6051       && !want_value
6052       /* Don't do this for calls that return addressable types, expand_call
6053            relies on those having a lhs.  */
6054       && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
6055              && TREE_CODE (*from_p) == CALL_EXPR))
6056     {
6057       gimplify_stmt (from_p, pre_p);
6058       gimplify_stmt (to_p, pre_p);
6059       *expr_p = NULL_TREE;
6060       return GS_ALL_DONE;
6061     }
6062 
6063   /* If the value being copied is of variable width, compute the length
6064      of the copy into a WITH_SIZE_EXPR.   Note that we need to do this
6065      before gimplifying any of the operands so that we can resolve any
6066      PLACEHOLDER_EXPRs in the size.  Also note that the RTL expander uses
6067      the size of the expression to be copied, not of the destination, so
6068      that is what we must do here.  */
6069   maybe_with_size_expr (from_p);
6070 
6071   /* As a special case, we have to temporarily allow for assignments
6072      with a CALL_EXPR on the RHS.  Since in GIMPLE a function call is
6073      a toplevel statement, when gimplifying the GENERIC expression
6074      MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
6075      GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
6076 
6077      Instead, we need to create the tuple GIMPLE_CALL <a, foo>.  To
6078      prevent gimplify_expr from trying to create a new temporary for
6079      foo's LHS, we tell it that it should only gimplify until it
6080      reaches the CALL_EXPR.  On return from gimplify_expr, the newly
6081      created GIMPLE_CALL <foo> will be the last statement in *PRE_P
6082      and all we need to do here is set 'a' to be its LHS.  */
6083 
6084   /* Gimplify the RHS first for C++17 and bug 71104.  */
6085   gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
6086   ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
6087   if (ret == GS_ERROR)
6088     return ret;
6089 
6090   /* Then gimplify the LHS.  */
6091   /* If we gimplified the RHS to a CALL_EXPR and that call may return
6092      twice we have to make sure to gimplify into non-SSA as otherwise
6093      the abnormal edge added later will make those defs not dominate
6094      their uses.
6095      ???  Technically this applies only to the registers used in the
6096      resulting non-register *TO_P.  */
6097   bool saved_into_ssa = gimplify_ctxp->into_ssa;
6098   if (saved_into_ssa
6099       && TREE_CODE (*from_p) == CALL_EXPR
6100       && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
6101     gimplify_ctxp->into_ssa = false;
6102   ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
6103   gimplify_ctxp->into_ssa = saved_into_ssa;
6104   if (ret == GS_ERROR)
6105     return ret;
6106 
6107   /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
6108      guess for the predicate was wrong.  */
6109   gimple_predicate final_pred = rhs_predicate_for (*to_p);
6110   if (final_pred != initial_pred)
6111     {
6112       ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
6113       if (ret == GS_ERROR)
6114           return ret;
6115     }
6116 
6117   /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
6118      size as argument to the call.  */
6119   if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
6120     {
6121       tree call = TREE_OPERAND (*from_p, 0);
6122       tree vlasize = TREE_OPERAND (*from_p, 1);
6123 
6124       if (TREE_CODE (call) == CALL_EXPR
6125             && CALL_EXPR_IFN (call) == IFN_VA_ARG)
6126           {
6127             int nargs = call_expr_nargs (call);
6128             tree type = TREE_TYPE (call);
6129             tree ap = CALL_EXPR_ARG (call, 0);
6130             tree tag = CALL_EXPR_ARG (call, 1);
6131             tree aptag = CALL_EXPR_ARG (call, 2);
6132             tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
6133                                                                    IFN_VA_ARG, type,
6134                                                                    nargs + 1, ap, tag,
6135                                                                    aptag, vlasize);
6136             TREE_OPERAND (*from_p, 0) = newcall;
6137           }
6138     }
6139 
6140   /* Now see if the above changed *from_p to something we handle specially.  */
6141   ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
6142                                           want_value);
6143   if (ret != GS_UNHANDLED)
6144     return ret;
6145 
6146   /* If we've got a variable sized assignment between two lvalues (i.e. does
6147      not involve a call), then we can make things a bit more straightforward
6148      by converting the assignment to memcpy or memset.  */
6149   if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
6150     {
6151       tree from = TREE_OPERAND (*from_p, 0);
6152       tree size = TREE_OPERAND (*from_p, 1);
6153 
6154       if (TREE_CODE (from) == CONSTRUCTOR)
6155           return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
6156 
6157       if (is_gimple_addressable (from))
6158           {
6159             *from_p = from;
6160             return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
6161                                                              pre_p);
6162           }
6163     }
6164 
6165   /* Transform partial stores to non-addressable complex variables into
6166      total stores.  This allows us to use real instead of virtual operands
6167      for these variables, which improves optimization.  */
6168   if ((TREE_CODE (*to_p) == REALPART_EXPR
6169        || TREE_CODE (*to_p) == IMAGPART_EXPR)
6170       && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
6171     return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
6172 
6173   /* Try to alleviate the effects of the gimplification creating artificial
6174      temporaries (see for example is_gimple_reg_rhs) on the debug info, but
6175      make sure not to create DECL_DEBUG_EXPR links across functions.  */
6176   if (!gimplify_ctxp->into_ssa
6177       && VAR_P (*from_p)
6178       && DECL_IGNORED_P (*from_p)
6179       && DECL_P (*to_p)
6180       && !DECL_IGNORED_P (*to_p)
6181       && decl_function_context (*to_p) == current_function_decl
6182       && decl_function_context (*from_p) == current_function_decl)
6183     {
6184       if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
6185           DECL_NAME (*from_p)
6186             = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
6187       DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
6188       SET_DECL_DEBUG_EXPR (*from_p, *to_p);
6189    }
6190 
6191   if (want_value && TREE_THIS_VOLATILE (*to_p))
6192     *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
6193 
6194   if (TREE_CODE (*from_p) == CALL_EXPR)
6195     {
6196       /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
6197            instead of a GIMPLE_ASSIGN.  */
6198       gcall *call_stmt;
6199       if (CALL_EXPR_FN (*from_p) == NULL_TREE)
6200           {
6201             /* Gimplify internal functions created in the FEs.  */
6202             int nargs = call_expr_nargs (*from_p), i;
6203             enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
6204             auto_vec<tree> vargs (nargs);
6205 
6206             for (i = 0; i < nargs; i++)
6207               {
6208                 gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
6209                                   EXPR_LOCATION (*from_p));
6210                 vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
6211               }
6212             call_stmt = gimple_build_call_internal_vec (ifn, vargs);
6213             gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
6214             gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
6215           }
6216       else
6217           {
6218             tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
6219             CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
6220             STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
6221             tree fndecl = get_callee_fndecl (*from_p);
6222             if (fndecl
6223                 && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
6224                 && call_expr_nargs (*from_p) == 3)
6225               call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
6226                                                                 CALL_EXPR_ARG (*from_p, 0),
6227                                                                 CALL_EXPR_ARG (*from_p, 1),
6228                                                                 CALL_EXPR_ARG (*from_p, 2));
6229             else
6230               {
6231                 call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
6232               }
6233           }
6234       notice_special_calls (call_stmt);
6235       if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
6236           gimple_call_set_lhs (call_stmt, *to_p);
6237       else if (TREE_CODE (*to_p) == SSA_NAME)
6238           /* The above is somewhat premature, avoid ICEing later for a
6239              SSA name w/o a definition.  We may have uses in the GIMPLE IL.
6240              ???  This doesn't make it a default-def.  */
6241           SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
6242 
6243       assign = call_stmt;
6244     }
6245   else
6246     {
6247       assign = gimple_build_assign (*to_p, *from_p);
6248       gimple_set_location (assign, EXPR_LOCATION (*expr_p));
6249       if (COMPARISON_CLASS_P (*from_p))
6250           copy_warning (assign, *from_p);
6251     }
6252 
6253   if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
6254     {
6255       /* We should have got an SSA name from the start.  */
6256       gcc_assert (TREE_CODE (*to_p) == SSA_NAME
6257                       || ! gimple_in_ssa_p (cfun));
6258     }
6259 
6260   gimplify_seq_add_stmt (pre_p, assign);
6261   gsi = gsi_last (*pre_p);
6262   maybe_fold_stmt (&gsi);
6263 
6264   if (want_value)
6265     {
6266       *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
6267       return GS_OK;
6268     }
6269   else
6270     *expr_p = NULL;
6271 
6272   return GS_ALL_DONE;
6273 }
6274 
6275 /* Gimplify a comparison between two variable-sized objects.  Do this
6276    with a call to BUILT_IN_MEMCMP.  */
6277 
6278 static enum gimplify_status
gimplify_variable_sized_compare(tree * expr_p)6279 gimplify_variable_sized_compare (tree *expr_p)
6280 {
6281   location_t loc = EXPR_LOCATION (*expr_p);
6282   tree op0 = TREE_OPERAND (*expr_p, 0);
6283   tree op1 = TREE_OPERAND (*expr_p, 1);
6284   tree t, arg, dest, src, expr;
6285 
6286   arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
6287   arg = unshare_expr (arg);
6288   arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
6289   src = build_fold_addr_expr_loc (loc, op1);
6290   dest = build_fold_addr_expr_loc (loc, op0);
6291   t = builtin_decl_implicit (BUILT_IN_MEMCMP);
6292   t = build_call_expr_loc (loc, t, 3, dest, src, arg);
6293 
6294   expr
6295     = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
6296   SET_EXPR_LOCATION (expr, loc);
6297   *expr_p = expr;
6298 
6299   return GS_OK;
6300 }
6301 
6302 /* Gimplify a comparison between two aggregate objects of integral scalar
6303    mode as a comparison between the bitwise equivalent scalar values.  */
6304 
6305 static enum gimplify_status
gimplify_scalar_mode_aggregate_compare(tree * expr_p)6306 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
6307 {
6308   location_t loc = EXPR_LOCATION (*expr_p);
6309   tree op0 = TREE_OPERAND (*expr_p, 0);
6310   tree op1 = TREE_OPERAND (*expr_p, 1);
6311 
6312   tree type = TREE_TYPE (op0);
6313   tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
6314 
6315   op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
6316   op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
6317 
6318   *expr_p
6319     = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
6320 
6321   return GS_OK;
6322 }
6323 
6324 /* Gimplify an expression sequence.  This function gimplifies each
6325    expression and rewrites the original expression with the last
6326    expression of the sequence in GIMPLE form.
6327 
6328    PRE_P points to the list where the side effects for all the
6329        expressions in the sequence will be emitted.
6330 
6331    WANT_VALUE is true when the result of the last COMPOUND_EXPR is used.  */
6332 
6333 static enum gimplify_status
gimplify_compound_expr(tree * expr_p,gimple_seq * pre_p,bool want_value)6334 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
6335 {
6336   tree t = *expr_p;
6337 
6338   do
6339     {
6340       tree *sub_p = &TREE_OPERAND (t, 0);
6341 
6342       if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
6343           gimplify_compound_expr (sub_p, pre_p, false);
6344       else
6345           gimplify_stmt (sub_p, pre_p);
6346 
6347       t = TREE_OPERAND (t, 1);
6348     }
6349   while (TREE_CODE (t) == COMPOUND_EXPR);
6350 
6351   *expr_p = t;
6352   if (want_value)
6353     return GS_OK;
6354   else
6355     {
6356       gimplify_stmt (expr_p, pre_p);
6357       return GS_ALL_DONE;
6358     }
6359 }
6360 
6361 /* Gimplify a SAVE_EXPR node.  EXPR_P points to the expression to
6362    gimplify.  After gimplification, EXPR_P will point to a new temporary
6363    that holds the original value of the SAVE_EXPR node.
6364 
6365    PRE_P points to the list where side effects that must happen before
6366    *EXPR_P should be stored.  */
6367 
6368 static enum gimplify_status
gimplify_save_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p)6369 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6370 {
6371   enum gimplify_status ret = GS_ALL_DONE;
6372   tree val;
6373 
6374   gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
6375   val = TREE_OPERAND (*expr_p, 0);
6376 
6377   if (val && TREE_TYPE (val) == error_mark_node)
6378     return GS_ERROR;
6379 
6380   /* If the SAVE_EXPR has not been resolved, then evaluate it once.  */
6381   if (!SAVE_EXPR_RESOLVED_P (*expr_p))
6382     {
6383       /* The operand may be a void-valued expression.  It is
6384            being executed only for its side-effects.  */
6385       if (TREE_TYPE (val) == void_type_node)
6386           {
6387             ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
6388                                      is_gimple_stmt, fb_none);
6389             val = NULL;
6390           }
6391       else
6392           /* The temporary may not be an SSA name as later abnormal and EH
6393              control flow may invalidate use/def domination.  When in SSA
6394              form then assume there are no such issues and SAVE_EXPRs only
6395              appear via GENERIC foldings.  */
6396           val = get_initialized_tmp_var (val, pre_p, post_p,
6397                                                gimple_in_ssa_p (cfun));
6398 
6399       TREE_OPERAND (*expr_p, 0) = val;
6400       SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
6401     }
6402 
6403   *expr_p = val;
6404 
6405   return ret;
6406 }
6407 
6408 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
6409 
6410       unary_expr
6411                 : ...
6412                 | '&' varname
6413                 ...
6414 
6415     PRE_P points to the list where side effects that must happen before
6416           *EXPR_P should be stored.
6417 
6418     POST_P points to the list where side effects that must happen after
6419           *EXPR_P should be stored.  */
6420 
6421 static enum gimplify_status
gimplify_addr_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p)6422 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6423 {
6424   tree expr = *expr_p;
6425   tree op0 = TREE_OPERAND (expr, 0);
6426   enum gimplify_status ret;
6427   location_t loc = EXPR_LOCATION (*expr_p);
6428 
6429   switch (TREE_CODE (op0))
6430     {
6431     case INDIRECT_REF:
6432     do_indirect_ref:
6433       /* Check if we are dealing with an expression of the form '&*ptr'.
6434            While the front end folds away '&*ptr' into 'ptr', these
6435            expressions may be generated internally by the compiler (e.g.,
6436            builtins like __builtin_va_end).  */
6437       /* Caution: the silent array decomposition semantics we allow for
6438            ADDR_EXPR means we can't always discard the pair.  */
6439       /* Gimplification of the ADDR_EXPR operand may drop
6440            cv-qualification conversions, so make sure we add them if
6441            needed.  */
6442       {
6443           tree op00 = TREE_OPERAND (op0, 0);
6444           tree t_expr = TREE_TYPE (expr);
6445           tree t_op00 = TREE_TYPE (op00);
6446 
6447         if (!useless_type_conversion_p (t_expr, t_op00))
6448             op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
6449         *expr_p = op00;
6450         ret = GS_OK;
6451       }
6452       break;
6453 
6454     case VIEW_CONVERT_EXPR:
6455       /* Take the address of our operand and then convert it to the type of
6456            this ADDR_EXPR.
6457 
6458            ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
6459            all clear.  The impact of this transformation is even less clear.  */
6460 
6461       /* If the operand is a useless conversion, look through it.  Doing so
6462            guarantees that the ADDR_EXPR and its operand will remain of the
6463            same type.  */
6464       if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
6465           op0 = TREE_OPERAND (op0, 0);
6466 
6467       *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
6468                                           build_fold_addr_expr_loc (loc,
6469                                                                       TREE_OPERAND (op0, 0)));
6470       ret = GS_OK;
6471       break;
6472 
6473     case MEM_REF:
6474       if (integer_zerop (TREE_OPERAND (op0, 1)))
6475           goto do_indirect_ref;
6476 
6477       /* fall through */
6478 
6479     default:
6480       /* If we see a call to a declared builtin or see its address
6481            being taken (we can unify those cases here) then we can mark
6482            the builtin for implicit generation by GCC.  */
6483       if (TREE_CODE (op0) == FUNCTION_DECL
6484             && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
6485             && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
6486           set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
6487 
6488       /* We use fb_either here because the C frontend sometimes takes
6489            the address of a call that returns a struct; see
6490            gcc.dg/c99-array-lval-1.c.  The gimplifier will correctly make
6491            the implied temporary explicit.  */
6492 
6493       /* Make the operand addressable.  */
6494       ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
6495                                  is_gimple_addressable, fb_either);
6496       if (ret == GS_ERROR)
6497           break;
6498 
6499       /* Then mark it.  Beware that it may not be possible to do so directly
6500            if a temporary has been created by the gimplification.  */
6501       prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
6502 
6503       op0 = TREE_OPERAND (expr, 0);
6504 
6505       /* For various reasons, the gimplification of the expression
6506            may have made a new INDIRECT_REF.  */
6507       if (TREE_CODE (op0) == INDIRECT_REF
6508             || (TREE_CODE (op0) == MEM_REF
6509                 && integer_zerop (TREE_OPERAND (op0, 1))))
6510           goto do_indirect_ref;
6511 
6512       mark_addressable (TREE_OPERAND (expr, 0));
6513 
6514       /* The FEs may end up building ADDR_EXPRs early on a decl with
6515            an incomplete type.  Re-build ADDR_EXPRs in canonical form
6516            here.  */
6517       if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
6518           *expr_p = build_fold_addr_expr (op0);
6519 
6520       /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly.  */
6521       recompute_tree_invariant_for_addr_expr (*expr_p);
6522 
6523       /* If we re-built the ADDR_EXPR add a conversion to the original type
6524          if required.  */
6525       if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
6526           *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
6527 
6528       break;
6529     }
6530 
6531   return ret;
6532 }
6533 
6534 /* Gimplify the operands of an ASM_EXPR.  Input operands should be a gimple
6535    value; output operands should be a gimple lvalue.  */
6536 
6537 static enum gimplify_status
gimplify_asm_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p)6538 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
6539 {
6540   tree expr;
6541   int noutputs;
6542   const char **oconstraints;
6543   int i;
6544   tree link;
6545   const char *constraint;
6546   bool allows_mem, allows_reg, is_inout;
6547   enum gimplify_status ret, tret;
6548   gasm *stmt;
6549   vec<tree, va_gc> *inputs;
6550   vec<tree, va_gc> *outputs;
6551   vec<tree, va_gc> *clobbers;
6552   vec<tree, va_gc> *labels;
6553   tree link_next;
6554 
6555   expr = *expr_p;
6556   noutputs = list_length (ASM_OUTPUTS (expr));
6557   oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
6558 
6559   inputs = NULL;
6560   outputs = NULL;
6561   clobbers = NULL;
6562   labels = NULL;
6563 
6564   ret = GS_ALL_DONE;
6565   link_next = NULL_TREE;
6566   for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
6567     {
6568       bool ok;
6569       size_t constraint_len;
6570 
6571       link_next = TREE_CHAIN (link);
6572 
6573       oconstraints[i]
6574           = constraint
6575           = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6576       constraint_len = strlen (constraint);
6577       if (constraint_len == 0)
6578         continue;
6579 
6580       ok = parse_output_constraint (&constraint, i, 0, 0,
6581                                             &allows_mem, &allows_reg, &is_inout);
6582       if (!ok)
6583           {
6584             ret = GS_ERROR;
6585             is_inout = false;
6586           }
6587 
6588       /* If we can't make copies, we can only accept memory.
6589            Similarly for VLAs.  */
6590       tree outtype = TREE_TYPE (TREE_VALUE (link));
6591       if (outtype != error_mark_node
6592             && (TREE_ADDRESSABLE (outtype)
6593                 || !COMPLETE_TYPE_P (outtype)
6594                 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
6595           {
6596             if (allows_mem)
6597               allows_reg = 0;
6598             else
6599               {
6600                 error ("impossible constraint in %<asm%>");
6601                 error ("non-memory output %d must stay in memory", i);
6602                 return GS_ERROR;
6603               }
6604           }
6605 
6606       if (!allows_reg && allows_mem)
6607           mark_addressable (TREE_VALUE (link));
6608 
6609       tree orig = TREE_VALUE (link);
6610       tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6611                                   is_inout ? is_gimple_min_lval : is_gimple_lvalue,
6612                                   fb_lvalue | fb_mayfail);
6613       if (tret == GS_ERROR)
6614           {
6615             if (orig != error_mark_node)
6616               error ("invalid lvalue in %<asm%> output %d", i);
6617             ret = tret;
6618           }
6619 
6620       /* If the constraint does not allow memory make sure we gimplify
6621          it to a register if it is not already but its base is.  This
6622            happens for complex and vector components.  */
6623       if (!allows_mem)
6624           {
6625             tree op = TREE_VALUE (link);
6626             if (! is_gimple_val (op)
6627                 && is_gimple_reg_type (TREE_TYPE (op))
6628                 && is_gimple_reg (get_base_address (op)))
6629               {
6630                 tree tem = create_tmp_reg (TREE_TYPE (op));
6631                 tree ass;
6632                 if (is_inout)
6633                     {
6634                       ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
6635                                         tem, unshare_expr (op));
6636                       gimplify_and_add (ass, pre_p);
6637                     }
6638                 ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
6639                 gimplify_and_add (ass, post_p);
6640 
6641                 TREE_VALUE (link) = tem;
6642                 tret = GS_OK;
6643               }
6644           }
6645 
6646       vec_safe_push (outputs, link);
6647       TREE_CHAIN (link) = NULL_TREE;
6648 
6649       if (is_inout)
6650           {
6651             /* An input/output operand.  To give the optimizers more
6652                flexibility, split it into separate input and output
6653                operands.  */
6654             tree input;
6655             /* Buffer big enough to format a 32-bit UINT_MAX into.  */
6656             char buf[11];
6657 
6658             /* Turn the in/out constraint into an output constraint.  */
6659             char *p = xstrdup (constraint);
6660             p[0] = '=';
6661             TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
6662 
6663             /* And add a matching input constraint.  */
6664             if (allows_reg)
6665               {
6666                 sprintf (buf, "%u", i);
6667 
6668                 /* If there are multiple alternatives in the constraint,
6669                      handle each of them individually.  Those that allow register
6670                      will be replaced with operand number, the others will stay
6671                      unchanged.  */
6672                 if (strchr (p, ',') != NULL)
6673                     {
6674                       size_t len = 0, buflen = strlen (buf);
6675                       char *beg, *end, *str, *dst;
6676 
6677                       for (beg = p + 1;;)
6678                         {
6679                           end = strchr (beg, ',');
6680                           if (end == NULL)
6681                               end = strchr (beg, '\0');
6682                           if ((size_t) (end - beg) < buflen)
6683                               len += buflen + 1;
6684                           else
6685                               len += end - beg + 1;
6686                           if (*end)
6687                               beg = end + 1;
6688                           else
6689                               break;
6690                         }
6691 
6692                       str = (char *) alloca (len);
6693                       for (beg = p + 1, dst = str;;)
6694                         {
6695                           const char *tem;
6696                           bool mem_p, reg_p, inout_p;
6697 
6698                           end = strchr (beg, ',');
6699                           if (end)
6700                               *end = '\0';
6701                           beg[-1] = '=';
6702                           tem = beg - 1;
6703                           parse_output_constraint (&tem, i, 0, 0,
6704                                                          &mem_p, &reg_p, &inout_p);
6705                           if (dst != str)
6706                               *dst++ = ',';
6707                           if (reg_p)
6708                               {
6709                                 memcpy (dst, buf, buflen);
6710                                 dst += buflen;
6711                               }
6712                           else
6713                               {
6714                                 if (end)
6715                                   len = end - beg;
6716                                 else
6717                                   len = strlen (beg);
6718                                 memcpy (dst, beg, len);
6719                                 dst += len;
6720                               }
6721                           if (end)
6722                               beg = end + 1;
6723                           else
6724                               break;
6725                         }
6726                       *dst = '\0';
6727                       input = build_string (dst - str, str);
6728                     }
6729                 else
6730                     input = build_string (strlen (buf), buf);
6731               }
6732             else
6733               input = build_string (constraint_len - 1, constraint + 1);
6734 
6735             free (p);
6736 
6737             input = build_tree_list (build_tree_list (NULL_TREE, input),
6738                                            unshare_expr (TREE_VALUE (link)));
6739             ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
6740           }
6741     }
6742 
6743   link_next = NULL_TREE;
6744   for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
6745     {
6746       link_next = TREE_CHAIN (link);
6747       constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
6748       parse_input_constraint (&constraint, 0, 0, noutputs, 0,
6749                                     oconstraints, &allows_mem, &allows_reg);
6750 
6751       /* If we can't make copies, we can only accept memory.  */
6752       tree intype = TREE_TYPE (TREE_VALUE (link));
6753       if (intype != error_mark_node
6754             && (TREE_ADDRESSABLE (intype)
6755                 || !COMPLETE_TYPE_P (intype)
6756                 || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
6757           {
6758             if (allows_mem)
6759               allows_reg = 0;
6760             else
6761               {
6762                 error ("impossible constraint in %<asm%>");
6763                 error ("non-memory input %d must stay in memory", i);
6764                 return GS_ERROR;
6765               }
6766           }
6767 
6768       /* If the operand is a memory input, it should be an lvalue.  */
6769       if (!allows_reg && allows_mem)
6770           {
6771             tree inputv = TREE_VALUE (link);
6772             STRIP_NOPS (inputv);
6773             if (TREE_CODE (inputv) == PREDECREMENT_EXPR
6774                 || TREE_CODE (inputv) == PREINCREMENT_EXPR
6775                 || TREE_CODE (inputv) == POSTDECREMENT_EXPR
6776                 || TREE_CODE (inputv) == POSTINCREMENT_EXPR
6777                 || TREE_CODE (inputv) == MODIFY_EXPR)
6778               TREE_VALUE (link) = error_mark_node;
6779             tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6780                                         is_gimple_lvalue, fb_lvalue | fb_mayfail);
6781             if (tret != GS_ERROR)
6782               {
6783                 /* Unlike output operands, memory inputs are not guaranteed
6784                      to be lvalues by the FE, and while the expressions are
6785                      marked addressable there, if it is e.g. a statement
6786                      expression, temporaries in it might not end up being
6787                      addressable.  They might be already used in the IL and thus
6788                      it is too late to make them addressable now though.  */
6789                 tree x = TREE_VALUE (link);
6790                 while (handled_component_p (x))
6791                     x = TREE_OPERAND (x, 0);
6792                 if (TREE_CODE (x) == MEM_REF
6793                       && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
6794                     x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
6795                 if ((VAR_P (x)
6796                        || TREE_CODE (x) == PARM_DECL
6797                        || TREE_CODE (x) == RESULT_DECL)
6798                       && !TREE_ADDRESSABLE (x)
6799                       && is_gimple_reg (x))
6800                     {
6801                       warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
6802                                                          input_location), 0,
6803                                     "memory input %d is not directly addressable",
6804                                     i);
6805                       prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
6806                     }
6807               }
6808             mark_addressable (TREE_VALUE (link));
6809             if (tret == GS_ERROR)
6810               {
6811                 if (inputv != error_mark_node)
6812                     error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
6813                                 "memory input %d is not directly addressable", i);
6814                 ret = tret;
6815               }
6816           }
6817       else
6818           {
6819             tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
6820                                         is_gimple_asm_val, fb_rvalue);
6821             if (tret == GS_ERROR)
6822               ret = tret;
6823           }
6824 
6825       TREE_CHAIN (link) = NULL_TREE;
6826       vec_safe_push (inputs, link);
6827     }
6828 
6829   link_next = NULL_TREE;
6830   for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
6831     {
6832       link_next = TREE_CHAIN (link);
6833       TREE_CHAIN (link) = NULL_TREE;
6834       vec_safe_push (clobbers, link);
6835     }
6836 
6837   link_next = NULL_TREE;
6838   for (link = ASM_LABELS (expr); link; ++i, link = link_next)
6839     {
6840       link_next = TREE_CHAIN (link);
6841       TREE_CHAIN (link) = NULL_TREE;
6842       vec_safe_push (labels, link);
6843     }
6844 
6845   /* Do not add ASMs with errors to the gimple IL stream.  */
6846   if (ret != GS_ERROR)
6847     {
6848       stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
6849                                            inputs, outputs, clobbers, labels);
6850 
6851       /* asm is volatile if it was marked by the user as volatile or
6852            there are no outputs or this is an asm goto.  */
6853       gimple_asm_set_volatile (stmt,
6854                                      ASM_VOLATILE_P (expr)
6855                                      || noutputs == 0
6856                                      || labels);
6857       gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
6858       gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
6859 
6860       gimplify_seq_add_stmt (pre_p, stmt);
6861     }
6862 
6863   return ret;
6864 }
6865 
6866 /* Gimplify a CLEANUP_POINT_EXPR.  Currently this works by adding
6867    GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
6868    gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
6869    return to this function.
6870 
6871    FIXME should we complexify the prequeue handling instead?  Or use flags
6872    for all the cleanups and let the optimizer tighten them up?  The current
6873    code seems pretty fragile; it will break on a cleanup within any
6874    non-conditional nesting.  But any such nesting would be broken, anyway;
6875    we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
6876    and continues out of it.  We can do that at the RTL level, though, so
6877    having an optimizer to tighten up try/finally regions would be a Good
6878    Thing.  */
6879 
6880 static enum gimplify_status
gimplify_cleanup_point_expr(tree * expr_p,gimple_seq * pre_p)6881 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
6882 {
6883   gimple_stmt_iterator iter;
6884   gimple_seq body_sequence = NULL;
6885 
6886   tree temp = voidify_wrapper_expr (*expr_p, NULL);
6887 
6888   /* We only care about the number of conditions between the innermost
6889      CLEANUP_POINT_EXPR and the cleanup.  So save and reset the count and
6890      any cleanups collected outside the CLEANUP_POINT_EXPR.  */
6891   int old_conds = gimplify_ctxp->conditions;
6892   gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
6893   bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
6894   gimplify_ctxp->conditions = 0;
6895   gimplify_ctxp->conditional_cleanups = NULL;
6896   gimplify_ctxp->in_cleanup_point_expr = true;
6897 
6898   gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
6899 
6900   gimplify_ctxp->conditions = old_conds;
6901   gimplify_ctxp->conditional_cleanups = old_cleanups;
6902   gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
6903 
6904   for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
6905     {
6906       gimple *wce = gsi_stmt (iter);
6907 
6908       if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
6909           {
6910             if (gsi_one_before_end_p (iter))
6911               {
6912               /* Note that gsi_insert_seq_before and gsi_remove do not
6913                  scan operands, unlike some other sequence mutators.  */
6914                 if (!gimple_wce_cleanup_eh_only (wce))
6915                     gsi_insert_seq_before_without_update (&iter,
6916                                                                   gimple_wce_cleanup (wce),
6917                                                                   GSI_SAME_STMT);
6918                 gsi_remove (&iter, true);
6919                 break;
6920               }
6921             else
6922               {
6923                 gtry *gtry;
6924                 gimple_seq seq;
6925                 enum gimple_try_flags kind;
6926 
6927                 if (gimple_wce_cleanup_eh_only (wce))
6928                     kind = GIMPLE_TRY_CATCH;
6929                 else
6930                     kind = GIMPLE_TRY_FINALLY;
6931                 seq = gsi_split_seq_after (iter);
6932 
6933                 gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
6934               /* Do not use gsi_replace here, as it may scan operands.
6935                  We want to do a simple structural modification only.  */
6936                 gsi_set_stmt (&iter, gtry);
6937                 iter = gsi_start (gtry->eval);
6938               }
6939           }
6940       else
6941           gsi_next (&iter);
6942     }
6943 
6944   gimplify_seq_add_seq (pre_p, body_sequence);
6945   if (temp)
6946     {
6947       *expr_p = temp;
6948       return GS_OK;
6949     }
6950   else
6951     {
6952       *expr_p = NULL;
6953       return GS_ALL_DONE;
6954     }
6955 }
6956 
6957 /* Insert a cleanup marker for gimplify_cleanup_point_expr.  CLEANUP
6958    is the cleanup action required.  EH_ONLY is true if the cleanup should
6959    only be executed if an exception is thrown, not on normal exit.
6960    If FORCE_UNCOND is true perform the cleanup unconditionally;  this is
6961    only valid for clobbers.  */
6962 
6963 static void
gimple_push_cleanup(tree var,tree cleanup,bool eh_only,gimple_seq * pre_p,bool force_uncond=false)6964 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
6965                          bool force_uncond = false)
6966 {
6967   gimple *wce;
6968   gimple_seq cleanup_stmts = NULL;
6969 
6970   /* Errors can result in improperly nested cleanups.  Which results in
6971      confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR.  */
6972   if (seen_error ())
6973     return;
6974 
6975   if (gimple_conditional_context ())
6976     {
6977       /* If we're in a conditional context, this is more complex.  We only
6978            want to run the cleanup if we actually ran the initialization that
6979            necessitates it, but we want to run it after the end of the
6980            conditional context.  So we wrap the try/finally around the
6981            condition and use a flag to determine whether or not to actually
6982            run the destructor.  Thus
6983 
6984              test ? f(A()) : 0
6985 
6986            becomes (approximately)
6987 
6988              flag = 0;
6989              try {
6990                if (test) { A::A(temp); flag = 1; val = f(temp); }
6991                else { val = 0; }
6992              } finally {
6993                if (flag) A::~A(temp);
6994              }
6995              val
6996       */
6997       if (force_uncond)
6998           {
6999             gimplify_stmt (&cleanup, &cleanup_stmts);
7000             wce = gimple_build_wce (cleanup_stmts);
7001             gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
7002           }
7003       else
7004           {
7005             tree flag = create_tmp_var (boolean_type_node, "cleanup");
7006             gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
7007             gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
7008 
7009             cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
7010             gimplify_stmt (&cleanup, &cleanup_stmts);
7011             wce = gimple_build_wce (cleanup_stmts);
7012             gimple_wce_set_cleanup_eh_only (wce, eh_only);
7013 
7014             gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
7015             gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
7016             gimplify_seq_add_stmt (pre_p, ftrue);
7017 
7018             /* Because of this manipulation, and the EH edges that jump
7019                threading cannot redirect, the temporary (VAR) will appear
7020                to be used uninitialized.  Don't warn.  */
7021             suppress_warning (var, OPT_Wuninitialized);
7022           }
7023     }
7024   else
7025     {
7026       gimplify_stmt (&cleanup, &cleanup_stmts);
7027       wce = gimple_build_wce (cleanup_stmts);
7028       gimple_wce_set_cleanup_eh_only (wce, eh_only);
7029       gimplify_seq_add_stmt (pre_p, wce);
7030     }
7031 }
7032 
7033 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR.  */
7034 
7035 static enum gimplify_status
gimplify_target_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p)7036 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
7037 {
7038   tree targ = *expr_p;
7039   tree temp = TARGET_EXPR_SLOT (targ);
7040   tree init = TARGET_EXPR_INITIAL (targ);
7041   enum gimplify_status ret;
7042 
7043   bool unpoison_empty_seq = false;
7044   gimple_stmt_iterator unpoison_it;
7045 
7046   if (init)
7047     {
7048       gimple_seq init_pre_p = NULL;
7049 
7050       /* TARGET_EXPR temps aren't part of the enclosing block, so add it
7051            to the temps list.  Handle also variable length TARGET_EXPRs.  */
7052       if (!poly_int_tree_p (DECL_SIZE (temp)))
7053           {
7054             if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
7055               gimplify_type_sizes (TREE_TYPE (temp), &init_pre_p);
7056             /* FIXME: this is correct only when the size of the type does
7057                not depend on expressions evaluated in init.  */
7058             gimplify_vla_decl (temp, &init_pre_p);
7059           }
7060       else
7061           {
7062             /* Save location where we need to place unpoisoning.  It's possible
7063                that a variable will be converted to needs_to_live_in_memory.  */
7064             unpoison_it = gsi_last (*pre_p);
7065             unpoison_empty_seq = gsi_end_p (unpoison_it);
7066 
7067             gimple_add_tmp_var (temp);
7068           }
7069 
7070       /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
7071            expression is supposed to initialize the slot.  */
7072       if (VOID_TYPE_P (TREE_TYPE (init)))
7073           ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
7074                                    fb_none);
7075       else
7076           {
7077             tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
7078             init = init_expr;
7079             ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
7080                                      fb_none);
7081             init = NULL;
7082             ggc_free (init_expr);
7083           }
7084       if (ret == GS_ERROR)
7085           {
7086             /* PR c++/28266 Make sure this is expanded only once. */
7087             TARGET_EXPR_INITIAL (targ) = NULL_TREE;
7088             return GS_ERROR;
7089           }
7090 
7091       if (init)
7092           gimplify_and_add (init, &init_pre_p);
7093 
7094       /* Add a clobber for the temporary going out of scope, like
7095            gimplify_bind_expr.  */
7096       if (gimplify_ctxp->in_cleanup_point_expr
7097             && needs_to_live_in_memory (temp))
7098           {
7099             if (flag_stack_reuse == SR_ALL)
7100               {
7101                 tree clobber = build_clobber (TREE_TYPE (temp), CLOBBER_EOL);
7102                 clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
7103                 gimple_push_cleanup (temp, clobber, false, pre_p, true);
7104               }
7105             if (asan_poisoned_variables
7106                 && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
7107                 && !TREE_STATIC (temp)
7108                 && dbg_cnt (asan_use_after_scope)
7109                 && !gimplify_omp_ctxp)
7110               {
7111                 tree asan_cleanup = build_asan_poison_call_expr (temp);
7112                 if (asan_cleanup)
7113                     {
7114                       if (unpoison_empty_seq)
7115                         unpoison_it = gsi_start (*pre_p);
7116 
7117                       asan_poison_variable (temp, false, &unpoison_it,
7118                                                   unpoison_empty_seq);
7119                       gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
7120                     }
7121               }
7122           }
7123 
7124       gimple_seq_add_seq (pre_p, init_pre_p);
7125 
7126       /* If needed, push the cleanup for the temp.  */
7127       if (TARGET_EXPR_CLEANUP (targ))
7128           gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
7129                                    CLEANUP_EH_ONLY (targ), pre_p);
7130 
7131       /* Only expand this once.  */
7132       TREE_OPERAND (targ, 3) = init;
7133       TARGET_EXPR_INITIAL (targ) = NULL_TREE;
7134     }
7135   else
7136     /* We should have expanded this before.  */
7137     gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
7138 
7139   *expr_p = temp;
7140   return GS_OK;
7141 }
7142 
7143 /* Gimplification of expression trees.  */
7144 
7145 /* Gimplify an expression which appears at statement context.  The
7146    corresponding GIMPLE statements are added to *SEQ_P.  If *SEQ_P is
7147    NULL, a new sequence is allocated.
7148 
7149    Return true if we actually added a statement to the queue.  */
7150 
7151 bool
gimplify_stmt(tree * stmt_p,gimple_seq * seq_p)7152 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
7153 {
7154   gimple_seq_node last;
7155 
7156   last = gimple_seq_last (*seq_p);
7157   gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
7158   return last != gimple_seq_last (*seq_p);
7159 }
7160 
7161 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
7162    to CTX.  If entries already exist, force them to be some flavor of private.
7163    If there is no enclosing parallel, do nothing.  */
7164 
7165 void
omp_firstprivatize_variable(struct gimplify_omp_ctx * ctx,tree decl)7166 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
7167 {
7168   splay_tree_node n;
7169 
7170   if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
7171     return;
7172 
7173   do
7174     {
7175       n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7176       if (n != NULL)
7177           {
7178             if (n->value & GOVD_SHARED)
7179               n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
7180             else if (n->value & GOVD_MAP)
7181               n->value |= GOVD_MAP_TO_ONLY;
7182             else
7183               return;
7184           }
7185       else if ((ctx->region_type & ORT_TARGET) != 0)
7186           {
7187             if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
7188               omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7189             else
7190               omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
7191           }
7192       else if (ctx->region_type != ORT_WORKSHARE
7193                  && ctx->region_type != ORT_TASKGROUP
7194                  && ctx->region_type != ORT_SIMD
7195                  && ctx->region_type != ORT_ACC
7196                  && !(ctx->region_type & ORT_TARGET_DATA))
7197           omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
7198 
7199       ctx = ctx->outer_context;
7200     }
7201   while (ctx);
7202 }
7203 
7204 /* Similarly for each of the type sizes of TYPE.  */
7205 
7206 static void
omp_firstprivatize_type_sizes(struct gimplify_omp_ctx * ctx,tree type)7207 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
7208 {
7209   if (type == NULL || type == error_mark_node)
7210     return;
7211   type = TYPE_MAIN_VARIANT (type);
7212 
7213   if (ctx->privatized_types->add (type))
7214     return;
7215 
7216   switch (TREE_CODE (type))
7217     {
7218     case INTEGER_TYPE:
7219     case ENUMERAL_TYPE:
7220     case BOOLEAN_TYPE:
7221     case REAL_TYPE:
7222     case FIXED_POINT_TYPE:
7223       omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
7224       omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
7225       break;
7226 
7227     case ARRAY_TYPE:
7228       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7229       omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
7230       break;
7231 
7232     case RECORD_TYPE:
7233     case UNION_TYPE:
7234     case QUAL_UNION_TYPE:
7235       {
7236           tree field;
7237           for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
7238             if (TREE_CODE (field) == FIELD_DECL)
7239               {
7240                 omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
7241                 omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
7242               }
7243       }
7244       break;
7245 
7246     case POINTER_TYPE:
7247     case REFERENCE_TYPE:
7248       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
7249       break;
7250 
7251     default:
7252       break;
7253     }
7254 
7255   omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
7256   omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
7257   lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
7258 }
7259 
7260 /* Add an entry for DECL in the OMP context CTX with FLAGS.  */
7261 
7262 static void
omp_add_variable(struct gimplify_omp_ctx * ctx,tree decl,unsigned int flags)7263 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
7264 {
7265   splay_tree_node n;
7266   unsigned int nflags;
7267   tree t;
7268 
7269   if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
7270     return;
7271 
7272   /* Never elide decls whose type has TREE_ADDRESSABLE set.  This means
7273      there are constructors involved somewhere.  Exception is a shared clause,
7274      there is nothing privatized in that case.  */
7275   if ((flags & GOVD_SHARED) == 0
7276       && (TREE_ADDRESSABLE (TREE_TYPE (decl))
7277             || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
7278     flags |= GOVD_SEEN;
7279 
7280   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7281   if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7282     {
7283       /* We shouldn't be re-adding the decl with the same data
7284            sharing class.  */
7285       gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
7286       nflags = n->value | flags;
7287       /* The only combination of data sharing classes we should see is
7288            FIRSTPRIVATE and LASTPRIVATE.  However, OpenACC permits
7289            reduction variables to be used in data sharing clauses.  */
7290       gcc_assert ((ctx->region_type & ORT_ACC) != 0
7291                       || ((nflags & GOVD_DATA_SHARE_CLASS)
7292                           == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
7293                       || (flags & GOVD_DATA_SHARE_CLASS) == 0);
7294       n->value = nflags;
7295       return;
7296     }
7297 
7298   /* When adding a variable-sized variable, we have to handle all sorts
7299      of additional bits of data: the pointer replacement variable, and
7300      the parameters of the type.  */
7301   if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7302     {
7303       /* Add the pointer replacement variable as PRIVATE if the variable
7304            replacement is private, else FIRSTPRIVATE since we'll need the
7305            address of the original variable either for SHARED, or for the
7306            copy into or out of the context.  */
7307       if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
7308           {
7309             if (flags & GOVD_MAP)
7310               nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
7311             else if (flags & GOVD_PRIVATE)
7312               nflags = GOVD_PRIVATE;
7313             else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
7314                         && (flags & GOVD_FIRSTPRIVATE))
7315                        || (ctx->region_type == ORT_TARGET_DATA
7316                            && (flags & GOVD_DATA_SHARE_CLASS) == 0))
7317               nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
7318             else
7319               nflags = GOVD_FIRSTPRIVATE;
7320             nflags |= flags & GOVD_SEEN;
7321             t = DECL_VALUE_EXPR (decl);
7322             gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7323             t = TREE_OPERAND (t, 0);
7324             gcc_assert (DECL_P (t));
7325             omp_add_variable (ctx, t, nflags);
7326           }
7327 
7328       /* Add all of the variable and type parameters (which should have
7329            been gimplified to a formal temporary) as FIRSTPRIVATE.  */
7330       omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
7331       omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
7332       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7333 
7334       /* The variable-sized variable itself is never SHARED, only some form
7335            of PRIVATE.  The sharing would take place via the pointer variable
7336            which we remapped above.  */
7337       if (flags & GOVD_SHARED)
7338           flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
7339                     | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
7340 
7341       /* We're going to make use of the TYPE_SIZE_UNIT at least in the
7342            alloca statement we generate for the variable, so make sure it
7343            is available.  This isn't automatically needed for the SHARED
7344            case, since we won't be allocating local storage then.
7345            For local variables TYPE_SIZE_UNIT might not be gimplified yet,
7346            in this case omp_notice_variable will be called later
7347            on when it is gimplified.  */
7348       else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
7349                  && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
7350           omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
7351     }
7352   else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
7353              && omp_privatize_by_reference (decl))
7354     {
7355       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
7356 
7357       /* Similar to the direct variable sized case above, we'll need the
7358            size of references being privatized.  */
7359       if ((flags & GOVD_SHARED) == 0)
7360           {
7361             t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7362             if (t && DECL_P (t))
7363               omp_notice_variable (ctx, t, true);
7364           }
7365     }
7366 
7367   if (n != NULL)
7368     n->value |= flags;
7369   else
7370     splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
7371 
7372   /* For reductions clauses in OpenACC loop directives, by default create a
7373      copy clause on the enclosing parallel construct for carrying back the
7374      results.  */
7375   if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
7376     {
7377       struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
7378       while (outer_ctx)
7379           {
7380             n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
7381             if (n != NULL)
7382               {
7383                 /* Ignore local variables and explicitly declared clauses.  */
7384                 if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
7385                     break;
7386                 else if (outer_ctx->region_type == ORT_ACC_KERNELS)
7387                     {
7388                       /* According to the OpenACC spec, such a reduction variable
7389                          should already have a copy map on a kernels construct,
7390                          verify that here.  */
7391                       gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
7392                                     && (n->value & GOVD_MAP));
7393                     }
7394                 else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7395                     {
7396                       /* Remove firstprivate and make it a copy map.  */
7397                       n->value &= ~GOVD_FIRSTPRIVATE;
7398                       n->value |= GOVD_MAP;
7399                     }
7400               }
7401             else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
7402               {
7403                 splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
7404                                          GOVD_MAP | GOVD_SEEN);
7405                 break;
7406               }
7407             outer_ctx = outer_ctx->outer_context;
7408           }
7409     }
7410 }
7411 
7412 /* Notice a threadprivate variable DECL used in OMP context CTX.
7413    This just prints out diagnostics about threadprivate variable uses
7414    in untied tasks.  If DECL2 is non-NULL, prevent this warning
7415    on that variable.  */
7416 
7417 static bool
omp_notice_threadprivate_variable(struct gimplify_omp_ctx * ctx,tree decl,tree decl2)7418 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
7419                                            tree decl2)
7420 {
7421   splay_tree_node n;
7422   struct gimplify_omp_ctx *octx;
7423 
7424   for (octx = ctx; octx; octx = octx->outer_context)
7425     if ((octx->region_type & ORT_TARGET) != 0
7426           || octx->order_concurrent)
7427       {
7428           n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
7429           if (n == NULL)
7430             {
7431               if (octx->order_concurrent)
7432                 {
7433                     error ("threadprivate variable %qE used in a region with"
7434                            " %<order(concurrent)%> clause", DECL_NAME (decl));
7435                     inform (octx->location, "enclosing region");
7436                 }
7437               else
7438                 {
7439                     error ("threadprivate variable %qE used in target region",
7440                            DECL_NAME (decl));
7441                     inform (octx->location, "enclosing target region");
7442                 }
7443               splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
7444             }
7445           if (decl2)
7446             splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
7447       }
7448 
7449   if (ctx->region_type != ORT_UNTIED_TASK)
7450     return false;
7451   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7452   if (n == NULL)
7453     {
7454       error ("threadprivate variable %qE used in untied task",
7455                DECL_NAME (decl));
7456       inform (ctx->location, "enclosing task");
7457       splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
7458     }
7459   if (decl2)
7460     splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
7461   return false;
7462 }
7463 
7464 /* Return true if global var DECL is device resident.  */
7465 
7466 static bool
device_resident_p(tree decl)7467 device_resident_p (tree decl)
7468 {
7469   tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
7470 
7471   if (!attr)
7472     return false;
7473 
7474   for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
7475     {
7476       tree c = TREE_VALUE (t);
7477       if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
7478           return true;
7479     }
7480 
7481   return false;
7482 }
7483 
7484 /* Return true if DECL has an ACC DECLARE attribute.  */
7485 
7486 static bool
is_oacc_declared(tree decl)7487 is_oacc_declared (tree decl)
7488 {
7489   tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
7490   tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
7491   return declared != NULL_TREE;
7492 }
7493 
7494 /* Determine outer default flags for DECL mentioned in an OMP region
7495    but not declared in an enclosing clause.
7496 
7497    ??? Some compiler-generated variables (like SAVE_EXPRs) could be
7498    remapped firstprivate instead of shared.  To some extent this is
7499    addressed in omp_firstprivatize_type_sizes, but not
7500    effectively.  */
7501 
7502 static unsigned
omp_default_clause(struct gimplify_omp_ctx * ctx,tree decl,bool in_code,unsigned flags)7503 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
7504                         bool in_code, unsigned flags)
7505 {
7506   enum omp_clause_default_kind default_kind = ctx->default_kind;
7507   enum omp_clause_default_kind kind;
7508 
7509   kind = lang_hooks.decls.omp_predetermined_sharing (decl);
7510   if (ctx->region_type & ORT_TASK)
7511     {
7512       tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH);
7513 
7514       /* The event-handle specified by a detach clause should always be firstprivate,
7515            regardless of the current default.  */
7516       if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl)
7517           kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
7518     }
7519   if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
7520     default_kind = kind;
7521   else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
7522     default_kind = OMP_CLAUSE_DEFAULT_SHARED;
7523   /* For C/C++ default({,first}private), variables with static storage duration
7524      declared in a namespace or global scope and referenced in construct
7525      must be explicitly specified, i.e. acts as default(none).  */
7526   else if ((default_kind == OMP_CLAUSE_DEFAULT_PRIVATE
7527               || default_kind == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
7528              && VAR_P (decl)
7529              && is_global_var (decl)
7530              && (DECL_FILE_SCOPE_P (decl)
7531                  || (DECL_CONTEXT (decl)
7532                        && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
7533              && !lang_GNU_Fortran ())
7534     default_kind = OMP_CLAUSE_DEFAULT_NONE;
7535 
7536   switch (default_kind)
7537     {
7538     case OMP_CLAUSE_DEFAULT_NONE:
7539       {
7540           const char *rtype;
7541 
7542           if (ctx->region_type & ORT_PARALLEL)
7543             rtype = "parallel";
7544           else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
7545             rtype = "taskloop";
7546           else if (ctx->region_type & ORT_TASK)
7547             rtype = "task";
7548           else if (ctx->region_type & ORT_TEAMS)
7549             rtype = "teams";
7550           else
7551             gcc_unreachable ();
7552 
7553           error ("%qE not specified in enclosing %qs",
7554                  DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
7555           inform (ctx->location, "enclosing %qs", rtype);
7556       }
7557       /* FALLTHRU */
7558     case OMP_CLAUSE_DEFAULT_SHARED:
7559       flags |= GOVD_SHARED;
7560       break;
7561     case OMP_CLAUSE_DEFAULT_PRIVATE:
7562       flags |= GOVD_PRIVATE;
7563       break;
7564     case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
7565       flags |= GOVD_FIRSTPRIVATE;
7566       break;
7567     case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
7568       /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED.  */
7569       gcc_assert ((ctx->region_type & ORT_TASK) != 0);
7570       if (struct gimplify_omp_ctx *octx = ctx->outer_context)
7571           {
7572             omp_notice_variable (octx, decl, in_code);
7573             for (; octx; octx = octx->outer_context)
7574               {
7575                 splay_tree_node n2;
7576 
7577                 n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
7578                 if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
7579                       && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
7580                     continue;
7581                 if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
7582                     {
7583                       flags |= GOVD_FIRSTPRIVATE;
7584                       goto found_outer;
7585                     }
7586                 if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
7587                     {
7588                       flags |= GOVD_SHARED;
7589                       goto found_outer;
7590                     }
7591               }
7592           }
7593 
7594       if (TREE_CODE (decl) == PARM_DECL
7595             || (!is_global_var (decl)
7596                 && DECL_CONTEXT (decl) == current_function_decl))
7597           flags |= GOVD_FIRSTPRIVATE;
7598       else
7599           flags |= GOVD_SHARED;
7600     found_outer:
7601       break;
7602 
7603     default:
7604       gcc_unreachable ();
7605     }
7606 
7607   return flags;
7608 }
7609 
7610 
7611 /* Determine outer default flags for DECL mentioned in an OACC region
7612    but not declared in an enclosing clause.  */
7613 
7614 static unsigned
oacc_default_clause(struct gimplify_omp_ctx * ctx,tree decl,unsigned flags)7615 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
7616 {
7617   const char *rkind;
7618   bool on_device = false;
7619   bool is_private = false;
7620   bool declared = is_oacc_declared (decl);
7621   tree type = TREE_TYPE (decl);
7622 
7623   if (omp_privatize_by_reference (decl))
7624     type = TREE_TYPE (type);
7625 
7626   /* For Fortran COMMON blocks, only used variables in those blocks are
7627      transfered and remapped.  The block itself will have a private clause to
7628      avoid transfering the data twice.
7629      The hook evaluates to false by default.  For a variable in Fortran's COMMON
7630      or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
7631      the variables in such a COMMON/EQUIVALENCE block shall be privatized not
7632      the whole block.  For C++ and Fortran, it can also be true under certain
7633      other conditions, if DECL_HAS_VALUE_EXPR.  */
7634   if (RECORD_OR_UNION_TYPE_P (type))
7635     is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
7636 
7637   if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
7638       && is_global_var (decl)
7639       && device_resident_p (decl)
7640       && !is_private)
7641     {
7642       on_device = true;
7643       flags |= GOVD_MAP_TO_ONLY;
7644     }
7645 
7646   switch (ctx->region_type)
7647     {
7648     case ORT_ACC_KERNELS:
7649       rkind = "kernels";
7650 
7651       if (is_private)
7652           flags |= GOVD_FIRSTPRIVATE;
7653       else if (AGGREGATE_TYPE_P (type))
7654           {
7655             /* Aggregates default to 'present_or_copy', or 'present'.  */
7656             if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7657               flags |= GOVD_MAP;
7658             else
7659               flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7660           }
7661       else
7662           /* Scalars default to 'copy'.  */
7663           flags |= GOVD_MAP | GOVD_MAP_FORCE;
7664 
7665       break;
7666 
7667     case ORT_ACC_PARALLEL:
7668     case ORT_ACC_SERIAL:
7669       rkind = ctx->region_type == ORT_ACC_PARALLEL ? "parallel" : "serial";
7670 
7671       if (is_private)
7672           flags |= GOVD_FIRSTPRIVATE;
7673       else if (on_device || declared)
7674           flags |= GOVD_MAP;
7675       else if (AGGREGATE_TYPE_P (type))
7676           {
7677             /* Aggregates default to 'present_or_copy', or 'present'.  */
7678             if (ctx->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
7679               flags |= GOVD_MAP;
7680             else
7681               flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
7682           }
7683       else
7684           /* Scalars default to 'firstprivate'.  */
7685           flags |= GOVD_FIRSTPRIVATE;
7686 
7687       break;
7688 
7689     default:
7690       gcc_unreachable ();
7691     }
7692 
7693   if (DECL_ARTIFICIAL (decl))
7694     ; /* We can get compiler-generated decls, and should not complain
7695            about them.  */
7696   else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_NONE)
7697     {
7698       error ("%qE not specified in enclosing OpenACC %qs construct",
7699                DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rkind);
7700       inform (ctx->location, "enclosing OpenACC %qs construct", rkind);
7701     }
7702   else if (ctx->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
7703     ; /* Handled above.  */
7704   else
7705     gcc_checking_assert (ctx->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
7706 
7707   return flags;
7708 }
7709 
7710 /* Record the fact that DECL was used within the OMP context CTX.
7711    IN_CODE is true when real code uses DECL, and false when we should
7712    merely emit default(none) errors.  Return true if DECL is going to
7713    be remapped and thus DECL shouldn't be gimplified into its
7714    DECL_VALUE_EXPR (if any).  */
7715 
7716 static bool
omp_notice_variable(struct gimplify_omp_ctx * ctx,tree decl,bool in_code)7717 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
7718 {
7719   splay_tree_node n;
7720   unsigned flags = in_code ? GOVD_SEEN : 0;
7721   bool ret = false, shared;
7722 
7723   if (error_operand_p (decl))
7724     return false;
7725 
7726   if (ctx->region_type == ORT_NONE)
7727     return lang_hooks.decls.omp_disregard_value_expr (decl, false);
7728 
7729   if (is_global_var (decl))
7730     {
7731       /* Threadprivate variables are predetermined.  */
7732       if (DECL_THREAD_LOCAL_P (decl))
7733           return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
7734 
7735       if (DECL_HAS_VALUE_EXPR_P (decl))
7736           {
7737             if (ctx->region_type & ORT_ACC)
7738               /* For OpenACC, defer expansion of value to avoid transfering
7739                  privatized common block data instead of im-/explicitly transfered
7740                  variables which are in common blocks.  */
7741               ;
7742             else
7743               {
7744                 tree value = get_base_address (DECL_VALUE_EXPR (decl));
7745 
7746                 if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
7747                     return omp_notice_threadprivate_variable (ctx, decl, value);
7748               }
7749           }
7750 
7751       if (gimplify_omp_ctxp->outer_context == NULL
7752             && VAR_P (decl)
7753             && oacc_get_fn_attrib (current_function_decl))
7754           {
7755             location_t loc = DECL_SOURCE_LOCATION (decl);
7756 
7757             if (lookup_attribute ("omp declare target link",
7758                                         DECL_ATTRIBUTES (decl)))
7759               {
7760                 error_at (loc,
7761                               "%qE with %<link%> clause used in %<routine%> function",
7762                               DECL_NAME (decl));
7763                 return false;
7764               }
7765             else if (!lookup_attribute ("omp declare target",
7766                                               DECL_ATTRIBUTES (decl)))
7767               {
7768                 error_at (loc,
7769                               "%qE requires a %<declare%> directive for use "
7770                               "in a %<routine%> function", DECL_NAME (decl));
7771                 return false;
7772               }
7773           }
7774     }
7775 
7776   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
7777   if ((ctx->region_type & ORT_TARGET) != 0)
7778     {
7779       if (ctx->region_type & ORT_ACC)
7780           /* For OpenACC, as remarked above, defer expansion.  */
7781           shared = false;
7782       else
7783           shared = true;
7784 
7785       ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7786       if (n == NULL)
7787           {
7788             unsigned nflags = flags;
7789             if ((ctx->region_type & ORT_ACC) == 0)
7790               {
7791                 bool is_declare_target = false;
7792                 if (is_global_var (decl)
7793                       && varpool_node::get_create (decl)->offloadable)
7794                     {
7795                       struct gimplify_omp_ctx *octx;
7796                       for (octx = ctx->outer_context;
7797                            octx; octx = octx->outer_context)
7798                         {
7799                           n = splay_tree_lookup (octx->variables,
7800                                                        (splay_tree_key)decl);
7801                           if (n
7802                                 && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
7803                                 && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
7804                               break;
7805                         }
7806                       is_declare_target = octx == NULL;
7807                     }
7808                 if (!is_declare_target)
7809                     {
7810                       int gdmk;
7811                       enum omp_clause_defaultmap_kind kind;
7812                       if (lang_hooks.decls.omp_allocatable_p (decl))
7813                         gdmk = GDMK_ALLOCATABLE;
7814                       else if (lang_hooks.decls.omp_scalar_target_p (decl))
7815                         gdmk = GDMK_SCALAR_TARGET;
7816                       else if (lang_hooks.decls.omp_scalar_p (decl, false))
7817                         gdmk = GDMK_SCALAR;
7818                       else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
7819                                  || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
7820                                      && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
7821                                            == POINTER_TYPE)))
7822                         gdmk = GDMK_POINTER;
7823                       else
7824                         gdmk = GDMK_AGGREGATE;
7825                       kind = lang_hooks.decls.omp_predetermined_mapping (decl);
7826                       if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
7827                         {
7828                           if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
7829                               nflags |= GOVD_FIRSTPRIVATE;
7830                           else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
7831                               nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
7832                           else
7833                               gcc_unreachable ();
7834                         }
7835                       else if (ctx->defaultmap[gdmk] == 0)
7836                         {
7837                           tree d = lang_hooks.decls.omp_report_decl (decl);
7838                           error ("%qE not specified in enclosing %<target%>",
7839                                    DECL_NAME (d));
7840                           inform (ctx->location, "enclosing %<target%>");
7841                         }
7842                       else if (ctx->defaultmap[gdmk]
7843                                  & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
7844                         nflags |= ctx->defaultmap[gdmk];
7845                       else
7846                         {
7847                           gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
7848                           nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
7849                         }
7850                     }
7851               }
7852 
7853             struct gimplify_omp_ctx *octx = ctx->outer_context;
7854             if ((ctx->region_type & ORT_ACC) && octx)
7855               {
7856                 /* Look in outer OpenACC contexts, to see if there's a
7857                      data attribute for this variable.  */
7858                 omp_notice_variable (octx, decl, in_code);
7859 
7860                 for (; octx; octx = octx->outer_context)
7861                     {
7862                       if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
7863                         break;
7864                       splay_tree_node n2
7865                         = splay_tree_lookup (octx->variables,
7866                                                    (splay_tree_key) decl);
7867                       if (n2)
7868                         {
7869                           if (octx->region_type == ORT_ACC_HOST_DATA)
7870                             error ("variable %qE declared in enclosing "
7871                                      "%<host_data%> region", DECL_NAME (decl));
7872                           nflags |= GOVD_MAP;
7873                           if (octx->region_type == ORT_ACC_DATA
7874                                 && (n2->value & GOVD_MAP_0LEN_ARRAY))
7875                               nflags |= GOVD_MAP_0LEN_ARRAY;
7876                           goto found_outer;
7877                         }
7878                     }
7879               }
7880 
7881             if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
7882                                 | GOVD_MAP_ALLOC_ONLY)) == flags)
7883               {
7884                 tree type = TREE_TYPE (decl);
7885 
7886                 if (gimplify_omp_ctxp->target_firstprivatize_array_bases
7887                       && omp_privatize_by_reference (decl))
7888                     type = TREE_TYPE (type);
7889                 if (!lang_hooks.types.omp_mappable_type (type))
7890                     {
7891                       error ("%qD referenced in target region does not have "
7892                                "a mappable type", decl);
7893                       nflags |= GOVD_MAP | GOVD_EXPLICIT;
7894                     }
7895                 else
7896                     {
7897                       if ((ctx->region_type & ORT_ACC) != 0)
7898                         nflags = oacc_default_clause (ctx, decl, flags);
7899                       else
7900                         nflags |= GOVD_MAP;
7901                     }
7902               }
7903           found_outer:
7904             omp_add_variable (ctx, decl, nflags);
7905           }
7906       else
7907           {
7908             /* If nothing changed, there's nothing left to do.  */
7909             if ((n->value & flags) == flags)
7910               return ret;
7911             flags |= n->value;
7912             n->value = flags;
7913           }
7914       goto do_outer;
7915     }
7916 
7917   if (n == NULL)
7918     {
7919       if (ctx->region_type == ORT_WORKSHARE
7920             || ctx->region_type == ORT_TASKGROUP
7921             || ctx->region_type == ORT_SIMD
7922             || ctx->region_type == ORT_ACC
7923             || (ctx->region_type & ORT_TARGET_DATA) != 0)
7924           goto do_outer;
7925 
7926       flags = omp_default_clause (ctx, decl, in_code, flags);
7927 
7928       if ((flags & GOVD_PRIVATE)
7929             && lang_hooks.decls.omp_private_outer_ref (decl))
7930           flags |= GOVD_PRIVATE_OUTER_REF;
7931 
7932       omp_add_variable (ctx, decl, flags);
7933 
7934       shared = (flags & GOVD_SHARED) != 0;
7935       ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7936       goto do_outer;
7937     }
7938 
7939   /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
7940      lb, b or incr expressions, those shouldn't be turned into simd arrays.  */
7941   if (ctx->region_type == ORT_SIMD
7942       && ctx->in_for_exprs
7943       && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
7944             == GOVD_PRIVATE))
7945     flags &= ~GOVD_SEEN;
7946 
7947   if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
7948       && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
7949       && DECL_SIZE (decl))
7950     {
7951       if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
7952           {
7953             splay_tree_node n2;
7954             tree t = DECL_VALUE_EXPR (decl);
7955             gcc_assert (TREE_CODE (t) == INDIRECT_REF);
7956             t = TREE_OPERAND (t, 0);
7957             gcc_assert (DECL_P (t));
7958             n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7959             n2->value |= GOVD_SEEN;
7960           }
7961       else if (omp_privatize_by_reference (decl)
7962                  && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
7963                  && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
7964                        != INTEGER_CST))
7965           {
7966             splay_tree_node n2;
7967             tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
7968             gcc_assert (DECL_P (t));
7969             n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
7970             if (n2)
7971               omp_notice_variable (ctx, t, true);
7972           }
7973     }
7974 
7975   if (ctx->region_type & ORT_ACC)
7976     /* For OpenACC, as remarked above, defer expansion.  */
7977     shared = false;
7978   else
7979     shared = ((flags | n->value) & GOVD_SHARED) != 0;
7980   ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
7981 
7982   /* If nothing changed, there's nothing left to do.  */
7983   if ((n->value & flags) == flags)
7984     return ret;
7985   flags |= n->value;
7986   n->value = flags;
7987 
7988  do_outer:
7989   /* If the variable is private in the current context, then we don't
7990      need to propagate anything to an outer context.  */
7991   if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
7992     return ret;
7993   if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7994       == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7995     return ret;
7996   if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
7997                     | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7998       == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
7999     return ret;
8000   if (ctx->outer_context
8001       && omp_notice_variable (ctx->outer_context, decl, in_code))
8002     return true;
8003   return ret;
8004 }
8005 
8006 /* Verify that DECL is private within CTX.  If there's specific information
8007    to the contrary in the innermost scope, generate an error.  */
8008 
8009 static bool
omp_is_private(struct gimplify_omp_ctx * ctx,tree decl,int simd)8010 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
8011 {
8012   splay_tree_node n;
8013 
8014   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
8015   if (n != NULL)
8016     {
8017       if (n->value & GOVD_SHARED)
8018           {
8019             if (ctx == gimplify_omp_ctxp)
8020               {
8021                 if (simd)
8022                     error ("iteration variable %qE is predetermined linear",
8023                            DECL_NAME (decl));
8024                 else
8025                     error ("iteration variable %qE should be private",
8026                            DECL_NAME (decl));
8027                 n->value = GOVD_PRIVATE;
8028                 return true;
8029               }
8030             else
8031               return false;
8032           }
8033       else if ((n->value & GOVD_EXPLICIT) != 0
8034                  && (ctx == gimplify_omp_ctxp
8035                        || (ctx->region_type == ORT_COMBINED_PARALLEL
8036                            && gimplify_omp_ctxp->outer_context == ctx)))
8037           {
8038             if ((n->value & GOVD_FIRSTPRIVATE) != 0)
8039               error ("iteration variable %qE should not be firstprivate",
8040                        DECL_NAME (decl));
8041             else if ((n->value & GOVD_REDUCTION) != 0)
8042               error ("iteration variable %qE should not be reduction",
8043                        DECL_NAME (decl));
8044             else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
8045               error ("iteration variable %qE should not be linear",
8046                        DECL_NAME (decl));
8047           }
8048       return (ctx == gimplify_omp_ctxp
8049                 || (ctx->region_type == ORT_COMBINED_PARALLEL
8050                       && gimplify_omp_ctxp->outer_context == ctx));
8051     }
8052 
8053   if (ctx->region_type != ORT_WORKSHARE
8054       && ctx->region_type != ORT_TASKGROUP
8055       && ctx->region_type != ORT_SIMD
8056       && ctx->region_type != ORT_ACC)
8057     return false;
8058   else if (ctx->outer_context)
8059     return omp_is_private (ctx->outer_context, decl, simd);
8060   return false;
8061 }
8062 
8063 /* Return true if DECL is private within a parallel region
8064    that binds to the current construct's context or in parallel
8065    region's REDUCTION clause.  */
8066 
8067 static bool
omp_check_private(struct gimplify_omp_ctx * ctx,tree decl,bool copyprivate)8068 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
8069 {
8070   splay_tree_node n;
8071 
8072   do
8073     {
8074       ctx = ctx->outer_context;
8075       if (ctx == NULL)
8076           {
8077             if (is_global_var (decl))
8078               return false;
8079 
8080             /* References might be private, but might be shared too,
8081                when checking for copyprivate, assume they might be
8082                private, otherwise assume they might be shared.  */
8083             if (copyprivate)
8084               return true;
8085 
8086             if (omp_privatize_by_reference (decl))
8087               return false;
8088 
8089             /* Treat C++ privatized non-static data members outside
8090                of the privatization the same.  */
8091             if (omp_member_access_dummy_var (decl))
8092               return false;
8093 
8094             return true;
8095           }
8096 
8097       n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
8098 
8099       if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
8100             && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
8101           {
8102             if ((ctx->region_type & ORT_TARGET_DATA) != 0
8103                 || n == NULL
8104                 || (n->value & GOVD_MAP) == 0)
8105               continue;
8106             return false;
8107           }
8108 
8109       if (n != NULL)
8110           {
8111             if ((n->value & GOVD_LOCAL) != 0
8112                 && omp_member_access_dummy_var (decl))
8113               return false;
8114             return (n->value & GOVD_SHARED) == 0;
8115           }
8116 
8117       if (ctx->region_type == ORT_WORKSHARE
8118             || ctx->region_type == ORT_TASKGROUP
8119             || ctx->region_type == ORT_SIMD
8120             || ctx->region_type == ORT_ACC)
8121           continue;
8122 
8123       break;
8124     }
8125   while (1);
8126   return false;
8127 }
8128 
8129 /* Callback for walk_tree to find a DECL_EXPR for the given DECL.  */
8130 
8131 static tree
find_decl_expr(tree * tp,int * walk_subtrees,void * data)8132 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
8133 {
8134   tree t = *tp;
8135 
8136   /* If this node has been visited, unmark it and keep looking.  */
8137   if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
8138     return t;
8139 
8140   if (IS_TYPE_OR_DECL_P (t))
8141     *walk_subtrees = 0;
8142   return NULL_TREE;
8143 }
8144 
8145 
8146 /* Gimplify the affinity clause but effectively ignore it.
8147    Generate:
8148      var = begin;
8149      if ((step > 1) ? var <= end : var > end)
8150        locatator_var_expr;  */
8151 
8152 static void
gimplify_omp_affinity(tree * list_p,gimple_seq * pre_p)8153 gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p)
8154 {
8155   tree last_iter = NULL_TREE;
8156   tree last_bind = NULL_TREE;
8157   tree label = NULL_TREE;
8158   tree *last_body = NULL;
8159   for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8160     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
8161       {
8162           tree t = OMP_CLAUSE_DECL (c);
8163           if (TREE_CODE (t) == TREE_LIST
8164                         && TREE_PURPOSE (t)
8165                         && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8166             {
8167               if (TREE_VALUE (t) == null_pointer_node)
8168                 continue;
8169               if (TREE_PURPOSE (t) != last_iter)
8170                 {
8171                     if (last_bind)
8172                       {
8173                         append_to_statement_list (label, last_body);
8174                         gimplify_and_add (last_bind, pre_p);
8175                         last_bind = NULL_TREE;
8176                       }
8177                     for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8178                       {
8179                         if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8180                                                is_gimple_val, fb_rvalue) == GS_ERROR
8181                               || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8182                                                     is_gimple_val, fb_rvalue) == GS_ERROR
8183                               || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8184                                                     is_gimple_val, fb_rvalue) == GS_ERROR
8185                               || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8186                                                      is_gimple_val, fb_rvalue)
8187                                   == GS_ERROR))
8188                           return;
8189                       }
8190               last_iter = TREE_PURPOSE (t);
8191               tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8192               last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
8193                                         NULL, block);
8194               last_body = &BIND_EXPR_BODY (last_bind);
8195               tree cond = NULL_TREE;
8196               location_t loc = OMP_CLAUSE_LOCATION (c);
8197               for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8198                 {
8199                     tree var = TREE_VEC_ELT (it, 0);
8200                     tree begin = TREE_VEC_ELT (it, 1);
8201                     tree end = TREE_VEC_ELT (it, 2);
8202                     tree step = TREE_VEC_ELT (it, 3);
8203                     loc = DECL_SOURCE_LOCATION (var);
8204                     tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8205                                                var, begin);
8206                     append_to_statement_list_force (tem, last_body);
8207 
8208                     tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8209                                      step, build_zero_cst (TREE_TYPE (step)));
8210                     tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node,
8211                                                         var, end);
8212                     tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8213                                                         var, end);
8214                     cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node,
8215                                                    cond1, cond2, cond3);
8216                     if (cond)
8217                       cond = fold_build2_loc (loc, TRUTH_AND_EXPR,
8218                                                     boolean_type_node, cond, cond1);
8219                     else
8220                       cond = cond1;
8221                 }
8222               tree cont_label = create_artificial_label (loc);
8223               label = build1 (LABEL_EXPR, void_type_node, cont_label);
8224               tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
8225                                                   void_node,
8226                                                   build_and_jump (&cont_label));
8227               append_to_statement_list_force (tem, last_body);
8228                 }
8229               if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8230                 {
8231                     append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0),
8232                                                     last_body);
8233                     TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8234                 }
8235               if (error_operand_p (TREE_VALUE (t)))
8236                 return;
8237               append_to_statement_list_force (TREE_VALUE (t), last_body);
8238               TREE_VALUE (t) = null_pointer_node;
8239             }
8240           else
8241             {
8242               if (last_bind)
8243                 {
8244                     append_to_statement_list (label, last_body);
8245                     gimplify_and_add (last_bind, pre_p);
8246                     last_bind = NULL_TREE;
8247                 }
8248               if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8249                 {
8250                     gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8251                                      NULL, is_gimple_val, fb_rvalue);
8252                     OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8253                 }
8254               if (error_operand_p (OMP_CLAUSE_DECL (c)))
8255                 return;
8256               if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8257                                      is_gimple_lvalue, fb_lvalue) == GS_ERROR)
8258                 return;
8259               gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p);
8260             }
8261       }
8262   if (last_bind)
8263     {
8264       append_to_statement_list (label, last_body);
8265       gimplify_and_add (last_bind, pre_p);
8266     }
8267   return;
8268 }
8269 
8270 /* If *LIST_P contains any OpenMP depend clauses with iterators,
8271    lower all the depend clauses by populating corresponding depend
8272    array.  Returns 0 if there are no such depend clauses, or
8273    2 if all depend clauses should be removed, 1 otherwise.  */
8274 
8275 static int
gimplify_omp_depend(tree * list_p,gimple_seq * pre_p)8276 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
8277 {
8278   tree c;
8279   gimple *g;
8280   size_t n[4] = { 0, 0, 0, 0 };
8281   bool unused[4];
8282   tree counts[4] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
8283   tree last_iter = NULL_TREE, last_count = NULL_TREE;
8284   size_t i, j;
8285   location_t first_loc = UNKNOWN_LOCATION;
8286 
8287   for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8288     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8289       {
8290           switch (OMP_CLAUSE_DEPEND_KIND (c))
8291             {
8292             case OMP_CLAUSE_DEPEND_IN:
8293               i = 2;
8294               break;
8295             case OMP_CLAUSE_DEPEND_OUT:
8296             case OMP_CLAUSE_DEPEND_INOUT:
8297               i = 0;
8298               break;
8299             case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8300               i = 1;
8301               break;
8302             case OMP_CLAUSE_DEPEND_DEPOBJ:
8303               i = 3;
8304               break;
8305             case OMP_CLAUSE_DEPEND_SOURCE:
8306             case OMP_CLAUSE_DEPEND_SINK:
8307               continue;
8308             default:
8309               gcc_unreachable ();
8310             }
8311           tree t = OMP_CLAUSE_DECL (c);
8312           if (first_loc == UNKNOWN_LOCATION)
8313             first_loc = OMP_CLAUSE_LOCATION (c);
8314           if (TREE_CODE (t) == TREE_LIST
8315               && TREE_PURPOSE (t)
8316               && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8317             {
8318               if (TREE_PURPOSE (t) != last_iter)
8319                 {
8320                     tree tcnt = size_one_node;
8321                     for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8322                       {
8323                         if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
8324                                                is_gimple_val, fb_rvalue) == GS_ERROR
8325                               || gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
8326                                                     is_gimple_val, fb_rvalue) == GS_ERROR
8327                               || gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
8328                                                     is_gimple_val, fb_rvalue) == GS_ERROR
8329                               || (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
8330                                                      is_gimple_val, fb_rvalue)
8331                                   == GS_ERROR))
8332                           return 2;
8333                         tree var = TREE_VEC_ELT (it, 0);
8334                         tree begin = TREE_VEC_ELT (it, 1);
8335                         tree end = TREE_VEC_ELT (it, 2);
8336                         tree step = TREE_VEC_ELT (it, 3);
8337                         tree orig_step = TREE_VEC_ELT (it, 4);
8338                         tree type = TREE_TYPE (var);
8339                         tree stype = TREE_TYPE (step);
8340                         location_t loc = DECL_SOURCE_LOCATION (var);
8341                         tree endmbegin;
8342                         /* Compute count for this iterator as
8343                            orig_step > 0
8344                            ? (begin < end ? (end - begin + (step - 1)) / step : 0)
8345                            : (begin > end ? (end - begin + (step + 1)) / step : 0)
8346                            and compute product of those for the entire depend
8347                            clause.  */
8348                         if (POINTER_TYPE_P (type))
8349                           endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
8350                                                                stype, end, begin);
8351                         else
8352                           endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
8353                                                                end, begin);
8354                         tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
8355                                                                step,
8356                                                                build_int_cst (stype, 1));
8357                         tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
8358                                                                build_int_cst (stype, 1));
8359                         tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
8360                                                             unshare_expr (endmbegin),
8361                                                             stepm1);
8362                         pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8363                                                      pos, step);
8364                         tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
8365                                                             endmbegin, stepp1);
8366                         if (TYPE_UNSIGNED (stype))
8367                           {
8368                               neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
8369                               step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
8370                           }
8371                         neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
8372                                                      neg, step);
8373                         step = NULL_TREE;
8374                         tree cond = fold_build2_loc (loc, LT_EXPR,
8375                                                              boolean_type_node,
8376                                                              begin, end);
8377                         pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
8378                                                      build_int_cst (stype, 0));
8379                         cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
8380                                                       end, begin);
8381                         neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
8382                                                      build_int_cst (stype, 0));
8383                         tree osteptype = TREE_TYPE (orig_step);
8384                         cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8385                                                       orig_step,
8386                                                       build_int_cst (osteptype, 0));
8387                         tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
8388                                                             cond, pos, neg);
8389                         cnt = fold_convert_loc (loc, sizetype, cnt);
8390                         if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
8391                                                fb_rvalue) == GS_ERROR)
8392                           return 2;
8393                         tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
8394                       }
8395                     if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
8396                                            fb_rvalue) == GS_ERROR)
8397                       return 2;
8398                     last_iter = TREE_PURPOSE (t);
8399                     last_count = tcnt;
8400                 }
8401               if (counts[i] == NULL_TREE)
8402                 counts[i] = last_count;
8403               else
8404                 counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
8405                                                     PLUS_EXPR, counts[i], last_count);
8406             }
8407           else
8408             n[i]++;
8409       }
8410   for (i = 0; i < 4; i++)
8411     if (counts[i])
8412       break;
8413   if (i == 4)
8414     return 0;
8415 
8416   tree total = size_zero_node;
8417   for (i = 0; i < 4; i++)
8418     {
8419       unused[i] = counts[i] == NULL_TREE && n[i] == 0;
8420       if (counts[i] == NULL_TREE)
8421           counts[i] = size_zero_node;
8422       if (n[i])
8423           counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
8424       if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
8425                                fb_rvalue) == GS_ERROR)
8426           return 2;
8427       total = size_binop (PLUS_EXPR, total, counts[i]);
8428     }
8429 
8430   if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
8431       == GS_ERROR)
8432     return 2;
8433   bool is_old = unused[1] && unused[3];
8434   tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
8435                                    size_int (is_old ? 1 : 4));
8436   tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
8437   tree array = create_tmp_var_raw (type);
8438   TREE_ADDRESSABLE (array) = 1;
8439   if (!poly_int_tree_p (totalpx))
8440     {
8441       if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
8442           gimplify_type_sizes (TREE_TYPE (array), pre_p);
8443       if (gimplify_omp_ctxp)
8444           {
8445             struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
8446             while (ctx
8447                      && (ctx->region_type == ORT_WORKSHARE
8448                          || ctx->region_type == ORT_TASKGROUP
8449                          || ctx->region_type == ORT_SIMD
8450                          || ctx->region_type == ORT_ACC))
8451               ctx = ctx->outer_context;
8452             if (ctx)
8453               omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
8454           }
8455       gimplify_vla_decl (array, pre_p);
8456     }
8457   else
8458     gimple_add_tmp_var (array);
8459   tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
8460                        NULL_TREE);
8461   tree tem;
8462   if (!is_old)
8463     {
8464       tem = build2 (MODIFY_EXPR, void_type_node, r,
8465                         build_int_cst (ptr_type_node, 0));
8466       gimplify_and_add (tem, pre_p);
8467       r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
8468                       NULL_TREE);
8469     }
8470   tem = build2 (MODIFY_EXPR, void_type_node, r,
8471                     fold_convert (ptr_type_node, total));
8472   gimplify_and_add (tem, pre_p);
8473   for (i = 1; i < (is_old ? 2 : 4); i++)
8474     {
8475       r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
8476                       NULL_TREE, NULL_TREE);
8477       tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
8478       gimplify_and_add (tem, pre_p);
8479     }
8480 
8481   tree cnts[4];
8482   for (j = 4; j; j--)
8483     if (!unused[j - 1])
8484       break;
8485   for (i = 0; i < 4; i++)
8486     {
8487       if (i && (i >= j || unused[i - 1]))
8488           {
8489             cnts[i] = cnts[i - 1];
8490             continue;
8491           }
8492       cnts[i] = create_tmp_var (sizetype);
8493       if (i == 0)
8494           g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
8495       else
8496           {
8497             tree t;
8498             if (is_old)
8499               t = size_binop (PLUS_EXPR, counts[0], size_int (2));
8500             else
8501               t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
8502             if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
8503                 == GS_ERROR)
8504               return 2;
8505             g = gimple_build_assign (cnts[i], t);
8506           }
8507       gimple_seq_add_stmt (pre_p, g);
8508     }
8509 
8510   last_iter = NULL_TREE;
8511   tree last_bind = NULL_TREE;
8512   tree *last_body = NULL;
8513   for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
8514     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
8515       {
8516           switch (OMP_CLAUSE_DEPEND_KIND (c))
8517             {
8518             case OMP_CLAUSE_DEPEND_IN:
8519               i = 2;
8520               break;
8521             case OMP_CLAUSE_DEPEND_OUT:
8522             case OMP_CLAUSE_DEPEND_INOUT:
8523               i = 0;
8524               break;
8525             case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
8526               i = 1;
8527               break;
8528             case OMP_CLAUSE_DEPEND_DEPOBJ:
8529               i = 3;
8530               break;
8531             case OMP_CLAUSE_DEPEND_SOURCE:
8532             case OMP_CLAUSE_DEPEND_SINK:
8533               continue;
8534             default:
8535               gcc_unreachable ();
8536             }
8537           tree t = OMP_CLAUSE_DECL (c);
8538           if (TREE_CODE (t) == TREE_LIST
8539               && TREE_PURPOSE (t)
8540               && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
8541             {
8542               if (TREE_PURPOSE (t) != last_iter)
8543                 {
8544                     if (last_bind)
8545                       gimplify_and_add (last_bind, pre_p);
8546                     tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
8547                     last_bind = build3 (BIND_EXPR, void_type_node,
8548                                             BLOCK_VARS (block), NULL, block);
8549                     TREE_SIDE_EFFECTS (last_bind) = 1;
8550                     SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
8551                     tree *p = &BIND_EXPR_BODY (last_bind);
8552                     for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
8553                       {
8554                         tree var = TREE_VEC_ELT (it, 0);
8555                         tree begin = TREE_VEC_ELT (it, 1);
8556                         tree end = TREE_VEC_ELT (it, 2);
8557                         tree step = TREE_VEC_ELT (it, 3);
8558                         tree orig_step = TREE_VEC_ELT (it, 4);
8559                         tree type = TREE_TYPE (var);
8560                         location_t loc = DECL_SOURCE_LOCATION (var);
8561                         /* Emit:
8562                            var = begin;
8563                            goto cond_label;
8564                            beg_label:
8565                            ...
8566                            var = var + step;
8567                            cond_label:
8568                            if (orig_step > 0) {
8569                                if (var < end) goto beg_label;
8570                            } else {
8571                                if (var > end) goto beg_label;
8572                            }
8573                            for each iterator, with inner iterators added to
8574                            the ... above.  */
8575                         tree beg_label = create_artificial_label (loc);
8576                         tree cond_label = NULL_TREE;
8577                         tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8578                                               var, begin);
8579                         append_to_statement_list_force (tem, p);
8580                         tem = build_and_jump (&cond_label);
8581                         append_to_statement_list_force (tem, p);
8582                         tem = build1 (LABEL_EXPR, void_type_node, beg_label);
8583                         append_to_statement_list (tem, p);
8584                         tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
8585                                                   NULL_TREE, NULL_TREE);
8586                         TREE_SIDE_EFFECTS (bind) = 1;
8587                         SET_EXPR_LOCATION (bind, loc);
8588                         append_to_statement_list_force (bind, p);
8589                         if (POINTER_TYPE_P (type))
8590                           tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
8591                                                   var, fold_convert_loc (loc, sizetype,
8592                                                                              step));
8593                         else
8594                           tem = build2_loc (loc, PLUS_EXPR, type, var, step);
8595                         tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
8596                                               var, tem);
8597                         append_to_statement_list_force (tem, p);
8598                         tem = build1 (LABEL_EXPR, void_type_node, cond_label);
8599                         append_to_statement_list (tem, p);
8600                         tree cond = fold_build2_loc (loc, LT_EXPR,
8601                                                              boolean_type_node,
8602                                                              var, end);
8603                         tree pos
8604                           = fold_build3_loc (loc, COND_EXPR, void_type_node,
8605                                                    cond, build_and_jump (&beg_label),
8606                                                    void_node);
8607                         cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8608                                                       var, end);
8609                         tree neg
8610                           = fold_build3_loc (loc, COND_EXPR, void_type_node,
8611                                                    cond, build_and_jump (&beg_label),
8612                                                    void_node);
8613                         tree osteptype = TREE_TYPE (orig_step);
8614                         cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
8615                                                       orig_step,
8616                                                       build_int_cst (osteptype, 0));
8617                         tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
8618                                                      cond, pos, neg);
8619                         append_to_statement_list_force (tem, p);
8620                         p = &BIND_EXPR_BODY (bind);
8621                       }
8622                     last_body = p;
8623                 }
8624               last_iter = TREE_PURPOSE (t);
8625               if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
8626                 {
8627                     append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
8628                                                     0), last_body);
8629                     TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
8630                 }
8631               if (error_operand_p (TREE_VALUE (t)))
8632                 return 2;
8633               TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
8634               r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8635                               NULL_TREE, NULL_TREE);
8636               tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8637                                     void_type_node, r, TREE_VALUE (t));
8638               append_to_statement_list_force (tem, last_body);
8639               tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
8640                                     void_type_node, cnts[i],
8641                                     size_binop (PLUS_EXPR, cnts[i], size_int (1)));
8642               append_to_statement_list_force (tem, last_body);
8643               TREE_VALUE (t) = null_pointer_node;
8644             }
8645           else
8646             {
8647               if (last_bind)
8648                 {
8649                     gimplify_and_add (last_bind, pre_p);
8650                     last_bind = NULL_TREE;
8651                 }
8652               if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
8653                 {
8654                     gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
8655                                      NULL, is_gimple_val, fb_rvalue);
8656                     OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
8657                 }
8658               if (error_operand_p (OMP_CLAUSE_DECL (c)))
8659                 return 2;
8660               OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
8661               if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
8662                                      is_gimple_val, fb_rvalue) == GS_ERROR)
8663                 return 2;
8664               r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
8665                               NULL_TREE, NULL_TREE);
8666               tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
8667               gimplify_and_add (tem, pre_p);
8668               g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR, cnts[i],
8669                                                                         size_int (1)));
8670               gimple_seq_add_stmt (pre_p, g);
8671             }
8672       }
8673   if (last_bind)
8674     gimplify_and_add (last_bind, pre_p);
8675   tree cond = boolean_false_node;
8676   if (is_old)
8677     {
8678       if (!unused[0])
8679           cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
8680                                  size_binop_loc (first_loc, PLUS_EXPR, counts[0],
8681                                                      size_int (2)));
8682       if (!unused[2])
8683           cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8684                                  build2_loc (first_loc, NE_EXPR, boolean_type_node,
8685                                                cnts[2],
8686                                                size_binop_loc (first_loc, PLUS_EXPR,
8687                                                                    totalpx,
8688                                                                    size_int (1))));
8689     }
8690   else
8691     {
8692       tree prev = size_int (5);
8693       for (i = 0; i < 4; i++)
8694           {
8695             if (unused[i])
8696               continue;
8697             prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
8698             cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
8699                                    build2_loc (first_loc, NE_EXPR, boolean_type_node,
8700                                                    cnts[i], unshare_expr (prev)));
8701           }
8702     }
8703   tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
8704                         build_call_expr_loc (first_loc,
8705                                                    builtin_decl_explicit (BUILT_IN_TRAP),
8706                                                    0), void_node);
8707   gimplify_and_add (tem, pre_p);
8708   c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
8709   OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
8710   OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
8711   OMP_CLAUSE_CHAIN (c) = *list_p;
8712   *list_p = c;
8713   return 1;
8714 }
8715 
8716 /* Insert a GOMP_MAP_ALLOC or GOMP_MAP_RELEASE node following a
8717    GOMP_MAP_STRUCT mapping.  C is an always_pointer mapping.  STRUCT_NODE is
8718    the struct node to insert the new mapping after (when the struct node is
8719    initially created).  PREV_NODE is the first of two or three mappings for a
8720    pointer, and is either:
8721      - the node before C, when a pair of mappings is used, e.g. for a C/C++
8722        array section.
8723      - not the node before C.  This is true when we have a reference-to-pointer
8724        type (with a mapping for the reference and for the pointer), or for
8725        Fortran derived-type mappings with a GOMP_MAP_TO_PSET.
8726    If SCP is non-null, the new node is inserted before *SCP.
8727    if SCP is null, the new node is inserted before PREV_NODE.
8728    The return type is:
8729      - PREV_NODE, if SCP is non-null.
8730      - The newly-created ALLOC or RELEASE node, if SCP is null.
8731      - The second newly-created ALLOC or RELEASE node, if we are mapping a
8732        reference to a pointer.  */
8733 
8734 static tree
insert_struct_comp_map(enum tree_code code,tree c,tree struct_node,tree prev_node,tree * scp)8735 insert_struct_comp_map (enum tree_code code, tree c, tree struct_node,
8736                               tree prev_node, tree *scp)
8737 {
8738   enum gomp_map_kind mkind
8739     = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
8740       ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
8741 
8742   tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8743   tree cl = scp ? prev_node : c2;
8744   OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
8745   OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (c));
8746   OMP_CLAUSE_CHAIN (c2) = scp ? *scp : prev_node;
8747   if (OMP_CLAUSE_CHAIN (prev_node) != c
8748       && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8749       && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8750             == GOMP_MAP_TO_PSET))
8751     OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (OMP_CLAUSE_CHAIN (prev_node));
8752   else
8753     OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
8754   if (struct_node)
8755     OMP_CLAUSE_CHAIN (struct_node) = c2;
8756 
8757   /* We might need to create an additional mapping if we have a reference to a
8758      pointer (in C++).  Don't do this if we have something other than a
8759      GOMP_MAP_ALWAYS_POINTER though, i.e. a GOMP_MAP_TO_PSET.  */
8760   if (OMP_CLAUSE_CHAIN (prev_node) != c
8761       && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
8762       && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8763              == GOMP_MAP_ALWAYS_POINTER)
8764             || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
8765                 == GOMP_MAP_ATTACH_DETACH)))
8766     {
8767       tree c4 = OMP_CLAUSE_CHAIN (prev_node);
8768       tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
8769       OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
8770       OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (c4));
8771       OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
8772       OMP_CLAUSE_CHAIN (c3) = prev_node;
8773       if (!scp)
8774           OMP_CLAUSE_CHAIN (c2) = c3;
8775       else
8776           cl = c3;
8777     }
8778 
8779   if (scp)
8780     *scp = c2;
8781 
8782   return cl;
8783 }
8784 
8785 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
8786    and set *BITPOSP and *POFFSETP to the bit offset of the access.
8787    If BASE_REF is non-NULL and the containing object is a reference, set
8788    *BASE_REF to that reference before dereferencing the object.
8789    If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
8790    has array type, else return NULL.  */
8791 
8792 static tree
extract_base_bit_offset(tree base,tree * base_ref,poly_int64 * bitposp,poly_offset_int * poffsetp,tree * offsetp)8793 extract_base_bit_offset (tree base, tree *base_ref, poly_int64 *bitposp,
8794                                poly_offset_int *poffsetp, tree *offsetp)
8795 {
8796   tree offset;
8797   poly_int64 bitsize, bitpos;
8798   machine_mode mode;
8799   int unsignedp, reversep, volatilep = 0;
8800   poly_offset_int poffset;
8801 
8802   if (base_ref)
8803     {
8804       *base_ref = NULL_TREE;
8805 
8806       while (TREE_CODE (base) == ARRAY_REF)
8807           base = TREE_OPERAND (base, 0);
8808 
8809       if (TREE_CODE (base) == INDIRECT_REF)
8810           base = TREE_OPERAND (base, 0);
8811     }
8812   else
8813     {
8814       if (TREE_CODE (base) == ARRAY_REF)
8815           {
8816             while (TREE_CODE (base) == ARRAY_REF)
8817               base = TREE_OPERAND (base, 0);
8818             if (TREE_CODE (base) != COMPONENT_REF
8819                 || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
8820               return NULL_TREE;
8821           }
8822       else if (TREE_CODE (base) == INDIRECT_REF
8823                  && TREE_CODE (TREE_OPERAND (base, 0)) == COMPONENT_REF
8824                  && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
8825                        == REFERENCE_TYPE))
8826           base = TREE_OPERAND (base, 0);
8827     }
8828 
8829   base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
8830                                     &unsignedp, &reversep, &volatilep);
8831 
8832   tree orig_base = base;
8833 
8834   if ((TREE_CODE (base) == INDIRECT_REF
8835        || (TREE_CODE (base) == MEM_REF
8836              && integer_zerop (TREE_OPERAND (base, 1))))
8837       && DECL_P (TREE_OPERAND (base, 0))
8838       && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == REFERENCE_TYPE)
8839     base = TREE_OPERAND (base, 0);
8840 
8841   if (offset && poly_int_tree_p (offset))
8842     {
8843       poffset = wi::to_poly_offset (offset);
8844       offset = NULL_TREE;
8845     }
8846   else
8847     poffset = 0;
8848 
8849   if (maybe_ne (bitpos, 0))
8850     poffset += bits_to_bytes_round_down (bitpos);
8851 
8852   *bitposp = bitpos;
8853   *poffsetp = poffset;
8854   *offsetp = offset;
8855 
8856   /* Set *BASE_REF if BASE was a dereferenced reference variable.  */
8857   if (base_ref && orig_base != base)
8858     *base_ref = orig_base;
8859 
8860   return base;
8861 }
8862 
8863 /* Returns true if EXPR is or contains (as a sub-component) BASE_PTR.  */
8864 
8865 static bool
is_or_contains_p(tree expr,tree base_ptr)8866 is_or_contains_p (tree expr, tree base_ptr)
8867 {
8868   if ((TREE_CODE (expr) == INDIRECT_REF && TREE_CODE (base_ptr) == MEM_REF)
8869       || (TREE_CODE (expr) == MEM_REF && TREE_CODE (base_ptr) == INDIRECT_REF))
8870     return operand_equal_p (TREE_OPERAND (expr, 0),
8871                                   TREE_OPERAND (base_ptr, 0));
8872   while (!operand_equal_p (expr, base_ptr))
8873     {
8874       if (TREE_CODE (base_ptr) == COMPOUND_EXPR)
8875           base_ptr = TREE_OPERAND (base_ptr, 1);
8876       if (TREE_CODE (base_ptr) == COMPONENT_REF
8877             || TREE_CODE (base_ptr) == POINTER_PLUS_EXPR
8878             || TREE_CODE (base_ptr) == SAVE_EXPR)
8879           base_ptr = TREE_OPERAND (base_ptr, 0);
8880       else
8881           break;
8882     }
8883   return operand_equal_p (expr, base_ptr);
8884 }
8885 
8886 /* Implement OpenMP 5.x map ordering rules for target directives. There are
8887    several rules, and with some level of ambiguity, hopefully we can at least
8888    collect the complexity here in one place.  */
8889 
8890 static void
omp_target_reorder_clauses(tree * list_p)8891 omp_target_reorder_clauses (tree *list_p)
8892 {
8893   /* Collect refs to alloc/release/delete maps.  */
8894   auto_vec<tree, 32> ard;
8895   tree *cp = list_p;
8896   while (*cp != NULL_TREE)
8897     if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8898           && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALLOC
8899               || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_RELEASE
8900               || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_DELETE))
8901       {
8902           /* Unlink cp and push to ard.  */
8903           tree c = *cp;
8904           tree nc = OMP_CLAUSE_CHAIN (c);
8905           *cp = nc;
8906           ard.safe_push (c);
8907 
8908           /* Any associated pointer type maps should also move along.  */
8909           while (*cp != NULL_TREE
8910                  && OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
8911                  && (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
8912                        || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_FIRSTPRIVATE_POINTER
8913                        || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH
8914                        || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_POINTER
8915                        || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ALWAYS_POINTER
8916                        || OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_TO_PSET))
8917             {
8918               c = *cp;
8919               nc = OMP_CLAUSE_CHAIN (c);
8920               *cp = nc;
8921               ard.safe_push (c);
8922             }
8923       }
8924     else
8925       cp = &OMP_CLAUSE_CHAIN (*cp);
8926 
8927   /* Link alloc/release/delete maps to the end of list.  */
8928   for (unsigned int i = 0; i < ard.length (); i++)
8929     {
8930       *cp = ard[i];
8931       cp = &OMP_CLAUSE_CHAIN (ard[i]);
8932     }
8933   *cp = NULL_TREE;
8934 
8935   /* OpenMP 5.0 requires that pointer variables are mapped before
8936      its use as a base-pointer.  */
8937   auto_vec<tree *, 32> atf;
8938   for (tree *cp = list_p; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
8939     if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
8940       {
8941           /* Collect alloc, to, from, to/from clause tree pointers.  */
8942           gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
8943           if (k == GOMP_MAP_ALLOC
8944               || k == GOMP_MAP_TO
8945               || k == GOMP_MAP_FROM
8946               || k == GOMP_MAP_TOFROM
8947               || k == GOMP_MAP_ALWAYS_TO
8948               || k == GOMP_MAP_ALWAYS_FROM
8949               || k == GOMP_MAP_ALWAYS_TOFROM)
8950             atf.safe_push (cp);
8951       }
8952 
8953   for (unsigned int i = 0; i < atf.length (); i++)
8954     if (atf[i])
8955       {
8956           tree *cp = atf[i];
8957           tree decl = OMP_CLAUSE_DECL (*cp);
8958           if (TREE_CODE (decl) == INDIRECT_REF || TREE_CODE (decl) == MEM_REF)
8959             {
8960               tree base_ptr = TREE_OPERAND (decl, 0);
8961               STRIP_TYPE_NOPS (base_ptr);
8962               for (unsigned int j = i + 1; j < atf.length (); j++)
8963                 if (atf[j])
8964                     {
8965                       tree *cp2 = atf[j];
8966                       tree decl2 = OMP_CLAUSE_DECL (*cp2);
8967 
8968                       decl2 = OMP_CLAUSE_DECL (*cp2);
8969                       if (is_or_contains_p (decl2, base_ptr))
8970                         {
8971                           /* Move *cp2 to before *cp.  */
8972                           tree c = *cp2;
8973                           *cp2 = OMP_CLAUSE_CHAIN (c);
8974                           OMP_CLAUSE_CHAIN (c) = *cp;
8975                           *cp = c;
8976 
8977                           if (*cp2 != NULL_TREE
8978                                 && OMP_CLAUSE_CODE (*cp2) == OMP_CLAUSE_MAP
8979                                 && OMP_CLAUSE_MAP_KIND (*cp2) == GOMP_MAP_ALWAYS_POINTER)
8980                               {
8981                                 tree c2 = *cp2;
8982                                 *cp2 = OMP_CLAUSE_CHAIN (c2);
8983                                 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
8984                                 OMP_CLAUSE_CHAIN (c) = c2;
8985                               }
8986 
8987                           atf[j] = NULL;
8988                       }
8989                     }
8990             }
8991       }
8992 
8993   /* For attach_detach map clauses, if there is another map that maps the
8994      attached/detached pointer, make sure that map is ordered before the
8995      attach_detach.  */
8996   atf.truncate (0);
8997   for (tree *cp = list_p; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
8998     if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP)
8999       {
9000           /* Collect alloc, to, from, to/from clauses, and
9001              always_pointer/attach_detach clauses.  */
9002           gomp_map_kind k = OMP_CLAUSE_MAP_KIND (*cp);
9003           if (k == GOMP_MAP_ALLOC
9004               || k == GOMP_MAP_TO
9005               || k == GOMP_MAP_FROM
9006               || k == GOMP_MAP_TOFROM
9007               || k == GOMP_MAP_ALWAYS_TO
9008               || k == GOMP_MAP_ALWAYS_FROM
9009               || k == GOMP_MAP_ALWAYS_TOFROM
9010               || k == GOMP_MAP_ATTACH_DETACH
9011               || k == GOMP_MAP_ALWAYS_POINTER)
9012             atf.safe_push (cp);
9013       }
9014 
9015   for (unsigned int i = 0; i < atf.length (); i++)
9016     if (atf[i])
9017       {
9018           tree *cp = atf[i];
9019           tree ptr = OMP_CLAUSE_DECL (*cp);
9020           STRIP_TYPE_NOPS (ptr);
9021           if (OMP_CLAUSE_MAP_KIND (*cp) == GOMP_MAP_ATTACH_DETACH)
9022             for (unsigned int j = i + 1; j < atf.length (); j++)
9023               {
9024                 tree *cp2 = atf[j];
9025                 tree decl2 = OMP_CLAUSE_DECL (*cp2);
9026                 if (OMP_CLAUSE_MAP_KIND (*cp2) != GOMP_MAP_ATTACH_DETACH
9027                       && OMP_CLAUSE_MAP_KIND (*cp2) != GOMP_MAP_ALWAYS_POINTER
9028                       && is_or_contains_p (decl2, ptr))
9029                     {
9030                       /* Move *cp2 to before *cp.  */
9031                       tree c = *cp2;
9032                       *cp2 = OMP_CLAUSE_CHAIN (c);
9033                       OMP_CLAUSE_CHAIN (c) = *cp;
9034                       *cp = c;
9035                       atf[j] = NULL;
9036 
9037                       /* If decl2 is of the form '*decl2_opnd0', and followed by an
9038                          ALWAYS_POINTER or ATTACH_DETACH of 'decl2_opnd0', move the
9039                          pointer operation along with *cp2. This can happen for C++
9040                          reference sequences.  */
9041                       if (j + 1 < atf.length ()
9042                           && (TREE_CODE (decl2) == INDIRECT_REF
9043                                 || TREE_CODE (decl2) == MEM_REF))
9044                         {
9045                           tree *cp3 = atf[j + 1];
9046                           tree decl3 = OMP_CLAUSE_DECL (*cp3);
9047                           tree decl2_opnd0 = TREE_OPERAND (decl2, 0);
9048                           if ((OMP_CLAUSE_MAP_KIND (*cp3) == GOMP_MAP_ALWAYS_POINTER
9049                                  || OMP_CLAUSE_MAP_KIND (*cp3) == GOMP_MAP_ATTACH_DETACH)
9050                                 && operand_equal_p (decl3, decl2_opnd0))
9051                               {
9052                                 /* Also move *cp3 to before *cp.  */
9053                                 c = *cp3;
9054                                 *cp2 = OMP_CLAUSE_CHAIN (c);
9055                                 OMP_CLAUSE_CHAIN (c) = *cp;
9056                                 *cp = c;
9057                                 atf[j + 1] = NULL;
9058                                 j += 1;
9059                               }
9060                         }
9061                     }
9062               }
9063       }
9064 }
9065 
9066 /* DECL is supposed to have lastprivate semantics in the outer contexts
9067    of combined/composite constructs, starting with OCTX.
9068    Add needed lastprivate, shared or map clause if no data sharing or
9069    mapping clause are present.  IMPLICIT_P is true if it is an implicit
9070    clause (IV on simd), in which case the lastprivate will not be
9071    copied to some constructs.  */
9072 
9073 static void
omp_lastprivate_for_combined_outer_constructs(struct gimplify_omp_ctx * octx,tree decl,bool implicit_p)9074 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx,
9075                                                          tree decl, bool implicit_p)
9076 {
9077   struct gimplify_omp_ctx *orig_octx = octx;
9078   for (; octx; octx = octx->outer_context)
9079     {
9080       if ((octx->region_type == ORT_COMBINED_PARALLEL
9081              || (octx->region_type & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS)
9082             && splay_tree_lookup (octx->variables,
9083                                         (splay_tree_key) decl) == NULL)
9084           {
9085             omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
9086             continue;
9087           }
9088       if ((octx->region_type & ORT_TASK) != 0
9089             && octx->combined_loop
9090             && splay_tree_lookup (octx->variables,
9091                                         (splay_tree_key) decl) == NULL)
9092           {
9093             omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
9094             continue;
9095           }
9096       if (implicit_p
9097             && octx->region_type == ORT_WORKSHARE
9098             && octx->combined_loop
9099             && splay_tree_lookup (octx->variables,
9100                                         (splay_tree_key) decl) == NULL
9101             && octx->outer_context
9102             && octx->outer_context->region_type == ORT_COMBINED_PARALLEL
9103             && splay_tree_lookup (octx->outer_context->variables,
9104                                         (splay_tree_key) decl) == NULL)
9105           {
9106             octx = octx->outer_context;
9107             omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
9108             continue;
9109           }
9110       if ((octx->region_type == ORT_WORKSHARE || octx->region_type == ORT_ACC)
9111             && octx->combined_loop
9112             && splay_tree_lookup (octx->variables,
9113                                         (splay_tree_key) decl) == NULL
9114             && !omp_check_private (octx, decl, false))
9115           {
9116             omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
9117             continue;
9118           }
9119       if (octx->region_type == ORT_COMBINED_TARGET)
9120           {
9121             splay_tree_node n = splay_tree_lookup (octx->variables,
9122                                                              (splay_tree_key) decl);
9123             if (n == NULL)
9124               {
9125                 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
9126                 octx = octx->outer_context;
9127               }
9128             else if (!implicit_p
9129                        && (n->value & GOVD_FIRSTPRIVATE_IMPLICIT))
9130               {
9131                 n->value &= ~(GOVD_FIRSTPRIVATE
9132                                   | GOVD_FIRSTPRIVATE_IMPLICIT
9133                                   | GOVD_EXPLICIT);
9134                 omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
9135                 octx = octx->outer_context;
9136               }
9137           }
9138       break;
9139     }
9140   if (octx && (implicit_p || octx != orig_octx))
9141     omp_notice_variable (octx, decl, true);
9142 }
9143 
9144 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
9145    and previous omp contexts.  */
9146 
9147 static void
gimplify_scan_omp_clauses(tree * list_p,gimple_seq * pre_p,enum omp_region_type region_type,enum tree_code code)9148 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
9149                                  enum omp_region_type region_type,
9150                                  enum tree_code code)
9151 {
9152   struct gimplify_omp_ctx *ctx, *outer_ctx;
9153   tree c;
9154   hash_map<tree_operand_hash, tree> *struct_map_to_clause = NULL;
9155   hash_map<tree_operand_hash, tree *> *struct_seen_clause = NULL;
9156   hash_set<tree> *struct_deref_set = NULL;
9157   tree *prev_list_p = NULL, *orig_list_p = list_p;
9158   int handled_depend_iterators = -1;
9159   int nowait = -1;
9160 
9161   ctx = new_omp_context (region_type);
9162   ctx->code = code;
9163   outer_ctx = ctx->outer_context;
9164   if (code == OMP_TARGET)
9165     {
9166       if (!lang_GNU_Fortran ())
9167           ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
9168       ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
9169       ctx->defaultmap[GDMK_SCALAR_TARGET] = (lang_GNU_Fortran ()
9170                                                        ? GOVD_MAP : GOVD_FIRSTPRIVATE);
9171     }
9172   if (!lang_GNU_Fortran ())
9173     switch (code)
9174       {
9175       case OMP_TARGET:
9176       case OMP_TARGET_DATA:
9177       case OMP_TARGET_ENTER_DATA:
9178       case OMP_TARGET_EXIT_DATA:
9179       case OACC_DECLARE:
9180       case OACC_HOST_DATA:
9181       case OACC_PARALLEL:
9182       case OACC_KERNELS:
9183           ctx->target_firstprivatize_array_bases = true;
9184       default:
9185           break;
9186       }
9187 
9188   if (code == OMP_TARGET
9189       || code == OMP_TARGET_DATA
9190       || code == OMP_TARGET_ENTER_DATA
9191       || code == OMP_TARGET_EXIT_DATA)
9192     omp_target_reorder_clauses (list_p);
9193 
9194   while ((c = *list_p) != NULL)
9195     {
9196       bool remove = false;
9197       bool notice_outer = true;
9198       const char *check_non_private = NULL;
9199       unsigned int flags;
9200       tree decl;
9201 
9202       switch (OMP_CLAUSE_CODE (c))
9203           {
9204           case OMP_CLAUSE_PRIVATE:
9205             flags = GOVD_PRIVATE | GOVD_EXPLICIT;
9206             if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
9207               {
9208                 flags |= GOVD_PRIVATE_OUTER_REF;
9209                 OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
9210               }
9211             else
9212               notice_outer = false;
9213             goto do_add;
9214           case OMP_CLAUSE_SHARED:
9215             flags = GOVD_SHARED | GOVD_EXPLICIT;
9216             goto do_add;
9217           case OMP_CLAUSE_FIRSTPRIVATE:
9218             flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
9219             check_non_private = "firstprivate";
9220             if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
9221               {
9222                 gcc_assert (code == OMP_TARGET);
9223                 flags |= GOVD_FIRSTPRIVATE_IMPLICIT;
9224               }
9225             goto do_add;
9226           case OMP_CLAUSE_LASTPRIVATE:
9227             if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
9228               switch (code)
9229                 {
9230                 case OMP_DISTRIBUTE:
9231                     error_at (OMP_CLAUSE_LOCATION (c),
9232                                 "conditional %<lastprivate%> clause on "
9233                                 "%qs construct", "distribute");
9234                     OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9235                     break;
9236                 case OMP_TASKLOOP:
9237                     error_at (OMP_CLAUSE_LOCATION (c),
9238                                 "conditional %<lastprivate%> clause on "
9239                                 "%qs construct", "taskloop");
9240                     OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9241                     break;
9242                 default:
9243                     break;
9244                 }
9245             flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
9246             if (code != OMP_LOOP)
9247               check_non_private = "lastprivate";
9248             decl = OMP_CLAUSE_DECL (c);
9249             if (error_operand_p (decl))
9250               goto do_add;
9251             if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
9252                 && !lang_hooks.decls.omp_scalar_p (decl, true))
9253               {
9254                 error_at (OMP_CLAUSE_LOCATION (c),
9255                               "non-scalar variable %qD in conditional "
9256                               "%<lastprivate%> clause", decl);
9257                 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
9258               }
9259             if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
9260               flags |= GOVD_LASTPRIVATE_CONDITIONAL;
9261             omp_lastprivate_for_combined_outer_constructs (outer_ctx, decl,
9262                                                                        false);
9263             goto do_add;
9264           case OMP_CLAUSE_REDUCTION:
9265             if (OMP_CLAUSE_REDUCTION_TASK (c))
9266               {
9267                 if (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
9268                     {
9269                       if (nowait == -1)
9270                         nowait = omp_find_clause (*list_p,
9271                                                         OMP_CLAUSE_NOWAIT) != NULL_TREE;
9272                       if (nowait
9273                           && (outer_ctx == NULL
9274                                 || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
9275                         {
9276                           error_at (OMP_CLAUSE_LOCATION (c),
9277                                         "%<task%> reduction modifier on a construct "
9278                                         "with a %<nowait%> clause");
9279                           OMP_CLAUSE_REDUCTION_TASK (c) = 0;
9280                         }
9281                     }
9282                 else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
9283                     {
9284                       error_at (OMP_CLAUSE_LOCATION (c),
9285                                   "invalid %<task%> reduction modifier on construct "
9286                                   "other than %<parallel%>, %qs, %<sections%> or "
9287                                   "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
9288                       OMP_CLAUSE_REDUCTION_TASK (c) = 0;
9289                     }
9290               }
9291             if (OMP_CLAUSE_REDUCTION_INSCAN (c))
9292               switch (code)
9293                 {
9294                 case OMP_SECTIONS:
9295                     error_at (OMP_CLAUSE_LOCATION (c),
9296                                 "%<inscan%> %<reduction%> clause on "
9297                                 "%qs construct", "sections");
9298                     OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9299                     break;
9300                 case OMP_PARALLEL:
9301                     error_at (OMP_CLAUSE_LOCATION (c),
9302                                 "%<inscan%> %<reduction%> clause on "
9303                                 "%qs construct", "parallel");
9304                     OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9305                     break;
9306                 case OMP_TEAMS:
9307                     error_at (OMP_CLAUSE_LOCATION (c),
9308                                 "%<inscan%> %<reduction%> clause on "
9309                                 "%qs construct", "teams");
9310                     OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9311                     break;
9312                 case OMP_TASKLOOP:
9313                     error_at (OMP_CLAUSE_LOCATION (c),
9314                                 "%<inscan%> %<reduction%> clause on "
9315                                 "%qs construct", "taskloop");
9316                     OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9317                     break;
9318                 case OMP_SCOPE:
9319                     error_at (OMP_CLAUSE_LOCATION (c),
9320                                 "%<inscan%> %<reduction%> clause on "
9321                                 "%qs construct", "scope");
9322                     OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
9323                     break;
9324                 default:
9325                     break;
9326                 }
9327             /* FALLTHRU */
9328           case OMP_CLAUSE_IN_REDUCTION:
9329           case OMP_CLAUSE_TASK_REDUCTION:
9330             flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
9331             /* OpenACC permits reductions on private variables.  */
9332             if (!(region_type & ORT_ACC)
9333                 /* taskgroup is actually not a worksharing region.  */
9334                 && code != OMP_TASKGROUP)
9335               check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
9336             decl = OMP_CLAUSE_DECL (c);
9337             if (TREE_CODE (decl) == MEM_REF)
9338               {
9339                 tree type = TREE_TYPE (decl);
9340                 bool saved_into_ssa = gimplify_ctxp->into_ssa;
9341                 gimplify_ctxp->into_ssa = false;
9342                 if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
9343                                          NULL, is_gimple_val, fb_rvalue, false)
9344                       == GS_ERROR)
9345                     {
9346                       gimplify_ctxp->into_ssa = saved_into_ssa;
9347                       remove = true;
9348                       break;
9349                     }
9350                 gimplify_ctxp->into_ssa = saved_into_ssa;
9351                 tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
9352                 if (DECL_P (v))
9353                     {
9354                       omp_firstprivatize_variable (ctx, v);
9355                       omp_notice_variable (ctx, v, true);
9356                     }
9357                 decl = TREE_OPERAND (decl, 0);
9358                 if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
9359                     {
9360                       gimplify_ctxp->into_ssa = false;
9361                       if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
9362                                              NULL, is_gimple_val, fb_rvalue, false)
9363                           == GS_ERROR)
9364                         {
9365                           gimplify_ctxp->into_ssa = saved_into_ssa;
9366                           remove = true;
9367                           break;
9368                         }
9369                       gimplify_ctxp->into_ssa = saved_into_ssa;
9370                       v = TREE_OPERAND (decl, 1);
9371                       if (DECL_P (v))
9372                         {
9373                           omp_firstprivatize_variable (ctx, v);
9374                           omp_notice_variable (ctx, v, true);
9375                         }
9376                       decl = TREE_OPERAND (decl, 0);
9377                     }
9378                 if (TREE_CODE (decl) == ADDR_EXPR
9379                       || TREE_CODE (decl) == INDIRECT_REF)
9380                     decl = TREE_OPERAND (decl, 0);
9381               }
9382             goto do_add_decl;
9383           case OMP_CLAUSE_LINEAR:
9384             if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
9385                                    is_gimple_val, fb_rvalue) == GS_ERROR)
9386               {
9387                 remove = true;
9388                 break;
9389               }
9390             else
9391               {
9392                 if (code == OMP_SIMD
9393                       && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9394                     {
9395                       struct gimplify_omp_ctx *octx = outer_ctx;
9396                       if (octx
9397                           && octx->region_type == ORT_WORKSHARE
9398                           && octx->combined_loop
9399                           && !octx->distribute)
9400                         {
9401                           if (octx->outer_context
9402                                 && (octx->outer_context->region_type
9403                                     == ORT_COMBINED_PARALLEL))
9404                               octx = octx->outer_context->outer_context;
9405                           else
9406                               octx = octx->outer_context;
9407                         }
9408                       if (octx
9409                           && octx->region_type == ORT_WORKSHARE
9410                           && octx->combined_loop
9411                           && octx->distribute)
9412                         {
9413                           error_at (OMP_CLAUSE_LOCATION (c),
9414                                         "%<linear%> clause for variable other than "
9415                                         "loop iterator specified on construct "
9416                                         "combined with %<distribute%>");
9417                           remove = true;
9418                           break;
9419                         }
9420                     }
9421                 /* For combined #pragma omp parallel for simd, need to put
9422                      lastprivate and perhaps firstprivate too on the
9423                      parallel.  Similarly for #pragma omp for simd.  */
9424                 struct gimplify_omp_ctx *octx = outer_ctx;
9425                 bool taskloop_seen = false;
9426                 decl = NULL_TREE;
9427                 do
9428                     {
9429                       if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9430                           && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9431                         break;
9432                       decl = OMP_CLAUSE_DECL (c);
9433                       if (error_operand_p (decl))
9434                         {
9435                           decl = NULL_TREE;
9436                           break;
9437                         }
9438                       flags = GOVD_SEEN;
9439                       if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
9440                         flags |= GOVD_FIRSTPRIVATE;
9441                       if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9442                         flags |= GOVD_LASTPRIVATE;
9443                       if (octx
9444                           && octx->region_type == ORT_WORKSHARE
9445                           && octx->combined_loop)
9446                         {
9447                           if (octx->outer_context
9448                                 && (octx->outer_context->region_type
9449                                     == ORT_COMBINED_PARALLEL))
9450                               octx = octx->outer_context;
9451                           else if (omp_check_private (octx, decl, false))
9452                               break;
9453                         }
9454                       else if (octx
9455                                  && (octx->region_type & ORT_TASK) != 0
9456                                  && octx->combined_loop)
9457                         taskloop_seen = true;
9458                       else if (octx
9459                                  && octx->region_type == ORT_COMBINED_PARALLEL
9460                                  && ((ctx->region_type == ORT_WORKSHARE
9461                                         && octx == outer_ctx)
9462                                      || taskloop_seen))
9463                         flags = GOVD_SEEN | GOVD_SHARED;
9464                       else if (octx
9465                                  && ((octx->region_type & ORT_COMBINED_TEAMS)
9466                                      == ORT_COMBINED_TEAMS))
9467                         flags = GOVD_SEEN | GOVD_SHARED;
9468                       else if (octx
9469                                  && octx->region_type == ORT_COMBINED_TARGET)
9470                         {
9471                           if (flags & GOVD_LASTPRIVATE)
9472                               flags = GOVD_SEEN | GOVD_MAP;
9473                         }
9474                       else
9475                         break;
9476                       splay_tree_node on
9477                         = splay_tree_lookup (octx->variables,
9478                                                    (splay_tree_key) decl);
9479                       if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
9480                         {
9481                           octx = NULL;
9482                           break;
9483                         }
9484                       omp_add_variable (octx, decl, flags);
9485                       if (octx->outer_context == NULL)
9486                         break;
9487                       octx = octx->outer_context;
9488                     }
9489                 while (1);
9490                 if (octx
9491                       && decl
9492                       && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9493                           || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
9494                     omp_notice_variable (octx, decl, true);
9495               }
9496             flags = GOVD_LINEAR | GOVD_EXPLICIT;
9497             if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
9498                 && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
9499               {
9500                 notice_outer = false;
9501                 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
9502               }
9503             goto do_add;
9504 
9505           case OMP_CLAUSE_MAP:
9506             decl = OMP_CLAUSE_DECL (c);
9507             if (error_operand_p (decl))
9508               remove = true;
9509             switch (code)
9510               {
9511               case OMP_TARGET:
9512                 break;
9513               case OACC_DATA:
9514                 if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
9515                     break;
9516                 /* FALLTHRU */
9517               case OMP_TARGET_DATA:
9518               case OMP_TARGET_ENTER_DATA:
9519               case OMP_TARGET_EXIT_DATA:
9520               case OACC_ENTER_DATA:
9521               case OACC_EXIT_DATA:
9522               case OACC_HOST_DATA:
9523                 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9524                       || (OMP_CLAUSE_MAP_KIND (c)
9525                           == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9526                     /* For target {,enter ,exit }data only the array slice is
9527                        mapped, but not the pointer to it.  */
9528                     remove = true;
9529                 break;
9530               default:
9531                 break;
9532               }
9533             /* For Fortran, not only the pointer to the data is mapped but also
9534                the address of the pointer, the array descriptor etc.; for
9535                'exit data' - and in particular for 'delete:' - having an 'alloc:'
9536                does not make sense.  Likewise, for 'update' only transferring the
9537                data itself is needed as the rest has been handled in previous
9538                directives.  However, for 'exit data', the array descriptor needs
9539                to be delete; hence, we turn the MAP_TO_PSET into a MAP_DELETE.
9540 
9541                NOTE: Generally, it is not safe to perform "enter data" operations
9542                on arrays where the data *or the descriptor* may go out of scope
9543                before a corresponding "exit data" operation -- and such a
9544                descriptor may be synthesized temporarily, e.g. to pass an
9545                explicit-shape array to a function expecting an assumed-shape
9546                argument.  Performing "enter data" inside the called function
9547                would thus be problematic.  */
9548             if (code == OMP_TARGET_EXIT_DATA
9549                 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
9550               OMP_CLAUSE_SET_MAP_KIND (c, OMP_CLAUSE_MAP_KIND (*prev_list_p)
9551                                                   == GOMP_MAP_DELETE
9552                                                   ? GOMP_MAP_DELETE : GOMP_MAP_RELEASE);
9553             else if ((code == OMP_TARGET_EXIT_DATA || code == OMP_TARGET_UPDATE)
9554                        && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9555                            || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET))
9556               remove = true;
9557 
9558             if (remove)
9559               break;
9560             if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
9561               {
9562                 struct gimplify_omp_ctx *octx;
9563                 for (octx = outer_ctx; octx; octx = octx->outer_context)
9564                   {
9565                       if (octx->region_type != ORT_ACC_HOST_DATA)
9566                         break;
9567                       splay_tree_node n2
9568                         = splay_tree_lookup (octx->variables,
9569                                                    (splay_tree_key) decl);
9570                       if (n2)
9571                         error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
9572                                     "declared in enclosing %<host_data%> region",
9573                                     DECL_NAME (decl));
9574                     }
9575               }
9576             if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
9577               OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
9578                                           : TYPE_SIZE_UNIT (TREE_TYPE (decl));
9579             if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
9580                                    NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
9581               {
9582                 remove = true;
9583                 break;
9584               }
9585             else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
9586                         || (OMP_CLAUSE_MAP_KIND (c)
9587                               == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9588                         || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9589                        && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
9590               {
9591                 OMP_CLAUSE_SIZE (c)
9592                     = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
9593                                                      false);
9594                 if ((region_type & ORT_TARGET) != 0)
9595                     omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
9596                                           GOVD_FIRSTPRIVATE | GOVD_SEEN);
9597               }
9598 
9599             if (TREE_CODE (decl) == TARGET_EXPR)
9600               {
9601                 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
9602                                          is_gimple_lvalue, fb_lvalue)
9603                       == GS_ERROR)
9604                     remove = true;
9605               }
9606             else if (!DECL_P (decl))
9607               {
9608                 tree d = decl, *pd;
9609                 if (TREE_CODE (d) == ARRAY_REF)
9610                     {
9611                       while (TREE_CODE (d) == ARRAY_REF)
9612                         d = TREE_OPERAND (d, 0);
9613                       if (TREE_CODE (d) == COMPONENT_REF
9614                           && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
9615                         decl = d;
9616                     }
9617                 pd = &OMP_CLAUSE_DECL (c);
9618                 if (d == decl
9619                       && TREE_CODE (decl) == INDIRECT_REF
9620                       && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
9621                       && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9622                           == REFERENCE_TYPE)
9623                       && (OMP_CLAUSE_MAP_KIND (c)
9624                           != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
9625                     {
9626                       pd = &TREE_OPERAND (decl, 0);
9627                       decl = TREE_OPERAND (decl, 0);
9628                     }
9629                 bool indir_p = false;
9630                 bool component_ref_p = false;
9631                 tree indir_base = NULL_TREE;
9632                 tree orig_decl = decl;
9633                 tree decl_ref = NULL_TREE;
9634                 if ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA)) != 0
9635                       && TREE_CODE (*pd) == COMPONENT_REF
9636                       && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
9637                       && code != OACC_UPDATE)
9638                     {
9639                       while (TREE_CODE (decl) == COMPONENT_REF)
9640                         {
9641                           decl = TREE_OPERAND (decl, 0);
9642                           component_ref_p = true;
9643                           if (((TREE_CODE (decl) == MEM_REF
9644                                   && integer_zerop (TREE_OPERAND (decl, 1)))
9645                                  || INDIRECT_REF_P (decl))
9646                                 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9647                                     == POINTER_TYPE))
9648                               {
9649                                 indir_p = true;
9650                                 indir_base = decl;
9651                                 decl = TREE_OPERAND (decl, 0);
9652                                 STRIP_NOPS (decl);
9653                               }
9654                           if (TREE_CODE (decl) == INDIRECT_REF
9655                                 && DECL_P (TREE_OPERAND (decl, 0))
9656                                 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9657                                     == REFERENCE_TYPE))
9658                               {
9659                                 decl_ref = decl;
9660                                 decl = TREE_OPERAND (decl, 0);
9661                               }
9662                         }
9663                     }
9664                 else if (TREE_CODE (decl) == COMPONENT_REF
9665                            && (OMP_CLAUSE_MAP_KIND (c)
9666                                  != GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION))
9667                     {
9668                       component_ref_p = true;
9669                       while (TREE_CODE (decl) == COMPONENT_REF)
9670                         decl = TREE_OPERAND (decl, 0);
9671                       if (TREE_CODE (decl) == INDIRECT_REF
9672                           && DECL_P (TREE_OPERAND (decl, 0))
9673                           && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
9674                                 == REFERENCE_TYPE))
9675                         decl = TREE_OPERAND (decl, 0);
9676                     }
9677                 if (decl != orig_decl && DECL_P (decl) && indir_p
9678                       && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
9679                           || (decl_ref
9680                                 && TREE_CODE (TREE_TYPE (decl_ref)) == POINTER_TYPE)))
9681                     {
9682                       gomp_map_kind k
9683                         = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9684                            ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9685                       /* We have a dereference of a struct member.  Make this an
9686                          attach/detach operation, and ensure the base pointer is
9687                          mapped as a FIRSTPRIVATE_POINTER.  */
9688                       OMP_CLAUSE_SET_MAP_KIND (c, k);
9689                       flags = GOVD_MAP | GOVD_SEEN | GOVD_EXPLICIT;
9690                       tree next_clause = OMP_CLAUSE_CHAIN (c);
9691                       if (k == GOMP_MAP_ATTACH
9692                           && code != OACC_ENTER_DATA
9693                           && code != OMP_TARGET_ENTER_DATA
9694                           && (!next_clause
9695                                  || (OMP_CLAUSE_CODE (next_clause) != OMP_CLAUSE_MAP)
9696                                  || (OMP_CLAUSE_MAP_KIND (next_clause)
9697                                      != GOMP_MAP_POINTER)
9698                                  || OMP_CLAUSE_DECL (next_clause) != decl)
9699                           && (!struct_deref_set
9700                                 || !struct_deref_set->contains (decl))
9701                           && (!struct_map_to_clause
9702                                 || !struct_map_to_clause->get (indir_base)))
9703                         {
9704                           if (!struct_deref_set)
9705                               struct_deref_set = new hash_set<tree> ();
9706                           /* As well as the attach, we also need a
9707                                FIRSTPRIVATE_POINTER clause to properly map the
9708                                pointer to the struct base.  */
9709                           tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9710                                                               OMP_CLAUSE_MAP);
9711                           OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALLOC);
9712                           OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c2)
9713                               = 1;
9714                           tree charptr_zero
9715                               = build_int_cst (build_pointer_type (char_type_node),
9716                                                    0);
9717                           OMP_CLAUSE_DECL (c2)
9718                               = build2 (MEM_REF, char_type_node,
9719                                           decl_ref ? decl_ref : decl, charptr_zero);
9720                           OMP_CLAUSE_SIZE (c2) = size_zero_node;
9721                           tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9722                                                               OMP_CLAUSE_MAP);
9723                           OMP_CLAUSE_SET_MAP_KIND (c3,
9724                                                          GOMP_MAP_FIRSTPRIVATE_POINTER);
9725                           OMP_CLAUSE_DECL (c3) = decl;
9726                           OMP_CLAUSE_SIZE (c3) = size_zero_node;
9727                           tree mapgrp = *prev_list_p;
9728                           *prev_list_p = c2;
9729                           OMP_CLAUSE_CHAIN (c3) = mapgrp;
9730                           OMP_CLAUSE_CHAIN (c2) = c3;
9731 
9732                           struct_deref_set->add (decl);
9733                         }
9734                       goto do_add_decl;
9735                     }
9736                 /* An "attach/detach" operation on an update directive should
9737                      behave as a GOMP_MAP_ALWAYS_POINTER.  Beware that
9738                      unlike attach or detach map kinds, GOMP_MAP_ALWAYS_POINTER
9739                      depends on the previous mapping.  */
9740                 if (code == OACC_UPDATE
9741                       && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9742                     OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
9743                 if ((DECL_P (decl)
9744                        || (component_ref_p
9745                            && (INDIRECT_REF_P (decl)
9746                                  || TREE_CODE (decl) == MEM_REF
9747                                  || TREE_CODE (decl) == ARRAY_REF)))
9748                       && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
9749                       && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
9750                       && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
9751                       && code != OACC_UPDATE
9752                       && code != OMP_TARGET_UPDATE)
9753                     {
9754                       if (error_operand_p (decl))
9755                         {
9756                           remove = true;
9757                           break;
9758                         }
9759 
9760                       tree stype = TREE_TYPE (decl);
9761                       if (TREE_CODE (stype) == REFERENCE_TYPE)
9762                         stype = TREE_TYPE (stype);
9763                       if (TYPE_SIZE_UNIT (stype) == NULL
9764                           || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
9765                         {
9766                           error_at (OMP_CLAUSE_LOCATION (c),
9767                                         "mapping field %qE of variable length "
9768                                         "structure", OMP_CLAUSE_DECL (c));
9769                           remove = true;
9770                           break;
9771                         }
9772 
9773                       if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
9774                           || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
9775                         {
9776                           /* Error recovery.  */
9777                           if (prev_list_p == NULL)
9778                               {
9779                                 remove = true;
9780                                 break;
9781                               }
9782 
9783                           /* The below prev_list_p based error recovery code is
9784                                currently no longer valid for OpenMP.  */
9785                           if (code != OMP_TARGET
9786                                 && code != OMP_TARGET_DATA
9787                                 && code != OMP_TARGET_UPDATE
9788                                 && code != OMP_TARGET_ENTER_DATA
9789                                 && code != OMP_TARGET_EXIT_DATA
9790                                 && OMP_CLAUSE_CHAIN (*prev_list_p) != c)
9791                               {
9792                                 tree ch = OMP_CLAUSE_CHAIN (*prev_list_p);
9793                                 if (ch == NULL_TREE || OMP_CLAUSE_CHAIN (ch) != c)
9794                                   {
9795                                     remove = true;
9796                                     break;
9797                                   }
9798                               }
9799                         }
9800 
9801                       poly_offset_int offset1;
9802                       poly_int64 bitpos1;
9803                       tree tree_offset1;
9804                       tree base_ref;
9805 
9806                       tree base
9807                         = extract_base_bit_offset (OMP_CLAUSE_DECL (c), &base_ref,
9808                                                          &bitpos1, &offset1,
9809                                                          &tree_offset1);
9810 
9811                       bool do_map_struct = (base == decl && !tree_offset1);
9812 
9813                       splay_tree_node n
9814                         = (DECL_P (decl)
9815                            ? splay_tree_lookup (ctx->variables,
9816                                                       (splay_tree_key) decl)
9817                            : NULL);
9818                       bool ptr = (OMP_CLAUSE_MAP_KIND (c)
9819                                     == GOMP_MAP_ALWAYS_POINTER);
9820                       bool attach_detach = (OMP_CLAUSE_MAP_KIND (c)
9821                                                   == GOMP_MAP_ATTACH_DETACH);
9822                       bool attach = OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9823                                         || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH;
9824                       bool has_attachments = false;
9825                       /* For OpenACC, pointers in structs should trigger an
9826                          attach action.  */
9827                       if (attach_detach
9828                           && ((region_type & (ORT_ACC | ORT_TARGET | ORT_TARGET_DATA))
9829                                 || code == OMP_TARGET_ENTER_DATA
9830                                 || code == OMP_TARGET_EXIT_DATA))
9831 
9832                         {
9833                           /* Turn a GOMP_MAP_ATTACH_DETACH clause into a
9834                                GOMP_MAP_ATTACH or GOMP_MAP_DETACH clause after we
9835                                have detected a case that needs a GOMP_MAP_STRUCT
9836                                mapping added.  */
9837                           gomp_map_kind k
9838                               = ((code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
9839                                  ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
9840                           OMP_CLAUSE_SET_MAP_KIND (c, k);
9841                           has_attachments = true;
9842                         }
9843 
9844                       /* We currently don't handle non-constant offset accesses wrt to
9845                          GOMP_MAP_STRUCT elements.  */
9846                       if (!do_map_struct)
9847                         goto skip_map_struct;
9848 
9849                       /* Nor for attach_detach for OpenMP.  */
9850                       if ((code == OMP_TARGET
9851                            || code == OMP_TARGET_DATA
9852                            || code == OMP_TARGET_UPDATE
9853                            || code == OMP_TARGET_ENTER_DATA
9854                            || code == OMP_TARGET_EXIT_DATA)
9855                           && attach_detach)
9856                         {
9857                           if (DECL_P (decl))
9858                               {
9859                                 if (struct_seen_clause == NULL)
9860                                   struct_seen_clause
9861                                     = new hash_map<tree_operand_hash, tree *>;
9862                                 if (!struct_seen_clause->get (decl))
9863                                   struct_seen_clause->put (decl, list_p);
9864                               }
9865 
9866                           goto skip_map_struct;
9867                         }
9868 
9869                       if ((DECL_P (decl)
9870                            && (n == NULL || (n->value & GOVD_MAP) == 0))
9871                           || (!DECL_P (decl)
9872                                 && (!struct_map_to_clause
9873                                     || struct_map_to_clause->get (decl) == NULL)))
9874                         {
9875                           tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9876                                                              OMP_CLAUSE_MAP);
9877                           gomp_map_kind k = attach ? GOMP_MAP_FORCE_PRESENT
9878                                                          : GOMP_MAP_STRUCT;
9879 
9880                           OMP_CLAUSE_SET_MAP_KIND (l, k);
9881                           if (base_ref)
9882                               OMP_CLAUSE_DECL (l) = unshare_expr (base_ref);
9883                           else
9884                               {
9885                                 OMP_CLAUSE_DECL (l) = unshare_expr (decl);
9886                                 if (!DECL_P (OMP_CLAUSE_DECL (l))
9887                                     && (gimplify_expr (&OMP_CLAUSE_DECL (l),
9888                                                              pre_p, NULL, is_gimple_lvalue,
9889                                                              fb_lvalue)
9890                                           == GS_ERROR))
9891                                   {
9892                                     remove = true;
9893                                     break;
9894                                   }
9895                               }
9896                           OMP_CLAUSE_SIZE (l)
9897                               = (!attach
9898                                  ? size_int (1)
9899                                  : DECL_P (OMP_CLAUSE_DECL (l))
9900                                  ? DECL_SIZE_UNIT (OMP_CLAUSE_DECL (l))
9901                                  : TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (l))));
9902                           if (struct_map_to_clause == NULL)
9903                               struct_map_to_clause
9904                                 = new hash_map<tree_operand_hash, tree>;
9905                           struct_map_to_clause->put (decl, l);
9906                           if (ptr || attach_detach)
9907                               {
9908                                 tree **sc = (struct_seen_clause
9909                                                ? struct_seen_clause->get (decl)
9910                                                : NULL);
9911                                 tree *insert_node_pos = sc ? *sc : prev_list_p;
9912 
9913                                 insert_struct_comp_map (code, c, l, *insert_node_pos,
9914                                                               NULL);
9915                                 *insert_node_pos = l;
9916                                 prev_list_p = NULL;
9917                               }
9918                           else
9919                               {
9920                                 OMP_CLAUSE_CHAIN (l) = c;
9921                                 *list_p = l;
9922                                 list_p = &OMP_CLAUSE_CHAIN (l);
9923                               }
9924                           if (base_ref && code == OMP_TARGET)
9925                               {
9926                                 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9927                                                                   OMP_CLAUSE_MAP);
9928                                 enum gomp_map_kind mkind
9929                                   = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
9930                                 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9931                                 OMP_CLAUSE_DECL (c2) = decl;
9932                                 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9933                                 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
9934                                 OMP_CLAUSE_CHAIN (l) = c2;
9935                               }
9936                           flags = GOVD_MAP | GOVD_EXPLICIT;
9937                           if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9938                                 || ptr
9939                                 || attach_detach)
9940                               flags |= GOVD_SEEN;
9941                           if (has_attachments)
9942                               flags |= GOVD_MAP_HAS_ATTACHMENTS;
9943 
9944                           /* If this is a *pointer-to-struct expression, make sure a
9945                                firstprivate map of the base-pointer exists.  */
9946                           if (component_ref_p
9947                                 && ((TREE_CODE (decl) == MEM_REF
9948                                      && integer_zerop (TREE_OPERAND (decl, 1)))
9949                                     || INDIRECT_REF_P (decl))
9950                                 && DECL_P (TREE_OPERAND (decl, 0))
9951                                 && !splay_tree_lookup (ctx->variables,
9952                                                              ((splay_tree_key)
9953                                                               TREE_OPERAND (decl, 0))))
9954                               {
9955                                 decl = TREE_OPERAND (decl, 0);
9956                                 tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
9957                                                                   OMP_CLAUSE_MAP);
9958                                 enum gomp_map_kind mkind
9959                                   = GOMP_MAP_FIRSTPRIVATE_POINTER;
9960                                 OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
9961                                 OMP_CLAUSE_DECL (c2) = decl;
9962                                 OMP_CLAUSE_SIZE (c2) = size_zero_node;
9963                                 OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c);
9964                                 OMP_CLAUSE_CHAIN (c) = c2;
9965                               }
9966 
9967                           if (DECL_P (decl))
9968                               goto do_add_decl;
9969                         }
9970                       else if (struct_map_to_clause)
9971                         {
9972                           tree *osc = struct_map_to_clause->get (decl);
9973                           tree *sc = NULL, *scp = NULL;
9974                           if (n != NULL
9975                                 && (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c))
9976                                     || ptr
9977                                     || attach_detach))
9978                               n->value |= GOVD_SEEN;
9979                           sc = &OMP_CLAUSE_CHAIN (*osc);
9980                           if (*sc != c
9981                                 && (OMP_CLAUSE_MAP_KIND (*sc)
9982                                     == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9983                               sc = &OMP_CLAUSE_CHAIN (*sc);
9984                           /* Here "prev_list_p" is the end of the inserted
9985                                alloc/release nodes after the struct node, OSC.  */
9986                           for (; *sc != c; sc = &OMP_CLAUSE_CHAIN (*sc))
9987                               if ((ptr || attach_detach) && sc == prev_list_p)
9988                                 break;
9989                               else if (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9990                                          != COMPONENT_REF
9991                                          && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9992                                              != INDIRECT_REF)
9993                                          && (TREE_CODE (OMP_CLAUSE_DECL (*sc))
9994                                              != ARRAY_REF))
9995                                 break;
9996                               else
9997                                 {
9998                                   tree sc_decl = OMP_CLAUSE_DECL (*sc);
9999                                   poly_offset_int offsetn;
10000                                   poly_int64 bitposn;
10001                                   tree tree_offsetn;
10002                                   tree base
10003                                     = extract_base_bit_offset (sc_decl, NULL,
10004                                                                        &bitposn, &offsetn,
10005                                                                        &tree_offsetn);
10006                                   if (base != decl)
10007                                     break;
10008                                   if (scp)
10009                                     continue;
10010                                   if ((region_type & ORT_ACC) != 0)
10011                                     {
10012                                         /* This duplicate checking code is currently only
10013                                            enabled for OpenACC.  */
10014                                         tree d1 = OMP_CLAUSE_DECL (*sc);
10015                                         tree d2 = OMP_CLAUSE_DECL (c);
10016                                         while (TREE_CODE (d1) == ARRAY_REF)
10017                                           d1 = TREE_OPERAND (d1, 0);
10018                                         while (TREE_CODE (d2) == ARRAY_REF)
10019                                           d2 = TREE_OPERAND (d2, 0);
10020                                         if (TREE_CODE (d1) == INDIRECT_REF)
10021                                           d1 = TREE_OPERAND (d1, 0);
10022                                         if (TREE_CODE (d2) == INDIRECT_REF)
10023                                           d2 = TREE_OPERAND (d2, 0);
10024                                         while (TREE_CODE (d1) == COMPONENT_REF)
10025                                           if (TREE_CODE (d2) == COMPONENT_REF
10026                                               && TREE_OPERAND (d1, 1)
10027                                               == TREE_OPERAND (d2, 1))
10028                                             {
10029                                               d1 = TREE_OPERAND (d1, 0);
10030                                               d2 = TREE_OPERAND (d2, 0);
10031                                             }
10032                                           else
10033                                             break;
10034                                         if (d1 == d2)
10035                                           {
10036                                             error_at (OMP_CLAUSE_LOCATION (c),
10037                                                         "%qE appears more than once in map "
10038                                                         "clauses", OMP_CLAUSE_DECL (c));
10039                                             remove = true;
10040                                             break;
10041                                           }
10042                                     }
10043                                   if (maybe_lt (offset1, offsetn)
10044                                         || (known_eq (offset1, offsetn)
10045                                             && maybe_lt (bitpos1, bitposn)))
10046                                     {
10047                                         if (ptr || attach_detach)
10048                                           scp = sc;
10049                                         else
10050                                           break;
10051                                     }
10052                                 }
10053                           if (remove)
10054                               break;
10055                           if (!attach)
10056                               OMP_CLAUSE_SIZE (*osc)
10057                                 = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc),
10058                                                   size_one_node);
10059                           if (ptr || attach_detach)
10060                               {
10061                                 tree cl = insert_struct_comp_map (code, c, NULL,
10062                                                                           *prev_list_p, scp);
10063                                 if (sc == prev_list_p)
10064                                   {
10065                                     *sc = cl;
10066                                     prev_list_p = NULL;
10067                                   }
10068                                 else
10069                                   {
10070                                     *prev_list_p = OMP_CLAUSE_CHAIN (c);
10071                                     list_p = prev_list_p;
10072                                     prev_list_p = NULL;
10073                                     OMP_CLAUSE_CHAIN (c) = *sc;
10074                                     *sc = cl;
10075                                     continue;
10076                                   }
10077                               }
10078                           else if (*sc != c)
10079                               {
10080                                 if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
10081                                                        fb_lvalue)
10082                                     == GS_ERROR)
10083                                   {
10084                                     remove = true;
10085                                     break;
10086                                   }
10087                                 *list_p = OMP_CLAUSE_CHAIN (c);
10088                                 OMP_CLAUSE_CHAIN (c) = *sc;
10089                                 *sc = c;
10090                                 continue;
10091                               }
10092                         }
10093                     skip_map_struct:
10094                       ;
10095                     }
10096                 else if ((code == OACC_ENTER_DATA
10097                               || code == OACC_EXIT_DATA
10098                               || code == OACC_DATA
10099                               || code == OACC_PARALLEL
10100                               || code == OACC_KERNELS
10101                               || code == OACC_SERIAL
10102                               || code == OMP_TARGET_ENTER_DATA
10103                               || code == OMP_TARGET_EXIT_DATA)
10104                            && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
10105                     {
10106                       gomp_map_kind k = ((code == OACC_EXIT_DATA
10107                                               || code == OMP_TARGET_EXIT_DATA)
10108                                              ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH);
10109                       OMP_CLAUSE_SET_MAP_KIND (c, k);
10110                     }
10111 
10112                 if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
10113                     {
10114                       /* Don't gimplify *pd fully at this point, as the base
10115                          will need to be adjusted during omp lowering.  */
10116                       auto_vec<tree, 10> expr_stack;
10117                       tree *p = pd;
10118                       while (handled_component_p (*p)
10119                                || TREE_CODE (*p) == INDIRECT_REF
10120                                || TREE_CODE (*p) == ADDR_EXPR
10121                                || TREE_CODE (*p) == MEM_REF
10122                                || TREE_CODE (*p) == NON_LVALUE_EXPR)
10123                         {
10124                           expr_stack.safe_push (*p);
10125                           p = &TREE_OPERAND (*p, 0);
10126                         }
10127                       for (int i = expr_stack.length () - 1; i >= 0; i--)
10128                         {
10129                           tree t = expr_stack[i];
10130                           if (TREE_CODE (t) == ARRAY_REF
10131                                 || TREE_CODE (t) == ARRAY_RANGE_REF)
10132                               {
10133                                 if (TREE_OPERAND (t, 2) == NULL_TREE)
10134                                   {
10135                                     tree low = unshare_expr (array_ref_low_bound (t));
10136                                     if (!is_gimple_min_invariant (low))
10137                                         {
10138                                           TREE_OPERAND (t, 2) = low;
10139                                           if (gimplify_expr (&TREE_OPERAND (t, 2),
10140                                                                  pre_p, NULL,
10141                                                                  is_gimple_reg,
10142                                                                  fb_rvalue) == GS_ERROR)
10143                                             remove = true;
10144                                         }
10145                                   }
10146                                 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
10147                                                               NULL, is_gimple_reg,
10148                                                               fb_rvalue) == GS_ERROR)
10149                                   remove = true;
10150                                 if (TREE_OPERAND (t, 3) == NULL_TREE)
10151                                   {
10152                                     tree elmt_size = array_ref_element_size (t);
10153                                     if (!is_gimple_min_invariant (elmt_size))
10154                                         {
10155                                           elmt_size = unshare_expr (elmt_size);
10156                                           tree elmt_type
10157                                             = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t,
10158                                                                                             0)));
10159                                           tree factor
10160                                             = size_int (TYPE_ALIGN_UNIT (elmt_type));
10161                                           elmt_size
10162                                             = size_binop (EXACT_DIV_EXPR, elmt_size,
10163                                                               factor);
10164                                           TREE_OPERAND (t, 3) = elmt_size;
10165                                           if (gimplify_expr (&TREE_OPERAND (t, 3),
10166                                                                  pre_p, NULL,
10167                                                                  is_gimple_reg,
10168                                                                  fb_rvalue) == GS_ERROR)
10169                                             remove = true;
10170                                         }
10171                                   }
10172                                 else if (gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
10173                                                               NULL, is_gimple_reg,
10174                                                               fb_rvalue) == GS_ERROR)
10175                                   remove = true;
10176                               }
10177                           else if (TREE_CODE (t) == COMPONENT_REF)
10178                               {
10179                                 if (TREE_OPERAND (t, 2) == NULL_TREE)
10180                                   {
10181                                     tree offset = component_ref_field_offset (t);
10182                                     if (!is_gimple_min_invariant (offset))
10183                                         {
10184                                           offset = unshare_expr (offset);
10185                                           tree field = TREE_OPERAND (t, 1);
10186                                           tree factor
10187                                             = size_int (DECL_OFFSET_ALIGN (field)
10188                                                             / BITS_PER_UNIT);
10189                                           offset = size_binop (EXACT_DIV_EXPR, offset,
10190                                                                    factor);
10191                                           TREE_OPERAND (t, 2) = offset;
10192                                           if (gimplify_expr (&TREE_OPERAND (t, 2),
10193                                                                  pre_p, NULL,
10194                                                                  is_gimple_reg,
10195                                                                  fb_rvalue) == GS_ERROR)
10196                                             remove = true;
10197                                         }
10198                                   }
10199                                 else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
10200                                                               NULL, is_gimple_reg,
10201                                                               fb_rvalue) == GS_ERROR)
10202                                   remove = true;
10203                               }
10204                         }
10205                       for (; expr_stack.length () > 0; )
10206                         {
10207                           tree t = expr_stack.pop ();
10208 
10209                           if (TREE_CODE (t) == ARRAY_REF
10210                                 || TREE_CODE (t) == ARRAY_RANGE_REF)
10211                               {
10212                                 if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))
10213                                     && gimplify_expr (&TREE_OPERAND (t, 1), pre_p,
10214                                                             NULL, is_gimple_val,
10215                                                             fb_rvalue) == GS_ERROR)
10216                                   remove = true;
10217                               }
10218                         }
10219                     }
10220                 else if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
10221                                               fb_lvalue) == GS_ERROR)
10222                     {
10223                       remove = true;
10224                       break;
10225                     }
10226 
10227                 /* If this was of the form map(*pointer_to_struct), then the
10228                      'pointer_to_struct' DECL should be considered deref'ed.  */
10229                 if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALLOC
10230                        || GOMP_MAP_COPY_TO_P (OMP_CLAUSE_MAP_KIND (c))
10231                        || GOMP_MAP_COPY_FROM_P (OMP_CLAUSE_MAP_KIND (c)))
10232                       && INDIRECT_REF_P (orig_decl)
10233                       && DECL_P (TREE_OPERAND (orig_decl, 0))
10234                       && TREE_CODE (TREE_TYPE (orig_decl)) == RECORD_TYPE)
10235                     {
10236                       tree ptr = TREE_OPERAND (orig_decl, 0);
10237                       if (!struct_deref_set || !struct_deref_set->contains (ptr))
10238                         {
10239                           if (!struct_deref_set)
10240                               struct_deref_set = new hash_set<tree> ();
10241                           struct_deref_set->add (ptr);
10242                         }
10243                     }
10244 
10245                 if (!remove
10246                       && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
10247                       && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
10248                       && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
10249                       && OMP_CLAUSE_CHAIN (c)
10250                       && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (c)) == OMP_CLAUSE_MAP
10251                       && ((OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10252                            == GOMP_MAP_ALWAYS_POINTER)
10253                           || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10254                                 == GOMP_MAP_ATTACH_DETACH)
10255                           || (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c))
10256                                 == GOMP_MAP_TO_PSET)))
10257                     prev_list_p = list_p;
10258 
10259                 break;
10260               }
10261             else
10262               {
10263                 /* DECL_P (decl) == true  */
10264                 tree *sc;
10265                 if (struct_map_to_clause
10266                       && (sc = struct_map_to_clause->get (decl)) != NULL
10267                       && OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_STRUCT
10268                       && decl == OMP_CLAUSE_DECL (*sc))
10269                     {
10270                       /* We have found a map of the whole structure after a
10271                          leading GOMP_MAP_STRUCT has been created, so refill the
10272                          leading clause into a map of the whole structure
10273                          variable, and remove the current one.
10274                          TODO: we should be able to remove some maps of the
10275                          following structure element maps if they are of
10276                          compatible TO/FROM/ALLOC type.  */
10277                       OMP_CLAUSE_SET_MAP_KIND (*sc, OMP_CLAUSE_MAP_KIND (c));
10278                       OMP_CLAUSE_SIZE (*sc) = unshare_expr (OMP_CLAUSE_SIZE (c));
10279                       remove = true;
10280                       break;
10281                     }
10282               }
10283             flags = GOVD_MAP | GOVD_EXPLICIT;
10284             if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
10285                 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM)
10286               flags |= GOVD_MAP_ALWAYS_TO;
10287 
10288             if ((code == OMP_TARGET
10289                  || code == OMP_TARGET_DATA
10290                  || code == OMP_TARGET_ENTER_DATA
10291                  || code == OMP_TARGET_EXIT_DATA)
10292                 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
10293               {
10294                 for (struct gimplify_omp_ctx *octx = outer_ctx; octx;
10295                        octx = octx->outer_context)
10296                     {
10297                       splay_tree_node n
10298                         = splay_tree_lookup (octx->variables,
10299                                                    (splay_tree_key) OMP_CLAUSE_DECL (c));
10300                       /* If this is contained in an outer OpenMP region as a
10301                          firstprivate value, remove the attach/detach.  */
10302                       if (n && (n->value & GOVD_FIRSTPRIVATE))
10303                         {
10304                           OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FIRSTPRIVATE_POINTER);
10305                           goto do_add;
10306                         }
10307                     }
10308 
10309                 enum gomp_map_kind map_kind = (code == OMP_TARGET_EXIT_DATA
10310                                                        ? GOMP_MAP_DETACH
10311                                                        : GOMP_MAP_ATTACH);
10312                 OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
10313               }
10314 
10315             goto do_add;
10316 
10317           case OMP_CLAUSE_AFFINITY:
10318             gimplify_omp_affinity (list_p, pre_p);
10319             remove = true;
10320             break;
10321           case OMP_CLAUSE_DEPEND:
10322             if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
10323               {
10324                 tree deps = OMP_CLAUSE_DECL (c);
10325                 while (deps && TREE_CODE (deps) == TREE_LIST)
10326                     {
10327                       if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
10328                           && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
10329                         gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
10330                                            pre_p, NULL, is_gimple_val, fb_rvalue);
10331                       deps = TREE_CHAIN (deps);
10332                     }
10333                 break;
10334               }
10335             else if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
10336               break;
10337             if (handled_depend_iterators == -1)
10338               handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
10339             if (handled_depend_iterators)
10340               {
10341                 if (handled_depend_iterators == 2)
10342                     remove = true;
10343                 break;
10344               }
10345             if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
10346               {
10347                 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
10348                                    NULL, is_gimple_val, fb_rvalue);
10349                 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
10350               }
10351             if (error_operand_p (OMP_CLAUSE_DECL (c)))
10352               {
10353                 remove = true;
10354                 break;
10355               }
10356             OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
10357             if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
10358                                    is_gimple_val, fb_rvalue) == GS_ERROR)
10359               {
10360                 remove = true;
10361                 break;
10362               }
10363             if (code == OMP_TASK)
10364               ctx->has_depend = true;
10365             break;
10366 
10367           case OMP_CLAUSE_TO:
10368           case OMP_CLAUSE_FROM:
10369           case OMP_CLAUSE__CACHE_:
10370             decl = OMP_CLAUSE_DECL (c);
10371             if (error_operand_p (decl))
10372               {
10373                 remove = true;
10374                 break;
10375               }
10376             if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
10377               OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
10378                                           : TYPE_SIZE_UNIT (TREE_TYPE (decl));
10379             if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
10380                                    NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
10381               {
10382                 remove = true;
10383                 break;
10384               }
10385             if (!DECL_P (decl))
10386               {
10387                 if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
10388                                          NULL, is_gimple_lvalue, fb_lvalue)
10389                       == GS_ERROR)
10390                     {
10391                       remove = true;
10392                       break;
10393                     }
10394                 break;
10395               }
10396             goto do_notice;
10397 
10398           case OMP_CLAUSE_USE_DEVICE_PTR:
10399           case OMP_CLAUSE_USE_DEVICE_ADDR:
10400             flags = GOVD_EXPLICIT;
10401             goto do_add;
10402 
10403           case OMP_CLAUSE_HAS_DEVICE_ADDR:
10404             decl = OMP_CLAUSE_DECL (c);
10405             while (TREE_CODE (decl) == INDIRECT_REF
10406                      || TREE_CODE (decl) == ARRAY_REF)
10407               decl = TREE_OPERAND (decl, 0);
10408             flags = GOVD_EXPLICIT;
10409             goto do_add_decl;
10410 
10411           case OMP_CLAUSE_IS_DEVICE_PTR:
10412             flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
10413             goto do_add;
10414 
10415           do_add:
10416             decl = OMP_CLAUSE_DECL (c);
10417           do_add_decl:
10418             if (error_operand_p (decl))
10419               {
10420                 remove = true;
10421                 break;
10422               }
10423             if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
10424               {
10425                 tree t = omp_member_access_dummy_var (decl);
10426                 if (t)
10427                     {
10428                       tree v = DECL_VALUE_EXPR (decl);
10429                       DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
10430                       if (outer_ctx)
10431                         omp_notice_variable (outer_ctx, t, true);
10432                     }
10433               }
10434             if (code == OACC_DATA
10435                 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10436                 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
10437               flags |= GOVD_MAP_0LEN_ARRAY;
10438             omp_add_variable (ctx, decl, flags);
10439             if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10440                  || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
10441                  || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
10442                 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
10443               {
10444                 struct gimplify_omp_ctx *pctx
10445                     = code == OMP_TARGET ? outer_ctx : ctx;
10446                 if (pctx)
10447                     omp_add_variable (pctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
10448                                           GOVD_LOCAL | GOVD_SEEN);
10449                 if (pctx
10450                       && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
10451                       && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
10452                                         find_decl_expr,
10453                                         OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
10454                                         NULL) == NULL_TREE)
10455                     omp_add_variable (pctx,
10456                                           OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
10457                                           GOVD_LOCAL | GOVD_SEEN);
10458                 gimplify_omp_ctxp = pctx;
10459                 push_gimplify_context ();
10460 
10461                 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
10462                 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
10463 
10464                 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
10465                                         &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
10466                 pop_gimplify_context
10467                     (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
10468                 push_gimplify_context ();
10469                 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
10470                                         &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
10471                 pop_gimplify_context
10472                     (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
10473                 OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
10474                 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
10475 
10476                 gimplify_omp_ctxp = outer_ctx;
10477               }
10478             else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
10479                        && OMP_CLAUSE_LASTPRIVATE_STMT (c))
10480               {
10481                 gimplify_omp_ctxp = ctx;
10482                 push_gimplify_context ();
10483                 if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
10484                     {
10485                       tree bind = build3 (BIND_EXPR, void_type_node, NULL,
10486                                               NULL, NULL);
10487                       TREE_SIDE_EFFECTS (bind) = 1;
10488                       BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
10489                       OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
10490                     }
10491                 gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
10492                                         &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
10493                 pop_gimplify_context
10494                     (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
10495                 OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
10496 
10497                 gimplify_omp_ctxp = outer_ctx;
10498               }
10499             else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
10500                        && OMP_CLAUSE_LINEAR_STMT (c))
10501               {
10502                 gimplify_omp_ctxp = ctx;
10503                 push_gimplify_context ();
10504                 if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
10505                     {
10506                       tree bind = build3 (BIND_EXPR, void_type_node, NULL,
10507                                               NULL, NULL);
10508                       TREE_SIDE_EFFECTS (bind) = 1;
10509                       BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
10510                       OMP_CLAUSE_LINEAR_STMT (c) = bind;
10511                     }
10512                 gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
10513                                         &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
10514                 pop_gimplify_context
10515                     (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
10516                 OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
10517 
10518                 gimplify_omp_ctxp = outer_ctx;
10519               }
10520             if (notice_outer)
10521               goto do_notice;
10522             break;
10523 
10524           case OMP_CLAUSE_COPYIN:
10525           case OMP_CLAUSE_COPYPRIVATE:
10526             decl = OMP_CLAUSE_DECL (c);
10527             if (error_operand_p (decl))
10528               {
10529                 remove = true;
10530                 break;
10531               }
10532             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
10533                 && !remove
10534                 && !omp_check_private (ctx, decl, true))
10535               {
10536                 remove = true;
10537                 if (is_global_var (decl))
10538                     {
10539                       if (DECL_THREAD_LOCAL_P (decl))
10540                         remove = false;
10541                       else if (DECL_HAS_VALUE_EXPR_P (decl))
10542                         {
10543                           tree value = get_base_address (DECL_VALUE_EXPR (decl));
10544 
10545                           if (value
10546                                 && DECL_P (value)
10547                                 && DECL_THREAD_LOCAL_P (value))
10548                               remove = false;
10549                         }
10550                     }
10551                 if (remove)
10552                     error_at (OMP_CLAUSE_LOCATION (c),
10553                                 "copyprivate variable %qE is not threadprivate"
10554                                 " or private in outer context", DECL_NAME (decl));
10555               }
10556           do_notice:
10557             if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10558                  || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10559                  || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
10560                 && outer_ctx
10561                 && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
10562                        || (region_type == ORT_WORKSHARE
10563                            && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10564                            && (OMP_CLAUSE_REDUCTION_INSCAN (c)
10565                                  || code == OMP_LOOP)))
10566                 && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
10567                       || (code == OMP_LOOP
10568                           && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10569                           && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
10570                                 == ORT_COMBINED_TEAMS))))
10571               {
10572                 splay_tree_node on
10573                     = splay_tree_lookup (outer_ctx->variables,
10574                                              (splay_tree_key)decl);
10575                 if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
10576                     {
10577                       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10578                           && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10579                           && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
10580                                 || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
10581                                     && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
10582                                           == POINTER_TYPE))))
10583                         omp_firstprivatize_variable (outer_ctx, decl);
10584                       else
10585                         {
10586                           omp_add_variable (outer_ctx, decl,
10587                                                   GOVD_SEEN | GOVD_SHARED);
10588                           if (outer_ctx->outer_context)
10589                               omp_notice_variable (outer_ctx->outer_context, decl,
10590                                                        true);
10591                         }
10592                     }
10593               }
10594             if (outer_ctx)
10595               omp_notice_variable (outer_ctx, decl, true);
10596             if (check_non_private
10597                 && (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
10598                 && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
10599                       || decl == OMP_CLAUSE_DECL (c)
10600                       || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
10601                           && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10602                                 == ADDR_EXPR
10603                                 || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
10604                                     == POINTER_PLUS_EXPR
10605                                     && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
10606                                                             (OMP_CLAUSE_DECL (c), 0), 0))
10607                                           == ADDR_EXPR)))))
10608                 && omp_check_private (ctx, decl, false))
10609               {
10610                 error ("%s variable %qE is private in outer context",
10611                          check_non_private, DECL_NAME (decl));
10612                 remove = true;
10613               }
10614             break;
10615 
10616           case OMP_CLAUSE_DETACH:
10617             flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
10618             goto do_add;
10619 
10620           case OMP_CLAUSE_IF:
10621             if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
10622                 && OMP_CLAUSE_IF_MODIFIER (c) != code)
10623               {
10624                 const char *p[2];
10625                 for (int i = 0; i < 2; i++)
10626                     switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
10627                       {
10628                       case VOID_CST: p[i] = "cancel"; break;
10629                       case OMP_PARALLEL: p[i] = "parallel"; break;
10630                       case OMP_SIMD: p[i] = "simd"; break;
10631                       case OMP_TASK: p[i] = "task"; break;
10632                       case OMP_TASKLOOP: p[i] = "taskloop"; break;
10633                       case OMP_TARGET_DATA: p[i] = "target data"; break;
10634                       case OMP_TARGET: p[i] = "target"; break;
10635                       case OMP_TARGET_UPDATE: p[i] = "target update"; break;
10636                       case OMP_TARGET_ENTER_DATA:
10637                         p[i] = "target enter data"; break;
10638                       case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
10639                       default: gcc_unreachable ();
10640                       }
10641                 error_at (OMP_CLAUSE_LOCATION (c),
10642                               "expected %qs %<if%> clause modifier rather than %qs",
10643                               p[0], p[1]);
10644                 remove = true;
10645               }
10646             /* Fall through.  */
10647 
10648           case OMP_CLAUSE_FINAL:
10649             OMP_CLAUSE_OPERAND (c, 0)
10650               = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
10651             /* Fall through.  */
10652 
10653           case OMP_CLAUSE_NUM_TEAMS:
10654             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
10655                 && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
10656                 && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
10657               {
10658                 if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
10659                     {
10660                       remove = true;
10661                       break;
10662                     }
10663                 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
10664                     = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c),
10665                                                      pre_p, NULL, true);
10666               }
10667             /* Fall through.  */
10668 
10669           case OMP_CLAUSE_SCHEDULE:
10670           case OMP_CLAUSE_NUM_THREADS:
10671           case OMP_CLAUSE_THREAD_LIMIT:
10672           case OMP_CLAUSE_DIST_SCHEDULE:
10673           case OMP_CLAUSE_DEVICE:
10674             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE
10675                 && OMP_CLAUSE_DEVICE_ANCESTOR (c))
10676               {
10677                 if (code != OMP_TARGET)
10678                     {
10679                       error_at (OMP_CLAUSE_LOCATION (c),
10680                                   "%<device%> clause with %<ancestor%> is only "
10681                                   "allowed on %<target%> construct");
10682                       remove = true;
10683                       break;
10684                     }
10685 
10686                 tree clauses = *orig_list_p;
10687                 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
10688                     if (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEVICE
10689                         && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_FIRSTPRIVATE
10690                         && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_PRIVATE
10691                         && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEFAULTMAP
10692                         && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_MAP
10693                        )
10694                       {
10695                         error_at (OMP_CLAUSE_LOCATION (c),
10696                                     "with %<ancestor%>, only the %<device%>, "
10697                                     "%<firstprivate%>, %<private%>, %<defaultmap%>, "
10698                                     "and %<map%> clauses may appear on the "
10699                                     "construct");
10700                         remove = true;
10701                         break;
10702                       }
10703               }
10704             /* Fall through.  */
10705 
10706           case OMP_CLAUSE_PRIORITY:
10707           case OMP_CLAUSE_GRAINSIZE:
10708           case OMP_CLAUSE_NUM_TASKS:
10709           case OMP_CLAUSE_FILTER:
10710           case OMP_CLAUSE_HINT:
10711           case OMP_CLAUSE_ASYNC:
10712           case OMP_CLAUSE_WAIT:
10713           case OMP_CLAUSE_NUM_GANGS:
10714           case OMP_CLAUSE_NUM_WORKERS:
10715           case OMP_CLAUSE_VECTOR_LENGTH:
10716           case OMP_CLAUSE_WORKER:
10717           case OMP_CLAUSE_VECTOR:
10718             if (OMP_CLAUSE_OPERAND (c, 0)
10719                 && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0)))
10720               {
10721                 if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0)))
10722                     {
10723                       remove = true;
10724                       break;
10725                     }
10726                 /* All these clauses care about value, not a particular decl,
10727                      so try to force it into a SSA_NAME or fresh temporary.  */
10728                 OMP_CLAUSE_OPERAND (c, 0)
10729                     = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0),
10730                                                      pre_p, NULL, true);
10731               }
10732             break;
10733 
10734           case OMP_CLAUSE_GANG:
10735             if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
10736                                    is_gimple_val, fb_rvalue) == GS_ERROR)
10737               remove = true;
10738             if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
10739                                    is_gimple_val, fb_rvalue) == GS_ERROR)
10740               remove = true;
10741             break;
10742 
10743           case OMP_CLAUSE_NOWAIT:
10744             nowait = 1;
10745             break;
10746 
10747           case OMP_CLAUSE_ORDERED:
10748           case OMP_CLAUSE_UNTIED:
10749           case OMP_CLAUSE_COLLAPSE:
10750           case OMP_CLAUSE_TILE:
10751           case OMP_CLAUSE_AUTO:
10752           case OMP_CLAUSE_SEQ:
10753           case OMP_CLAUSE_INDEPENDENT:
10754           case OMP_CLAUSE_MERGEABLE:
10755           case OMP_CLAUSE_PROC_BIND:
10756           case OMP_CLAUSE_SAFELEN:
10757           case OMP_CLAUSE_SIMDLEN:
10758           case OMP_CLAUSE_NOGROUP:
10759           case OMP_CLAUSE_THREADS:
10760           case OMP_CLAUSE_SIMD:
10761           case OMP_CLAUSE_BIND:
10762           case OMP_CLAUSE_IF_PRESENT:
10763           case OMP_CLAUSE_FINALIZE:
10764             break;
10765 
10766           case OMP_CLAUSE_ORDER:
10767             ctx->order_concurrent = true;
10768             break;
10769 
10770           case OMP_CLAUSE_DEFAULTMAP:
10771             enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
10772             switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
10773               {
10774               case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
10775                 gdmkmin = GDMK_SCALAR;
10776                 gdmkmax = GDMK_POINTER;
10777                 break;
10778               case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
10779                 gdmkmin = GDMK_SCALAR;
10780                 gdmkmax = GDMK_SCALAR_TARGET;
10781                 break;
10782               case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
10783                 gdmkmin = gdmkmax = GDMK_AGGREGATE;
10784                 break;
10785               case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
10786                 gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
10787                 break;
10788               case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
10789                 gdmkmin = gdmkmax = GDMK_POINTER;
10790                 break;
10791               default:
10792                 gcc_unreachable ();
10793               }
10794             for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
10795               switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
10796                 {
10797                 case OMP_CLAUSE_DEFAULTMAP_ALLOC:
10798                     ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
10799                     break;
10800                 case OMP_CLAUSE_DEFAULTMAP_TO:
10801                     ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
10802                     break;
10803                 case OMP_CLAUSE_DEFAULTMAP_FROM:
10804                     ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
10805                     break;
10806                 case OMP_CLAUSE_DEFAULTMAP_TOFROM:
10807                     ctx->defaultmap[gdmk] = GOVD_MAP;
10808                     break;
10809                 case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
10810                     ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10811                     break;
10812                 case OMP_CLAUSE_DEFAULTMAP_NONE:
10813                     ctx->defaultmap[gdmk] = 0;
10814                     break;
10815                 case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
10816                     switch (gdmk)
10817                       {
10818                       case GDMK_SCALAR:
10819                         ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
10820                         break;
10821                       case GDMK_SCALAR_TARGET:
10822                         ctx->defaultmap[gdmk] = (lang_GNU_Fortran ()
10823                                                        ? GOVD_MAP : GOVD_FIRSTPRIVATE);
10824                         break;
10825                       case GDMK_AGGREGATE:
10826                       case GDMK_ALLOCATABLE:
10827                         ctx->defaultmap[gdmk] = GOVD_MAP;
10828                         break;
10829                       case GDMK_POINTER:
10830                         ctx->defaultmap[gdmk] = GOVD_MAP;
10831                         if (!lang_GNU_Fortran ())
10832                           ctx->defaultmap[gdmk] |= GOVD_MAP_0LEN_ARRAY;
10833                         break;
10834                       default:
10835                         gcc_unreachable ();
10836                       }
10837                     break;
10838                 default:
10839                     gcc_unreachable ();
10840                 }
10841             break;
10842 
10843           case OMP_CLAUSE_ALIGNED:
10844             decl = OMP_CLAUSE_DECL (c);
10845             if (error_operand_p (decl))
10846               {
10847                 remove = true;
10848                 break;
10849               }
10850             if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
10851                                    is_gimple_val, fb_rvalue) == GS_ERROR)
10852               {
10853                 remove = true;
10854                 break;
10855               }
10856             if (!is_global_var (decl)
10857                 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
10858               omp_add_variable (ctx, decl, GOVD_ALIGNED);
10859             break;
10860 
10861           case OMP_CLAUSE_NONTEMPORAL:
10862             decl = OMP_CLAUSE_DECL (c);
10863             if (error_operand_p (decl))
10864               {
10865                 remove = true;
10866                 break;
10867               }
10868             omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
10869             break;
10870 
10871           case OMP_CLAUSE_ALLOCATE:
10872             decl = OMP_CLAUSE_DECL (c);
10873             if (error_operand_p (decl))
10874               {
10875                 remove = true;
10876                 break;
10877               }
10878             if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL,
10879                                    is_gimple_val, fb_rvalue) == GS_ERROR)
10880               {
10881                 remove = true;
10882                 break;
10883               }
10884             else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
10885                        || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
10886                            == INTEGER_CST))
10887               ;
10888             else if (code == OMP_TASKLOOP
10889                        || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
10890               OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
10891                 = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
10892                                                    pre_p, NULL, false);
10893             break;
10894 
10895           case OMP_CLAUSE_DEFAULT:
10896             ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
10897             break;
10898 
10899           case OMP_CLAUSE_INCLUSIVE:
10900           case OMP_CLAUSE_EXCLUSIVE:
10901             decl = OMP_CLAUSE_DECL (c);
10902             {
10903               splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
10904                                                                (splay_tree_key) decl);
10905               if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
10906                 {
10907                     error_at (OMP_CLAUSE_LOCATION (c),
10908                                 "%qD specified in %qs clause but not in %<inscan%> "
10909                                 "%<reduction%> clause on the containing construct",
10910                                 decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10911                     remove = true;
10912                 }
10913               else
10914                 {
10915                     n->value |= GOVD_REDUCTION_INSCAN;
10916                     if (outer_ctx->region_type == ORT_SIMD
10917                         && outer_ctx->outer_context
10918                         && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
10919                       {
10920                         n = splay_tree_lookup (outer_ctx->outer_context->variables,
10921                                                      (splay_tree_key) decl);
10922                         if (n && (n->value & GOVD_REDUCTION) != 0)
10923                           n->value |= GOVD_REDUCTION_INSCAN;
10924                       }
10925                 }
10926             }
10927             break;
10928 
10929           case OMP_CLAUSE_NOHOST:
10930           default:
10931             gcc_unreachable ();
10932           }
10933 
10934       if (code == OACC_DATA
10935             && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
10936             && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
10937                 || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
10938           remove = true;
10939       if (remove)
10940           *list_p = OMP_CLAUSE_CHAIN (c);
10941       else
10942           list_p = &OMP_CLAUSE_CHAIN (c);
10943     }
10944 
10945   ctx->clauses = *orig_list_p;
10946   gimplify_omp_ctxp = ctx;
10947   if (struct_seen_clause)
10948     delete struct_seen_clause;
10949   if (struct_map_to_clause)
10950     delete struct_map_to_clause;
10951   if (struct_deref_set)
10952     delete struct_deref_set;
10953 }
10954 
10955 /* Return true if DECL is a candidate for shared to firstprivate
10956    optimization.  We only consider non-addressable scalars, not
10957    too big, and not references.  */
10958 
10959 static bool
omp_shared_to_firstprivate_optimizable_decl_p(tree decl)10960 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
10961 {
10962   if (TREE_ADDRESSABLE (decl))
10963     return false;
10964   tree type = TREE_TYPE (decl);
10965   if (!is_gimple_reg_type (type)
10966       || TREE_CODE (type) == REFERENCE_TYPE
10967       || TREE_ADDRESSABLE (type))
10968     return false;
10969   /* Don't optimize too large decls, as each thread/task will have
10970      its own.  */
10971   HOST_WIDE_INT len = int_size_in_bytes (type);
10972   if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
10973     return false;
10974   if (omp_privatize_by_reference (decl))
10975     return false;
10976   return true;
10977 }
10978 
10979 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
10980    For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
10981    GOVD_WRITTEN in outer contexts.  */
10982 
10983 static void
omp_mark_stores(struct gimplify_omp_ctx * ctx,tree decl)10984 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
10985 {
10986   for (; ctx; ctx = ctx->outer_context)
10987     {
10988       splay_tree_node n = splay_tree_lookup (ctx->variables,
10989                                                        (splay_tree_key) decl);
10990       if (n == NULL)
10991           continue;
10992       else if (n->value & GOVD_SHARED)
10993           {
10994             n->value |= GOVD_WRITTEN;
10995             return;
10996           }
10997       else if (n->value & GOVD_DATA_SHARE_CLASS)
10998           return;
10999     }
11000 }
11001 
11002 /* Helper callback for walk_gimple_seq to discover possible stores
11003    to omp_shared_to_firstprivate_optimizable_decl_p decls and set
11004    GOVD_WRITTEN if they are GOVD_SHARED in some outer context
11005    for those.  */
11006 
11007 static tree
omp_find_stores_op(tree * tp,int * walk_subtrees,void * data)11008 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
11009 {
11010   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
11011 
11012   *walk_subtrees = 0;
11013   if (!wi->is_lhs)
11014     return NULL_TREE;
11015 
11016   tree op = *tp;
11017   do
11018     {
11019       if (handled_component_p (op))
11020           op = TREE_OPERAND (op, 0);
11021       else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
11022                  && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
11023           op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
11024       else
11025           break;
11026     }
11027   while (1);
11028   if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
11029     return NULL_TREE;
11030 
11031   omp_mark_stores (gimplify_omp_ctxp, op);
11032   return NULL_TREE;
11033 }
11034 
11035 /* Helper callback for walk_gimple_seq to discover possible stores
11036    to omp_shared_to_firstprivate_optimizable_decl_p decls and set
11037    GOVD_WRITTEN if they are GOVD_SHARED in some outer context
11038    for those.  */
11039 
11040 static tree
omp_find_stores_stmt(gimple_stmt_iterator * gsi_p,bool * handled_ops_p,struct walk_stmt_info * wi)11041 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
11042                           bool *handled_ops_p,
11043                           struct walk_stmt_info *wi)
11044 {
11045   gimple *stmt = gsi_stmt (*gsi_p);
11046   switch (gimple_code (stmt))
11047     {
11048     /* Don't recurse on OpenMP constructs for which
11049        gimplify_adjust_omp_clauses already handled the bodies,
11050        except handle gimple_omp_for_pre_body.  */
11051     case GIMPLE_OMP_FOR:
11052       *handled_ops_p = true;
11053       if (gimple_omp_for_pre_body (stmt))
11054           walk_gimple_seq (gimple_omp_for_pre_body (stmt),
11055                                omp_find_stores_stmt, omp_find_stores_op, wi);
11056       break;
11057     case GIMPLE_OMP_PARALLEL:
11058     case GIMPLE_OMP_TASK:
11059     case GIMPLE_OMP_SECTIONS:
11060     case GIMPLE_OMP_SINGLE:
11061     case GIMPLE_OMP_SCOPE:
11062     case GIMPLE_OMP_TARGET:
11063     case GIMPLE_OMP_TEAMS:
11064     case GIMPLE_OMP_CRITICAL:
11065       *handled_ops_p = true;
11066       break;
11067     default:
11068       break;
11069     }
11070   return NULL_TREE;
11071 }
11072 
11073 struct gimplify_adjust_omp_clauses_data
11074 {
11075   tree *list_p;
11076   gimple_seq *pre_p;
11077 };
11078 
11079 /* For all variables that were not actually used within the context,
11080    remove PRIVATE, SHARED, and FIRSTPRIVATE clauses.  */
11081 
11082 static int
gimplify_adjust_omp_clauses_1(splay_tree_node n,void * data)11083 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
11084 {
11085   tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
11086   gimple_seq *pre_p
11087     = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
11088   tree decl = (tree) n->key;
11089   unsigned flags = n->value;
11090   enum omp_clause_code code;
11091   tree clause;
11092   bool private_debug;
11093 
11094   if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
11095       && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
11096     flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
11097   if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
11098     return 0;
11099   if ((flags & GOVD_SEEN) == 0)
11100     return 0;
11101   if ((flags & GOVD_MAP_HAS_ATTACHMENTS) != 0)
11102     return 0;
11103   if (flags & GOVD_DEBUG_PRIVATE)
11104     {
11105       gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
11106       private_debug = true;
11107     }
11108   else if (flags & GOVD_MAP)
11109     private_debug = false;
11110   else
11111     private_debug
11112       = lang_hooks.decls.omp_private_debug_clause (decl,
11113                                                                !!(flags & GOVD_SHARED));
11114   if (private_debug)
11115     code = OMP_CLAUSE_PRIVATE;
11116   else if (flags & GOVD_MAP)
11117     {
11118       code = OMP_CLAUSE_MAP;
11119       if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
11120             && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
11121           {
11122             error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
11123             return 0;
11124           }
11125       if (VAR_P (decl)
11126             && DECL_IN_CONSTANT_POOL (decl)
11127           && !lookup_attribute ("omp declare target",
11128                                         DECL_ATTRIBUTES (decl)))
11129           {
11130             tree id = get_identifier ("omp declare target");
11131             DECL_ATTRIBUTES (decl)
11132               = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
11133             varpool_node *node = varpool_node::get (decl);
11134             if (node)
11135               {
11136                 node->offloadable = 1;
11137                 if (ENABLE_OFFLOADING)
11138                     g->have_offload = true;
11139               }
11140           }
11141     }
11142   else if (flags & GOVD_SHARED)
11143     {
11144       if (is_global_var (decl))
11145           {
11146             struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
11147             while (ctx != NULL)
11148               {
11149                 splay_tree_node on
11150                     = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11151                 if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
11152                                               | GOVD_PRIVATE | GOVD_REDUCTION
11153                                               | GOVD_LINEAR | GOVD_MAP)) != 0)
11154                     break;
11155                 ctx = ctx->outer_context;
11156               }
11157             if (ctx == NULL)
11158               return 0;
11159           }
11160       code = OMP_CLAUSE_SHARED;
11161       /* Don't optimize shared into firstprivate for read-only vars
11162            on tasks with depend clause, we shouldn't try to copy them
11163            until the dependencies are satisfied.  */
11164       if (gimplify_omp_ctxp->has_depend)
11165           flags |= GOVD_WRITTEN;
11166     }
11167   else if (flags & GOVD_PRIVATE)
11168     code = OMP_CLAUSE_PRIVATE;
11169   else if (flags & GOVD_FIRSTPRIVATE)
11170     {
11171       code = OMP_CLAUSE_FIRSTPRIVATE;
11172       if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
11173             && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
11174             && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
11175           {
11176             error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
11177                      "%<target%> construct", decl);
11178             return 0;
11179           }
11180     }
11181   else if (flags & GOVD_LASTPRIVATE)
11182     code = OMP_CLAUSE_LASTPRIVATE;
11183   else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
11184     return 0;
11185   else if (flags & GOVD_CONDTEMP)
11186     {
11187       code = OMP_CLAUSE__CONDTEMP_;
11188       gimple_add_tmp_var (decl);
11189     }
11190   else
11191     gcc_unreachable ();
11192 
11193   if (((flags & GOVD_LASTPRIVATE)
11194        || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
11195       && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11196     omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11197 
11198   tree chain = *list_p;
11199   clause = build_omp_clause (input_location, code);
11200   OMP_CLAUSE_DECL (clause) = decl;
11201   OMP_CLAUSE_CHAIN (clause) = chain;
11202   if (private_debug)
11203     OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
11204   else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
11205     OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
11206   else if (code == OMP_CLAUSE_SHARED
11207              && (flags & GOVD_WRITTEN) == 0
11208              && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11209     OMP_CLAUSE_SHARED_READONLY (clause) = 1;
11210   else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
11211     OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
11212   else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
11213     {
11214       tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
11215       OMP_CLAUSE_DECL (nc) = decl;
11216       if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
11217             && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
11218           OMP_CLAUSE_DECL (clause)
11219             = build_simple_mem_ref_loc (input_location, decl);
11220       OMP_CLAUSE_DECL (clause)
11221           = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
11222                       build_int_cst (build_pointer_type (char_type_node), 0));
11223       OMP_CLAUSE_SIZE (clause) = size_zero_node;
11224       OMP_CLAUSE_SIZE (nc) = size_zero_node;
11225       OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
11226       OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
11227       OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
11228       OMP_CLAUSE_CHAIN (nc) = chain;
11229       OMP_CLAUSE_CHAIN (clause) = nc;
11230       struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11231       gimplify_omp_ctxp = ctx->outer_context;
11232       gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
11233                          pre_p, NULL, is_gimple_val, fb_rvalue);
11234       gimplify_omp_ctxp = ctx;
11235     }
11236   else if (code == OMP_CLAUSE_MAP)
11237     {
11238       int kind;
11239       /* Not all combinations of these GOVD_MAP flags are actually valid.  */
11240       switch (flags & (GOVD_MAP_TO_ONLY
11241                            | GOVD_MAP_FORCE
11242                            | GOVD_MAP_FORCE_PRESENT
11243                            | GOVD_MAP_ALLOC_ONLY
11244                            | GOVD_MAP_FROM_ONLY))
11245           {
11246           case 0:
11247             kind = GOMP_MAP_TOFROM;
11248             break;
11249           case GOVD_MAP_FORCE:
11250             kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
11251             break;
11252           case GOVD_MAP_TO_ONLY:
11253             kind = GOMP_MAP_TO;
11254             break;
11255           case GOVD_MAP_FROM_ONLY:
11256             kind = GOMP_MAP_FROM;
11257             break;
11258           case GOVD_MAP_ALLOC_ONLY:
11259             kind = GOMP_MAP_ALLOC;
11260             break;
11261           case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
11262             kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
11263             break;
11264           case GOVD_MAP_FORCE_PRESENT:
11265             kind = GOMP_MAP_FORCE_PRESENT;
11266             break;
11267           default:
11268             gcc_unreachable ();
11269           }
11270       OMP_CLAUSE_SET_MAP_KIND (clause, kind);
11271       /* Setting of the implicit flag for the runtime is currently disabled for
11272            OpenACC.  */
11273       if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
11274           OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
11275       if (DECL_SIZE (decl)
11276             && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
11277           {
11278             tree decl2 = DECL_VALUE_EXPR (decl);
11279             gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11280             decl2 = TREE_OPERAND (decl2, 0);
11281             gcc_assert (DECL_P (decl2));
11282             tree mem = build_simple_mem_ref (decl2);
11283             OMP_CLAUSE_DECL (clause) = mem;
11284             OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11285             if (gimplify_omp_ctxp->outer_context)
11286               {
11287                 struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
11288                 omp_notice_variable (ctx, decl2, true);
11289                 omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
11290               }
11291             tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
11292                                               OMP_CLAUSE_MAP);
11293             OMP_CLAUSE_DECL (nc) = decl;
11294             OMP_CLAUSE_SIZE (nc) = size_zero_node;
11295             if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
11296               OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
11297             else
11298               OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
11299             OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
11300             OMP_CLAUSE_CHAIN (clause) = nc;
11301           }
11302       else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
11303                  && omp_privatize_by_reference (decl))
11304           {
11305             OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
11306             OMP_CLAUSE_SIZE (clause)
11307               = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
11308             struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11309             gimplify_omp_ctxp = ctx->outer_context;
11310             gimplify_expr (&OMP_CLAUSE_SIZE (clause),
11311                                pre_p, NULL, is_gimple_val, fb_rvalue);
11312             gimplify_omp_ctxp = ctx;
11313             tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
11314                                               OMP_CLAUSE_MAP);
11315             OMP_CLAUSE_DECL (nc) = decl;
11316             OMP_CLAUSE_SIZE (nc) = size_zero_node;
11317             OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
11318             OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
11319             OMP_CLAUSE_CHAIN (clause) = nc;
11320           }
11321       else
11322           OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
11323     }
11324   if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
11325     {
11326       tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
11327       OMP_CLAUSE_DECL (nc) = decl;
11328       OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
11329       OMP_CLAUSE_CHAIN (nc) = chain;
11330       OMP_CLAUSE_CHAIN (clause) = nc;
11331       struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11332       gimplify_omp_ctxp = ctx->outer_context;
11333       lang_hooks.decls.omp_finish_clause (nc, pre_p,
11334                                                     (ctx->region_type & ORT_ACC) != 0);
11335       gimplify_omp_ctxp = ctx;
11336     }
11337   *list_p = clause;
11338   struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11339   gimplify_omp_ctxp = ctx->outer_context;
11340   /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
11341      in simd.  Those are only added for the local vars inside of simd body
11342      and they don't need to be e.g. default constructible.  */
11343   if (code != OMP_CLAUSE_PRIVATE || ctx->region_type != ORT_SIMD)
11344     lang_hooks.decls.omp_finish_clause (clause, pre_p,
11345                                                   (ctx->region_type & ORT_ACC) != 0);
11346   if (gimplify_omp_ctxp)
11347     for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
11348       if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
11349             && DECL_P (OMP_CLAUSE_SIZE (clause)))
11350           omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
11351                                    true);
11352   gimplify_omp_ctxp = ctx;
11353   return 0;
11354 }
11355 
11356 static void
gimplify_adjust_omp_clauses(gimple_seq * pre_p,gimple_seq body,tree * list_p,enum tree_code code)11357 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
11358                                    enum tree_code code)
11359 {
11360   struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
11361   tree *orig_list_p = list_p;
11362   tree c, decl;
11363   bool has_inscan_reductions = false;
11364 
11365   if (body)
11366     {
11367       struct gimplify_omp_ctx *octx;
11368       for (octx = ctx; octx; octx = octx->outer_context)
11369           if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
11370             break;
11371       if (octx)
11372           {
11373             struct walk_stmt_info wi;
11374             memset (&wi, 0, sizeof (wi));
11375             walk_gimple_seq (body, omp_find_stores_stmt,
11376                                  omp_find_stores_op, &wi);
11377           }
11378     }
11379 
11380   if (ctx->add_safelen1)
11381     {
11382       /* If there are VLAs in the body of simd loop, prevent
11383            vectorization.  */
11384       gcc_assert (ctx->region_type == ORT_SIMD);
11385       c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
11386       OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
11387       OMP_CLAUSE_CHAIN (c) = *list_p;
11388       *list_p = c;
11389       list_p = &OMP_CLAUSE_CHAIN (c);
11390     }
11391 
11392   if (ctx->region_type == ORT_WORKSHARE
11393       && ctx->outer_context
11394       && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
11395     {
11396       for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
11397           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11398               && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
11399             {
11400               decl = OMP_CLAUSE_DECL (c);
11401               splay_tree_node n
11402                 = splay_tree_lookup (ctx->outer_context->variables,
11403                                            (splay_tree_key) decl);
11404               gcc_checking_assert (!splay_tree_lookup (ctx->variables,
11405                                                                  (splay_tree_key) decl));
11406               omp_add_variable (ctx, decl, n->value);
11407               tree c2 = copy_node (c);
11408               OMP_CLAUSE_CHAIN (c2) = *list_p;
11409               *list_p = c2;
11410               if ((n->value & GOVD_FIRSTPRIVATE) == 0)
11411                 continue;
11412               c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11413                                            OMP_CLAUSE_FIRSTPRIVATE);
11414               OMP_CLAUSE_DECL (c2) = decl;
11415               OMP_CLAUSE_CHAIN (c2) = *list_p;
11416               *list_p = c2;
11417             }
11418     }
11419   while ((c = *list_p) != NULL)
11420     {
11421       splay_tree_node n;
11422       bool remove = false;
11423 
11424       switch (OMP_CLAUSE_CODE (c))
11425           {
11426           case OMP_CLAUSE_FIRSTPRIVATE:
11427             if ((ctx->region_type & ORT_TARGET)
11428                 && (ctx->region_type & ORT_ACC) == 0
11429                 && TYPE_ATOMIC (strip_array_types
11430                                                   (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
11431               {
11432                 error_at (OMP_CLAUSE_LOCATION (c),
11433                               "%<_Atomic%> %qD in %<firstprivate%> clause on "
11434                               "%<target%> construct", OMP_CLAUSE_DECL (c));
11435                 remove = true;
11436                 break;
11437               }
11438             if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
11439               {
11440                 decl = OMP_CLAUSE_DECL (c);
11441                 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11442                 if ((n->value & GOVD_MAP) != 0)
11443                     {
11444                       remove = true;
11445                       break;
11446                     }
11447                 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) = 0;
11448                 OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) = 0;
11449               }
11450             /* FALLTHRU */
11451           case OMP_CLAUSE_PRIVATE:
11452           case OMP_CLAUSE_SHARED:
11453           case OMP_CLAUSE_LINEAR:
11454             decl = OMP_CLAUSE_DECL (c);
11455             n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11456             remove = !(n->value & GOVD_SEEN);
11457             if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
11458                 && code == OMP_PARALLEL
11459                 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
11460               remove = true;
11461             if (! remove)
11462               {
11463                 bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
11464                 if ((n->value & GOVD_DEBUG_PRIVATE)
11465                       || lang_hooks.decls.omp_private_debug_clause (decl, shared))
11466                     {
11467                       gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
11468                                     || ((n->value & GOVD_DATA_SHARE_CLASS)
11469                                           == GOVD_SHARED));
11470                       OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
11471                       OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
11472                     }
11473               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11474                       && ctx->has_depend
11475                       && DECL_P (decl))
11476                     n->value |= GOVD_WRITTEN;
11477                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11478                       && (n->value & GOVD_WRITTEN) == 0
11479                       && DECL_P (decl)
11480                       && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11481                     OMP_CLAUSE_SHARED_READONLY (c) = 1;
11482                 else if (DECL_P (decl)
11483                            && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
11484                                   && (n->value & GOVD_WRITTEN) != 0)
11485                                  || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11486                                      && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
11487                            && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11488                     omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11489               }
11490             else
11491               n->value &= ~GOVD_EXPLICIT;
11492             break;
11493 
11494           case OMP_CLAUSE_LASTPRIVATE:
11495             /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
11496                accurately reflect the presence of a FIRSTPRIVATE clause.  */
11497             decl = OMP_CLAUSE_DECL (c);
11498             n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11499             OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
11500               = (n->value & GOVD_FIRSTPRIVATE) != 0;
11501             if (code == OMP_DISTRIBUTE
11502                 && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
11503               {
11504                 remove = true;
11505                 error_at (OMP_CLAUSE_LOCATION (c),
11506                               "same variable used in %<firstprivate%> and "
11507                               "%<lastprivate%> clauses on %<distribute%> "
11508                               "construct");
11509               }
11510             if (!remove
11511                 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11512                 && DECL_P (decl)
11513                 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11514               omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11515             if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
11516               remove = true;
11517             break;
11518 
11519           case OMP_CLAUSE_ALIGNED:
11520             decl = OMP_CLAUSE_DECL (c);
11521             if (!is_global_var (decl))
11522               {
11523                 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11524                 remove = n == NULL || !(n->value & GOVD_SEEN);
11525                 if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
11526                     {
11527                       struct gimplify_omp_ctx *octx;
11528                       if (n != NULL
11529                           && (n->value & (GOVD_DATA_SHARE_CLASS
11530                                               & ~GOVD_FIRSTPRIVATE)))
11531                         remove = true;
11532                       else
11533                         for (octx = ctx->outer_context; octx;
11534                                octx = octx->outer_context)
11535                           {
11536                               n = splay_tree_lookup (octx->variables,
11537                                                          (splay_tree_key) decl);
11538                               if (n == NULL)
11539                                 continue;
11540                               if (n->value & GOVD_LOCAL)
11541                                 break;
11542                               /* We have to avoid assigning a shared variable
11543                                  to itself when trying to add
11544                                  __builtin_assume_aligned.  */
11545                               if (n->value & GOVD_SHARED)
11546                                 {
11547                                   remove = true;
11548                                   break;
11549                                 }
11550                           }
11551                     }
11552               }
11553             else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
11554               {
11555                 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11556                 if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
11557                     remove = true;
11558               }
11559             break;
11560 
11561           case OMP_CLAUSE_HAS_DEVICE_ADDR:
11562             decl = OMP_CLAUSE_DECL (c);
11563             while (TREE_CODE (decl) == INDIRECT_REF
11564                      || TREE_CODE (decl) == ARRAY_REF)
11565               decl = TREE_OPERAND (decl, 0);
11566             n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11567             remove = n == NULL || !(n->value & GOVD_SEEN);
11568             break;
11569 
11570           case OMP_CLAUSE_IS_DEVICE_PTR:
11571           case OMP_CLAUSE_NONTEMPORAL:
11572             decl = OMP_CLAUSE_DECL (c);
11573             n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11574             remove = n == NULL || !(n->value & GOVD_SEEN);
11575             break;
11576 
11577           case OMP_CLAUSE_MAP:
11578             if (code == OMP_TARGET_EXIT_DATA
11579                 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
11580               {
11581                 remove = true;
11582                 break;
11583               }
11584             decl = OMP_CLAUSE_DECL (c);
11585             /* Data clauses associated with reductions must be
11586                compatible with present_or_copy.  Warn and adjust the clause
11587                if that is not the case.  */
11588             if (ctx->region_type == ORT_ACC_PARALLEL
11589                 || ctx->region_type == ORT_ACC_SERIAL)
11590               {
11591                 tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
11592                 n = NULL;
11593 
11594                 if (DECL_P (t))
11595                     n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
11596 
11597                 if (n && (n->value & GOVD_REDUCTION))
11598                     {
11599                       enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
11600 
11601                       OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
11602                       if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
11603                           && kind != GOMP_MAP_FORCE_PRESENT
11604                           && kind != GOMP_MAP_POINTER)
11605                         {
11606                           warning_at (OMP_CLAUSE_LOCATION (c), 0,
11607                                           "incompatible data clause with reduction "
11608                                           "on %qE; promoting to %<present_or_copy%>",
11609                                           DECL_NAME (t));
11610                           OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
11611                         }
11612                     }
11613               }
11614             if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
11615                 && (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA))
11616               {
11617                 remove = true;
11618                 break;
11619               }
11620             if (!DECL_P (decl))
11621               {
11622                 if ((ctx->region_type & ORT_TARGET) != 0
11623                       && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
11624                     {
11625                       if (TREE_CODE (decl) == INDIRECT_REF
11626                           && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
11627                           && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
11628                                 == REFERENCE_TYPE))
11629                         decl = TREE_OPERAND (decl, 0);
11630                       if (TREE_CODE (decl) == COMPONENT_REF)
11631                         {
11632                           while (TREE_CODE (decl) == COMPONENT_REF)
11633                               decl = TREE_OPERAND (decl, 0);
11634                           if (DECL_P (decl))
11635                               {
11636                                 n = splay_tree_lookup (ctx->variables,
11637                                                              (splay_tree_key) decl);
11638                                 if (!(n->value & GOVD_SEEN))
11639                                   remove = true;
11640                               }
11641                         }
11642                     }
11643                 break;
11644               }
11645             n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11646             if ((ctx->region_type & ORT_TARGET) != 0
11647                 && !(n->value & GOVD_SEEN)
11648                 && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
11649                 && (!is_global_var (decl)
11650                       || !lookup_attribute ("omp declare target link",
11651                                                   DECL_ATTRIBUTES (decl))))
11652               {
11653                 remove = true;
11654                 /* For struct element mapping, if struct is never referenced
11655                      in target block and none of the mapping has always modifier,
11656                      remove all the struct element mappings, which immediately
11657                      follow the GOMP_MAP_STRUCT map clause.  */
11658                 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
11659                     {
11660                       HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
11661                       while (cnt--)
11662                         OMP_CLAUSE_CHAIN (c)
11663                           = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
11664                     }
11665               }
11666             else if (DECL_SIZE (decl)
11667                        && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
11668                        && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
11669                        && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
11670                        && (OMP_CLAUSE_MAP_KIND (c)
11671                            != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
11672               {
11673                 /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
11674                      for these, TREE_CODE (DECL_SIZE (decl)) will always be
11675                      INTEGER_CST.  */
11676                 gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
11677 
11678                 tree decl2 = DECL_VALUE_EXPR (decl);
11679                 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11680                 decl2 = TREE_OPERAND (decl2, 0);
11681                 gcc_assert (DECL_P (decl2));
11682                 tree mem = build_simple_mem_ref (decl2);
11683                 OMP_CLAUSE_DECL (c) = mem;
11684                 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11685                 if (ctx->outer_context)
11686                     {
11687                       omp_notice_variable (ctx->outer_context, decl2, true);
11688                       omp_notice_variable (ctx->outer_context,
11689                                                OMP_CLAUSE_SIZE (c), true);
11690                     }
11691                 if (((ctx->region_type & ORT_TARGET) != 0
11692                        || !ctx->target_firstprivatize_array_bases)
11693                       && ((n->value & GOVD_SEEN) == 0
11694                           || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
11695                     {
11696                       tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
11697                                                         OMP_CLAUSE_MAP);
11698                       OMP_CLAUSE_DECL (nc) = decl;
11699                       OMP_CLAUSE_SIZE (nc) = size_zero_node;
11700                       if (ctx->target_firstprivatize_array_bases)
11701                         OMP_CLAUSE_SET_MAP_KIND (nc,
11702                                                        GOMP_MAP_FIRSTPRIVATE_POINTER);
11703                       else
11704                         OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
11705                       OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
11706                       OMP_CLAUSE_CHAIN (c) = nc;
11707                       c = nc;
11708                     }
11709               }
11710             else
11711               {
11712                 if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11713                     OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11714                 gcc_assert ((n->value & GOVD_SEEN) == 0
11715                                 || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11716                                     == 0));
11717               }
11718             break;
11719 
11720           case OMP_CLAUSE_TO:
11721           case OMP_CLAUSE_FROM:
11722           case OMP_CLAUSE__CACHE_:
11723             decl = OMP_CLAUSE_DECL (c);
11724             if (!DECL_P (decl))
11725               break;
11726             if (DECL_SIZE (decl)
11727                 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
11728               {
11729                 tree decl2 = DECL_VALUE_EXPR (decl);
11730                 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
11731                 decl2 = TREE_OPERAND (decl2, 0);
11732                 gcc_assert (DECL_P (decl2));
11733                 tree mem = build_simple_mem_ref (decl2);
11734                 OMP_CLAUSE_DECL (c) = mem;
11735                 OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
11736                 if (ctx->outer_context)
11737                     {
11738                       omp_notice_variable (ctx->outer_context, decl2, true);
11739                       omp_notice_variable (ctx->outer_context,
11740                                                OMP_CLAUSE_SIZE (c), true);
11741                     }
11742               }
11743             else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
11744               OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
11745             break;
11746 
11747           case OMP_CLAUSE_REDUCTION:
11748             if (OMP_CLAUSE_REDUCTION_INSCAN (c))
11749               {
11750                 decl = OMP_CLAUSE_DECL (c);
11751                 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11752                 if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
11753                     {
11754                       remove = true;
11755                       error_at (OMP_CLAUSE_LOCATION (c),
11756                                   "%qD specified in %<inscan%> %<reduction%> clause "
11757                                   "but not in %<scan%> directive clause", decl);
11758                       break;
11759                     }
11760                 has_inscan_reductions = true;
11761               }
11762             /* FALLTHRU */
11763           case OMP_CLAUSE_IN_REDUCTION:
11764           case OMP_CLAUSE_TASK_REDUCTION:
11765             decl = OMP_CLAUSE_DECL (c);
11766             /* OpenACC reductions need a present_or_copy data clause.
11767                Add one if necessary.  Emit error when the reduction is private.  */
11768             if (ctx->region_type == ORT_ACC_PARALLEL
11769                 || ctx->region_type == ORT_ACC_SERIAL)
11770               {
11771                 n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11772                 if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
11773                     {
11774                       remove = true;
11775                       error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
11776                                   "reduction on %qE", DECL_NAME (decl));
11777                     }
11778                 else if ((n->value & GOVD_MAP) == 0)
11779                     {
11780                       tree next = OMP_CLAUSE_CHAIN (c);
11781                       tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
11782                       OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
11783                       OMP_CLAUSE_DECL (nc) = decl;
11784                       OMP_CLAUSE_CHAIN (c) = nc;
11785                       lang_hooks.decls.omp_finish_clause (nc, pre_p,
11786                                                                   (ctx->region_type
11787                                                                    & ORT_ACC) != 0);
11788                       while (1)
11789                         {
11790                           OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
11791                           if (OMP_CLAUSE_CHAIN (nc) == NULL)
11792                               break;
11793                           nc = OMP_CLAUSE_CHAIN (nc);
11794                         }
11795                       OMP_CLAUSE_CHAIN (nc) = next;
11796                       n->value |= GOVD_MAP;
11797                     }
11798               }
11799             if (DECL_P (decl)
11800                 && omp_shared_to_firstprivate_optimizable_decl_p (decl))
11801               omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
11802             break;
11803 
11804           case OMP_CLAUSE_ALLOCATE:
11805             decl = OMP_CLAUSE_DECL (c);
11806             n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
11807             if (n != NULL && !(n->value & GOVD_SEEN))
11808               {
11809                 if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR))
11810                       != 0
11811                       && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0)
11812                     remove = true;
11813               }
11814             if (!remove
11815                 && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
11816                 && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST
11817                 && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0
11818                       || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK
11819                       || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS))
11820               {
11821                 tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
11822                 n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator);
11823                 if (n == NULL)
11824                     {
11825                       enum omp_clause_default_kind default_kind
11826                         = ctx->default_kind;
11827                       ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
11828                       omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11829                                                true);
11830                       ctx->default_kind = default_kind;
11831                     }
11832                 else
11833                     omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
11834                                              true);
11835               }
11836             break;
11837 
11838           case OMP_CLAUSE_COPYIN:
11839           case OMP_CLAUSE_COPYPRIVATE:
11840           case OMP_CLAUSE_IF:
11841           case OMP_CLAUSE_NUM_THREADS:
11842           case OMP_CLAUSE_NUM_TEAMS:
11843           case OMP_CLAUSE_THREAD_LIMIT:
11844           case OMP_CLAUSE_DIST_SCHEDULE:
11845           case OMP_CLAUSE_DEVICE:
11846           case OMP_CLAUSE_SCHEDULE:
11847           case OMP_CLAUSE_NOWAIT:
11848           case OMP_CLAUSE_ORDERED:
11849           case OMP_CLAUSE_DEFAULT:
11850           case OMP_CLAUSE_UNTIED:
11851           case OMP_CLAUSE_COLLAPSE:
11852           case OMP_CLAUSE_FINAL:
11853           case OMP_CLAUSE_MERGEABLE:
11854           case OMP_CLAUSE_PROC_BIND:
11855           case OMP_CLAUSE_SAFELEN:
11856           case OMP_CLAUSE_SIMDLEN:
11857           case OMP_CLAUSE_DEPEND:
11858           case OMP_CLAUSE_PRIORITY:
11859           case OMP_CLAUSE_GRAINSIZE:
11860           case OMP_CLAUSE_NUM_TASKS:
11861           case OMP_CLAUSE_NOGROUP:
11862           case OMP_CLAUSE_THREADS:
11863           case OMP_CLAUSE_SIMD:
11864           case OMP_CLAUSE_FILTER:
11865           case OMP_CLAUSE_HINT:
11866           case OMP_CLAUSE_DEFAULTMAP:
11867           case OMP_CLAUSE_ORDER:
11868           case OMP_CLAUSE_BIND:
11869           case OMP_CLAUSE_DETACH:
11870           case OMP_CLAUSE_USE_DEVICE_PTR:
11871           case OMP_CLAUSE_USE_DEVICE_ADDR:
11872           case OMP_CLAUSE_ASYNC:
11873           case OMP_CLAUSE_WAIT:
11874           case OMP_CLAUSE_INDEPENDENT:
11875           case OMP_CLAUSE_NUM_GANGS:
11876           case OMP_CLAUSE_NUM_WORKERS:
11877           case OMP_CLAUSE_VECTOR_LENGTH:
11878           case OMP_CLAUSE_GANG:
11879           case OMP_CLAUSE_WORKER:
11880           case OMP_CLAUSE_VECTOR:
11881           case OMP_CLAUSE_AUTO:
11882           case OMP_CLAUSE_SEQ:
11883           case OMP_CLAUSE_TILE:
11884           case OMP_CLAUSE_IF_PRESENT:
11885           case OMP_CLAUSE_FINALIZE:
11886           case OMP_CLAUSE_INCLUSIVE:
11887           case OMP_CLAUSE_EXCLUSIVE:
11888             break;
11889 
11890           case OMP_CLAUSE_NOHOST:
11891           default:
11892             gcc_unreachable ();
11893           }
11894 
11895       if (remove)
11896           *list_p = OMP_CLAUSE_CHAIN (c);
11897       else
11898           list_p = &OMP_CLAUSE_CHAIN (c);
11899     }
11900 
11901   /* Add in any implicit data sharing.  */
11902   struct gimplify_adjust_omp_clauses_data data;
11903   if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
11904     {
11905       /* OpenMP.  Implicit clauses are added at the start of the clause list,
11906            but after any non-map clauses.  */
11907       tree *implicit_add_list_p = orig_list_p;
11908       while (*implicit_add_list_p
11909                && OMP_CLAUSE_CODE (*implicit_add_list_p) != OMP_CLAUSE_MAP)
11910           implicit_add_list_p = &OMP_CLAUSE_CHAIN (*implicit_add_list_p);
11911       data.list_p = implicit_add_list_p;
11912     }
11913   else
11914     /* OpenACC.  */
11915     data.list_p = list_p;
11916   data.pre_p = pre_p;
11917   splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
11918 
11919   if (has_inscan_reductions)
11920     for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
11921       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
11922             && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
11923           {
11924             error_at (OMP_CLAUSE_LOCATION (c),
11925                         "%<inscan%> %<reduction%> clause used together with "
11926                         "%<linear%> clause for a variable other than loop "
11927                         "iterator");
11928             break;
11929           }
11930 
11931   gimplify_omp_ctxp = ctx->outer_context;
11932   delete_omp_context (ctx);
11933 }
11934 
11935 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
11936    -1 if unknown yet (simd is involved, won't be known until vectorization)
11937    and 1 if they do.  If SCORES is non-NULL, it should point to an array
11938    of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
11939    of the CONSTRUCTS (position -1 if it will never match) followed by
11940    number of constructs in the OpenMP context construct trait.  If the
11941    score depends on whether it will be in a declare simd clone or not,
11942    the function returns 2 and there will be two sets of the scores, the first
11943    one for the case that it is not in a declare simd clone, the other
11944    that it is in a declare simd clone.  */
11945 
11946 int
omp_construct_selector_matches(enum tree_code * constructs,int nconstructs,int * scores)11947 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
11948                                         int *scores)
11949 {
11950   int matched = 0, cnt = 0;
11951   bool simd_seen = false;
11952   bool target_seen = false;
11953   int declare_simd_cnt = -1;
11954   auto_vec<enum tree_code, 16> codes;
11955   for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
11956     {
11957       if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
11958             || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
11959                 == ORT_TARGET && ctx->code == OMP_TARGET)
11960             || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
11961             || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
11962             || (ctx->region_type == ORT_SIMD
11963                 && ctx->code == OMP_SIMD
11964                 && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
11965           {
11966             ++cnt;
11967             if (scores)
11968               codes.safe_push (ctx->code);
11969             else if (matched < nconstructs && ctx->code == constructs[matched])
11970               {
11971                 if (ctx->code == OMP_SIMD)
11972                     {
11973                       if (matched)
11974                         return 0;
11975                       simd_seen = true;
11976                     }
11977                 ++matched;
11978               }
11979             if (ctx->code == OMP_TARGET)
11980               {
11981                 if (scores == NULL)
11982                     return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
11983                 target_seen = true;
11984                 break;
11985               }
11986           }
11987       else if (ctx->region_type == ORT_WORKSHARE
11988                  && ctx->code == OMP_LOOP
11989                  && ctx->outer_context
11990                  && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
11991                  && ctx->outer_context->outer_context
11992                  && ctx->outer_context->outer_context->code == OMP_LOOP
11993                  && ctx->outer_context->outer_context->distribute)
11994           ctx = ctx->outer_context->outer_context;
11995       ctx = ctx->outer_context;
11996     }
11997   if (!target_seen
11998       && lookup_attribute ("omp declare simd",
11999                                  DECL_ATTRIBUTES (current_function_decl)))
12000     {
12001       /* Declare simd is a maybe case, it is supposed to be added only to the
12002            omp-simd-clone.cc added clones and not to the base function.  */
12003       declare_simd_cnt = cnt++;
12004       if (scores)
12005           codes.safe_push (OMP_SIMD);
12006       else if (cnt == 0
12007                  && constructs[0] == OMP_SIMD)
12008           {
12009             gcc_assert (matched == 0);
12010             simd_seen = true;
12011             if (++matched == nconstructs)
12012               return -1;
12013           }
12014     }
12015   if (tree attr = lookup_attribute ("omp declare variant variant",
12016                                             DECL_ATTRIBUTES (current_function_decl)))
12017     {
12018       enum tree_code variant_constructs[5];
12019       int variant_nconstructs = 0;
12020       if (!target_seen)
12021           variant_nconstructs
12022             = omp_constructor_traits_to_codes (TREE_VALUE (attr),
12023                                                        variant_constructs);
12024       for (int i = 0; i < variant_nconstructs; i++)
12025           {
12026             ++cnt;
12027             if (scores)
12028               codes.safe_push (variant_constructs[i]);
12029             else if (matched < nconstructs
12030                        && variant_constructs[i] == constructs[matched])
12031               {
12032                 if (variant_constructs[i] == OMP_SIMD)
12033                     {
12034                       if (matched)
12035                         return 0;
12036                       simd_seen = true;
12037                     }
12038                 ++matched;
12039               }
12040           }
12041     }
12042   if (!target_seen
12043       && lookup_attribute ("omp declare target block",
12044                                  DECL_ATTRIBUTES (current_function_decl)))
12045     {
12046       if (scores)
12047           codes.safe_push (OMP_TARGET);
12048       else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
12049           ++matched;
12050     }
12051   if (scores)
12052     {
12053       for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
12054           {
12055             int j = codes.length () - 1;
12056             for (int i = nconstructs - 1; i >= 0; i--)
12057               {
12058                 while (j >= 0
12059                          && (pass != 0 || declare_simd_cnt != j)
12060                          && constructs[i] != codes[j])
12061                     --j;
12062                 if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
12063                     *scores++ = j - 1;
12064                 else
12065                     *scores++ = j;
12066               }
12067             *scores++ = ((pass == 0 && declare_simd_cnt != -1)
12068                            ? codes.length () - 1 : codes.length ());
12069           }
12070       return declare_simd_cnt == -1 ? 1 : 2;
12071     }
12072   if (matched == nconstructs)
12073     return simd_seen ? -1 : 1;
12074   return 0;
12075 }
12076 
12077 /* Gimplify OACC_CACHE.  */
12078 
12079 static void
gimplify_oacc_cache(tree * expr_p,gimple_seq * pre_p)12080 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
12081 {
12082   tree expr = *expr_p;
12083 
12084   gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
12085                                    OACC_CACHE);
12086   gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
12087                                      OACC_CACHE);
12088 
12089   /* TODO: Do something sensible with this information.  */
12090 
12091   *expr_p = NULL_TREE;
12092 }
12093 
12094 /* Helper function of gimplify_oacc_declare.  The helper's purpose is to,
12095    if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
12096    kind.  The entry kind will replace the one in CLAUSE, while the exit
12097    kind will be used in a new omp_clause and returned to the caller.  */
12098 
12099 static tree
gimplify_oacc_declare_1(tree clause)12100 gimplify_oacc_declare_1 (tree clause)
12101 {
12102   HOST_WIDE_INT kind, new_op;
12103   bool ret = false;
12104   tree c = NULL;
12105 
12106   kind = OMP_CLAUSE_MAP_KIND (clause);
12107 
12108   switch (kind)
12109     {
12110       case GOMP_MAP_ALLOC:
12111           new_op = GOMP_MAP_RELEASE;
12112           ret = true;
12113           break;
12114 
12115       case GOMP_MAP_FROM:
12116           OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
12117           new_op = GOMP_MAP_FROM;
12118           ret = true;
12119           break;
12120 
12121       case GOMP_MAP_TOFROM:
12122           OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
12123           new_op = GOMP_MAP_FROM;
12124           ret = true;
12125           break;
12126 
12127       case GOMP_MAP_DEVICE_RESIDENT:
12128       case GOMP_MAP_FORCE_DEVICEPTR:
12129       case GOMP_MAP_FORCE_PRESENT:
12130       case GOMP_MAP_LINK:
12131       case GOMP_MAP_POINTER:
12132       case GOMP_MAP_TO:
12133           break;
12134 
12135       default:
12136           gcc_unreachable ();
12137           break;
12138     }
12139 
12140   if (ret)
12141     {
12142       c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
12143       OMP_CLAUSE_SET_MAP_KIND (c, new_op);
12144       OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
12145     }
12146 
12147   return c;
12148 }
12149 
12150 /* Gimplify OACC_DECLARE.  */
12151 
12152 static void
gimplify_oacc_declare(tree * expr_p,gimple_seq * pre_p)12153 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
12154 {
12155   tree expr = *expr_p;
12156   gomp_target *stmt;
12157   tree clauses, t, decl;
12158 
12159   clauses = OACC_DECLARE_CLAUSES (expr);
12160 
12161   gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
12162   gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
12163 
12164   for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
12165     {
12166       decl = OMP_CLAUSE_DECL (t);
12167 
12168       if (TREE_CODE (decl) == MEM_REF)
12169           decl = TREE_OPERAND (decl, 0);
12170 
12171       if (VAR_P (decl) && !is_oacc_declared (decl))
12172           {
12173             tree attr = get_identifier ("oacc declare target");
12174             DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
12175                                                         DECL_ATTRIBUTES (decl));
12176           }
12177 
12178       if (VAR_P (decl)
12179             && !is_global_var (decl)
12180             && DECL_CONTEXT (decl) == current_function_decl)
12181           {
12182             tree c = gimplify_oacc_declare_1 (t);
12183             if (c)
12184               {
12185                 if (oacc_declare_returns == NULL)
12186                     oacc_declare_returns = new hash_map<tree, tree>;
12187 
12188                 oacc_declare_returns->put (decl, c);
12189               }
12190           }
12191 
12192       if (gimplify_omp_ctxp)
12193           omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
12194     }
12195 
12196   stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
12197                                           clauses);
12198 
12199   gimplify_seq_add_stmt (pre_p, stmt);
12200 
12201   *expr_p = NULL_TREE;
12202 }
12203 
12204 /* Gimplify the contents of an OMP_PARALLEL statement.  This involves
12205    gimplification of the body, as well as scanning the body for used
12206    variables.  We need to do this scan now, because variable-sized
12207    decls will be decomposed during gimplification.  */
12208 
12209 static void
gimplify_omp_parallel(tree * expr_p,gimple_seq * pre_p)12210 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
12211 {
12212   tree expr = *expr_p;
12213   gimple *g;
12214   gimple_seq body = NULL;
12215 
12216   gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
12217                                    OMP_PARALLEL_COMBINED (expr)
12218                                    ? ORT_COMBINED_PARALLEL
12219                                    : ORT_PARALLEL, OMP_PARALLEL);
12220 
12221   push_gimplify_context ();
12222 
12223   g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
12224   if (gimple_code (g) == GIMPLE_BIND)
12225     pop_gimplify_context (g);
12226   else
12227     pop_gimplify_context (NULL);
12228 
12229   gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
12230                                      OMP_PARALLEL);
12231 
12232   g = gimple_build_omp_parallel (body,
12233                                          OMP_PARALLEL_CLAUSES (expr),
12234                                          NULL_TREE, NULL_TREE);
12235   if (OMP_PARALLEL_COMBINED (expr))
12236     gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
12237   gimplify_seq_add_stmt (pre_p, g);
12238   *expr_p = NULL_TREE;
12239 }
12240 
12241 /* Gimplify the contents of an OMP_TASK statement.  This involves
12242    gimplification of the body, as well as scanning the body for used
12243    variables.  We need to do this scan now, because variable-sized
12244    decls will be decomposed during gimplification.  */
12245 
12246 static void
gimplify_omp_task(tree * expr_p,gimple_seq * pre_p)12247 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
12248 {
12249   tree expr = *expr_p;
12250   gimple *g;
12251   gimple_seq body = NULL;
12252 
12253   if (OMP_TASK_BODY (expr) == NULL_TREE)
12254     for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
12255       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
12256             && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
12257           {
12258             error_at (OMP_CLAUSE_LOCATION (c),
12259                         "%<mutexinoutset%> kind in %<depend%> clause on a "
12260                         "%<taskwait%> construct");
12261             break;
12262           }
12263 
12264   gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
12265                                    omp_find_clause (OMP_TASK_CLAUSES (expr),
12266                                                         OMP_CLAUSE_UNTIED)
12267                                    ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
12268 
12269   if (OMP_TASK_BODY (expr))
12270     {
12271       push_gimplify_context ();
12272 
12273       g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
12274       if (gimple_code (g) == GIMPLE_BIND)
12275           pop_gimplify_context (g);
12276       else
12277           pop_gimplify_context (NULL);
12278     }
12279 
12280   gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
12281                                      OMP_TASK);
12282 
12283   g = gimple_build_omp_task (body,
12284                                    OMP_TASK_CLAUSES (expr),
12285                                    NULL_TREE, NULL_TREE,
12286                                    NULL_TREE, NULL_TREE, NULL_TREE);
12287   if (OMP_TASK_BODY (expr) == NULL_TREE)
12288     gimple_omp_task_set_taskwait_p (g, true);
12289   gimplify_seq_add_stmt (pre_p, g);
12290   *expr_p = NULL_TREE;
12291 }
12292 
12293 /* Helper function for gimplify_omp_for.  If *TP is not a gimple constant,
12294    force it into a temporary initialized in PRE_P and add firstprivate clause
12295    to ORIG_FOR_STMT.  */
12296 
12297 static void
gimplify_omp_taskloop_expr(tree type,tree * tp,gimple_seq * pre_p,tree orig_for_stmt)12298 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
12299                                   tree orig_for_stmt)
12300 {
12301   if (*tp == NULL || is_gimple_constant (*tp))
12302     return;
12303 
12304   *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
12305   /* Reference to pointer conversion is considered useless,
12306      but is significant for firstprivate clause.  Force it
12307      here.  */
12308   if (type
12309       && TREE_CODE (type) == POINTER_TYPE
12310       && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
12311     {
12312       tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
12313       tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
12314       gimplify_and_add (m, pre_p);
12315       *tp = v;
12316     }
12317 
12318   tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
12319   OMP_CLAUSE_DECL (c) = *tp;
12320   OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
12321   OMP_FOR_CLAUSES (orig_for_stmt) = c;
12322 }
12323 
12324 /* Gimplify the gross structure of an OMP_FOR statement.  */
12325 
12326 static enum gimplify_status
gimplify_omp_for(tree * expr_p,gimple_seq * pre_p)12327 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
12328 {
12329   tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
12330   enum gimplify_status ret = GS_ALL_DONE;
12331   enum gimplify_status tret;
12332   gomp_for *gfor;
12333   gimple_seq for_body, for_pre_body;
12334   int i;
12335   bitmap has_decl_expr = NULL;
12336   enum omp_region_type ort = ORT_WORKSHARE;
12337   bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
12338 
12339   orig_for_stmt = for_stmt = *expr_p;
12340 
12341   bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
12342                      != NULL_TREE);
12343   if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
12344     {
12345       tree *data[4] = { NULL, NULL, NULL, NULL };
12346       gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
12347       inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
12348                                           find_combined_omp_for, data, NULL);
12349       if (inner_for_stmt == NULL_TREE)
12350           {
12351             gcc_assert (seen_error ());
12352             *expr_p = NULL_TREE;
12353             return GS_ERROR;
12354           }
12355       if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
12356           {
12357             append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
12358                                                     &OMP_FOR_PRE_BODY (for_stmt));
12359             OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
12360           }
12361       if (OMP_FOR_PRE_BODY (inner_for_stmt))
12362           {
12363             append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
12364                                                     &OMP_FOR_PRE_BODY (for_stmt));
12365             OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
12366           }
12367 
12368       if (data[0])
12369           {
12370             /* We have some statements or variable declarations in between
12371                the composite construct directives.  Move them around the
12372                inner_for_stmt.  */
12373             data[0] = expr_p;
12374             for (i = 0; i < 3; i++)
12375               if (data[i])
12376                 {
12377                     tree t = *data[i];
12378                     if (i < 2 && data[i + 1] == &OMP_BODY (t))
12379                       data[i + 1] = data[i];
12380                     *data[i] = OMP_BODY (t);
12381                     tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
12382                                             NULL_TREE, make_node (BLOCK));
12383                     OMP_BODY (t) = body;
12384                     append_to_statement_list_force (inner_for_stmt,
12385                                                             &BIND_EXPR_BODY (body));
12386                     *data[3] = t;
12387                     data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
12388                     gcc_assert (*data[3] == inner_for_stmt);
12389                 }
12390             return GS_OK;
12391           }
12392 
12393       for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
12394           if (!loop_p
12395               && OMP_FOR_ORIG_DECLS (inner_for_stmt)
12396               && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12397                                                   i)) == TREE_LIST
12398               && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12399                                                      i)))
12400             {
12401               tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
12402               /* Class iterators aren't allowed on OMP_SIMD, so the only
12403                  case we need to solve is distribute parallel for.  They are
12404                  allowed on the loop construct, but that is already handled
12405                  in gimplify_omp_loop.  */
12406               gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
12407                               && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
12408                               && data[1]);
12409               tree orig_decl = TREE_PURPOSE (orig);
12410               tree last = TREE_VALUE (orig);
12411               tree *pc;
12412               for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
12413                      *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
12414                 if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
12415                        || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
12416                       && OMP_CLAUSE_DECL (*pc) == orig_decl)
12417                     break;
12418               if (*pc == NULL_TREE)
12419                 {
12420                     tree *spc;
12421                     for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
12422                          *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
12423                       if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
12424                           && OMP_CLAUSE_DECL (*spc) == orig_decl)
12425                         break;
12426                     if (*spc)
12427                       {
12428                         tree c = *spc;
12429                         *spc = OMP_CLAUSE_CHAIN (c);
12430                         OMP_CLAUSE_CHAIN (c) = NULL_TREE;
12431                         *pc = c;
12432                       }
12433                 }
12434               if (*pc == NULL_TREE)
12435                 ;
12436               else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
12437                 {
12438                     /* private clause will appear only on inner_for_stmt.
12439                        Change it into firstprivate, and add private clause
12440                        on for_stmt.  */
12441                     tree c = copy_node (*pc);
12442                     OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12443                     OMP_FOR_CLAUSES (for_stmt) = c;
12444                     OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
12445                     lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12446                 }
12447               else
12448                 {
12449                     /* lastprivate clause will appear on both inner_for_stmt
12450                        and for_stmt.  Add firstprivate clause to
12451                        inner_for_stmt.  */
12452                     tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
12453                                                      OMP_CLAUSE_FIRSTPRIVATE);
12454                     OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
12455                     OMP_CLAUSE_CHAIN (c) = *pc;
12456                     *pc = c;
12457                     lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
12458                 }
12459               tree c = build_omp_clause (UNKNOWN_LOCATION,
12460                                                OMP_CLAUSE_FIRSTPRIVATE);
12461               OMP_CLAUSE_DECL (c) = last;
12462               OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12463               OMP_PARALLEL_CLAUSES (*data[1]) = c;
12464               c = build_omp_clause (UNKNOWN_LOCATION,
12465                                           *pc ? OMP_CLAUSE_SHARED
12466                                               : OMP_CLAUSE_FIRSTPRIVATE);
12467               OMP_CLAUSE_DECL (c) = orig_decl;
12468               OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12469               OMP_PARALLEL_CLAUSES (*data[1]) = c;
12470             }
12471       /* Similarly, take care of C++ range for temporaries, those should
12472            be firstprivate on OMP_PARALLEL if any.  */
12473       if (data[1])
12474           for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
12475             if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
12476                 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12477                                                     i)) == TREE_LIST
12478                 && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
12479                                                      i)))
12480               {
12481                 tree orig
12482                     = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
12483                 tree v = TREE_CHAIN (orig);
12484                 tree c = build_omp_clause (UNKNOWN_LOCATION,
12485                                                    OMP_CLAUSE_FIRSTPRIVATE);
12486                 /* First add firstprivate clause for the __for_end artificial
12487                      decl.  */
12488                 OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
12489                 if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12490                       == REFERENCE_TYPE)
12491                     OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12492                 OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12493                 OMP_PARALLEL_CLAUSES (*data[1]) = c;
12494                 if (TREE_VEC_ELT (v, 0))
12495                     {
12496                       /* And now the same for __for_range artificial decl if it
12497                          exists.  */
12498                       c = build_omp_clause (UNKNOWN_LOCATION,
12499                                                   OMP_CLAUSE_FIRSTPRIVATE);
12500                       OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
12501                       if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
12502                           == REFERENCE_TYPE)
12503                         OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
12504                       OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
12505                       OMP_PARALLEL_CLAUSES (*data[1]) = c;
12506                     }
12507               }
12508     }
12509 
12510   switch (TREE_CODE (for_stmt))
12511     {
12512     case OMP_FOR:
12513       if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
12514           {
12515             if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12516                                      OMP_CLAUSE_SCHEDULE))
12517               error_at (EXPR_LOCATION (for_stmt),
12518                           "%qs clause may not appear on non-rectangular %qs",
12519                           "schedule", "for");
12520             if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
12521               error_at (EXPR_LOCATION (for_stmt),
12522                           "%qs clause may not appear on non-rectangular %qs",
12523                           "ordered", "for");
12524           }
12525       break;
12526     case OMP_DISTRIBUTE:
12527       if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
12528             && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12529                                     OMP_CLAUSE_DIST_SCHEDULE))
12530           error_at (EXPR_LOCATION (for_stmt),
12531                       "%qs clause may not appear on non-rectangular %qs",
12532                       "dist_schedule", "distribute");
12533       break;
12534     case OACC_LOOP:
12535       ort = ORT_ACC;
12536       break;
12537     case OMP_TASKLOOP:
12538       if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
12539           ort = ORT_UNTIED_TASKLOOP;
12540       else
12541           ort = ORT_TASKLOOP;
12542       break;
12543     case OMP_SIMD:
12544       ort = ORT_SIMD;
12545       break;
12546     default:
12547       gcc_unreachable ();
12548     }
12549 
12550   /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
12551      clause for the IV.  */
12552   if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12553     {
12554       t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
12555       gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12556       decl = TREE_OPERAND (t, 0);
12557       for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
12558           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
12559               && OMP_CLAUSE_DECL (c) == decl)
12560             {
12561               OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12562               break;
12563             }
12564     }
12565 
12566   if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
12567     gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
12568                                      loop_p && TREE_CODE (for_stmt) != OMP_SIMD
12569                                      ? OMP_LOOP : TREE_CODE (for_stmt));
12570 
12571   if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
12572     gimplify_omp_ctxp->distribute = true;
12573 
12574   /* Handle OMP_FOR_INIT.  */
12575   for_pre_body = NULL;
12576   if ((ort == ORT_SIMD
12577        || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
12578       && OMP_FOR_PRE_BODY (for_stmt))
12579     {
12580       has_decl_expr = BITMAP_ALLOC (NULL);
12581       if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
12582             && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
12583                == VAR_DECL)
12584           {
12585             t = OMP_FOR_PRE_BODY (for_stmt);
12586             bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12587           }
12588       else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
12589           {
12590             tree_stmt_iterator si;
12591             for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
12592                  tsi_next (&si))
12593               {
12594                 t = tsi_stmt (si);
12595                 if (TREE_CODE (t) == DECL_EXPR
12596                       && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
12597                     bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
12598               }
12599           }
12600     }
12601   if (OMP_FOR_PRE_BODY (for_stmt))
12602     {
12603       if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
12604           gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12605       else
12606           {
12607             struct gimplify_omp_ctx ctx;
12608             memset (&ctx, 0, sizeof (ctx));
12609             ctx.region_type = ORT_NONE;
12610             gimplify_omp_ctxp = &ctx;
12611             gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
12612             gimplify_omp_ctxp = NULL;
12613           }
12614     }
12615   OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
12616 
12617   if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
12618     for_stmt = inner_for_stmt;
12619 
12620   /* For taskloop, need to gimplify the start, end and step before the
12621      taskloop, outside of the taskloop omp context.  */
12622   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
12623     {
12624       for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12625           {
12626             t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12627             gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
12628                                            ? pre_p : &for_pre_body);
12629                 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
12630             if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12631               {
12632                 tree v = TREE_OPERAND (t, 1);
12633                 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12634                                                     for_pre_p, orig_for_stmt);
12635                 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12636                                                     for_pre_p, orig_for_stmt);
12637               }
12638             else
12639               gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12640                                                   orig_for_stmt);
12641 
12642             /* Handle OMP_FOR_COND.  */
12643             t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12644             if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12645               {
12646                 tree v = TREE_OPERAND (t, 1);
12647                 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
12648                                                     for_pre_p, orig_for_stmt);
12649                 gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
12650                                                     for_pre_p, orig_for_stmt);
12651               }
12652             else
12653               gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
12654                                                   orig_for_stmt);
12655 
12656             /* Handle OMP_FOR_INCR.  */
12657             t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12658             if (TREE_CODE (t) == MODIFY_EXPR)
12659               {
12660                 decl = TREE_OPERAND (t, 0);
12661                 t = TREE_OPERAND (t, 1);
12662                 tree *tp = &TREE_OPERAND (t, 1);
12663                 if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
12664                     tp = &TREE_OPERAND (t, 0);
12665 
12666                 gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
12667                                                     orig_for_stmt);
12668               }
12669           }
12670 
12671       gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
12672                                          OMP_TASKLOOP);
12673     }
12674 
12675   if (orig_for_stmt != for_stmt)
12676     gimplify_omp_ctxp->combined_loop = true;
12677 
12678   for_body = NULL;
12679   gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12680                 == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
12681   gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12682                 == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
12683 
12684   tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
12685   bool is_doacross = false;
12686   if (c && OMP_CLAUSE_ORDERED_EXPR (c))
12687     {
12688       is_doacross = true;
12689       gimplify_omp_ctxp->loop_iter_var.create (TREE_VEC_LENGTH
12690                                                              (OMP_FOR_INIT (for_stmt))
12691                                                          * 2);
12692     }
12693   int collapse = 1, tile = 0;
12694   c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
12695   if (c)
12696     collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
12697   c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
12698   if (c)
12699     tile = list_length (OMP_CLAUSE_TILE_LIST (c));
12700   c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
12701   hash_set<tree> *allocate_uids = NULL;
12702   if (c)
12703     {
12704       allocate_uids = new hash_set<tree>;
12705       for (; c; c = OMP_CLAUSE_CHAIN (c))
12706           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
12707             allocate_uids->add (OMP_CLAUSE_DECL (c));
12708     }
12709   for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
12710     {
12711       t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
12712       gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
12713       decl = TREE_OPERAND (t, 0);
12714       gcc_assert (DECL_P (decl));
12715       gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
12716                       || POINTER_TYPE_P (TREE_TYPE (decl)));
12717       if (is_doacross)
12718           {
12719             if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
12720               {
12721                 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12722                 if (TREE_CODE (orig_decl) == TREE_LIST)
12723                     {
12724                       orig_decl = TREE_PURPOSE (orig_decl);
12725                       if (!orig_decl)
12726                         orig_decl = decl;
12727                     }
12728                 gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
12729               }
12730             else
12731               gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12732             gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
12733           }
12734 
12735       if (for_stmt == orig_for_stmt)
12736           {
12737             tree orig_decl = decl;
12738             if (OMP_FOR_ORIG_DECLS (for_stmt))
12739               {
12740                 tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12741                 if (TREE_CODE (orig_decl) == TREE_LIST)
12742                     {
12743                       orig_decl = TREE_PURPOSE (orig_decl);
12744                       if (!orig_decl)
12745                         orig_decl = decl;
12746                     }
12747               }
12748             if (is_global_var (orig_decl) && DECL_THREAD_LOCAL_P (orig_decl))
12749               error_at (EXPR_LOCATION (for_stmt),
12750                           "threadprivate iteration variable %qD", orig_decl);
12751           }
12752 
12753       /* Make sure the iteration variable is private.  */
12754       tree c = NULL_TREE;
12755       tree c2 = NULL_TREE;
12756       if (orig_for_stmt != for_stmt)
12757           {
12758             /* Preserve this information until we gimplify the inner simd.  */
12759             if (has_decl_expr
12760                 && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12761               TREE_PRIVATE (t) = 1;
12762           }
12763       else if (ort == ORT_SIMD)
12764           {
12765             splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12766                                                              (splay_tree_key) decl);
12767             omp_is_private (gimplify_omp_ctxp, decl,
12768                                 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
12769                                      != 1));
12770             if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
12771               {
12772                 omp_notice_variable (gimplify_omp_ctxp, decl, true);
12773                 if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
12774                     for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12775                                                             OMP_CLAUSE_LASTPRIVATE);
12776                          c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12777                                                          OMP_CLAUSE_LASTPRIVATE))
12778                       if (OMP_CLAUSE_DECL (c3) == decl)
12779                         {
12780                           warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12781                                           "conditional %<lastprivate%> on loop "
12782                                           "iterator %qD ignored", decl);
12783                           OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12784                           n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12785                         }
12786               }
12787             else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
12788               {
12789                 c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12790                 OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
12791                 unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
12792                 if ((has_decl_expr
12793                        && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
12794                       || TREE_PRIVATE (t))
12795                     {
12796                       OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12797                       flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12798                     }
12799                 struct gimplify_omp_ctx *outer
12800                     = gimplify_omp_ctxp->outer_context;
12801                 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12802                     {
12803                       if (outer->region_type == ORT_WORKSHARE
12804                           && outer->combined_loop)
12805                         {
12806                           n = splay_tree_lookup (outer->variables,
12807                                                        (splay_tree_key)decl);
12808                           if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12809                               {
12810                                 OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12811                                 flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12812                               }
12813                           else
12814                               {
12815                                 struct gimplify_omp_ctx *octx = outer->outer_context;
12816                                 if (octx
12817                                     && octx->region_type == ORT_COMBINED_PARALLEL
12818                                     && octx->outer_context
12819                                     && (octx->outer_context->region_type
12820                                           == ORT_WORKSHARE)
12821                                     && octx->outer_context->combined_loop)
12822                                   {
12823                                     octx = octx->outer_context;
12824                                     n = splay_tree_lookup (octx->variables,
12825                                                                  (splay_tree_key)decl);
12826                                     if (n != NULL && (n->value & GOVD_LOCAL) != 0)
12827                                         {
12828                                           OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
12829                                           flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
12830                                         }
12831                                   }
12832                               }
12833                         }
12834                     }
12835 
12836                 OMP_CLAUSE_DECL (c) = decl;
12837                 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12838                 OMP_FOR_CLAUSES (for_stmt) = c;
12839                 omp_add_variable (gimplify_omp_ctxp, decl, flags);
12840                 if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
12841                     omp_lastprivate_for_combined_outer_constructs (outer, decl,
12842                                                                              true);
12843               }
12844             else
12845               {
12846                 bool lastprivate
12847                     = (!has_decl_expr
12848                        || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
12849                 if (TREE_PRIVATE (t))
12850                     lastprivate = false;
12851                 if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
12852                     {
12853                       tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
12854                       if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
12855                         lastprivate = false;
12856                     }
12857 
12858                 struct gimplify_omp_ctx *outer
12859                     = gimplify_omp_ctxp->outer_context;
12860                 if (outer && lastprivate)
12861                     omp_lastprivate_for_combined_outer_constructs (outer, decl,
12862                                                                              true);
12863 
12864                 c = build_omp_clause (input_location,
12865                                             lastprivate ? OMP_CLAUSE_LASTPRIVATE
12866                                                             : OMP_CLAUSE_PRIVATE);
12867                 OMP_CLAUSE_DECL (c) = decl;
12868                 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
12869                 OMP_FOR_CLAUSES (for_stmt) = c;
12870                 omp_add_variable (gimplify_omp_ctxp, decl,
12871                                         (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
12872                                         | GOVD_EXPLICIT | GOVD_SEEN);
12873                 c = NULL_TREE;
12874               }
12875           }
12876       else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
12877           {
12878             omp_notice_variable (gimplify_omp_ctxp, decl, true);
12879             splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
12880                                                              (splay_tree_key) decl);
12881             if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
12882               for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
12883                                                       OMP_CLAUSE_LASTPRIVATE);
12884                      c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
12885                                                      OMP_CLAUSE_LASTPRIVATE))
12886                 if (OMP_CLAUSE_DECL (c3) == decl)
12887                     {
12888                       warning_at (OMP_CLAUSE_LOCATION (c3), 0,
12889                                     "conditional %<lastprivate%> on loop "
12890                                     "iterator %qD ignored", decl);
12891                       OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
12892                       n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
12893                     }
12894           }
12895       else
12896           omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
12897 
12898       /* If DECL is not a gimple register, create a temporary variable to act
12899            as an iteration counter.  This is valid, since DECL cannot be
12900            modified in the body of the loop.  Similarly for any iteration vars
12901            in simd with collapse > 1 where the iterator vars must be
12902            lastprivate.  And similarly for vars mentioned in allocate clauses.  */
12903       if (orig_for_stmt != for_stmt)
12904           var = decl;
12905       else if (!is_gimple_reg (decl)
12906                  || (ort == ORT_SIMD
12907                        && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
12908                  || (allocate_uids && allocate_uids->contains (decl)))
12909           {
12910             struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
12911             /* Make sure omp_add_variable is not called on it prematurely.
12912                We call it ourselves a few lines later.  */
12913             gimplify_omp_ctxp = NULL;
12914             var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
12915             gimplify_omp_ctxp = ctx;
12916             TREE_OPERAND (t, 0) = var;
12917 
12918             gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
12919 
12920             if (ort == ORT_SIMD
12921                 && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
12922               {
12923                 c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
12924                 OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
12925                 OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
12926                 OMP_CLAUSE_DECL (c2) = var;
12927                 OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
12928                 OMP_FOR_CLAUSES (for_stmt) = c2;
12929                 omp_add_variable (gimplify_omp_ctxp, var,
12930                                         GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
12931                 if (c == NULL_TREE)
12932                     {
12933                       c = c2;
12934                       c2 = NULL_TREE;
12935                     }
12936               }
12937             else
12938               omp_add_variable (gimplify_omp_ctxp, var,
12939                                     GOVD_PRIVATE | GOVD_SEEN);
12940           }
12941       else
12942           var = decl;
12943 
12944       gimplify_omp_ctxp->in_for_exprs = true;
12945       if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12946           {
12947             tree lb = TREE_OPERAND (t, 1);
12948             tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
12949                                         is_gimple_val, fb_rvalue, false);
12950             ret = MIN (ret, tret);
12951             tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
12952                                         is_gimple_val, fb_rvalue, false);
12953           }
12954       else
12955           tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12956                                     is_gimple_val, fb_rvalue, false);
12957       gimplify_omp_ctxp->in_for_exprs = false;
12958       ret = MIN (ret, tret);
12959       if (ret == GS_ERROR)
12960           return ret;
12961 
12962       /* Handle OMP_FOR_COND.  */
12963       t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
12964       gcc_assert (COMPARISON_CLASS_P (t));
12965       gcc_assert (TREE_OPERAND (t, 0) == decl);
12966 
12967       gimplify_omp_ctxp->in_for_exprs = true;
12968       if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
12969           {
12970             tree ub = TREE_OPERAND (t, 1);
12971             tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
12972                                         is_gimple_val, fb_rvalue, false);
12973             ret = MIN (ret, tret);
12974             tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
12975                                         is_gimple_val, fb_rvalue, false);
12976           }
12977       else
12978           tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
12979                                     is_gimple_val, fb_rvalue, false);
12980       gimplify_omp_ctxp->in_for_exprs = false;
12981       ret = MIN (ret, tret);
12982 
12983       /* Handle OMP_FOR_INCR.  */
12984       t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
12985       switch (TREE_CODE (t))
12986           {
12987           case PREINCREMENT_EXPR:
12988           case POSTINCREMENT_EXPR:
12989             {
12990               tree decl = TREE_OPERAND (t, 0);
12991               /* c_omp_for_incr_canonicalize_ptr() should have been
12992                  called to massage things appropriately.  */
12993               gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
12994 
12995               if (orig_for_stmt != for_stmt)
12996                 break;
12997               t = build_int_cst (TREE_TYPE (decl), 1);
12998               if (c)
12999                 OMP_CLAUSE_LINEAR_STEP (c) = t;
13000               t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
13001               t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
13002               TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
13003               break;
13004             }
13005 
13006           case PREDECREMENT_EXPR:
13007           case POSTDECREMENT_EXPR:
13008             /* c_omp_for_incr_canonicalize_ptr() should have been
13009                called to massage things appropriately.  */
13010             gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
13011             if (orig_for_stmt != for_stmt)
13012               break;
13013             t = build_int_cst (TREE_TYPE (decl), -1);
13014             if (c)
13015               OMP_CLAUSE_LINEAR_STEP (c) = t;
13016             t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
13017             t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
13018             TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
13019             break;
13020 
13021           case MODIFY_EXPR:
13022             gcc_assert (TREE_OPERAND (t, 0) == decl);
13023             TREE_OPERAND (t, 0) = var;
13024 
13025             t = TREE_OPERAND (t, 1);
13026             switch (TREE_CODE (t))
13027               {
13028               case PLUS_EXPR:
13029                 if (TREE_OPERAND (t, 1) == decl)
13030                     {
13031                       TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
13032                       TREE_OPERAND (t, 0) = var;
13033                       break;
13034                     }
13035 
13036                 /* Fallthru.  */
13037               case MINUS_EXPR:
13038               case POINTER_PLUS_EXPR:
13039                 gcc_assert (TREE_OPERAND (t, 0) == decl);
13040                 TREE_OPERAND (t, 0) = var;
13041                 break;
13042               default:
13043                 gcc_unreachable ();
13044               }
13045 
13046             gimplify_omp_ctxp->in_for_exprs = true;
13047             tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
13048                                         is_gimple_val, fb_rvalue, false);
13049             ret = MIN (ret, tret);
13050             if (c)
13051               {
13052                 tree step = TREE_OPERAND (t, 1);
13053                 tree stept = TREE_TYPE (decl);
13054                 if (POINTER_TYPE_P (stept))
13055                     stept = sizetype;
13056                 step = fold_convert (stept, step);
13057                 if (TREE_CODE (t) == MINUS_EXPR)
13058                     step = fold_build1 (NEGATE_EXPR, stept, step);
13059                 OMP_CLAUSE_LINEAR_STEP (c) = step;
13060                 if (step != TREE_OPERAND (t, 1))
13061                     {
13062                       tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
13063                                                   &for_pre_body, NULL,
13064                                                   is_gimple_val, fb_rvalue, false);
13065                       ret = MIN (ret, tret);
13066                     }
13067               }
13068             gimplify_omp_ctxp->in_for_exprs = false;
13069             break;
13070 
13071           default:
13072             gcc_unreachable ();
13073           }
13074 
13075       if (c2)
13076           {
13077             gcc_assert (c);
13078             OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
13079           }
13080 
13081       if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
13082           {
13083             for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
13084               if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13085                       && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
13086                      || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
13087                          && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
13088                          && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
13089                     && OMP_CLAUSE_DECL (c) == decl)
13090                 {
13091                     if (is_doacross && (collapse == 1 || i >= collapse))
13092                       t = var;
13093                     else
13094                       {
13095                         t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
13096                         gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13097                         gcc_assert (TREE_OPERAND (t, 0) == var);
13098                         t = TREE_OPERAND (t, 1);
13099                         gcc_assert (TREE_CODE (t) == PLUS_EXPR
13100                                         || TREE_CODE (t) == MINUS_EXPR
13101                                         || TREE_CODE (t) == POINTER_PLUS_EXPR);
13102                         gcc_assert (TREE_OPERAND (t, 0) == var);
13103                         t = build2 (TREE_CODE (t), TREE_TYPE (decl),
13104                                         is_doacross ? var : decl,
13105                                         TREE_OPERAND (t, 1));
13106                       }
13107                     gimple_seq *seq;
13108                     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
13109                       seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
13110                     else
13111                       seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
13112                     push_gimplify_context ();
13113                     gimplify_assign (decl, t, seq);
13114                     gimple *bind = NULL;
13115                     if (gimplify_ctxp->temps)
13116                       {
13117                         bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
13118                         *seq = NULL;
13119                         gimplify_seq_add_stmt (seq, bind);
13120                       }
13121                     pop_gimplify_context (bind);
13122                 }
13123           }
13124       if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
13125           for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
13126             {
13127               t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
13128               gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13129               if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13130                     && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13131                 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13132               t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
13133               gcc_assert (COMPARISON_CLASS_P (t));
13134               if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13135                     && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13136                 TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13137             }
13138     }
13139 
13140   BITMAP_FREE (has_decl_expr);
13141   delete allocate_uids;
13142 
13143   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
13144       || (loop_p && orig_for_stmt == for_stmt))
13145     {
13146       push_gimplify_context ();
13147       if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
13148           {
13149             OMP_FOR_BODY (orig_for_stmt)
13150               = build3 (BIND_EXPR, void_type_node, NULL,
13151                           OMP_FOR_BODY (orig_for_stmt), NULL);
13152             TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
13153           }
13154     }
13155 
13156   gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
13157                                                    &for_body);
13158 
13159   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
13160       || (loop_p && orig_for_stmt == for_stmt))
13161     {
13162       if (gimple_code (g) == GIMPLE_BIND)
13163           pop_gimplify_context (g);
13164       else
13165           pop_gimplify_context (NULL);
13166     }
13167 
13168   if (orig_for_stmt != for_stmt)
13169     for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13170       {
13171           t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13172           decl = TREE_OPERAND (t, 0);
13173           struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13174           if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
13175             gimplify_omp_ctxp = ctx->outer_context;
13176           var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
13177           gimplify_omp_ctxp = ctx;
13178           omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
13179           TREE_OPERAND (t, 0) = var;
13180           t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
13181           TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13182           TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
13183           if (OMP_FOR_NON_RECTANGULAR (for_stmt))
13184             for (int j = i + 1;
13185                  j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
13186               {
13187                 t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
13188                 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13189                 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13190                       && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13191                     {
13192                       TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13193                       TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13194                     }
13195                 t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
13196                 gcc_assert (COMPARISON_CLASS_P (t));
13197                 if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
13198                       && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
13199                     {
13200                       TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
13201                       TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
13202                     }
13203             }
13204       }
13205 
13206   gimplify_adjust_omp_clauses (pre_p, for_body,
13207                                      &OMP_FOR_CLAUSES (orig_for_stmt),
13208                                      TREE_CODE (orig_for_stmt));
13209 
13210   int kind;
13211   switch (TREE_CODE (orig_for_stmt))
13212     {
13213     case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
13214     case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
13215     case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
13216     case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
13217     case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
13218     default:
13219       gcc_unreachable ();
13220     }
13221   if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
13222     {
13223       gimplify_seq_add_seq (pre_p, for_pre_body);
13224       for_pre_body = NULL;
13225     }
13226   gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
13227                                      TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
13228                                      for_pre_body);
13229   if (orig_for_stmt != for_stmt)
13230     gimple_omp_for_set_combined_p (gfor, true);
13231   if (gimplify_omp_ctxp
13232       && (gimplify_omp_ctxp->combined_loop
13233             || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
13234                 && gimplify_omp_ctxp->outer_context
13235                 && gimplify_omp_ctxp->outer_context->combined_loop)))
13236     {
13237       gimple_omp_for_set_combined_into_p (gfor, true);
13238       if (gimplify_omp_ctxp->combined_loop)
13239           gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
13240       else
13241           gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
13242     }
13243 
13244   for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13245     {
13246       t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13247       gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
13248       gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
13249       t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
13250       gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
13251       gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
13252       t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
13253       gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
13254     }
13255 
13256   /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
13257      constructs with GIMPLE_OMP_TASK sandwiched in between them.
13258      The outer taskloop stands for computing the number of iterations,
13259      counts for collapsed loops and holding taskloop specific clauses.
13260      The task construct stands for the effect of data sharing on the
13261      explicit task it creates and the inner taskloop stands for expansion
13262      of the static loop inside of the explicit task construct.  */
13263   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
13264     {
13265       tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
13266       tree task_clauses = NULL_TREE;
13267       tree c = *gfor_clauses_ptr;
13268       tree *gtask_clauses_ptr = &task_clauses;
13269       tree outer_for_clauses = NULL_TREE;
13270       tree *gforo_clauses_ptr = &outer_for_clauses;
13271       bitmap lastprivate_uids = NULL;
13272       if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
13273           {
13274             c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
13275             if (c)
13276               {
13277                 lastprivate_uids = BITMAP_ALLOC (NULL);
13278                 for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
13279                                                        OMP_CLAUSE_LASTPRIVATE))
13280                     bitmap_set_bit (lastprivate_uids,
13281                                         DECL_UID (OMP_CLAUSE_DECL (c)));
13282               }
13283             c = *gfor_clauses_ptr;
13284           }
13285       for (; c; c = OMP_CLAUSE_CHAIN (c))
13286           switch (OMP_CLAUSE_CODE (c))
13287             {
13288             /* These clauses are allowed on task, move them there.  */
13289             case OMP_CLAUSE_SHARED:
13290             case OMP_CLAUSE_FIRSTPRIVATE:
13291             case OMP_CLAUSE_DEFAULT:
13292             case OMP_CLAUSE_IF:
13293             case OMP_CLAUSE_UNTIED:
13294             case OMP_CLAUSE_FINAL:
13295             case OMP_CLAUSE_MERGEABLE:
13296             case OMP_CLAUSE_PRIORITY:
13297             case OMP_CLAUSE_REDUCTION:
13298             case OMP_CLAUSE_IN_REDUCTION:
13299               *gtask_clauses_ptr = c;
13300               gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13301               break;
13302             case OMP_CLAUSE_PRIVATE:
13303               if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
13304                 {
13305                     /* We want private on outer for and firstprivate
13306                        on task.  */
13307                     *gtask_clauses_ptr
13308                       = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13309                                               OMP_CLAUSE_FIRSTPRIVATE);
13310                     OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13311                     lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
13312                                                                 openacc);
13313                     gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13314                     *gforo_clauses_ptr = c;
13315                     gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13316                 }
13317               else
13318                 {
13319                     *gtask_clauses_ptr = c;
13320                     gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13321                 }
13322               break;
13323             /* These clauses go into outer taskloop clauses.  */
13324             case OMP_CLAUSE_GRAINSIZE:
13325             case OMP_CLAUSE_NUM_TASKS:
13326             case OMP_CLAUSE_NOGROUP:
13327               *gforo_clauses_ptr = c;
13328               gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13329               break;
13330             /* Collapse clause we duplicate on both taskloops.  */
13331             case OMP_CLAUSE_COLLAPSE:
13332               *gfor_clauses_ptr = c;
13333               gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13334               *gforo_clauses_ptr = copy_node (c);
13335               gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
13336               break;
13337             /* For lastprivate, keep the clause on inner taskloop, and add
13338                a shared clause on task.  If the same decl is also firstprivate,
13339                add also firstprivate clause on the inner taskloop.  */
13340             case OMP_CLAUSE_LASTPRIVATE:
13341               if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
13342                 {
13343                     /* For taskloop C++ lastprivate IVs, we want:
13344                        1) private on outer taskloop
13345                        2) firstprivate and shared on task
13346                        3) lastprivate on inner taskloop  */
13347                     *gtask_clauses_ptr
13348                       = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13349                                               OMP_CLAUSE_FIRSTPRIVATE);
13350                     OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13351                     lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
13352                                                                 openacc);
13353                     gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13354                     OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
13355                     *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13356                                                                    OMP_CLAUSE_PRIVATE);
13357                     OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
13358                     OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
13359                     TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
13360                     gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
13361                 }
13362               *gfor_clauses_ptr = c;
13363               gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13364               *gtask_clauses_ptr
13365                 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
13366               OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
13367               if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
13368                 OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
13369               gtask_clauses_ptr
13370                 = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13371               break;
13372             /* Allocate clause we duplicate on task and inner taskloop
13373                if the decl is lastprivate, otherwise just put on task.  */
13374             case OMP_CLAUSE_ALLOCATE:
13375               if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
13376                     && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
13377                 {
13378                     /* Additionally, put firstprivate clause on task
13379                        for the allocator if it is not constant.  */
13380                     *gtask_clauses_ptr
13381                       = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13382                                               OMP_CLAUSE_FIRSTPRIVATE);
13383                     OMP_CLAUSE_DECL (*gtask_clauses_ptr)
13384                       = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
13385                     gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13386                 }
13387               if (lastprivate_uids
13388                     && bitmap_bit_p (lastprivate_uids,
13389                                          DECL_UID (OMP_CLAUSE_DECL (c))))
13390                 {
13391                     *gfor_clauses_ptr = c;
13392                     gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13393                     *gtask_clauses_ptr = copy_node (c);
13394                     gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
13395                 }
13396               else
13397                 {
13398                     *gtask_clauses_ptr = c;
13399                     gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
13400                 }
13401               break;
13402             default:
13403               gcc_unreachable ();
13404             }
13405       *gfor_clauses_ptr = NULL_TREE;
13406       *gtask_clauses_ptr = NULL_TREE;
13407       *gforo_clauses_ptr = NULL_TREE;
13408       BITMAP_FREE (lastprivate_uids);
13409       gimple_set_location (gfor, input_location);
13410       g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
13411       g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
13412                                          NULL_TREE, NULL_TREE, NULL_TREE);
13413       gimple_set_location (g, input_location);
13414       gimple_omp_task_set_taskloop_p (g, true);
13415       g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
13416       gomp_for *gforo
13417           = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
13418                                         gimple_omp_for_collapse (gfor),
13419                                         gimple_omp_for_pre_body (gfor));
13420       gimple_omp_for_set_pre_body (gfor, NULL);
13421       gimple_omp_for_set_combined_p (gforo, true);
13422       gimple_omp_for_set_combined_into_p (gfor, true);
13423       for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
13424           {
13425             tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
13426             tree v = create_tmp_var (type);
13427             gimple_omp_for_set_index (gforo, i, v);
13428             t = unshare_expr (gimple_omp_for_initial (gfor, i));
13429             gimple_omp_for_set_initial (gforo, i, t);
13430             gimple_omp_for_set_cond (gforo, i,
13431                                            gimple_omp_for_cond (gfor, i));
13432             t = unshare_expr (gimple_omp_for_final (gfor, i));
13433             gimple_omp_for_set_final (gforo, i, t);
13434             t = unshare_expr (gimple_omp_for_incr (gfor, i));
13435             gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
13436             TREE_OPERAND (t, 0) = v;
13437             gimple_omp_for_set_incr (gforo, i, t);
13438             t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
13439             OMP_CLAUSE_DECL (t) = v;
13440             OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
13441             gimple_omp_for_set_clauses (gforo, t);
13442             if (OMP_FOR_NON_RECTANGULAR (for_stmt))
13443               {
13444                 tree *p1 = NULL, *p2 = NULL;
13445                 t = gimple_omp_for_initial (gforo, i);
13446                 if (TREE_CODE (t) == TREE_VEC)
13447                     p1 = &TREE_VEC_ELT (t, 0);
13448                 t = gimple_omp_for_final (gforo, i);
13449                 if (TREE_CODE (t) == TREE_VEC)
13450                     {
13451                       if (p1)
13452                         p2 = &TREE_VEC_ELT (t, 0);
13453                       else
13454                         p1 = &TREE_VEC_ELT (t, 0);
13455                     }
13456                 if (p1)
13457                     {
13458                       int j;
13459                       for (j = 0; j < i; j++)
13460                         if (*p1 == gimple_omp_for_index (gfor, j))
13461                           {
13462                               *p1 = gimple_omp_for_index (gforo, j);
13463                               if (p2)
13464                                 *p2 = *p1;
13465                               break;
13466                           }
13467                       gcc_assert (j < i);
13468                     }
13469               }
13470           }
13471       gimplify_seq_add_stmt (pre_p, gforo);
13472     }
13473   else
13474     gimplify_seq_add_stmt (pre_p, gfor);
13475 
13476   if (TREE_CODE (orig_for_stmt) == OMP_FOR)
13477     {
13478       struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
13479       unsigned lastprivate_conditional = 0;
13480       while (ctx
13481                && (ctx->region_type == ORT_TARGET_DATA
13482                      || ctx->region_type == ORT_TASKGROUP))
13483           ctx = ctx->outer_context;
13484       if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
13485           for (tree c = gimple_omp_for_clauses (gfor);
13486                c; c = OMP_CLAUSE_CHAIN (c))
13487             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13488                 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13489               ++lastprivate_conditional;
13490       if (lastprivate_conditional)
13491           {
13492             struct omp_for_data fd;
13493             omp_extract_for_data (gfor, &fd, NULL);
13494             tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
13495                                                         lastprivate_conditional);
13496             tree var = create_tmp_var_raw (type);
13497             tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
13498             OMP_CLAUSE_DECL (c) = var;
13499             OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13500             gimple_omp_for_set_clauses (gfor, c);
13501             omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
13502           }
13503     }
13504   else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
13505     {
13506       unsigned lastprivate_conditional = 0;
13507       for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
13508           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
13509               && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
13510             ++lastprivate_conditional;
13511       if (lastprivate_conditional)
13512           {
13513             struct omp_for_data fd;
13514             omp_extract_for_data (gfor, &fd, NULL);
13515             tree type = unsigned_type_for (fd.iter_type);
13516             while (lastprivate_conditional--)
13517               {
13518                 tree c = build_omp_clause (UNKNOWN_LOCATION,
13519                                                    OMP_CLAUSE__CONDTEMP_);
13520                 OMP_CLAUSE_DECL (c) = create_tmp_var (type);
13521                 OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
13522                 gimple_omp_for_set_clauses (gfor, c);
13523               }
13524           }
13525     }
13526 
13527   if (ret != GS_ALL_DONE)
13528     return GS_ERROR;
13529   *expr_p = NULL_TREE;
13530   return GS_ALL_DONE;
13531 }
13532 
13533 /* Helper for gimplify_omp_loop, called through walk_tree.  */
13534 
13535 static tree
note_no_context_vars(tree * tp,int *,void * data)13536 note_no_context_vars (tree *tp, int *, void *data)
13537 {
13538   if (VAR_P (*tp)
13539       && DECL_CONTEXT (*tp) == NULL_TREE
13540       && !is_global_var (*tp))
13541     {
13542       vec<tree> *d = (vec<tree> *) data;
13543       d->safe_push (*tp);
13544       DECL_CONTEXT (*tp) = current_function_decl;
13545     }
13546   return NULL_TREE;
13547 }
13548 
13549 /* Gimplify the gross structure of an OMP_LOOP statement.  */
13550 
13551 static enum gimplify_status
gimplify_omp_loop(tree * expr_p,gimple_seq * pre_p)13552 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
13553 {
13554   tree for_stmt = *expr_p;
13555   tree clauses = OMP_FOR_CLAUSES (for_stmt);
13556   struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
13557   enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
13558   int i;
13559 
13560   /* If order is not present, the behavior is as if order(concurrent)
13561      appeared.  */
13562   tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
13563   if (order == NULL_TREE)
13564     {
13565       order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
13566       OMP_CLAUSE_CHAIN (order) = clauses;
13567       OMP_FOR_CLAUSES (for_stmt) = clauses = order;
13568     }
13569 
13570   tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
13571   if (bind == NULL_TREE)
13572     {
13573       if (!flag_openmp) /* flag_openmp_simd */
13574           ;
13575       else if (octx && (octx->region_type & ORT_TEAMS) != 0)
13576           kind = OMP_CLAUSE_BIND_TEAMS;
13577       else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
13578           kind = OMP_CLAUSE_BIND_PARALLEL;
13579       else
13580           {
13581             for (; octx; octx = octx->outer_context)
13582               {
13583                 if ((octx->region_type & ORT_ACC) != 0
13584                       || octx->region_type == ORT_NONE
13585                       || octx->region_type == ORT_IMPLICIT_TARGET)
13586                     continue;
13587                 break;
13588               }
13589             if (octx == NULL && !in_omp_construct)
13590               error_at (EXPR_LOCATION (for_stmt),
13591                           "%<bind%> clause not specified on a %<loop%> "
13592                           "construct not nested inside another OpenMP construct");
13593           }
13594       bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
13595       OMP_CLAUSE_CHAIN (bind) = clauses;
13596       OMP_CLAUSE_BIND_KIND (bind) = kind;
13597       OMP_FOR_CLAUSES (for_stmt) = bind;
13598     }
13599   else
13600     switch (OMP_CLAUSE_BIND_KIND (bind))
13601       {
13602       case OMP_CLAUSE_BIND_THREAD:
13603           break;
13604       case OMP_CLAUSE_BIND_PARALLEL:
13605           if (!flag_openmp) /* flag_openmp_simd */
13606             {
13607               OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13608               break;
13609             }
13610           for (; octx; octx = octx->outer_context)
13611             if (octx->region_type == ORT_SIMD
13612                 && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
13613               {
13614                 error_at (EXPR_LOCATION (for_stmt),
13615                               "%<bind(parallel)%> on a %<loop%> construct nested "
13616                               "inside %<simd%> construct");
13617                 OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13618                 break;
13619               }
13620           kind = OMP_CLAUSE_BIND_PARALLEL;
13621           break;
13622       case OMP_CLAUSE_BIND_TEAMS:
13623           if (!flag_openmp) /* flag_openmp_simd */
13624             {
13625               OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13626               break;
13627             }
13628           if ((octx
13629                && octx->region_type != ORT_IMPLICIT_TARGET
13630                && octx->region_type != ORT_NONE
13631                && (octx->region_type & ORT_TEAMS) == 0)
13632               || in_omp_construct)
13633             {
13634               error_at (EXPR_LOCATION (for_stmt),
13635                           "%<bind(teams)%> on a %<loop%> region not strictly "
13636                           "nested inside of a %<teams%> region");
13637               OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
13638               break;
13639             }
13640           kind = OMP_CLAUSE_BIND_TEAMS;
13641           break;
13642       default:
13643           gcc_unreachable ();
13644       }
13645 
13646   for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
13647     switch (OMP_CLAUSE_CODE (*pc))
13648       {
13649       case OMP_CLAUSE_REDUCTION:
13650           if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
13651             {
13652               error_at (OMP_CLAUSE_LOCATION (*pc),
13653                           "%<inscan%> %<reduction%> clause on "
13654                           "%qs construct", "loop");
13655               OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
13656             }
13657           if (OMP_CLAUSE_REDUCTION_TASK (*pc))
13658             {
13659               error_at (OMP_CLAUSE_LOCATION (*pc),
13660                           "invalid %<task%> reduction modifier on construct "
13661                           "other than %<parallel%>, %qs or %<sections%>",
13662                           lang_GNU_Fortran () ? "do" : "for");
13663               OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
13664             }
13665           pc = &OMP_CLAUSE_CHAIN (*pc);
13666           break;
13667       case OMP_CLAUSE_LASTPRIVATE:
13668           for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13669             {
13670               tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
13671               gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
13672               if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
13673                 break;
13674               if (OMP_FOR_ORIG_DECLS (for_stmt)
13675                     && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13676                                                       i)) == TREE_LIST
13677                     && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
13678                                                          i)))
13679                 {
13680                     tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13681                     if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
13682                       break;
13683                 }
13684             }
13685           if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
13686             {
13687               error_at (OMP_CLAUSE_LOCATION (*pc),
13688                           "%<lastprivate%> clause on a %<loop%> construct refers "
13689                           "to a variable %qD which is not the loop iterator",
13690                           OMP_CLAUSE_DECL (*pc));
13691               *pc = OMP_CLAUSE_CHAIN (*pc);
13692               break;
13693             }
13694           pc = &OMP_CLAUSE_CHAIN (*pc);
13695           break;
13696       default:
13697           pc = &OMP_CLAUSE_CHAIN (*pc);
13698           break;
13699     }
13700 
13701   TREE_SET_CODE (for_stmt, OMP_SIMD);
13702 
13703   int last;
13704   switch (kind)
13705     {
13706     case OMP_CLAUSE_BIND_THREAD: last = 0; break;
13707     case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
13708     case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
13709     }
13710   for (int pass = 1; pass <= last; pass++)
13711     {
13712       if (pass == 2)
13713           {
13714             tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
13715                                     make_node (BLOCK));
13716             append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
13717             *expr_p = make_node (OMP_PARALLEL);
13718             TREE_TYPE (*expr_p) = void_type_node;
13719             OMP_PARALLEL_BODY (*expr_p) = bind;
13720             OMP_PARALLEL_COMBINED (*expr_p) = 1;
13721             SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
13722             tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
13723             for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
13724               if (OMP_FOR_ORIG_DECLS (for_stmt)
13725                     && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
13726                         == TREE_LIST))
13727                 {
13728                     tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
13729                     if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
13730                       {
13731                         *pc = build_omp_clause (UNKNOWN_LOCATION,
13732                                                       OMP_CLAUSE_FIRSTPRIVATE);
13733                         OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
13734                         pc = &OMP_CLAUSE_CHAIN (*pc);
13735                       }
13736                 }
13737           }
13738       tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
13739       tree *pc = &OMP_FOR_CLAUSES (t);
13740       TREE_TYPE (t) = void_type_node;
13741       OMP_FOR_BODY (t) = *expr_p;
13742       SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
13743       for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
13744           switch (OMP_CLAUSE_CODE (c))
13745             {
13746             case OMP_CLAUSE_BIND:
13747             case OMP_CLAUSE_ORDER:
13748             case OMP_CLAUSE_COLLAPSE:
13749               *pc = copy_node (c);
13750               pc = &OMP_CLAUSE_CHAIN (*pc);
13751               break;
13752             case OMP_CLAUSE_PRIVATE:
13753             case OMP_CLAUSE_FIRSTPRIVATE:
13754               /* Only needed on innermost.  */
13755               break;
13756             case OMP_CLAUSE_LASTPRIVATE:
13757               if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
13758                 {
13759                     *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
13760                                                   OMP_CLAUSE_FIRSTPRIVATE);
13761                     OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
13762                     lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13763                     pc = &OMP_CLAUSE_CHAIN (*pc);
13764                 }
13765               *pc = copy_node (c);
13766               OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
13767               TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13768               if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
13769                 {
13770                     if (pass != last)
13771                       OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
13772                     else
13773                       lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
13774                     OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
13775                 }
13776               pc = &OMP_CLAUSE_CHAIN (*pc);
13777               break;
13778             case OMP_CLAUSE_REDUCTION:
13779               *pc = copy_node (c);
13780               OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
13781               TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
13782               if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
13783                 {
13784                     auto_vec<tree> no_context_vars;
13785                     int walk_subtrees = 0;
13786                     note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13787                                               &walk_subtrees, &no_context_vars);
13788                     if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c))
13789                       note_no_context_vars (&p, &walk_subtrees, &no_context_vars);
13790                     walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c),
13791                                                         note_no_context_vars,
13792                                                         &no_context_vars);
13793                     walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c),
13794                                                         note_no_context_vars,
13795                                                         &no_context_vars);
13796 
13797                     OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
13798                       = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
13799                     if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13800                       OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
13801                         = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
13802 
13803                     hash_map<tree, tree> decl_map;
13804                     decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c));
13805                     decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
13806                                     OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc));
13807                     if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
13808                       decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
13809                                         OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc));
13810 
13811                     copy_body_data id;
13812                     memset (&id, 0, sizeof (id));
13813                     id.src_fn = current_function_decl;
13814                     id.dst_fn = current_function_decl;
13815                     id.src_cfun = cfun;
13816                     id.decl_map = &decl_map;
13817                     id.copy_decl = copy_decl_no_change;
13818                     id.transform_call_graph_edges = CB_CGE_DUPLICATE;
13819                     id.transform_new_cfg = true;
13820                     id.transform_return_to_modify = false;
13821                     id.eh_lp_nr = 0;
13822                     walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r,
13823                                  &id, NULL);
13824                     walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r,
13825                                  &id, NULL);
13826 
13827                     for (tree d : no_context_vars)
13828                       {
13829                         DECL_CONTEXT (d) = NULL_TREE;
13830                         DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE;
13831                       }
13832                 }
13833               else
13834                 {
13835                     OMP_CLAUSE_REDUCTION_INIT (*pc)
13836                       = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
13837                     OMP_CLAUSE_REDUCTION_MERGE (*pc)
13838                       = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
13839                 }
13840               pc = &OMP_CLAUSE_CHAIN (*pc);
13841               break;
13842             default:
13843               gcc_unreachable ();
13844             }
13845       *pc = NULL_TREE;
13846       *expr_p = t;
13847     }
13848   return gimplify_expr (expr_p, pre_p, NULL, is_gimple_stmt, fb_none);
13849 }
13850 
13851 
13852 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
13853    of OMP_TARGET's body.  */
13854 
13855 static tree
find_omp_teams(tree * tp,int * walk_subtrees,void *)13856 find_omp_teams (tree *tp, int *walk_subtrees, void *)
13857 {
13858   *walk_subtrees = 0;
13859   switch (TREE_CODE (*tp))
13860     {
13861     case OMP_TEAMS:
13862       return *tp;
13863     case BIND_EXPR:
13864     case STATEMENT_LIST:
13865       *walk_subtrees = 1;
13866       break;
13867     default:
13868       break;
13869     }
13870   return NULL_TREE;
13871 }
13872 
13873 /* Helper function of optimize_target_teams, determine if the expression
13874    can be computed safely before the target construct on the host.  */
13875 
13876 static tree
computable_teams_clause(tree * tp,int * walk_subtrees,void *)13877 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
13878 {
13879   splay_tree_node n;
13880 
13881   if (TYPE_P (*tp))
13882     {
13883       *walk_subtrees = 0;
13884       return NULL_TREE;
13885     }
13886   switch (TREE_CODE (*tp))
13887     {
13888     case VAR_DECL:
13889     case PARM_DECL:
13890     case RESULT_DECL:
13891       *walk_subtrees = 0;
13892       if (error_operand_p (*tp)
13893             || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
13894             || DECL_HAS_VALUE_EXPR_P (*tp)
13895             || DECL_THREAD_LOCAL_P (*tp)
13896             || TREE_SIDE_EFFECTS (*tp)
13897             || TREE_THIS_VOLATILE (*tp))
13898           return *tp;
13899       if (is_global_var (*tp)
13900             && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
13901                 || lookup_attribute ("omp declare target link",
13902                                            DECL_ATTRIBUTES (*tp))))
13903           return *tp;
13904       if (VAR_P (*tp)
13905             && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
13906             && !is_global_var (*tp)
13907             && decl_function_context (*tp) == current_function_decl)
13908           return *tp;
13909       n = splay_tree_lookup (gimplify_omp_ctxp->variables,
13910                                    (splay_tree_key) *tp);
13911       if (n == NULL)
13912           {
13913             if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
13914               return NULL_TREE;
13915             return *tp;
13916           }
13917       else if (n->value & GOVD_LOCAL)
13918           return *tp;
13919       else if (n->value & GOVD_FIRSTPRIVATE)
13920           return NULL_TREE;
13921       else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13922                  == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
13923           return NULL_TREE;
13924       return *tp;
13925     case INTEGER_CST:
13926       if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13927           return *tp;
13928       return NULL_TREE;
13929     case TARGET_EXPR:
13930       if (TARGET_EXPR_INITIAL (*tp)
13931             || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
13932           return *tp;
13933       return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
13934                                               walk_subtrees, NULL);
13935     /* Allow some reasonable subset of integral arithmetics.  */
13936     case PLUS_EXPR:
13937     case MINUS_EXPR:
13938     case MULT_EXPR:
13939     case TRUNC_DIV_EXPR:
13940     case CEIL_DIV_EXPR:
13941     case FLOOR_DIV_EXPR:
13942     case ROUND_DIV_EXPR:
13943     case TRUNC_MOD_EXPR:
13944     case CEIL_MOD_EXPR:
13945     case FLOOR_MOD_EXPR:
13946     case ROUND_MOD_EXPR:
13947     case RDIV_EXPR:
13948     case EXACT_DIV_EXPR:
13949     case MIN_EXPR:
13950     case MAX_EXPR:
13951     case LSHIFT_EXPR:
13952     case RSHIFT_EXPR:
13953     case BIT_IOR_EXPR:
13954     case BIT_XOR_EXPR:
13955     case BIT_AND_EXPR:
13956     case NEGATE_EXPR:
13957     case ABS_EXPR:
13958     case BIT_NOT_EXPR:
13959     case NON_LVALUE_EXPR:
13960     CASE_CONVERT:
13961       if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
13962           return *tp;
13963       return NULL_TREE;
13964     /* And disallow anything else, except for comparisons.  */
13965     default:
13966       if (COMPARISON_CLASS_P (*tp))
13967           return NULL_TREE;
13968       return *tp;
13969     }
13970 }
13971 
13972 /* Try to determine if the num_teams and/or thread_limit expressions
13973    can have their values determined already before entering the
13974    target construct.
13975    INTEGER_CSTs trivially are,
13976    integral decls that are firstprivate (explicitly or implicitly)
13977    or explicitly map(always, to:) or map(always, tofrom:) on the target
13978    region too, and expressions involving simple arithmetics on those
13979    too, function calls are not ok, dereferencing something neither etc.
13980    Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
13981    EXPR based on what we find:
13982    0 stands for clause not specified at all, use implementation default
13983    -1 stands for value that can't be determined easily before entering
13984       the target construct.
13985    If teams construct is not present at all, use 1 for num_teams
13986    and 0 for thread_limit (only one team is involved, and the thread
13987    limit is implementation defined.  */
13988 
13989 static void
optimize_target_teams(tree target,gimple_seq * pre_p)13990 optimize_target_teams (tree target, gimple_seq *pre_p)
13991 {
13992   tree body = OMP_BODY (target);
13993   tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
13994   tree num_teams_lower = NULL_TREE;
13995   tree num_teams_upper = integer_zero_node;
13996   tree thread_limit = integer_zero_node;
13997   location_t num_teams_loc = EXPR_LOCATION (target);
13998   location_t thread_limit_loc = EXPR_LOCATION (target);
13999   tree c, *p, expr;
14000   struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
14001 
14002   if (teams == NULL_TREE)
14003     num_teams_upper = integer_one_node;
14004   else
14005     for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
14006       {
14007           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
14008             {
14009               p = &num_teams_upper;
14010               num_teams_loc = OMP_CLAUSE_LOCATION (c);
14011               if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))
14012                 {
14013                     expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
14014                     if (TREE_CODE (expr) == INTEGER_CST)
14015                       num_teams_lower = expr;
14016                     else if (walk_tree (&expr, computable_teams_clause,
14017                                             NULL, NULL))
14018                       num_teams_lower = integer_minus_one_node;
14019                     else
14020                       {
14021                         num_teams_lower = expr;
14022                         gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
14023                         if (gimplify_expr (&num_teams_lower, pre_p, NULL,
14024                                                is_gimple_val, fb_rvalue, false)
14025                               == GS_ERROR)
14026                           {
14027                               gimplify_omp_ctxp = target_ctx;
14028                               num_teams_lower = integer_minus_one_node;
14029                           }
14030                         else
14031                           {
14032                               gimplify_omp_ctxp = target_ctx;
14033                               if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
14034                                 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
14035                                   = num_teams_lower;
14036                           }
14037                       }
14038                 }
14039             }
14040           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
14041             {
14042               p = &thread_limit;
14043               thread_limit_loc = OMP_CLAUSE_LOCATION (c);
14044             }
14045           else
14046             continue;
14047           expr = OMP_CLAUSE_OPERAND (c, 0);
14048           if (TREE_CODE (expr) == INTEGER_CST)
14049             {
14050               *p = expr;
14051               continue;
14052             }
14053           if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
14054             {
14055               *p = integer_minus_one_node;
14056               continue;
14057             }
14058           *p = expr;
14059           gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
14060           if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
14061               == GS_ERROR)
14062             {
14063               gimplify_omp_ctxp = target_ctx;
14064               *p = integer_minus_one_node;
14065               continue;
14066             }
14067           gimplify_omp_ctxp = target_ctx;
14068           if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
14069             OMP_CLAUSE_OPERAND (c, 0) = *p;
14070       }
14071   if (!omp_find_clause (OMP_TARGET_CLAUSES (target), OMP_CLAUSE_THREAD_LIMIT))
14072     {
14073       c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
14074       OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
14075       OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
14076       OMP_TARGET_CLAUSES (target) = c;
14077     }
14078   c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
14079   OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper;
14080   OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower;
14081   OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
14082   OMP_TARGET_CLAUSES (target) = c;
14083 }
14084 
14085 /* Gimplify the gross structure of several OMP constructs.  */
14086 
14087 static void
gimplify_omp_workshare(tree * expr_p,gimple_seq * pre_p)14088 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
14089 {
14090   tree expr = *expr_p;
14091   gimple *stmt;
14092   gimple_seq body = NULL;
14093   enum omp_region_type ort;
14094 
14095   switch (TREE_CODE (expr))
14096     {
14097     case OMP_SECTIONS:
14098     case OMP_SINGLE:
14099       ort = ORT_WORKSHARE;
14100       break;
14101     case OMP_SCOPE:
14102       ort = ORT_TASKGROUP;
14103       break;
14104     case OMP_TARGET:
14105       ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
14106       break;
14107     case OACC_KERNELS:
14108       ort = ORT_ACC_KERNELS;
14109       break;
14110     case OACC_PARALLEL:
14111       ort = ORT_ACC_PARALLEL;
14112       break;
14113     case OACC_SERIAL:
14114       ort = ORT_ACC_SERIAL;
14115       break;
14116     case OACC_DATA:
14117       ort = ORT_ACC_DATA;
14118       break;
14119     case OMP_TARGET_DATA:
14120       ort = ORT_TARGET_DATA;
14121       break;
14122     case OMP_TEAMS:
14123       ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
14124       if (gimplify_omp_ctxp == NULL
14125             || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
14126           ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
14127       break;
14128     case OACC_HOST_DATA:
14129       ort = ORT_ACC_HOST_DATA;
14130       break;
14131     default:
14132       gcc_unreachable ();
14133     }
14134 
14135   bool save_in_omp_construct = in_omp_construct;
14136   if ((ort & ORT_ACC) == 0)
14137     in_omp_construct = false;
14138   gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
14139                                    TREE_CODE (expr));
14140   if (TREE_CODE (expr) == OMP_TARGET)
14141     optimize_target_teams (expr, pre_p);
14142   if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
14143       || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
14144     {
14145       push_gimplify_context ();
14146       gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
14147       if (gimple_code (g) == GIMPLE_BIND)
14148           pop_gimplify_context (g);
14149       else
14150           pop_gimplify_context (NULL);
14151       if ((ort & ORT_TARGET_DATA) != 0)
14152           {
14153             enum built_in_function end_ix;
14154             switch (TREE_CODE (expr))
14155               {
14156               case OACC_DATA:
14157               case OACC_HOST_DATA:
14158                 end_ix = BUILT_IN_GOACC_DATA_END;
14159                 break;
14160               case OMP_TARGET_DATA:
14161                 end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
14162                 break;
14163               default:
14164                 gcc_unreachable ();
14165               }
14166             tree fn = builtin_decl_explicit (end_ix);
14167             g = gimple_build_call (fn, 0);
14168             gimple_seq cleanup = NULL;
14169             gimple_seq_add_stmt (&cleanup, g);
14170             g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
14171             body = NULL;
14172             gimple_seq_add_stmt (&body, g);
14173           }
14174     }
14175   else
14176     gimplify_and_add (OMP_BODY (expr), &body);
14177   gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
14178                                      TREE_CODE (expr));
14179   in_omp_construct = save_in_omp_construct;
14180 
14181   switch (TREE_CODE (expr))
14182     {
14183     case OACC_DATA:
14184       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
14185                                               OMP_CLAUSES (expr));
14186       break;
14187     case OACC_HOST_DATA:
14188       if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
14189           {
14190             for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14191               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
14192                 OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
14193           }
14194 
14195       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
14196                                               OMP_CLAUSES (expr));
14197       break;
14198     case OACC_KERNELS:
14199       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
14200                                               OMP_CLAUSES (expr));
14201       break;
14202     case OACC_PARALLEL:
14203       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
14204                                               OMP_CLAUSES (expr));
14205       break;
14206     case OACC_SERIAL:
14207       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
14208                                               OMP_CLAUSES (expr));
14209       break;
14210     case OMP_SECTIONS:
14211       stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
14212       break;
14213     case OMP_SINGLE:
14214       stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
14215       break;
14216     case OMP_SCOPE:
14217       stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr));
14218       break;
14219     case OMP_TARGET:
14220       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
14221                                               OMP_CLAUSES (expr));
14222       break;
14223     case OMP_TARGET_DATA:
14224       /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
14225            to be evaluated before the use_device_{ptr,addr} clauses if they
14226            refer to the same variables.  */
14227       {
14228           tree use_device_clauses;
14229           tree *pc, *uc = &use_device_clauses;
14230           for (pc = &OMP_CLAUSES (expr); *pc; )
14231             if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
14232                 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
14233               {
14234                 *uc = *pc;
14235                 *pc = OMP_CLAUSE_CHAIN (*pc);
14236                 uc = &OMP_CLAUSE_CHAIN (*uc);
14237               }
14238             else
14239               pc = &OMP_CLAUSE_CHAIN (*pc);
14240           *uc = NULL_TREE;
14241           *pc = use_device_clauses;
14242           stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
14243                                                   OMP_CLAUSES (expr));
14244       }
14245       break;
14246     case OMP_TEAMS:
14247       stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
14248       if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
14249           gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
14250       break;
14251     default:
14252       gcc_unreachable ();
14253     }
14254 
14255   gimplify_seq_add_stmt (pre_p, stmt);
14256   *expr_p = NULL_TREE;
14257 }
14258 
14259 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
14260    target update constructs.  */
14261 
14262 static void
gimplify_omp_target_update(tree * expr_p,gimple_seq * pre_p)14263 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
14264 {
14265   tree expr = *expr_p;
14266   int kind;
14267   gomp_target *stmt;
14268   enum omp_region_type ort = ORT_WORKSHARE;
14269 
14270   switch (TREE_CODE (expr))
14271     {
14272     case OACC_ENTER_DATA:
14273       kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA;
14274       ort = ORT_ACC;
14275       break;
14276     case OACC_EXIT_DATA:
14277       kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA;
14278       ort = ORT_ACC;
14279       break;
14280     case OACC_UPDATE:
14281       kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
14282       ort = ORT_ACC;
14283       break;
14284     case OMP_TARGET_UPDATE:
14285       kind = GF_OMP_TARGET_KIND_UPDATE;
14286       break;
14287     case OMP_TARGET_ENTER_DATA:
14288       kind = GF_OMP_TARGET_KIND_ENTER_DATA;
14289       break;
14290     case OMP_TARGET_EXIT_DATA:
14291       kind = GF_OMP_TARGET_KIND_EXIT_DATA;
14292       break;
14293     default:
14294       gcc_unreachable ();
14295     }
14296   gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
14297                                    ort, TREE_CODE (expr));
14298   gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
14299                                      TREE_CODE (expr));
14300   if (TREE_CODE (expr) == OACC_UPDATE
14301       && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
14302                                 OMP_CLAUSE_IF_PRESENT))
14303     {
14304       /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
14305            clause.  */
14306       for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14307           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
14308             switch (OMP_CLAUSE_MAP_KIND (c))
14309               {
14310               case GOMP_MAP_FORCE_TO:
14311                 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
14312                 break;
14313               case GOMP_MAP_FORCE_FROM:
14314                 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
14315                 break;
14316               default:
14317                 break;
14318               }
14319     }
14320   else if (TREE_CODE (expr) == OACC_EXIT_DATA
14321              && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
14322                                      OMP_CLAUSE_FINALIZE))
14323     {
14324       /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
14325            semantics.  */
14326       bool have_clause = false;
14327       for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14328           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
14329             switch (OMP_CLAUSE_MAP_KIND (c))
14330               {
14331               case GOMP_MAP_FROM:
14332                 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
14333                 have_clause = true;
14334                 break;
14335               case GOMP_MAP_RELEASE:
14336                 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
14337                 have_clause = true;
14338                 break;
14339               case GOMP_MAP_TO_PSET:
14340                 /* Fortran arrays with descriptors must map that descriptor when
14341                      doing standalone "attach" operations (in OpenACC).  In that
14342                      case GOMP_MAP_TO_PSET appears by itself with no preceding
14343                      clause (see trans-openmp.cc:gfc_trans_omp_clauses).  */
14344                 break;
14345               case GOMP_MAP_POINTER:
14346                 /* TODO PR92929: we may see these here, but they'll always follow
14347                      one of the clauses above, and will be handled by libgomp as
14348                      one group, so no handling required here.  */
14349                 gcc_assert (have_clause);
14350                 break;
14351               case GOMP_MAP_DETACH:
14352                 OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
14353                 have_clause = false;
14354                 break;
14355               case GOMP_MAP_STRUCT:
14356                 have_clause = false;
14357                 break;
14358               default:
14359                 gcc_unreachable ();
14360               }
14361     }
14362   stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
14363 
14364   gimplify_seq_add_stmt (pre_p, stmt);
14365   *expr_p = NULL_TREE;
14366 }
14367 
14368 /* A subroutine of gimplify_omp_atomic.  The front end is supposed to have
14369    stabilized the lhs of the atomic operation as *ADDR.  Return true if
14370    EXPR is this stabilized form.  */
14371 
14372 static bool
goa_lhs_expr_p(tree expr,tree addr)14373 goa_lhs_expr_p (tree expr, tree addr)
14374 {
14375   /* Also include casts to other type variants.  The C front end is fond
14376      of adding these for e.g. volatile variables.  This is like
14377      STRIP_TYPE_NOPS but includes the main variant lookup.  */
14378   STRIP_USELESS_TYPE_CONVERSION (expr);
14379 
14380   if (TREE_CODE (expr) == INDIRECT_REF)
14381     {
14382       expr = TREE_OPERAND (expr, 0);
14383       while (expr != addr
14384                && (CONVERT_EXPR_P (expr)
14385                      || TREE_CODE (expr) == NON_LVALUE_EXPR)
14386                && TREE_CODE (expr) == TREE_CODE (addr)
14387                && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
14388           {
14389             expr = TREE_OPERAND (expr, 0);
14390             addr = TREE_OPERAND (addr, 0);
14391           }
14392       if (expr == addr)
14393           return true;
14394       return (TREE_CODE (addr) == ADDR_EXPR
14395                 && TREE_CODE (expr) == ADDR_EXPR
14396                 && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
14397     }
14398   if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
14399     return true;
14400   return false;
14401 }
14402 
14403 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR.  If an
14404    expression does not involve the lhs, evaluate it into a temporary.
14405    Return 1 if the lhs appeared as a subexpression, 0 if it did not,
14406    or -1 if an error was encountered.  */
14407 
14408 static int
goa_stabilize_expr(tree * expr_p,gimple_seq * pre_p,tree lhs_addr,tree lhs_var,tree & target_expr,bool rhs,int depth)14409 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
14410                         tree lhs_var, tree &target_expr, bool rhs, int depth)
14411 {
14412   tree expr = *expr_p;
14413   int saw_lhs = 0;
14414 
14415   if (goa_lhs_expr_p (expr, lhs_addr))
14416     {
14417       if (pre_p)
14418           *expr_p = lhs_var;
14419       return 1;
14420     }
14421   if (is_gimple_val (expr))
14422     return 0;
14423 
14424   /* Maximum depth of lhs in expression is for the
14425      __builtin_clear_padding (...), __builtin_clear_padding (...),
14426      __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs;  */
14427   if (++depth > 7)
14428     goto finish;
14429 
14430   switch (TREE_CODE_CLASS (TREE_CODE (expr)))
14431     {
14432     case tcc_binary:
14433     case tcc_comparison:
14434       saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
14435                                              lhs_var, target_expr, true, depth);
14436       /* FALLTHRU */
14437     case tcc_unary:
14438       saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
14439                                              lhs_var, target_expr, true, depth);
14440       break;
14441     case tcc_expression:
14442       switch (TREE_CODE (expr))
14443           {
14444           case TRUTH_ANDIF_EXPR:
14445           case TRUTH_ORIF_EXPR:
14446           case TRUTH_AND_EXPR:
14447           case TRUTH_OR_EXPR:
14448           case TRUTH_XOR_EXPR:
14449           case BIT_INSERT_EXPR:
14450             saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14451                                                    lhs_addr, lhs_var, target_expr, true,
14452                                                    depth);
14453             /* FALLTHRU */
14454           case TRUTH_NOT_EXPR:
14455             saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14456                                                    lhs_addr, lhs_var, target_expr, true,
14457                                                    depth);
14458             break;
14459           case MODIFY_EXPR:
14460             if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14461                                                       target_expr, true, depth))
14462               break;
14463             saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14464                                                    lhs_addr, lhs_var, target_expr, true,
14465                                                    depth);
14466             saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14467                                                    lhs_addr, lhs_var, target_expr, false,
14468                                                    depth);
14469             break;
14470             /* FALLTHRU */
14471           case ADDR_EXPR:
14472             if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
14473                                                       target_expr, true, depth))
14474               break;
14475             saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14476                                                    lhs_addr, lhs_var, target_expr, false,
14477                                                    depth);
14478             break;
14479           case COMPOUND_EXPR:
14480             /* Break out any preevaluations from cp_build_modify_expr.  */
14481             for (; TREE_CODE (expr) == COMPOUND_EXPR;
14482                  expr = TREE_OPERAND (expr, 1))
14483               {
14484                 /* Special-case __builtin_clear_padding call before
14485                      __builtin_memcmp.  */
14486                 if (TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR)
14487                     {
14488                       tree fndecl = get_callee_fndecl (TREE_OPERAND (expr, 0));
14489                       if (fndecl
14490                           && fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14491                           && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
14492                           && (!pre_p
14493                                 || goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL,
14494                                                              lhs_addr, lhs_var,
14495                                                              target_expr, true, depth)))
14496                         {
14497                           if (pre_p)
14498                               *expr_p = expr;
14499                           saw_lhs = goa_stabilize_expr (&TREE_OPERAND (expr, 0),
14500                                                                 pre_p, lhs_addr, lhs_var,
14501                                                                 target_expr, true, depth);
14502                           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1),
14503                                                                  pre_p, lhs_addr, lhs_var,
14504                                                                  target_expr, rhs, depth);
14505                           return saw_lhs;
14506                         }
14507                     }
14508 
14509                 if (pre_p)
14510                     gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
14511               }
14512             if (!pre_p)
14513               return goa_stabilize_expr (&expr, pre_p, lhs_addr, lhs_var,
14514                                                target_expr, rhs, depth);
14515             *expr_p = expr;
14516             return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var,
14517                                              target_expr, rhs, depth);
14518           case COND_EXPR:
14519             if (!goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, lhs_addr,
14520                                            lhs_var, target_expr, true, depth))
14521               break;
14522             saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14523                                                    lhs_addr, lhs_var, target_expr, true,
14524                                                    depth);
14525             saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
14526                                                    lhs_addr, lhs_var, target_expr, true,
14527                                                    depth);
14528             saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 2), pre_p,
14529                                                    lhs_addr, lhs_var, target_expr, true,
14530                                                    depth);
14531             break;
14532           case TARGET_EXPR:
14533             if (TARGET_EXPR_INITIAL (expr))
14534               {
14535                 if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr,
14536                                                             lhs_var, target_expr, true,
14537                                                             depth))
14538                     break;
14539                 if (expr == target_expr)
14540                     saw_lhs = 1;
14541                 else
14542                     {
14543                       saw_lhs = goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr),
14544                                                             pre_p, lhs_addr, lhs_var,
14545                                                             target_expr, true, depth);
14546                       if (saw_lhs && target_expr == NULL_TREE && pre_p)
14547                         target_expr = expr;
14548                     }
14549               }
14550             break;
14551           default:
14552             break;
14553           }
14554       break;
14555     case tcc_reference:
14556       if (TREE_CODE (expr) == BIT_FIELD_REF
14557             || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
14558           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
14559                                                lhs_addr, lhs_var, target_expr, true,
14560                                                depth);
14561       break;
14562     case tcc_vl_exp:
14563       if (TREE_CODE (expr) == CALL_EXPR)
14564           {
14565             if (tree fndecl = get_callee_fndecl (expr))
14566               if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
14567                     || fndecl_built_in_p (fndecl, BUILT_IN_MEMCMP))
14568                 {
14569                     int nargs = call_expr_nargs (expr);
14570                     for (int i = 0; i < nargs; i++)
14571                       saw_lhs |= goa_stabilize_expr (&CALL_EXPR_ARG (expr, i),
14572                                                              pre_p, lhs_addr, lhs_var,
14573                                                              target_expr, true, depth);
14574                 }
14575           }
14576       break;
14577     default:
14578       break;
14579     }
14580 
14581  finish:
14582   if (saw_lhs == 0 && pre_p)
14583     {
14584       enum gimplify_status gs;
14585       if (TREE_CODE (expr) == CALL_EXPR && VOID_TYPE_P (TREE_TYPE (expr)))
14586           {
14587             gimplify_stmt (&expr, pre_p);
14588             return saw_lhs;
14589           }
14590       else if (rhs)
14591           gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
14592       else
14593           gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_lvalue, fb_lvalue);
14594       if (gs != GS_ALL_DONE)
14595           saw_lhs = -1;
14596     }
14597 
14598   return saw_lhs;
14599 }
14600 
14601 /* Gimplify an OMP_ATOMIC statement.  */
14602 
14603 static enum gimplify_status
gimplify_omp_atomic(tree * expr_p,gimple_seq * pre_p)14604 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
14605 {
14606   tree addr = TREE_OPERAND (*expr_p, 0);
14607   tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
14608                ? NULL : TREE_OPERAND (*expr_p, 1);
14609   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
14610   tree tmp_load;
14611   gomp_atomic_load *loadstmt;
14612   gomp_atomic_store *storestmt;
14613   tree target_expr = NULL_TREE;
14614 
14615   tmp_load = create_tmp_reg (type);
14616   if (rhs
14617       && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load, target_expr,
14618                                    true, 0) < 0)
14619     return GS_ERROR;
14620 
14621   if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
14622       != GS_ALL_DONE)
14623     return GS_ERROR;
14624 
14625   loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
14626                                                      OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14627   gimplify_seq_add_stmt (pre_p, loadstmt);
14628   if (rhs)
14629     {
14630       /* BIT_INSERT_EXPR is not valid for non-integral bitfield
14631            representatives.  Use BIT_FIELD_REF on the lhs instead.  */
14632       tree rhsarg = rhs;
14633       if (TREE_CODE (rhs) == COND_EXPR)
14634           rhsarg = TREE_OPERAND (rhs, 1);
14635       if (TREE_CODE (rhsarg) == BIT_INSERT_EXPR
14636             && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
14637           {
14638             tree bitpos = TREE_OPERAND (rhsarg, 2);
14639             tree op1 = TREE_OPERAND (rhsarg, 1);
14640             tree bitsize;
14641             tree tmp_store = tmp_load;
14642             if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
14643               tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
14644             if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
14645               bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
14646             else
14647               bitsize = TYPE_SIZE (TREE_TYPE (op1));
14648             gcc_assert (TREE_OPERAND (rhsarg, 0) == tmp_load);
14649             tree t = build2_loc (EXPR_LOCATION (rhsarg),
14650                                      MODIFY_EXPR, void_type_node,
14651                                      build3_loc (EXPR_LOCATION (rhsarg),
14652                                                      BIT_FIELD_REF, TREE_TYPE (op1),
14653                                                      tmp_store, bitsize, bitpos), op1);
14654             if (TREE_CODE (rhs) == COND_EXPR)
14655               t = build3_loc (EXPR_LOCATION (rhs), COND_EXPR, void_type_node,
14656                                   TREE_OPERAND (rhs, 0), t, void_node);
14657             gimplify_and_add (t, pre_p);
14658             rhs = tmp_store;
14659           }
14660       bool save_allow_rhs_cond_expr = gimplify_ctxp->allow_rhs_cond_expr;
14661       if (TREE_CODE (rhs) == COND_EXPR)
14662           gimplify_ctxp->allow_rhs_cond_expr = true;
14663       enum gimplify_status gs = gimplify_expr (&rhs, pre_p, NULL,
14664                                                          is_gimple_val, fb_rvalue);
14665       gimplify_ctxp->allow_rhs_cond_expr = save_allow_rhs_cond_expr;
14666       if (gs != GS_ALL_DONE)
14667           return GS_ERROR;
14668     }
14669 
14670   if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
14671     rhs = tmp_load;
14672   storestmt
14673     = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
14674   if (TREE_CODE (*expr_p) != OMP_ATOMIC_READ && OMP_ATOMIC_WEAK (*expr_p))
14675     {
14676       gimple_omp_atomic_set_weak (loadstmt);
14677       gimple_omp_atomic_set_weak (storestmt);
14678     }
14679   gimplify_seq_add_stmt (pre_p, storestmt);
14680   switch (TREE_CODE (*expr_p))
14681     {
14682     case OMP_ATOMIC_READ:
14683     case OMP_ATOMIC_CAPTURE_OLD:
14684       *expr_p = tmp_load;
14685       gimple_omp_atomic_set_need_value (loadstmt);
14686       break;
14687     case OMP_ATOMIC_CAPTURE_NEW:
14688       *expr_p = rhs;
14689       gimple_omp_atomic_set_need_value (storestmt);
14690       break;
14691     default:
14692       *expr_p = NULL;
14693       break;
14694     }
14695 
14696   return GS_ALL_DONE;
14697 }
14698 
14699 /* Gimplify a TRANSACTION_EXPR.  This involves gimplification of the
14700    body, and adding some EH bits.  */
14701 
14702 static enum gimplify_status
gimplify_transaction(tree * expr_p,gimple_seq * pre_p)14703 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
14704 {
14705   tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
14706   gimple *body_stmt;
14707   gtransaction *trans_stmt;
14708   gimple_seq body = NULL;
14709   int subcode = 0;
14710 
14711   /* Wrap the transaction body in a BIND_EXPR so we have a context
14712      where to put decls for OMP.  */
14713   if (TREE_CODE (tbody) != BIND_EXPR)
14714     {
14715       tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
14716       TREE_SIDE_EFFECTS (bind) = 1;
14717       SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
14718       TRANSACTION_EXPR_BODY (expr) = bind;
14719     }
14720 
14721   push_gimplify_context ();
14722   temp = voidify_wrapper_expr (*expr_p, NULL);
14723 
14724   body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
14725   pop_gimplify_context (body_stmt);
14726 
14727   trans_stmt = gimple_build_transaction (body);
14728   if (TRANSACTION_EXPR_OUTER (expr))
14729     subcode = GTMA_IS_OUTER;
14730   else if (TRANSACTION_EXPR_RELAXED (expr))
14731     subcode = GTMA_IS_RELAXED;
14732   gimple_transaction_set_subcode (trans_stmt, subcode);
14733 
14734   gimplify_seq_add_stmt (pre_p, trans_stmt);
14735 
14736   if (temp)
14737     {
14738       *expr_p = temp;
14739       return GS_OK;
14740     }
14741 
14742   *expr_p = NULL_TREE;
14743   return GS_ALL_DONE;
14744 }
14745 
14746 /* Gimplify an OMP_ORDERED construct.  EXPR is the tree version.  BODY
14747    is the OMP_BODY of the original EXPR (which has already been
14748    gimplified so it's not present in the EXPR).
14749 
14750    Return the gimplified GIMPLE_OMP_ORDERED tuple.  */
14751 
14752 static gimple *
gimplify_omp_ordered(tree expr,gimple_seq body)14753 gimplify_omp_ordered (tree expr, gimple_seq body)
14754 {
14755   tree c, decls;
14756   int failures = 0;
14757   unsigned int i;
14758   tree source_c = NULL_TREE;
14759   tree sink_c = NULL_TREE;
14760 
14761   if (gimplify_omp_ctxp)
14762     {
14763       for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
14764           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14765               && gimplify_omp_ctxp->loop_iter_var.is_empty ()
14766               && (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK
14767                     || OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE))
14768             {
14769               error_at (OMP_CLAUSE_LOCATION (c),
14770                           "%<ordered%> construct with %<depend%> clause must be "
14771                           "closely nested inside a loop with %<ordered%> clause "
14772                           "with a parameter");
14773               failures++;
14774             }
14775           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14776                      && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
14777             {
14778               bool fail = false;
14779               for (decls = OMP_CLAUSE_DECL (c), i = 0;
14780                      decls && TREE_CODE (decls) == TREE_LIST;
14781                      decls = TREE_CHAIN (decls), ++i)
14782                 if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
14783                     continue;
14784                 else if (TREE_VALUE (decls)
14785                            != gimplify_omp_ctxp->loop_iter_var[2 * i])
14786                     {
14787                       error_at (OMP_CLAUSE_LOCATION (c),
14788                                   "variable %qE is not an iteration "
14789                                   "of outermost loop %d, expected %qE",
14790                                   TREE_VALUE (decls), i + 1,
14791                                   gimplify_omp_ctxp->loop_iter_var[2 * i]);
14792                       fail = true;
14793                       failures++;
14794                     }
14795                 else
14796                     TREE_VALUE (decls)
14797                       = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
14798               if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
14799                 {
14800                     error_at (OMP_CLAUSE_LOCATION (c),
14801                                 "number of variables in %<depend%> clause with "
14802                                 "%<sink%> modifier does not match number of "
14803                                 "iteration variables");
14804                     failures++;
14805                 }
14806               sink_c = c;
14807             }
14808           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
14809                      && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SOURCE)
14810             {
14811               if (source_c)
14812                 {
14813                     error_at (OMP_CLAUSE_LOCATION (c),
14814                                 "more than one %<depend%> clause with %<source%> "
14815                                 "modifier on an %<ordered%> construct");
14816                     failures++;
14817                 }
14818               else
14819                 source_c = c;
14820             }
14821     }
14822   if (source_c && sink_c)
14823     {
14824       error_at (OMP_CLAUSE_LOCATION (source_c),
14825                     "%<depend%> clause with %<source%> modifier specified "
14826                     "together with %<depend%> clauses with %<sink%> modifier "
14827                     "on the same construct");
14828       failures++;
14829     }
14830 
14831   if (failures)
14832     return gimple_build_nop ();
14833   return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
14834 }
14835 
14836 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE.  If the
14837    expression produces a value to be used as an operand inside a GIMPLE
14838    statement, the value will be stored back in *EXPR_P.  This value will
14839    be a tree of class tcc_declaration, tcc_constant, tcc_reference or
14840    an SSA_NAME.  The corresponding sequence of GIMPLE statements is
14841    emitted in PRE_P and POST_P.
14842 
14843    Additionally, this process may overwrite parts of the input
14844    expression during gimplification.  Ideally, it should be
14845    possible to do non-destructive gimplification.
14846 
14847    EXPR_P points to the GENERIC expression to convert to GIMPLE.  If
14848       the expression needs to evaluate to a value to be used as
14849       an operand in a GIMPLE statement, this value will be stored in
14850       *EXPR_P on exit.  This happens when the caller specifies one
14851       of fb_lvalue or fb_rvalue fallback flags.
14852 
14853    PRE_P will contain the sequence of GIMPLE statements corresponding
14854        to the evaluation of EXPR and all the side-effects that must
14855        be executed before the main expression.  On exit, the last
14856        statement of PRE_P is the core statement being gimplified.  For
14857        instance, when gimplifying 'if (++a)' the last statement in
14858        PRE_P will be 'if (t.1)' where t.1 is the result of
14859        pre-incrementing 'a'.
14860 
14861    POST_P will contain the sequence of GIMPLE statements corresponding
14862        to the evaluation of all the side-effects that must be executed
14863        after the main expression.  If this is NULL, the post
14864        side-effects are stored at the end of PRE_P.
14865 
14866        The reason why the output is split in two is to handle post
14867        side-effects explicitly.  In some cases, an expression may have
14868        inner and outer post side-effects which need to be emitted in
14869        an order different from the one given by the recursive
14870        traversal.  For instance, for the expression (*p--)++ the post
14871        side-effects of '--' must actually occur *after* the post
14872        side-effects of '++'.  However, gimplification will first visit
14873        the inner expression, so if a separate POST sequence was not
14874        used, the resulting sequence would be:
14875 
14876               1     t.1 = *p
14877               2     p = p - 1
14878               3     t.2 = t.1 + 1
14879               4     *p = t.2
14880 
14881        However, the post-decrement operation in line #2 must not be
14882        evaluated until after the store to *p at line #4, so the
14883        correct sequence should be:
14884 
14885               1     t.1 = *p
14886               2     t.2 = t.1 + 1
14887               3     *p = t.2
14888               4     p = p - 1
14889 
14890        So, by specifying a separate post queue, it is possible
14891        to emit the post side-effects in the correct order.
14892        If POST_P is NULL, an internal queue will be used.  Before
14893        returning to the caller, the sequence POST_P is appended to
14894        the main output sequence PRE_P.
14895 
14896    GIMPLE_TEST_F points to a function that takes a tree T and
14897        returns nonzero if T is in the GIMPLE form requested by the
14898        caller.  The GIMPLE predicates are in gimple.cc.
14899 
14900    FALLBACK tells the function what sort of a temporary we want if
14901        gimplification cannot produce an expression that complies with
14902        GIMPLE_TEST_F.
14903 
14904        fb_none means that no temporary should be generated
14905        fb_rvalue means that an rvalue is OK to generate
14906        fb_lvalue means that an lvalue is OK to generate
14907        fb_either means that either is OK, but an lvalue is preferable.
14908        fb_mayfail means that gimplification may fail (in which case
14909        GS_ERROR will be returned)
14910 
14911    The return value is either GS_ERROR or GS_ALL_DONE, since this
14912    function iterates until EXPR is completely gimplified or an error
14913    occurs.  */
14914 
14915 enum gimplify_status
gimplify_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p,bool (* gimple_test_f)(tree),fallback_t fallback)14916 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
14917                  bool (*gimple_test_f) (tree), fallback_t fallback)
14918 {
14919   tree tmp;
14920   gimple_seq internal_pre = NULL;
14921   gimple_seq internal_post = NULL;
14922   tree save_expr;
14923   bool is_statement;
14924   location_t saved_location;
14925   enum gimplify_status ret;
14926   gimple_stmt_iterator pre_last_gsi, post_last_gsi;
14927   tree label;
14928 
14929   save_expr = *expr_p;
14930   if (save_expr == NULL_TREE)
14931     return GS_ALL_DONE;
14932 
14933   /* If we are gimplifying a top-level statement, PRE_P must be valid.  */
14934   is_statement = gimple_test_f == is_gimple_stmt;
14935   if (is_statement)
14936     gcc_assert (pre_p);
14937 
14938   /* Consistency checks.  */
14939   if (gimple_test_f == is_gimple_reg)
14940     gcc_assert (fallback & (fb_rvalue | fb_lvalue));
14941   else if (gimple_test_f == is_gimple_val
14942            || gimple_test_f == is_gimple_call_addr
14943            || gimple_test_f == is_gimple_condexpr
14944              || gimple_test_f == is_gimple_condexpr_for_cond
14945            || gimple_test_f == is_gimple_mem_rhs
14946            || gimple_test_f == is_gimple_mem_rhs_or_call
14947            || gimple_test_f == is_gimple_reg_rhs
14948            || gimple_test_f == is_gimple_reg_rhs_or_call
14949            || gimple_test_f == is_gimple_asm_val
14950              || gimple_test_f == is_gimple_mem_ref_addr)
14951     gcc_assert (fallback & fb_rvalue);
14952   else if (gimple_test_f == is_gimple_min_lval
14953              || gimple_test_f == is_gimple_lvalue)
14954     gcc_assert (fallback & fb_lvalue);
14955   else if (gimple_test_f == is_gimple_addressable)
14956     gcc_assert (fallback & fb_either);
14957   else if (gimple_test_f == is_gimple_stmt)
14958     gcc_assert (fallback == fb_none);
14959   else
14960     {
14961       /* We should have recognized the GIMPLE_TEST_F predicate to
14962            know what kind of fallback to use in case a temporary is
14963            needed to hold the value or address of *EXPR_P.  */
14964       gcc_unreachable ();
14965     }
14966 
14967   /* We used to check the predicate here and return immediately if it
14968      succeeds.  This is wrong; the design is for gimplification to be
14969      idempotent, and for the predicates to only test for valid forms, not
14970      whether they are fully simplified.  */
14971   if (pre_p == NULL)
14972     pre_p = &internal_pre;
14973 
14974   if (post_p == NULL)
14975     post_p = &internal_post;
14976 
14977   /* Remember the last statements added to PRE_P and POST_P.  Every
14978      new statement added by the gimplification helpers needs to be
14979      annotated with location information.  To centralize the
14980      responsibility, we remember the last statement that had been
14981      added to both queues before gimplifying *EXPR_P.  If
14982      gimplification produces new statements in PRE_P and POST_P, those
14983      statements will be annotated with the same location information
14984      as *EXPR_P.  */
14985   pre_last_gsi = gsi_last (*pre_p);
14986   post_last_gsi = gsi_last (*post_p);
14987 
14988   saved_location = input_location;
14989   if (save_expr != error_mark_node
14990       && EXPR_HAS_LOCATION (*expr_p))
14991     input_location = EXPR_LOCATION (*expr_p);
14992 
14993   /* Loop over the specific gimplifiers until the toplevel node
14994      remains the same.  */
14995   do
14996     {
14997       /* Strip away as many useless type conversions as possible
14998            at the toplevel.  */
14999       STRIP_USELESS_TYPE_CONVERSION (*expr_p);
15000 
15001       /* Remember the expr.  */
15002       save_expr = *expr_p;
15003 
15004       /* Die, die, die, my darling.  */
15005       if (error_operand_p (save_expr))
15006           {
15007             ret = GS_ERROR;
15008             break;
15009           }
15010 
15011       /* Do any language-specific gimplification.  */
15012       ret = ((enum gimplify_status)
15013                lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
15014       if (ret == GS_OK)
15015           {
15016             if (*expr_p == NULL_TREE)
15017               break;
15018             if (*expr_p != save_expr)
15019               continue;
15020           }
15021       else if (ret != GS_UNHANDLED)
15022           break;
15023 
15024       /* Make sure that all the cases set 'ret' appropriately.  */
15025       ret = GS_UNHANDLED;
15026       switch (TREE_CODE (*expr_p))
15027           {
15028             /* First deal with the special cases.  */
15029 
15030           case POSTINCREMENT_EXPR:
15031           case POSTDECREMENT_EXPR:
15032           case PREINCREMENT_EXPR:
15033           case PREDECREMENT_EXPR:
15034             ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
15035                                                   fallback != fb_none,
15036                                                   TREE_TYPE (*expr_p));
15037             break;
15038 
15039           case VIEW_CONVERT_EXPR:
15040             if ((fallback & fb_rvalue)
15041                 && is_gimple_reg_type (TREE_TYPE (*expr_p))
15042                 && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
15043               {
15044                 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15045                                            post_p, is_gimple_val, fb_rvalue);
15046                 recalculate_side_effects (*expr_p);
15047                 break;
15048               }
15049             /* Fallthru.  */
15050 
15051           case ARRAY_REF:
15052           case ARRAY_RANGE_REF:
15053           case REALPART_EXPR:
15054           case IMAGPART_EXPR:
15055           case COMPONENT_REF:
15056             ret = gimplify_compound_lval (expr_p, pre_p, post_p,
15057                                                   fallback ? fallback : fb_rvalue);
15058             break;
15059 
15060           case COND_EXPR:
15061             ret = gimplify_cond_expr (expr_p, pre_p, fallback);
15062 
15063             /* C99 code may assign to an array in a structure value of a
15064                conditional expression, and this has undefined behavior
15065                only on execution, so create a temporary if an lvalue is
15066                required.  */
15067             if (fallback == fb_lvalue)
15068               {
15069                 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
15070                 mark_addressable (*expr_p);
15071                 ret = GS_OK;
15072               }
15073             break;
15074 
15075           case CALL_EXPR:
15076             ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
15077 
15078             /* C99 code may assign to an array in a structure returned
15079                from a function, and this has undefined behavior only on
15080                execution, so create a temporary if an lvalue is
15081                required.  */
15082             if (fallback == fb_lvalue)
15083               {
15084                 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
15085                 mark_addressable (*expr_p);
15086                 ret = GS_OK;
15087               }
15088             break;
15089 
15090           case TREE_LIST:
15091             gcc_unreachable ();
15092 
15093           case COMPOUND_EXPR:
15094             ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
15095             break;
15096 
15097           case COMPOUND_LITERAL_EXPR:
15098             ret = gimplify_compound_literal_expr (expr_p, pre_p,
15099                                                             gimple_test_f, fallback);
15100             break;
15101 
15102           case MODIFY_EXPR:
15103           case INIT_EXPR:
15104             ret = gimplify_modify_expr (expr_p, pre_p, post_p,
15105                                               fallback != fb_none);
15106             break;
15107 
15108           case TRUTH_ANDIF_EXPR:
15109           case TRUTH_ORIF_EXPR:
15110             {
15111               /* Preserve the original type of the expression and the
15112                  source location of the outer expression.  */
15113               tree org_type = TREE_TYPE (*expr_p);
15114               *expr_p = gimple_boolify (*expr_p);
15115               *expr_p = build3_loc (input_location, COND_EXPR,
15116                                           org_type, *expr_p,
15117                                           fold_convert_loc
15118                                             (input_location,
15119                                              org_type, boolean_true_node),
15120                                           fold_convert_loc
15121                                             (input_location,
15122                                              org_type, boolean_false_node));
15123               ret = GS_OK;
15124               break;
15125             }
15126 
15127           case TRUTH_NOT_EXPR:
15128             {
15129               tree type = TREE_TYPE (*expr_p);
15130               /* The parsers are careful to generate TRUTH_NOT_EXPR
15131                  only with operands that are always zero or one.
15132                  We do not fold here but handle the only interesting case
15133                  manually, as fold may re-introduce the TRUTH_NOT_EXPR.  */
15134               *expr_p = gimple_boolify (*expr_p);
15135               if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
15136                 *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
15137                                             TREE_TYPE (*expr_p),
15138                                             TREE_OPERAND (*expr_p, 0));
15139               else
15140                 *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
15141                                             TREE_TYPE (*expr_p),
15142                                             TREE_OPERAND (*expr_p, 0),
15143                                             build_int_cst (TREE_TYPE (*expr_p), 1));
15144               if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
15145                 *expr_p = fold_convert_loc (input_location, type, *expr_p);
15146               ret = GS_OK;
15147               break;
15148             }
15149 
15150           case ADDR_EXPR:
15151             ret = gimplify_addr_expr (expr_p, pre_p, post_p);
15152             break;
15153 
15154           case ANNOTATE_EXPR:
15155             {
15156               tree cond = TREE_OPERAND (*expr_p, 0);
15157               tree kind = TREE_OPERAND (*expr_p, 1);
15158               tree data = TREE_OPERAND (*expr_p, 2);
15159               tree type = TREE_TYPE (cond);
15160               if (!INTEGRAL_TYPE_P (type))
15161                 {
15162                     *expr_p = cond;
15163                     ret = GS_OK;
15164                     break;
15165                 }
15166               tree tmp = create_tmp_var (type);
15167               gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
15168               gcall *call
15169                 = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
15170               gimple_call_set_lhs (call, tmp);
15171               gimplify_seq_add_stmt (pre_p, call);
15172               *expr_p = tmp;
15173               ret = GS_ALL_DONE;
15174               break;
15175             }
15176 
15177           case VA_ARG_EXPR:
15178             ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
15179             break;
15180 
15181           CASE_CONVERT:
15182             if (IS_EMPTY_STMT (*expr_p))
15183               {
15184                 ret = GS_ALL_DONE;
15185                 break;
15186               }
15187 
15188             if (VOID_TYPE_P (TREE_TYPE (*expr_p))
15189                 || fallback == fb_none)
15190               {
15191                 /* Just strip a conversion to void (or in void context) and
15192                      try again.  */
15193                 *expr_p = TREE_OPERAND (*expr_p, 0);
15194                 ret = GS_OK;
15195                 break;
15196               }
15197 
15198             ret = gimplify_conversion (expr_p);
15199             if (ret == GS_ERROR)
15200               break;
15201             if (*expr_p != save_expr)
15202               break;
15203             /* FALLTHRU */
15204 
15205           case FIX_TRUNC_EXPR:
15206             /* unary_expr: ... | '(' cast ')' val | ...  */
15207             ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15208                                      is_gimple_val, fb_rvalue);
15209             recalculate_side_effects (*expr_p);
15210             break;
15211 
15212           case INDIRECT_REF:
15213             {
15214               bool volatilep = TREE_THIS_VOLATILE (*expr_p);
15215               bool notrap = TREE_THIS_NOTRAP (*expr_p);
15216               tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
15217 
15218               *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
15219               if (*expr_p != save_expr)
15220                 {
15221                     ret = GS_OK;
15222                     break;
15223                 }
15224 
15225               ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15226                                          is_gimple_reg, fb_rvalue);
15227               if (ret == GS_ERROR)
15228                 break;
15229 
15230               recalculate_side_effects (*expr_p);
15231               *expr_p = fold_build2_loc (input_location, MEM_REF,
15232                                                TREE_TYPE (*expr_p),
15233                                                TREE_OPERAND (*expr_p, 0),
15234                                                build_int_cst (saved_ptr_type, 0));
15235               TREE_THIS_VOLATILE (*expr_p) = volatilep;
15236               TREE_THIS_NOTRAP (*expr_p) = notrap;
15237               ret = GS_OK;
15238               break;
15239             }
15240 
15241           /* We arrive here through the various re-gimplifcation paths.  */
15242           case MEM_REF:
15243             /* First try re-folding the whole thing.  */
15244             tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
15245                                    TREE_OPERAND (*expr_p, 0),
15246                                    TREE_OPERAND (*expr_p, 1));
15247             if (tmp)
15248               {
15249                 REF_REVERSE_STORAGE_ORDER (tmp)
15250                   = REF_REVERSE_STORAGE_ORDER (*expr_p);
15251                 *expr_p = tmp;
15252                 recalculate_side_effects (*expr_p);
15253                 ret = GS_OK;
15254                 break;
15255               }
15256             /* Avoid re-gimplifying the address operand if it is already
15257                in suitable form.  Re-gimplifying would mark the address
15258                operand addressable.  Always gimplify when not in SSA form
15259                as we still may have to gimplify decls with value-exprs.  */
15260             if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
15261                 || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
15262               {
15263                 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15264                                            is_gimple_mem_ref_addr, fb_rvalue);
15265                 if (ret == GS_ERROR)
15266                     break;
15267               }
15268             recalculate_side_effects (*expr_p);
15269             ret = GS_ALL_DONE;
15270             break;
15271 
15272           /* Constants need not be gimplified.  */
15273           case INTEGER_CST:
15274           case REAL_CST:
15275           case FIXED_CST:
15276           case STRING_CST:
15277           case COMPLEX_CST:
15278           case VECTOR_CST:
15279             /* Drop the overflow flag on constants, we do not want
15280                that in the GIMPLE IL.  */
15281             if (TREE_OVERFLOW_P (*expr_p))
15282               *expr_p = drop_tree_overflow (*expr_p);
15283             ret = GS_ALL_DONE;
15284             break;
15285 
15286           case CONST_DECL:
15287             /* If we require an lvalue, such as for ADDR_EXPR, retain the
15288                CONST_DECL node.  Otherwise the decl is replaceable by its
15289                value.  */
15290             /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either.  */
15291             if (fallback & fb_lvalue)
15292               ret = GS_ALL_DONE;
15293             else
15294               {
15295                 *expr_p = DECL_INITIAL (*expr_p);
15296                 ret = GS_OK;
15297               }
15298             break;
15299 
15300           case DECL_EXPR:
15301             ret = gimplify_decl_expr (expr_p, pre_p);
15302             break;
15303 
15304           case BIND_EXPR:
15305             ret = gimplify_bind_expr (expr_p, pre_p);
15306             break;
15307 
15308           case LOOP_EXPR:
15309             ret = gimplify_loop_expr (expr_p, pre_p);
15310             break;
15311 
15312           case SWITCH_EXPR:
15313             ret = gimplify_switch_expr (expr_p, pre_p);
15314             break;
15315 
15316           case EXIT_EXPR:
15317             ret = gimplify_exit_expr (expr_p);
15318             break;
15319 
15320           case GOTO_EXPR:
15321             /* If the target is not LABEL, then it is a computed jump
15322                and the target needs to be gimplified.  */
15323             if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
15324               {
15325                 ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
15326                                            NULL, is_gimple_val, fb_rvalue);
15327                 if (ret == GS_ERROR)
15328                     break;
15329               }
15330             gimplify_seq_add_stmt (pre_p,
15331                                 gimple_build_goto (GOTO_DESTINATION (*expr_p)));
15332             ret = GS_ALL_DONE;
15333             break;
15334 
15335           case PREDICT_EXPR:
15336             gimplify_seq_add_stmt (pre_p,
15337                               gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
15338                                                         PREDICT_EXPR_OUTCOME (*expr_p)));
15339             ret = GS_ALL_DONE;
15340             break;
15341 
15342           case LABEL_EXPR:
15343             ret = gimplify_label_expr (expr_p, pre_p);
15344             label = LABEL_EXPR_LABEL (*expr_p);
15345             gcc_assert (decl_function_context (label) == current_function_decl);
15346 
15347             /* If the label is used in a goto statement, or address of the label
15348                is taken, we need to unpoison all variables that were seen so far.
15349                Doing so would prevent us from reporting a false positives.  */
15350             if (asan_poisoned_variables
15351                 && asan_used_labels != NULL
15352                 && asan_used_labels->contains (label)
15353                 && !gimplify_omp_ctxp)
15354               asan_poison_variables (asan_poisoned_variables, false, pre_p);
15355             break;
15356 
15357           case CASE_LABEL_EXPR:
15358             ret = gimplify_case_label_expr (expr_p, pre_p);
15359 
15360             if (gimplify_ctxp->live_switch_vars)
15361               asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
15362                                            pre_p);
15363             break;
15364 
15365           case RETURN_EXPR:
15366             ret = gimplify_return_expr (*expr_p, pre_p);
15367             break;
15368 
15369           case CONSTRUCTOR:
15370             /* Don't reduce this in place; let gimplify_init_constructor work its
15371                magic.  Buf if we're just elaborating this for side effects, just
15372                gimplify any element that has side-effects.  */
15373             if (fallback == fb_none)
15374               {
15375                 unsigned HOST_WIDE_INT ix;
15376                 tree val;
15377                 tree temp = NULL_TREE;
15378                 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
15379                     if (TREE_SIDE_EFFECTS (val))
15380                       append_to_statement_list (val, &temp);
15381 
15382                 *expr_p = temp;
15383                 ret = temp ? GS_OK : GS_ALL_DONE;
15384               }
15385             /* C99 code may assign to an array in a constructed
15386                structure or union, and this has undefined behavior only
15387                on execution, so create a temporary if an lvalue is
15388                required.  */
15389             else if (fallback == fb_lvalue)
15390               {
15391                 *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
15392                 mark_addressable (*expr_p);
15393                 ret = GS_OK;
15394               }
15395             else
15396               ret = GS_ALL_DONE;
15397             break;
15398 
15399             /* The following are special cases that are not handled by the
15400                original GIMPLE grammar.  */
15401 
15402             /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
15403                eliminated.  */
15404           case SAVE_EXPR:
15405             ret = gimplify_save_expr (expr_p, pre_p, post_p);
15406             break;
15407 
15408           case BIT_FIELD_REF:
15409             ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15410                                      post_p, is_gimple_lvalue, fb_either);
15411             recalculate_side_effects (*expr_p);
15412             break;
15413 
15414           case TARGET_MEM_REF:
15415             {
15416               enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
15417 
15418               if (TMR_BASE (*expr_p))
15419                 r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
15420                                           post_p, is_gimple_mem_ref_addr, fb_either);
15421               if (TMR_INDEX (*expr_p))
15422                 r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
15423                                           post_p, is_gimple_val, fb_rvalue);
15424               if (TMR_INDEX2 (*expr_p))
15425                 r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
15426                                           post_p, is_gimple_val, fb_rvalue);
15427               /* TMR_STEP and TMR_OFFSET are always integer constants.  */
15428               ret = MIN (r0, r1);
15429             }
15430             break;
15431 
15432           case NON_LVALUE_EXPR:
15433             /* This should have been stripped above.  */
15434             gcc_unreachable ();
15435 
15436           case ASM_EXPR:
15437             ret = gimplify_asm_expr (expr_p, pre_p, post_p);
15438             break;
15439 
15440           case TRY_FINALLY_EXPR:
15441           case TRY_CATCH_EXPR:
15442             {
15443               gimple_seq eval, cleanup;
15444               gtry *try_;
15445 
15446               /* Calls to destructors are generated automatically in FINALLY/CATCH
15447                  block. They should have location as UNKNOWN_LOCATION. However,
15448                  gimplify_call_expr will reset these call stmts to input_location
15449                  if it finds stmt's location is unknown. To prevent resetting for
15450                  destructors, we set the input_location to unknown.
15451                  Note that this only affects the destructor calls in FINALLY/CATCH
15452                  block, and will automatically reset to its original value by the
15453                  end of gimplify_expr.  */
15454               input_location = UNKNOWN_LOCATION;
15455               eval = cleanup = NULL;
15456               gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
15457               if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15458                     && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
15459                 {
15460                     gimple_seq n = NULL, e = NULL;
15461                     gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15462                                                             0), &n);
15463                     gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
15464                                                             1), &e);
15465                     if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
15466                       {
15467                         geh_else *stmt = gimple_build_eh_else (n, e);
15468                         gimple_seq_add_stmt (&cleanup, stmt);
15469                       }
15470                 }
15471               else
15472                 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
15473               /* Don't create bogus GIMPLE_TRY with empty cleanup.  */
15474               if (gimple_seq_empty_p (cleanup))
15475                 {
15476                     gimple_seq_add_seq (pre_p, eval);
15477                     ret = GS_ALL_DONE;
15478                     break;
15479                 }
15480               try_ = gimple_build_try (eval, cleanup,
15481                                              TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
15482                                              ? GIMPLE_TRY_FINALLY
15483                                              : GIMPLE_TRY_CATCH);
15484               if (EXPR_HAS_LOCATION (save_expr))
15485                 gimple_set_location (try_, EXPR_LOCATION (save_expr));
15486               else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
15487                 gimple_set_location (try_, saved_location);
15488               if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
15489                 gimple_try_set_catch_is_cleanup (try_,
15490                                                          TRY_CATCH_IS_CLEANUP (*expr_p));
15491               gimplify_seq_add_stmt (pre_p, try_);
15492               ret = GS_ALL_DONE;
15493               break;
15494             }
15495 
15496           case CLEANUP_POINT_EXPR:
15497             ret = gimplify_cleanup_point_expr (expr_p, pre_p);
15498             break;
15499 
15500           case TARGET_EXPR:
15501             ret = gimplify_target_expr (expr_p, pre_p, post_p);
15502             break;
15503 
15504           case CATCH_EXPR:
15505             {
15506               gimple *c;
15507               gimple_seq handler = NULL;
15508               gimplify_and_add (CATCH_BODY (*expr_p), &handler);
15509               c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
15510               gimplify_seq_add_stmt (pre_p, c);
15511               ret = GS_ALL_DONE;
15512               break;
15513             }
15514 
15515           case EH_FILTER_EXPR:
15516             {
15517               gimple *ehf;
15518               gimple_seq failure = NULL;
15519 
15520               gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
15521               ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
15522               copy_warning (ehf, *expr_p);
15523               gimplify_seq_add_stmt (pre_p, ehf);
15524               ret = GS_ALL_DONE;
15525               break;
15526             }
15527 
15528           case OBJ_TYPE_REF:
15529             {
15530               enum gimplify_status r0, r1;
15531               r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
15532                                         post_p, is_gimple_val, fb_rvalue);
15533               r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
15534                                         post_p, is_gimple_val, fb_rvalue);
15535               TREE_SIDE_EFFECTS (*expr_p) = 0;
15536               ret = MIN (r0, r1);
15537             }
15538             break;
15539 
15540           case LABEL_DECL:
15541             /* We get here when taking the address of a label.  We mark
15542                the label as "forced"; meaning it can never be removed and
15543                it is a potential target for any computed goto.  */
15544             FORCED_LABEL (*expr_p) = 1;
15545             ret = GS_ALL_DONE;
15546             break;
15547 
15548           case STATEMENT_LIST:
15549             ret = gimplify_statement_list (expr_p, pre_p);
15550             break;
15551 
15552           case WITH_SIZE_EXPR:
15553             {
15554               gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15555                                  post_p == &internal_post ? NULL : post_p,
15556                                  gimple_test_f, fallback);
15557               gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15558                                  is_gimple_val, fb_rvalue);
15559               ret = GS_ALL_DONE;
15560             }
15561             break;
15562 
15563           case VAR_DECL:
15564           case PARM_DECL:
15565             ret = gimplify_var_or_parm_decl (expr_p);
15566             break;
15567 
15568           case RESULT_DECL:
15569             /* When within an OMP context, notice uses of variables.  */
15570             if (gimplify_omp_ctxp)
15571               omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
15572             ret = GS_ALL_DONE;
15573             break;
15574 
15575           case DEBUG_EXPR_DECL:
15576             gcc_unreachable ();
15577 
15578           case DEBUG_BEGIN_STMT:
15579             gimplify_seq_add_stmt (pre_p,
15580                                          gimple_build_debug_begin_stmt
15581                                          (TREE_BLOCK (*expr_p),
15582                                           EXPR_LOCATION (*expr_p)));
15583             ret = GS_ALL_DONE;
15584             *expr_p = NULL;
15585             break;
15586 
15587           case SSA_NAME:
15588             /* Allow callbacks into the gimplifier during optimization.  */
15589             ret = GS_ALL_DONE;
15590             break;
15591 
15592           case OMP_PARALLEL:
15593             gimplify_omp_parallel (expr_p, pre_p);
15594             ret = GS_ALL_DONE;
15595             break;
15596 
15597           case OMP_TASK:
15598             gimplify_omp_task (expr_p, pre_p);
15599             ret = GS_ALL_DONE;
15600             break;
15601 
15602           case OMP_SIMD:
15603             {
15604               /* Temporarily disable into_ssa, as scan_omp_simd
15605                  which calls copy_gimple_seq_and_replace_locals can't deal
15606                  with SSA_NAMEs defined outside of the body properly.  */
15607               bool saved_into_ssa = gimplify_ctxp->into_ssa;
15608               gimplify_ctxp->into_ssa = false;
15609               ret = gimplify_omp_for (expr_p, pre_p);
15610               gimplify_ctxp->into_ssa = saved_into_ssa;
15611               break;
15612             }
15613 
15614           case OMP_FOR:
15615           case OMP_DISTRIBUTE:
15616           case OMP_TASKLOOP:
15617           case OACC_LOOP:
15618             ret = gimplify_omp_for (expr_p, pre_p);
15619             break;
15620 
15621           case OMP_LOOP:
15622             ret = gimplify_omp_loop (expr_p, pre_p);
15623             break;
15624 
15625           case OACC_CACHE:
15626             gimplify_oacc_cache (expr_p, pre_p);
15627             ret = GS_ALL_DONE;
15628             break;
15629 
15630           case OACC_DECLARE:
15631             gimplify_oacc_declare (expr_p, pre_p);
15632             ret = GS_ALL_DONE;
15633             break;
15634 
15635           case OACC_HOST_DATA:
15636           case OACC_DATA:
15637           case OACC_KERNELS:
15638           case OACC_PARALLEL:
15639           case OACC_SERIAL:
15640           case OMP_SCOPE:
15641           case OMP_SECTIONS:
15642           case OMP_SINGLE:
15643           case OMP_TARGET:
15644           case OMP_TARGET_DATA:
15645           case OMP_TEAMS:
15646             gimplify_omp_workshare (expr_p, pre_p);
15647             ret = GS_ALL_DONE;
15648             break;
15649 
15650           case OACC_ENTER_DATA:
15651           case OACC_EXIT_DATA:
15652           case OACC_UPDATE:
15653           case OMP_TARGET_UPDATE:
15654           case OMP_TARGET_ENTER_DATA:
15655           case OMP_TARGET_EXIT_DATA:
15656             gimplify_omp_target_update (expr_p, pre_p);
15657             ret = GS_ALL_DONE;
15658             break;
15659 
15660           case OMP_SECTION:
15661           case OMP_MASTER:
15662           case OMP_MASKED:
15663           case OMP_ORDERED:
15664           case OMP_CRITICAL:
15665           case OMP_SCAN:
15666             {
15667               gimple_seq body = NULL;
15668               gimple *g;
15669               bool saved_in_omp_construct = in_omp_construct;
15670 
15671               in_omp_construct = true;
15672               gimplify_and_add (OMP_BODY (*expr_p), &body);
15673               in_omp_construct = saved_in_omp_construct;
15674               switch (TREE_CODE (*expr_p))
15675                 {
15676                 case OMP_SECTION:
15677                   g = gimple_build_omp_section (body);
15678                   break;
15679                 case OMP_MASTER:
15680                     g = gimple_build_omp_master (body);
15681                     break;
15682                 case OMP_ORDERED:
15683                     g = gimplify_omp_ordered (*expr_p, body);
15684                     break;
15685                 case OMP_MASKED:
15686                     gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p),
15687                                                      pre_p, ORT_WORKSHARE, OMP_MASKED);
15688                     gimplify_adjust_omp_clauses (pre_p, body,
15689                                                        &OMP_MASKED_CLAUSES (*expr_p),
15690                                                        OMP_MASKED);
15691                     g = gimple_build_omp_masked (body,
15692                                                        OMP_MASKED_CLAUSES (*expr_p));
15693                     break;
15694                 case OMP_CRITICAL:
15695                     gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
15696                                                      pre_p, ORT_WORKSHARE, OMP_CRITICAL);
15697                     gimplify_adjust_omp_clauses (pre_p, body,
15698                                                        &OMP_CRITICAL_CLAUSES (*expr_p),
15699                                                        OMP_CRITICAL);
15700                     g = gimple_build_omp_critical (body,
15701                                                          OMP_CRITICAL_NAME (*expr_p),
15702                                                          OMP_CRITICAL_CLAUSES (*expr_p));
15703                     break;
15704                 case OMP_SCAN:
15705                     gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
15706                                                      pre_p, ORT_WORKSHARE, OMP_SCAN);
15707                     gimplify_adjust_omp_clauses (pre_p, body,
15708                                                        &OMP_SCAN_CLAUSES (*expr_p),
15709                                                        OMP_SCAN);
15710                     g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
15711                     break;
15712                 default:
15713                     gcc_unreachable ();
15714                 }
15715               gimplify_seq_add_stmt (pre_p, g);
15716               ret = GS_ALL_DONE;
15717               break;
15718             }
15719 
15720           case OMP_TASKGROUP:
15721             {
15722               gimple_seq body = NULL;
15723 
15724               tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
15725               bool saved_in_omp_construct = in_omp_construct;
15726               gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
15727                                                OMP_TASKGROUP);
15728               gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
15729 
15730               in_omp_construct = true;
15731               gimplify_and_add (OMP_BODY (*expr_p), &body);
15732               in_omp_construct = saved_in_omp_construct;
15733               gimple_seq cleanup = NULL;
15734               tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
15735               gimple *g = gimple_build_call (fn, 0);
15736               gimple_seq_add_stmt (&cleanup, g);
15737               g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
15738               body = NULL;
15739               gimple_seq_add_stmt (&body, g);
15740               g = gimple_build_omp_taskgroup (body, *pclauses);
15741               gimplify_seq_add_stmt (pre_p, g);
15742               ret = GS_ALL_DONE;
15743               break;
15744             }
15745 
15746           case OMP_ATOMIC:
15747           case OMP_ATOMIC_READ:
15748           case OMP_ATOMIC_CAPTURE_OLD:
15749           case OMP_ATOMIC_CAPTURE_NEW:
15750             ret = gimplify_omp_atomic (expr_p, pre_p);
15751             break;
15752 
15753           case TRANSACTION_EXPR:
15754             ret = gimplify_transaction (expr_p, pre_p);
15755             break;
15756 
15757           case TRUTH_AND_EXPR:
15758           case TRUTH_OR_EXPR:
15759           case TRUTH_XOR_EXPR:
15760             {
15761               tree orig_type = TREE_TYPE (*expr_p);
15762               tree new_type, xop0, xop1;
15763               *expr_p = gimple_boolify (*expr_p);
15764               new_type = TREE_TYPE (*expr_p);
15765               if (!useless_type_conversion_p (orig_type, new_type))
15766                 {
15767                     *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
15768                     ret = GS_OK;
15769                     break;
15770                 }
15771 
15772             /* Boolified binary truth expressions are semantically equivalent
15773                to bitwise binary expressions.  Canonicalize them to the
15774                bitwise variant.  */
15775               switch (TREE_CODE (*expr_p))
15776                 {
15777                 case TRUTH_AND_EXPR:
15778                     TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
15779                     break;
15780                 case TRUTH_OR_EXPR:
15781                     TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
15782                     break;
15783                 case TRUTH_XOR_EXPR:
15784                     TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
15785                     break;
15786                 default:
15787                     break;
15788                 }
15789               /* Now make sure that operands have compatible type to
15790                  expression's new_type.  */
15791               xop0 = TREE_OPERAND (*expr_p, 0);
15792               xop1 = TREE_OPERAND (*expr_p, 1);
15793               if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
15794                 TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
15795                                                                           new_type,
15796                                                                           xop0);
15797               if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
15798                 TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
15799                                                                           new_type,
15800                                                                           xop1);
15801               /* Continue classified as tcc_binary.  */
15802               goto expr_2;
15803             }
15804 
15805           case VEC_COND_EXPR:
15806             goto expr_3;
15807 
15808           case VEC_PERM_EXPR:
15809             /* Classified as tcc_expression.  */
15810             goto expr_3;
15811 
15812           case BIT_INSERT_EXPR:
15813             /* Argument 3 is a constant.  */
15814             goto expr_2;
15815 
15816           case POINTER_PLUS_EXPR:
15817             {
15818               enum gimplify_status r0, r1;
15819               r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15820                                         post_p, is_gimple_val, fb_rvalue);
15821               r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15822                                         post_p, is_gimple_val, fb_rvalue);
15823               recalculate_side_effects (*expr_p);
15824               ret = MIN (r0, r1);
15825               break;
15826             }
15827 
15828           default:
15829             switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
15830               {
15831               case tcc_comparison:
15832                 /* Handle comparison of objects of non scalar mode aggregates
15833                      with a call to memcmp.  It would be nice to only have to do
15834                      this for variable-sized objects, but then we'd have to allow
15835                      the same nest of reference nodes we allow for MODIFY_EXPR and
15836                      that's too complex.
15837 
15838                      Compare scalar mode aggregates as scalar mode values.  Using
15839                      memcmp for them would be very inefficient at best, and is
15840                      plain wrong if bitfields are involved.  */
15841                 if (error_operand_p (TREE_OPERAND (*expr_p, 1)))
15842                     ret = GS_ERROR;
15843                 else
15844                     {
15845                       tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
15846 
15847                       /* Vector comparisons need no boolification.  */
15848                       if (TREE_CODE (type) == VECTOR_TYPE)
15849                         goto expr_2;
15850                       else if (!AGGREGATE_TYPE_P (type))
15851                         {
15852                           tree org_type = TREE_TYPE (*expr_p);
15853                           *expr_p = gimple_boolify (*expr_p);
15854                           if (!useless_type_conversion_p (org_type,
15855                                                                   TREE_TYPE (*expr_p)))
15856                               {
15857                                 *expr_p = fold_convert_loc (input_location,
15858                                                                   org_type, *expr_p);
15859                                 ret = GS_OK;
15860                               }
15861                           else
15862                               goto expr_2;
15863                         }
15864                       else if (TYPE_MODE (type) != BLKmode)
15865                         ret = gimplify_scalar_mode_aggregate_compare (expr_p);
15866                       else
15867                         ret = gimplify_variable_sized_compare (expr_p);
15868                     }
15869                 break;
15870 
15871               /* If *EXPR_P does not need to be special-cased, handle it
15872                  according to its class.  */
15873               case tcc_unary:
15874                 ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15875                                            post_p, is_gimple_val, fb_rvalue);
15876                 break;
15877 
15878               case tcc_binary:
15879               expr_2:
15880                 {
15881                     enum gimplify_status r0, r1;
15882 
15883                     r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15884                                         post_p, is_gimple_val, fb_rvalue);
15885                     r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15886                                             post_p, is_gimple_val, fb_rvalue);
15887 
15888                     ret = MIN (r0, r1);
15889                     break;
15890                 }
15891 
15892               expr_3:
15893                 {
15894                     enum gimplify_status r0, r1, r2;
15895 
15896                     r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
15897                                         post_p, is_gimple_val, fb_rvalue);
15898                     r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
15899                                             post_p, is_gimple_val, fb_rvalue);
15900                     r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
15901                                             post_p, is_gimple_val, fb_rvalue);
15902 
15903                     ret = MIN (MIN (r0, r1), r2);
15904                     break;
15905                 }
15906 
15907               case tcc_declaration:
15908               case tcc_constant:
15909                 ret = GS_ALL_DONE;
15910                 goto dont_recalculate;
15911 
15912               default:
15913                 gcc_unreachable ();
15914               }
15915 
15916             recalculate_side_effects (*expr_p);
15917 
15918           dont_recalculate:
15919             break;
15920           }
15921 
15922       gcc_assert (*expr_p || ret != GS_OK);
15923     }
15924   while (ret == GS_OK);
15925 
15926   /* If we encountered an error_mark somewhere nested inside, either
15927      stub out the statement or propagate the error back out.  */
15928   if (ret == GS_ERROR)
15929     {
15930       if (is_statement)
15931           *expr_p = NULL;
15932       goto out;
15933     }
15934 
15935   /* This was only valid as a return value from the langhook, which
15936      we handled.  Make sure it doesn't escape from any other context.  */
15937   gcc_assert (ret != GS_UNHANDLED);
15938 
15939   if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
15940     {
15941       /* We aren't looking for a value, and we don't have a valid
15942            statement.  If it doesn't have side-effects, throw it away.
15943            We can also get here with code such as "*&&L;", where L is
15944            a LABEL_DECL that is marked as FORCED_LABEL.  */
15945       if (TREE_CODE (*expr_p) == LABEL_DECL
15946             || !TREE_SIDE_EFFECTS (*expr_p))
15947           *expr_p = NULL;
15948       else if (!TREE_THIS_VOLATILE (*expr_p))
15949           {
15950             /* This is probably a _REF that contains something nested that
15951                has side effects.  Recurse through the operands to find it.  */
15952             enum tree_code code = TREE_CODE (*expr_p);
15953 
15954             switch (code)
15955               {
15956               case COMPONENT_REF:
15957               case REALPART_EXPR:
15958               case IMAGPART_EXPR:
15959               case VIEW_CONVERT_EXPR:
15960                 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15961                                    gimple_test_f, fallback);
15962                 break;
15963 
15964               case ARRAY_REF:
15965               case ARRAY_RANGE_REF:
15966                 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
15967                                    gimple_test_f, fallback);
15968                 gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
15969                                    gimple_test_f, fallback);
15970                 break;
15971 
15972               default:
15973                  /* Anything else with side-effects must be converted to
15974                       a valid statement before we get here.  */
15975                 gcc_unreachable ();
15976               }
15977 
15978             *expr_p = NULL;
15979           }
15980       else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
15981                  && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode
15982                  && !is_empty_type (TREE_TYPE (*expr_p)))
15983           {
15984             /* Historically, the compiler has treated a bare reference
15985                to a non-BLKmode volatile lvalue as forcing a load.  */
15986             tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
15987 
15988             /* Normally, we do not want to create a temporary for a
15989                TREE_ADDRESSABLE type because such a type should not be
15990                copied by bitwise-assignment.  However, we make an
15991                exception here, as all we are doing here is ensuring that
15992                we read the bytes that make up the type.  We use
15993                create_tmp_var_raw because create_tmp_var will abort when
15994                given a TREE_ADDRESSABLE type.  */
15995             tree tmp = create_tmp_var_raw (type, "vol");
15996             gimple_add_tmp_var (tmp);
15997             gimplify_assign (tmp, *expr_p, pre_p);
15998             *expr_p = NULL;
15999           }
16000       else
16001           /* We can't do anything useful with a volatile reference to
16002              an incomplete type, so just throw it away.  Likewise for
16003              a BLKmode type, since any implicit inner load should
16004              already have been turned into an explicit one by the
16005              gimplification process.  */
16006           *expr_p = NULL;
16007     }
16008 
16009   /* If we are gimplifying at the statement level, we're done.  Tack
16010      everything together and return.  */
16011   if (fallback == fb_none || is_statement)
16012     {
16013       /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
16014          it out for GC to reclaim it.  */
16015       *expr_p = NULL_TREE;
16016 
16017       if (!gimple_seq_empty_p (internal_pre)
16018             || !gimple_seq_empty_p (internal_post))
16019           {
16020             gimplify_seq_add_seq (&internal_pre, internal_post);
16021             gimplify_seq_add_seq (pre_p, internal_pre);
16022           }
16023 
16024       /* The result of gimplifying *EXPR_P is going to be the last few
16025            statements in *PRE_P and *POST_P.  Add location information
16026            to all the statements that were added by the gimplification
16027            helpers.  */
16028       if (!gimple_seq_empty_p (*pre_p))
16029           annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
16030 
16031       if (!gimple_seq_empty_p (*post_p))
16032           annotate_all_with_location_after (*post_p, post_last_gsi,
16033                                                     input_location);
16034 
16035       goto out;
16036     }
16037 
16038 #ifdef ENABLE_GIMPLE_CHECKING
16039   if (*expr_p)
16040     {
16041       enum tree_code code = TREE_CODE (*expr_p);
16042       /* These expressions should already be in gimple IR form.  */
16043       gcc_assert (code != MODIFY_EXPR
16044                       && code != ASM_EXPR
16045                       && code != BIND_EXPR
16046                       && code != CATCH_EXPR
16047                       && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
16048                       && code != EH_FILTER_EXPR
16049                       && code != GOTO_EXPR
16050                       && code != LABEL_EXPR
16051                       && code != LOOP_EXPR
16052                       && code != SWITCH_EXPR
16053                       && code != TRY_FINALLY_EXPR
16054                       && code != EH_ELSE_EXPR
16055                       && code != OACC_PARALLEL
16056                       && code != OACC_KERNELS
16057                       && code != OACC_SERIAL
16058                       && code != OACC_DATA
16059                       && code != OACC_HOST_DATA
16060                       && code != OACC_DECLARE
16061                       && code != OACC_UPDATE
16062                       && code != OACC_ENTER_DATA
16063                       && code != OACC_EXIT_DATA
16064                       && code != OACC_CACHE
16065                       && code != OMP_CRITICAL
16066                       && code != OMP_FOR
16067                       && code != OACC_LOOP
16068                       && code != OMP_MASTER
16069                       && code != OMP_MASKED
16070                       && code != OMP_TASKGROUP
16071                       && code != OMP_ORDERED
16072                       && code != OMP_PARALLEL
16073                       && code != OMP_SCAN
16074                       && code != OMP_SECTIONS
16075                       && code != OMP_SECTION
16076                       && code != OMP_SINGLE
16077                       && code != OMP_SCOPE);
16078     }
16079 #endif
16080 
16081   /* Otherwise we're gimplifying a subexpression, so the resulting
16082      value is interesting.  If it's a valid operand that matches
16083      GIMPLE_TEST_F, we're done. Unless we are handling some
16084      post-effects internally; if that's the case, we need to copy into
16085      a temporary before adding the post-effects to POST_P.  */
16086   if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
16087     goto out;
16088 
16089   /* Otherwise, we need to create a new temporary for the gimplified
16090      expression.  */
16091 
16092   /* We can't return an lvalue if we have an internal postqueue.  The
16093      object the lvalue refers to would (probably) be modified by the
16094      postqueue; we need to copy the value out first, which means an
16095      rvalue.  */
16096   if ((fallback & fb_lvalue)
16097       && gimple_seq_empty_p (internal_post)
16098       && is_gimple_addressable (*expr_p))
16099     {
16100       /* An lvalue will do.  Take the address of the expression, store it
16101            in a temporary, and replace the expression with an INDIRECT_REF of
16102            that temporary.  */
16103       tree ref_alias_type = reference_alias_ptr_type (*expr_p);
16104       unsigned int ref_align = get_object_alignment (*expr_p);
16105       tree ref_type = TREE_TYPE (*expr_p);
16106       tmp = build_fold_addr_expr_loc (input_location, *expr_p);
16107       gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
16108       if (TYPE_ALIGN (ref_type) != ref_align)
16109           ref_type = build_aligned_type (ref_type, ref_align);
16110       *expr_p = build2 (MEM_REF, ref_type,
16111                               tmp, build_zero_cst (ref_alias_type));
16112     }
16113   else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
16114     {
16115       /* An rvalue will do.  Assign the gimplified expression into a
16116            new temporary TMP and replace the original expression with
16117            TMP.  First, make sure that the expression has a type so that
16118            it can be assigned into a temporary.  */
16119       gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
16120       *expr_p = get_formal_tmp_var (*expr_p, pre_p);
16121     }
16122   else
16123     {
16124 #ifdef ENABLE_GIMPLE_CHECKING
16125       if (!(fallback & fb_mayfail))
16126           {
16127             fprintf (stderr, "gimplification failed:\n");
16128             print_generic_expr (stderr, *expr_p);
16129             debug_tree (*expr_p);
16130             internal_error ("gimplification failed");
16131           }
16132 #endif
16133       gcc_assert (fallback & fb_mayfail);
16134 
16135       /* If this is an asm statement, and the user asked for the
16136            impossible, don't die.  Fail and let gimplify_asm_expr
16137            issue an error.  */
16138       ret = GS_ERROR;
16139       goto out;
16140     }
16141 
16142   /* Make sure the temporary matches our predicate.  */
16143   gcc_assert ((*gimple_test_f) (*expr_p));
16144 
16145   if (!gimple_seq_empty_p (internal_post))
16146     {
16147       annotate_all_with_location (internal_post, input_location);
16148       gimplify_seq_add_seq (pre_p, internal_post);
16149     }
16150 
16151  out:
16152   input_location = saved_location;
16153   return ret;
16154 }
16155 
16156 /* Like gimplify_expr but make sure the gimplified result is not itself
16157    a SSA name (but a decl if it were).  Temporaries required by
16158    evaluating *EXPR_P may be still SSA names.  */
16159 
16160 static enum gimplify_status
gimplify_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p,bool (* gimple_test_f)(tree),fallback_t fallback,bool allow_ssa)16161 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
16162                  bool (*gimple_test_f) (tree), fallback_t fallback,
16163                  bool allow_ssa)
16164 {
16165   enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
16166                                                       gimple_test_f, fallback);
16167   if (! allow_ssa
16168       && TREE_CODE (*expr_p) == SSA_NAME)
16169     *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
16170   return ret;
16171 }
16172 
16173 /* Look through TYPE for variable-sized objects and gimplify each such
16174    size that we find.  Add to LIST_P any statements generated.  */
16175 
16176 void
gimplify_type_sizes(tree type,gimple_seq * list_p)16177 gimplify_type_sizes (tree type, gimple_seq *list_p)
16178 {
16179   if (type == NULL || type == error_mark_node)
16180     return;
16181 
16182   const bool ignored_p
16183     = TYPE_NAME (type)
16184       && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
16185       && DECL_IGNORED_P (TYPE_NAME (type));
16186   tree t;
16187 
16188   /* We first do the main variant, then copy into any other variants.  */
16189   type = TYPE_MAIN_VARIANT (type);
16190 
16191   /* Avoid infinite recursion.  */
16192   if (TYPE_SIZES_GIMPLIFIED (type))
16193     return;
16194 
16195   TYPE_SIZES_GIMPLIFIED (type) = 1;
16196 
16197   switch (TREE_CODE (type))
16198     {
16199     case INTEGER_TYPE:
16200     case ENUMERAL_TYPE:
16201     case BOOLEAN_TYPE:
16202     case REAL_TYPE:
16203     case FIXED_POINT_TYPE:
16204       gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
16205       gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
16206 
16207       for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
16208           {
16209             TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
16210             TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
16211           }
16212       break;
16213 
16214     case ARRAY_TYPE:
16215       /* These types may not have declarations, so handle them here.  */
16216       gimplify_type_sizes (TREE_TYPE (type), list_p);
16217       gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
16218       /* Ensure VLA bounds aren't removed, for -O0 they should be variables
16219            with assigned stack slots, for -O1+ -g they should be tracked
16220            by VTA.  */
16221       if (!ignored_p
16222             && TYPE_DOMAIN (type)
16223             && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
16224           {
16225             t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
16226             if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
16227               DECL_IGNORED_P (t) = 0;
16228             t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
16229             if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
16230               DECL_IGNORED_P (t) = 0;
16231           }
16232       break;
16233 
16234     case RECORD_TYPE:
16235     case UNION_TYPE:
16236     case QUAL_UNION_TYPE:
16237       for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
16238           if (TREE_CODE (field) == FIELD_DECL)
16239             {
16240               gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
16241               /* Likewise, ensure variable offsets aren't removed.  */
16242               if (!ignored_p
16243                     && (t = DECL_FIELD_OFFSET (field))
16244                     && VAR_P (t)
16245                     && DECL_ARTIFICIAL (t))
16246                 DECL_IGNORED_P (t) = 0;
16247               gimplify_one_sizepos (&DECL_SIZE (field), list_p);
16248               gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
16249               gimplify_type_sizes (TREE_TYPE (field), list_p);
16250             }
16251       break;
16252 
16253     case POINTER_TYPE:
16254     case REFERENCE_TYPE:
16255           /* We used to recurse on the pointed-to type here, which turned out to
16256              be incorrect because its definition might refer to variables not
16257              yet initialized at this point if a forward declaration is involved.
16258 
16259              It was actually useful for anonymous pointed-to types to ensure
16260              that the sizes evaluation dominates every possible later use of the
16261              values.  Restricting to such types here would be safe since there
16262              is no possible forward declaration around, but would introduce an
16263              undesirable middle-end semantic to anonymity.  We then defer to
16264              front-ends the responsibility of ensuring that the sizes are
16265              evaluated both early and late enough, e.g. by attaching artificial
16266              type declarations to the tree.  */
16267       break;
16268 
16269     default:
16270       break;
16271     }
16272 
16273   gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
16274   gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
16275 
16276   for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
16277     {
16278       TYPE_SIZE (t) = TYPE_SIZE (type);
16279       TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
16280       TYPE_SIZES_GIMPLIFIED (t) = 1;
16281     }
16282 }
16283 
16284 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
16285    a size or position, has had all of its SAVE_EXPRs evaluated.
16286    We add any required statements to *STMT_P.  */
16287 
16288 void
gimplify_one_sizepos(tree * expr_p,gimple_seq * stmt_p)16289 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
16290 {
16291   tree expr = *expr_p;
16292 
16293   /* We don't do anything if the value isn't there, is constant, or contains
16294      A PLACEHOLDER_EXPR.  We also don't want to do anything if it's already
16295      a VAR_DECL.  If it's a VAR_DECL from another function, the gimplifier
16296      will want to replace it with a new variable, but that will cause problems
16297      if this type is from outside the function.  It's OK to have that here.  */
16298   if (expr == NULL_TREE
16299       || is_gimple_constant (expr)
16300       || TREE_CODE (expr) == VAR_DECL
16301       || CONTAINS_PLACEHOLDER_P (expr))
16302     return;
16303 
16304   *expr_p = unshare_expr (expr);
16305 
16306   /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
16307      if the def vanishes.  */
16308   gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
16309 
16310   /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
16311      FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
16312      as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs.  */
16313   if (is_gimple_constant (*expr_p))
16314     *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
16315 }
16316 
16317 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
16318    containing the sequence of corresponding GIMPLE statements.  If DO_PARMS
16319    is true, also gimplify the parameters.  */
16320 
16321 gbind *
gimplify_body(tree fndecl,bool do_parms)16322 gimplify_body (tree fndecl, bool do_parms)
16323 {
16324   location_t saved_location = input_location;
16325   gimple_seq parm_stmts, parm_cleanup = NULL, seq;
16326   gimple *outer_stmt;
16327   gbind *outer_bind;
16328 
16329   timevar_push (TV_TREE_GIMPLIFY);
16330 
16331   init_tree_ssa (cfun);
16332 
16333   /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
16334      gimplification.  */
16335   default_rtl_profile ();
16336 
16337   gcc_assert (gimplify_ctxp == NULL);
16338   push_gimplify_context (true);
16339 
16340   if (flag_openacc || flag_openmp)
16341     {
16342       gcc_assert (gimplify_omp_ctxp == NULL);
16343       if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
16344           gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
16345     }
16346 
16347   /* Unshare most shared trees in the body and in that of any nested functions.
16348      It would seem we don't have to do this for nested functions because
16349      they are supposed to be output and then the outer function gimplified
16350      first, but the g++ front end doesn't always do it that way.  */
16351   unshare_body (fndecl);
16352   unvisit_body (fndecl);
16353 
16354   /* Make sure input_location isn't set to something weird.  */
16355   input_location = DECL_SOURCE_LOCATION (fndecl);
16356 
16357   /* Resolve callee-copies.  This has to be done before processing
16358      the body so that DECL_VALUE_EXPR gets processed correctly.  */
16359   parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
16360 
16361   /* Gimplify the function's body.  */
16362   seq = NULL;
16363   gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
16364   outer_stmt = gimple_seq_first_nondebug_stmt (seq);
16365   if (!outer_stmt)
16366     {
16367       outer_stmt = gimple_build_nop ();
16368       gimplify_seq_add_stmt (&seq, outer_stmt);
16369     }
16370 
16371   /* The body must contain exactly one statement, a GIMPLE_BIND.  If this is
16372      not the case, wrap everything in a GIMPLE_BIND to make it so.  */
16373   if (gimple_code (outer_stmt) == GIMPLE_BIND
16374       && (gimple_seq_first_nondebug_stmt (seq)
16375             == gimple_seq_last_nondebug_stmt (seq)))
16376     {
16377       outer_bind = as_a <gbind *> (outer_stmt);
16378       if (gimple_seq_first_stmt (seq) != outer_stmt
16379             || gimple_seq_last_stmt (seq) != outer_stmt)
16380           {
16381             /* If there are debug stmts before or after outer_stmt, move them
16382                inside of outer_bind body.  */
16383             gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
16384             gimple_seq second_seq = NULL;
16385             if (gimple_seq_first_stmt (seq) != outer_stmt
16386                 && gimple_seq_last_stmt (seq) != outer_stmt)
16387               {
16388                 second_seq = gsi_split_seq_after (gsi);
16389                 gsi_remove (&gsi, false);
16390               }
16391             else if (gimple_seq_first_stmt (seq) != outer_stmt)
16392               gsi_remove (&gsi, false);
16393             else
16394               {
16395                 gsi_remove (&gsi, false);
16396                 second_seq = seq;
16397                 seq = NULL;
16398               }
16399             gimple_seq_add_seq_without_update (&seq,
16400                                                        gimple_bind_body (outer_bind));
16401             gimple_seq_add_seq_without_update (&seq, second_seq);
16402             gimple_bind_set_body (outer_bind, seq);
16403           }
16404     }
16405   else
16406     outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
16407 
16408   DECL_SAVED_TREE (fndecl) = NULL_TREE;
16409 
16410   /* If we had callee-copies statements, insert them at the beginning
16411      of the function and clear DECL_VALUE_EXPR_P on the parameters.  */
16412   if (!gimple_seq_empty_p (parm_stmts))
16413     {
16414       tree parm;
16415 
16416       gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
16417       if (parm_cleanup)
16418           {
16419             gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
16420                                               GIMPLE_TRY_FINALLY);
16421             parm_stmts = NULL;
16422             gimple_seq_add_stmt (&parm_stmts, g);
16423           }
16424       gimple_bind_set_body (outer_bind, parm_stmts);
16425 
16426       for (parm = DECL_ARGUMENTS (current_function_decl);
16427              parm; parm = DECL_CHAIN (parm))
16428           if (DECL_HAS_VALUE_EXPR_P (parm))
16429             {
16430               DECL_HAS_VALUE_EXPR_P (parm) = 0;
16431               DECL_IGNORED_P (parm) = 0;
16432             }
16433     }
16434 
16435   if ((flag_openacc || flag_openmp || flag_openmp_simd)
16436       && gimplify_omp_ctxp)
16437     {
16438       delete_omp_context (gimplify_omp_ctxp);
16439       gimplify_omp_ctxp = NULL;
16440     }
16441 
16442   pop_gimplify_context (outer_bind);
16443   gcc_assert (gimplify_ctxp == NULL);
16444 
16445   if (flag_checking && !seen_error ())
16446     verify_gimple_in_seq (gimple_bind_body (outer_bind));
16447 
16448   timevar_pop (TV_TREE_GIMPLIFY);
16449   input_location = saved_location;
16450 
16451   return outer_bind;
16452 }
16453 
16454 typedef char *char_p; /* For DEF_VEC_P.  */
16455 
16456 /* Return whether we should exclude FNDECL from instrumentation.  */
16457 
16458 static bool
flag_instrument_functions_exclude_p(tree fndecl)16459 flag_instrument_functions_exclude_p (tree fndecl)
16460 {
16461   vec<char_p> *v;
16462 
16463   v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
16464   if (v && v->length () > 0)
16465     {
16466       const char *name;
16467       int i;
16468       char *s;
16469 
16470       name = lang_hooks.decl_printable_name (fndecl, 1);
16471       FOR_EACH_VEC_ELT (*v, i, s)
16472           if (strstr (name, s) != NULL)
16473             return true;
16474     }
16475 
16476   v = (vec<char_p> *) flag_instrument_functions_exclude_files;
16477   if (v && v->length () > 0)
16478     {
16479       const char *name;
16480       int i;
16481       char *s;
16482 
16483       name = DECL_SOURCE_FILE (fndecl);
16484       FOR_EACH_VEC_ELT (*v, i, s)
16485           if (strstr (name, s) != NULL)
16486             return true;
16487     }
16488 
16489   return false;
16490 }
16491 
16492 /* Entry point to the gimplification pass.  FNDECL is the FUNCTION_DECL
16493    node for the function we want to gimplify.
16494 
16495    Return the sequence of GIMPLE statements corresponding to the body
16496    of FNDECL.  */
16497 
16498 void
gimplify_function_tree(tree fndecl)16499 gimplify_function_tree (tree fndecl)
16500 {
16501   gimple_seq seq;
16502   gbind *bind;
16503 
16504   gcc_assert (!gimple_body (fndecl));
16505 
16506   if (DECL_STRUCT_FUNCTION (fndecl))
16507     push_cfun (DECL_STRUCT_FUNCTION (fndecl));
16508   else
16509     push_struct_function (fndecl);
16510 
16511   /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
16512      if necessary.  */
16513   cfun->curr_properties |= PROP_gimple_lva;
16514 
16515   if (asan_sanitize_use_after_scope ())
16516     asan_poisoned_variables = new hash_set<tree> ();
16517   bind = gimplify_body (fndecl, true);
16518   if (asan_poisoned_variables)
16519     {
16520       delete asan_poisoned_variables;
16521       asan_poisoned_variables = NULL;
16522     }
16523 
16524   /* The tree body of the function is no longer needed, replace it
16525      with the new GIMPLE body.  */
16526   seq = NULL;
16527   gimple_seq_add_stmt (&seq, bind);
16528   gimple_set_body (fndecl, seq);
16529 
16530   /* If we're instrumenting function entry/exit, then prepend the call to
16531      the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
16532      catch the exit hook.  */
16533   /* ??? Add some way to ignore exceptions for this TFE.  */
16534   if (flag_instrument_function_entry_exit
16535       && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
16536       /* Do not instrument extern inline functions.  */
16537       && !(DECL_DECLARED_INLINE_P (fndecl)
16538              && DECL_EXTERNAL (fndecl)
16539              && DECL_DISREGARD_INLINE_LIMITS (fndecl))
16540       && !flag_instrument_functions_exclude_p (fndecl))
16541     {
16542       tree x;
16543       gbind *new_bind;
16544       gimple *tf;
16545       gimple_seq cleanup = NULL, body = NULL;
16546       tree tmp_var, this_fn_addr;
16547       gcall *call;
16548 
16549       /* The instrumentation hooks aren't going to call the instrumented
16550            function and the address they receive is expected to be matchable
16551            against symbol addresses.  Make sure we don't create a trampoline,
16552            in case the current function is nested.  */
16553       this_fn_addr = build_fold_addr_expr (current_function_decl);
16554       TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
16555 
16556       x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
16557       call = gimple_build_call (x, 1, integer_zero_node);
16558       tmp_var = create_tmp_var (ptr_type_node, "return_addr");
16559       gimple_call_set_lhs (call, tmp_var);
16560       gimplify_seq_add_stmt (&cleanup, call);
16561       x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_EXIT);
16562       call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
16563       gimplify_seq_add_stmt (&cleanup, call);
16564       tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
16565 
16566       x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
16567       call = gimple_build_call (x, 1, integer_zero_node);
16568       tmp_var = create_tmp_var (ptr_type_node, "return_addr");
16569       gimple_call_set_lhs (call, tmp_var);
16570       gimplify_seq_add_stmt (&body, call);
16571       x = builtin_decl_implicit (BUILT_IN_PROFILE_FUNC_ENTER);
16572       call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
16573       gimplify_seq_add_stmt (&body, call);
16574       gimplify_seq_add_stmt (&body, tf);
16575       new_bind = gimple_build_bind (NULL, body, NULL);
16576 
16577       /* Replace the current function body with the body
16578          wrapped in the try/finally TF.  */
16579       seq = NULL;
16580       gimple_seq_add_stmt (&seq, new_bind);
16581       gimple_set_body (fndecl, seq);
16582       bind = new_bind;
16583     }
16584 
16585   if (sanitize_flags_p (SANITIZE_THREAD)
16586       && param_tsan_instrument_func_entry_exit)
16587     {
16588       gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
16589       gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
16590       gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
16591       /* Replace the current function body with the body
16592            wrapped in the try/finally TF.  */
16593       seq = NULL;
16594       gimple_seq_add_stmt (&seq, new_bind);
16595       gimple_set_body (fndecl, seq);
16596     }
16597 
16598   DECL_SAVED_TREE (fndecl) = NULL_TREE;
16599   cfun->curr_properties |= PROP_gimple_any;
16600 
16601   pop_cfun ();
16602 
16603   dump_function (TDI_gimple, fndecl);
16604 }
16605 
16606 /* Return a dummy expression of type TYPE in order to keep going after an
16607    error.  */
16608 
16609 static tree
dummy_object(tree type)16610 dummy_object (tree type)
16611 {
16612   tree t = build_int_cst (build_pointer_type (type), 0);
16613   return build2 (MEM_REF, type, t, t);
16614 }
16615 
16616 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
16617    builtin function, but a very special sort of operator.  */
16618 
16619 enum gimplify_status
gimplify_va_arg_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p ATTRIBUTE_UNUSED)16620 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
16621                           gimple_seq *post_p ATTRIBUTE_UNUSED)
16622 {
16623   tree promoted_type, have_va_type;
16624   tree valist = TREE_OPERAND (*expr_p, 0);
16625   tree type = TREE_TYPE (*expr_p);
16626   tree t, tag, aptag;
16627   location_t loc = EXPR_LOCATION (*expr_p);
16628 
16629   /* Verify that valist is of the proper type.  */
16630   have_va_type = TREE_TYPE (valist);
16631   if (have_va_type == error_mark_node)
16632     return GS_ERROR;
16633   have_va_type = targetm.canonical_va_list_type (have_va_type);
16634   if (have_va_type == NULL_TREE
16635       && POINTER_TYPE_P (TREE_TYPE (valist)))
16636     /* Handle 'Case 1: Not an array type' from c-common.cc/build_va_arg.  */
16637     have_va_type
16638       = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
16639   gcc_assert (have_va_type != NULL_TREE);
16640 
16641   /* Generate a diagnostic for requesting data of a type that cannot
16642      be passed through `...' due to type promotion at the call site.  */
16643   if ((promoted_type = lang_hooks.types.type_promotes_to (type))
16644              != type)
16645     {
16646       static bool gave_help;
16647       bool warned;
16648       /* Use the expansion point to handle cases such as passing bool (defined
16649            in a system header) through `...'.  */
16650       location_t xloc
16651           = expansion_point_location_if_in_system_header (loc);
16652 
16653       /* Unfortunately, this is merely undefined, rather than a constraint
16654            violation, so we cannot make this an error.  If this call is never
16655            executed, the program is still strictly conforming.  */
16656       auto_diagnostic_group d;
16657       warned = warning_at (xloc, 0,
16658                                  "%qT is promoted to %qT when passed through %<...%>",
16659                                  type, promoted_type);
16660       if (!gave_help && warned)
16661           {
16662             gave_help = true;
16663             inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
16664                       promoted_type, type);
16665           }
16666 
16667       /* We can, however, treat "undefined" any way we please.
16668            Call abort to encourage the user to fix the program.  */
16669       if (warned)
16670           inform (xloc, "if this code is reached, the program will abort");
16671       /* Before the abort, allow the evaluation of the va_list
16672            expression to exit or longjmp.  */
16673       gimplify_and_add (valist, pre_p);
16674       t = build_call_expr_loc (loc,
16675                                      builtin_decl_implicit (BUILT_IN_TRAP), 0);
16676       gimplify_and_add (t, pre_p);
16677 
16678       /* This is dead code, but go ahead and finish so that the
16679            mode of the result comes out right.  */
16680       *expr_p = dummy_object (type);
16681       return GS_ALL_DONE;
16682     }
16683 
16684   tag = build_int_cst (build_pointer_type (type), 0);
16685   aptag = build_int_cst (TREE_TYPE (valist), 0);
16686 
16687   *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
16688                                                     valist, tag, aptag);
16689 
16690   /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
16691      needs to be expanded.  */
16692   cfun->curr_properties &= ~PROP_gimple_lva;
16693 
16694   return GS_OK;
16695 }
16696 
16697 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
16698 
16699    DST/SRC are the destination and source respectively.  You can pass
16700    ungimplified trees in DST or SRC, in which case they will be
16701    converted to a gimple operand if necessary.
16702 
16703    This function returns the newly created GIMPLE_ASSIGN tuple.  */
16704 
16705 gimple *
gimplify_assign(tree dst,tree src,gimple_seq * seq_p)16706 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
16707 {
16708   tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
16709   gimplify_and_add (t, seq_p);
16710   ggc_free (t);
16711   return gimple_seq_last_stmt (*seq_p);
16712 }
16713 
16714 inline hashval_t
hash(const elt_t * p)16715 gimplify_hasher::hash (const elt_t *p)
16716 {
16717   tree t = p->val;
16718   return iterative_hash_expr (t, 0);
16719 }
16720 
16721 inline bool
equal(const elt_t * p1,const elt_t * p2)16722 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
16723 {
16724   tree t1 = p1->val;
16725   tree t2 = p2->val;
16726   enum tree_code code = TREE_CODE (t1);
16727 
16728   if (TREE_CODE (t2) != code
16729       || TREE_TYPE (t1) != TREE_TYPE (t2))
16730     return false;
16731 
16732   if (!operand_equal_p (t1, t2, 0))
16733     return false;
16734 
16735   /* Only allow them to compare equal if they also hash equal; otherwise
16736      results are nondeterminate, and we fail bootstrap comparison.  */
16737   gcc_checking_assert (hash (p1) == hash (p2));
16738 
16739   return true;
16740 }
16741