Home | History | Annotate | Line # | Download | only in gcc
      1 /* Tree lowering pass.  This pass converts the GENERIC functions-as-trees
      2    tree representation into the GIMPLE form.
      3    Copyright (C) 2002-2024 Free Software Foundation, Inc.
      4    Major work done by Sebastian Pop <s.pop (at) laposte.net>,
      5    Diego Novillo <dnovillo (at) redhat.com> and Jason Merrill <jason (at) 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 "diagnostic.h"		/* For errorcount.  */
     40 #include "alias.h"
     41 #include "fold-const.h"
     42 #include "calls.h"
     43 #include "varasm.h"
     44 #include "stmt.h"
     45 #include "expr.h"
     46 #include "gimple-iterator.h"
     47 #include "gimple-fold.h"
     48 #include "tree-eh.h"
     49 #include "gimplify.h"
     50 #include "stor-layout.h"
     51 #include "print-tree.h"
     52 #include "tree-iterator.h"
     53 #include "tree-inline.h"
     54 #include "langhooks.h"
     55 #include "tree-cfg.h"
     56 #include "tree-ssa.h"
     57 #include "tree-hash-traits.h"
     58 #include "omp-general.h"
     59 #include "omp-low.h"
     60 #include "gimple-low.h"
     61 #include "gomp-constants.h"
     62 #include "splay-tree.h"
     63 #include "gimple-walk.h"
     64 #include "langhooks-def.h"	/* FIXME: for lhd_set_decl_assembler_name */
     65 #include "builtins.h"
     66 #include "stringpool.h"
     67 #include "attribs.h"
     68 #include "asan.h"
     69 #include "dbgcnt.h"
     70 #include "omp-offload.h"
     71 #include "context.h"
     72 #include "tree-nested.h"
     73 
     74 /* Identifier for a basic condition, mapping it to other basic conditions of
     75    its Boolean expression.  Basic conditions given the same uid (in the same
     76    function) are parts of the same ANDIF/ORIF expression.  Used for condition
     77    coverage.  */
     78 static unsigned nextuid = 1;
     79 /* Get a fresh identifier for a new condition expression.  This is used for
     80    condition coverage.  */
     81 static unsigned
     82 next_cond_uid ()
     83 {
     84     return nextuid++;
     85 }
     86 /* Reset the condition uid to the value it should have when compiling a new
     87    function.  0 is already the default/untouched value, so start at non-zero.
     88    A valid and set id should always be > 0.  This is used for condition
     89    coverage.  */
     90 static void
     91 reset_cond_uid ()
     92 {
     93     nextuid = 1;
     94 }
     95 
     96 /* Hash set of poisoned variables in a bind expr.  */
     97 static hash_set<tree> *asan_poisoned_variables = NULL;
     98 
     99 enum gimplify_omp_var_data
    100 {
    101   GOVD_SEEN = 0x000001,
    102   GOVD_EXPLICIT = 0x000002,
    103   GOVD_SHARED = 0x000004,
    104   GOVD_PRIVATE = 0x000008,
    105   GOVD_FIRSTPRIVATE = 0x000010,
    106   GOVD_LASTPRIVATE = 0x000020,
    107   GOVD_REDUCTION = 0x000040,
    108   GOVD_LOCAL = 0x00080,
    109   GOVD_MAP = 0x000100,
    110   GOVD_DEBUG_PRIVATE = 0x000200,
    111   GOVD_PRIVATE_OUTER_REF = 0x000400,
    112   GOVD_LINEAR = 0x000800,
    113   GOVD_ALIGNED = 0x001000,
    114 
    115   /* Flag for GOVD_MAP: don't copy back.  */
    116   GOVD_MAP_TO_ONLY = 0x002000,
    117 
    118   /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference.  */
    119   GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 0x004000,
    120 
    121   GOVD_MAP_0LEN_ARRAY = 0x008000,
    122 
    123   /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping.  */
    124   GOVD_MAP_ALWAYS_TO = 0x010000,
    125 
    126   /* Flag for shared vars that are or might be stored to in the region.  */
    127   GOVD_WRITTEN = 0x020000,
    128 
    129   /* Flag for GOVD_MAP, if it is a forced mapping.  */
    130   GOVD_MAP_FORCE = 0x040000,
    131 
    132   /* Flag for GOVD_MAP: must be present already.  */
    133   GOVD_MAP_FORCE_PRESENT = 0x080000,
    134 
    135   /* Flag for GOVD_MAP: only allocate.  */
    136   GOVD_MAP_ALLOC_ONLY = 0x100000,
    137 
    138   /* Flag for GOVD_MAP: only copy back.  */
    139   GOVD_MAP_FROM_ONLY = 0x200000,
    140 
    141   GOVD_NONTEMPORAL = 0x400000,
    142 
    143   /* Flag for GOVD_LASTPRIVATE: conditional modifier.  */
    144   GOVD_LASTPRIVATE_CONDITIONAL = 0x800000,
    145 
    146   GOVD_CONDTEMP = 0x1000000,
    147 
    148   /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause.  */
    149   GOVD_REDUCTION_INSCAN = 0x2000000,
    150 
    151   /* Flag for GOVD_FIRSTPRIVATE: OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT.  */
    152   GOVD_FIRSTPRIVATE_IMPLICIT = 0x4000000,
    153 
    154   GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
    155 			   | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
    156 			   | GOVD_LOCAL)
    157 };
    158 
    159 
    160 enum omp_region_type
    161 {
    162   ORT_WORKSHARE = 0x00,
    163   ORT_TASKGROUP = 0x01,
    164   ORT_SIMD 	= 0x04,
    165 
    166   ORT_PARALLEL	= 0x08,
    167   ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1,
    168 
    169   ORT_TASK	= 0x10,
    170   ORT_UNTIED_TASK = ORT_TASK | 1,
    171   ORT_TASKLOOP  = ORT_TASK | 2,
    172   ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2,
    173 
    174   ORT_TEAMS	= 0x20,
    175   ORT_COMBINED_TEAMS = ORT_TEAMS | 1,
    176   ORT_HOST_TEAMS = ORT_TEAMS | 2,
    177   ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2,
    178 
    179   /* Data region.  */
    180   ORT_TARGET_DATA = 0x40,
    181 
    182   /* Data region with offloading.  */
    183   ORT_TARGET	= 0x80,
    184   ORT_COMBINED_TARGET = ORT_TARGET | 1,
    185   ORT_IMPLICIT_TARGET = ORT_TARGET | 2,
    186 
    187   /* OpenACC variants.  */
    188   ORT_ACC	= 0x100,  /* A generic OpenACC region.  */
    189   ORT_ACC_DATA	= ORT_ACC | ORT_TARGET_DATA, /* Data construct.  */
    190   ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET,  /* Parallel construct */
    191   ORT_ACC_KERNELS  = ORT_ACC | ORT_TARGET | 2,  /* Kernels construct.  */
    192   ORT_ACC_SERIAL   = ORT_ACC | ORT_TARGET | 4,  /* Serial construct.  */
    193   ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2,  /* Host data.  */
    194 
    195   /* Dummy OpenMP region, used to disable expansion of
    196      DECL_VALUE_EXPRs in taskloop pre body.  */
    197   ORT_NONE	= 0x200
    198 };
    199 
    200 /* Gimplify hashtable helper.  */
    201 
    202 struct gimplify_hasher : free_ptr_hash <elt_t>
    203 {
    204   static inline hashval_t hash (const elt_t *);
    205   static inline bool equal (const elt_t *, const elt_t *);
    206 };
    207 
    208 struct gimplify_ctx
    209 {
    210   struct gimplify_ctx *prev_context;
    211 
    212   vec<gbind *> bind_expr_stack;
    213   tree temps;
    214   gimple_seq conditional_cleanups;
    215   tree exit_label;
    216   tree return_temp;
    217 
    218   vec<tree> case_labels;
    219   hash_set<tree> *live_switch_vars;
    220   /* The formal temporary table.  Should this be persistent?  */
    221   hash_table<gimplify_hasher> *temp_htab;
    222 
    223   int conditions;
    224   unsigned into_ssa : 1;
    225   unsigned allow_rhs_cond_expr : 1;
    226   unsigned in_cleanup_point_expr : 1;
    227   unsigned keep_stack : 1;
    228   unsigned save_stack : 1;
    229   unsigned in_switch_expr : 1;
    230   unsigned in_handler_expr : 1;
    231 };
    232 
    233 enum gimplify_defaultmap_kind
    234 {
    235   GDMK_SCALAR,
    236   GDMK_SCALAR_TARGET, /* w/ Fortran's target attr, implicit mapping, only.  */
    237   GDMK_AGGREGATE,
    238   GDMK_ALLOCATABLE,
    239   GDMK_POINTER
    240 };
    241 
    242 struct gimplify_omp_ctx
    243 {
    244   struct gimplify_omp_ctx *outer_context;
    245   splay_tree variables;
    246   hash_set<tree> *privatized_types;
    247   tree clauses;
    248   /* Iteration variables in an OMP_FOR.  */
    249   vec<tree> loop_iter_var;
    250   location_t location;
    251   enum omp_clause_default_kind default_kind;
    252   enum omp_region_type region_type;
    253   enum tree_code code;
    254   bool combined_loop;
    255   bool distribute;
    256   bool target_firstprivatize_array_bases;
    257   bool add_safelen1;
    258   bool order_concurrent;
    259   bool has_depend;
    260   bool in_for_exprs;
    261   int defaultmap[5];
    262 };
    263 
    264 static struct gimplify_ctx *gimplify_ctxp;
    265 static struct gimplify_omp_ctx *gimplify_omp_ctxp;
    266 static bool in_omp_construct;
    267 
    268 /* Forward declaration.  */
    269 static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
    270 static hash_map<tree, tree> *oacc_declare_returns;
    271 static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
    272 					   bool (*) (tree), fallback_t, bool);
    273 static void prepare_gimple_addressable (tree *, gimple_seq *);
    274 
    275 /* Shorter alias name for the above function for use in gimplify.cc
    276    only.  */
    277 
    278 static inline void
    279 gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
    280 {
    281   gimple_seq_add_stmt_without_update (seq_p, gs);
    282 }
    283 
    284 /* Append sequence SRC to the end of sequence *DST_P.  If *DST_P is
    285    NULL, a new sequence is allocated.   This function is
    286    similar to gimple_seq_add_seq, but does not scan the operands.
    287    During gimplification, we need to manipulate statement sequences
    288    before the def/use vectors have been constructed.  */
    289 
    290 static void
    291 gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
    292 {
    293   gimple_stmt_iterator si;
    294 
    295   if (src == NULL)
    296     return;
    297 
    298   si = gsi_last (*dst_p);
    299   gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
    300 }
    301 
    302 
    303 /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
    304    and popping gimplify contexts.  */
    305 
    306 static struct gimplify_ctx *ctx_pool = NULL;
    307 
    308 /* Return a gimplify context struct from the pool.  */
    309 
    310 static inline struct gimplify_ctx *
    311 ctx_alloc (void)
    312 {
    313   struct gimplify_ctx * c = ctx_pool;
    314 
    315   if (c)
    316     ctx_pool = c->prev_context;
    317   else
    318     c = XNEW (struct gimplify_ctx);
    319 
    320   memset (c, '\0', sizeof (*c));
    321   return c;
    322 }
    323 
    324 /* Put gimplify context C back into the pool.  */
    325 
    326 static inline void
    327 ctx_free (struct gimplify_ctx *c)
    328 {
    329   c->prev_context = ctx_pool;
    330   ctx_pool = c;
    331 }
    332 
    333 /* Free allocated ctx stack memory.  */
    334 
    335 void
    336 free_gimplify_stack (void)
    337 {
    338   struct gimplify_ctx *c;
    339 
    340   while ((c = ctx_pool))
    341     {
    342       ctx_pool = c->prev_context;
    343       free (c);
    344     }
    345 }
    346 
    347 
    348 /* Set up a context for the gimplifier.  */
    349 
    350 void
    351 push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
    352 {
    353   struct gimplify_ctx *c = ctx_alloc ();
    354 
    355   c->prev_context = gimplify_ctxp;
    356   gimplify_ctxp = c;
    357   gimplify_ctxp->into_ssa = in_ssa;
    358   gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
    359 }
    360 
    361 /* Tear down a context for the gimplifier.  If BODY is non-null, then
    362    put the temporaries into the outer BIND_EXPR.  Otherwise, put them
    363    in the local_decls.
    364 
    365    BODY is not a sequence, but the first tuple in a sequence.  */
    366 
    367 void
    368 pop_gimplify_context (gimple *body)
    369 {
    370   struct gimplify_ctx *c = gimplify_ctxp;
    371 
    372   gcc_assert (c
    373               && (!c->bind_expr_stack.exists ()
    374 		  || c->bind_expr_stack.is_empty ()));
    375   c->bind_expr_stack.release ();
    376   gimplify_ctxp = c->prev_context;
    377 
    378   if (body)
    379     declare_vars (c->temps, body, false);
    380   else
    381     record_vars (c->temps);
    382 
    383   delete c->temp_htab;
    384   c->temp_htab = NULL;
    385   ctx_free (c);
    386 }
    387 
    388 /* Push a GIMPLE_BIND tuple onto the stack of bindings.  */
    389 
    390 static void
    391 gimple_push_bind_expr (gbind *bind_stmt)
    392 {
    393   gimplify_ctxp->bind_expr_stack.reserve (8);
    394   gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
    395 }
    396 
    397 /* Pop the first element off the stack of bindings.  */
    398 
    399 static void
    400 gimple_pop_bind_expr (void)
    401 {
    402   gimplify_ctxp->bind_expr_stack.pop ();
    403 }
    404 
    405 /* Return the first element of the stack of bindings.  */
    406 
    407 gbind *
    408 gimple_current_bind_expr (void)
    409 {
    410   return gimplify_ctxp->bind_expr_stack.last ();
    411 }
    412 
    413 /* Return the stack of bindings created during gimplification.  */
    414 
    415 vec<gbind *>
    416 gimple_bind_expr_stack (void)
    417 {
    418   return gimplify_ctxp->bind_expr_stack;
    419 }
    420 
    421 /* Return true iff there is a COND_EXPR between us and the innermost
    422    CLEANUP_POINT_EXPR.  This info is used by gimple_push_cleanup.  */
    423 
    424 static bool
    425 gimple_conditional_context (void)
    426 {
    427   return gimplify_ctxp->conditions > 0;
    428 }
    429 
    430 /* Note that we've entered a COND_EXPR.  */
    431 
    432 static void
    433 gimple_push_condition (void)
    434 {
    435 #ifdef ENABLE_GIMPLE_CHECKING
    436   if (gimplify_ctxp->conditions == 0)
    437     gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
    438 #endif
    439   ++(gimplify_ctxp->conditions);
    440 }
    441 
    442 /* Note that we've left a COND_EXPR.  If we're back at unconditional scope
    443    now, add any conditional cleanups we've seen to the prequeue.  */
    444 
    445 static void
    446 gimple_pop_condition (gimple_seq *pre_p)
    447 {
    448   int conds = --(gimplify_ctxp->conditions);
    449 
    450   gcc_assert (conds >= 0);
    451   if (conds == 0)
    452     {
    453       gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
    454       gimplify_ctxp->conditional_cleanups = NULL;
    455     }
    456 }
    457 
    458 /* A stable comparison routine for use with splay trees and DECLs.  */
    459 
    460 static int
    461 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
    462 {
    463   tree a = (tree) xa;
    464   tree b = (tree) xb;
    465 
    466   return DECL_UID (a) - DECL_UID (b);
    467 }
    468 
    469 /* Create a new omp construct that deals with variable remapping.  */
    470 
    471 static struct gimplify_omp_ctx *
    472 new_omp_context (enum omp_region_type region_type)
    473 {
    474   struct gimplify_omp_ctx *c;
    475 
    476   c = XCNEW (struct gimplify_omp_ctx);
    477   c->outer_context = gimplify_omp_ctxp;
    478   c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
    479   c->privatized_types = new hash_set<tree>;
    480   c->location = input_location;
    481   c->region_type = region_type;
    482   if ((region_type & ORT_TASK) == 0)
    483     c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
    484   else
    485     c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
    486   c->defaultmap[GDMK_SCALAR] = GOVD_MAP;
    487   c->defaultmap[GDMK_SCALAR_TARGET] = GOVD_MAP;
    488   c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
    489   c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
    490   c->defaultmap[GDMK_POINTER] = GOVD_MAP;
    491 
    492   return c;
    493 }
    494 
    495 /* Destroy an omp construct that deals with variable remapping.  */
    496 
    497 static void
    498 delete_omp_context (struct gimplify_omp_ctx *c)
    499 {
    500   splay_tree_delete (c->variables);
    501   delete c->privatized_types;
    502   c->loop_iter_var.release ();
    503   XDELETE (c);
    504 }
    505 
    506 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
    507 static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
    508 
    509 /* Both gimplify the statement T and append it to *SEQ_P.  This function
    510    behaves exactly as gimplify_stmt, but you don't have to pass T as a
    511    reference.  */
    512 
    513 void
    514 gimplify_and_add (tree t, gimple_seq *seq_p)
    515 {
    516   gimplify_stmt (&t, seq_p);
    517 }
    518 
    519 /* Gimplify statement T into sequence *SEQ_P, and return the first
    520    tuple in the sequence of generated tuples for this statement.
    521    Return NULL if gimplifying T produced no tuples.  */
    522 
    523 static gimple *
    524 gimplify_and_return_first (tree t, gimple_seq *seq_p)
    525 {
    526   gimple_stmt_iterator last = gsi_last (*seq_p);
    527 
    528   gimplify_and_add (t, seq_p);
    529 
    530   if (!gsi_end_p (last))
    531     {
    532       gsi_next (&last);
    533       return gsi_stmt (last);
    534     }
    535   else
    536     return gimple_seq_first_stmt (*seq_p);
    537 }
    538 
    539 /* Returns true iff T is a valid RHS for an assignment to an un-renamed
    540    LHS, or for a call argument.  */
    541 
    542 static bool
    543 is_gimple_mem_rhs (tree t)
    544 {
    545   /* If we're dealing with a renamable type, either source or dest must be
    546      a renamed variable.  */
    547   if (is_gimple_reg_type (TREE_TYPE (t)))
    548     return is_gimple_val (t);
    549   else
    550     return is_gimple_val (t) || is_gimple_lvalue (t);
    551 }
    552 
    553 /* Return true if T is a CALL_EXPR or an expression that can be
    554    assigned to a temporary.  Note that this predicate should only be
    555    used during gimplification.  See the rationale for this in
    556    gimplify_modify_expr.  */
    557 
    558 static bool
    559 is_gimple_reg_rhs_or_call (tree t)
    560 {
    561   return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
    562 	  || TREE_CODE (t) == CALL_EXPR);
    563 }
    564 
    565 /* Return true if T is a valid memory RHS or a CALL_EXPR.  Note that
    566    this predicate should only be used during gimplification.  See the
    567    rationale for this in gimplify_modify_expr.  */
    568 
    569 static bool
    570 is_gimple_mem_rhs_or_call (tree t)
    571 {
    572   /* If we're dealing with a renamable type, either source or dest must be
    573      a renamed variable.  */
    574   if (is_gimple_reg_type (TREE_TYPE (t)))
    575     return is_gimple_val (t);
    576   else
    577     return (is_gimple_val (t)
    578 	    || is_gimple_lvalue (t)
    579 	    || (TREE_CODE (t) == CONSTRUCTOR && CONSTRUCTOR_NELTS (t) == 0)
    580 	    || TREE_CODE (t) == CALL_EXPR);
    581 }
    582 
    583 /* Create a temporary with a name derived from VAL.  Subroutine of
    584    lookup_tmp_var; nobody else should call this function.  */
    585 
    586 static inline tree
    587 create_tmp_from_val (tree val)
    588 {
    589   /* Drop all qualifiers and address-space information from the value type.  */
    590   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
    591   tree var = create_tmp_var (type, get_name (val));
    592   return var;
    593 }
    594 
    595 /* Create a temporary to hold the value of VAL.  If IS_FORMAL, try to reuse
    596    an existing expression temporary.  If NOT_GIMPLE_REG, mark it as such.  */
    597 
    598 static tree
    599 lookup_tmp_var (tree val, bool is_formal, bool not_gimple_reg)
    600 {
    601   tree ret;
    602 
    603   /* We cannot mark a formal temporary with DECL_NOT_GIMPLE_REG_P.  */
    604   gcc_assert (!is_formal || !not_gimple_reg);
    605 
    606   /* If not optimizing, never really reuse a temporary.  local-alloc
    607      won't allocate any variable that is used in more than one basic
    608      block, which means it will go into memory, causing much extra
    609      work in reload and final and poorer code generation, outweighing
    610      the extra memory allocation here.  */
    611   if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
    612     {
    613       ret = create_tmp_from_val (val);
    614       DECL_NOT_GIMPLE_REG_P (ret) = not_gimple_reg;
    615     }
    616   else
    617     {
    618       elt_t elt, *elt_p;
    619       elt_t **slot;
    620 
    621       elt.val = val;
    622       if (!gimplify_ctxp->temp_htab)
    623         gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
    624       slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
    625       if (*slot == NULL)
    626 	{
    627 	  elt_p = XNEW (elt_t);
    628 	  elt_p->val = val;
    629 	  elt_p->temp = ret = create_tmp_from_val (val);
    630 	  *slot = elt_p;
    631 	}
    632       else
    633 	{
    634 	  elt_p = *slot;
    635           ret = elt_p->temp;
    636 	}
    637     }
    638 
    639   return ret;
    640 }
    641 
    642 /* Helper for get_formal_tmp_var and get_initialized_tmp_var.  */
    643 
    644 static tree
    645 internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
    646 		      bool is_formal, bool allow_ssa, bool not_gimple_reg)
    647 {
    648   tree t, mod;
    649 
    650   /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
    651      can create an INIT_EXPR and convert it into a GIMPLE_CALL below.  */
    652   gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
    653 		 fb_rvalue);
    654 
    655   if (allow_ssa
    656       && gimplify_ctxp->into_ssa
    657       && is_gimple_reg_type (TREE_TYPE (val)))
    658     {
    659       t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
    660       if (! gimple_in_ssa_p (cfun))
    661 	{
    662 	  const char *name = get_name (val);
    663 	  if (name)
    664 	    SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
    665 	}
    666     }
    667   else
    668     t = lookup_tmp_var (val, is_formal, not_gimple_reg);
    669 
    670   mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
    671 
    672   SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
    673 
    674   /* gimplify_modify_expr might want to reduce this further.  */
    675   gimplify_and_add (mod, pre_p);
    676   ggc_free (mod);
    677 
    678   /* If we failed to gimplify VAL then we can end up with the temporary
    679      SSA name not having a definition.  In this case return a decl.  */
    680   if (TREE_CODE (t) == SSA_NAME && ! SSA_NAME_DEF_STMT (t))
    681     return lookup_tmp_var (val, is_formal, not_gimple_reg);
    682 
    683   return t;
    684 }
    685 
    686 /* Return a formal temporary variable initialized with VAL.  PRE_P is as
    687    in gimplify_expr.  Only use this function if:
    688 
    689    1) The value of the unfactored expression represented by VAL will not
    690       change between the initialization and use of the temporary, and
    691    2) The temporary will not be otherwise modified.
    692 
    693    For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
    694    and #2 means it is inappropriate for && temps.
    695 
    696    For other cases, use get_initialized_tmp_var instead.  */
    697 
    698 tree
    699 get_formal_tmp_var (tree val, gimple_seq *pre_p)
    700 {
    701   return internal_get_tmp_var (val, pre_p, NULL, true, true, false);
    702 }
    703 
    704 /* Return a temporary variable initialized with VAL.  PRE_P and POST_P
    705    are as in gimplify_expr.  */
    706 
    707 tree
    708 get_initialized_tmp_var (tree val, gimple_seq *pre_p,
    709 			 gimple_seq *post_p /* = NULL */,
    710 			 bool allow_ssa /* = true */)
    711 {
    712   return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa, false);
    713 }
    714 
    715 /* Declare all the variables in VARS in SCOPE.  If DEBUG_INFO is true,
    716    generate debug info for them; otherwise don't.  */
    717 
    718 void
    719 declare_vars (tree vars, gimple *gs, bool debug_info)
    720 {
    721   tree last = vars;
    722   if (last)
    723     {
    724       tree temps, block;
    725 
    726       gbind *scope = as_a <gbind *> (gs);
    727 
    728       temps = nreverse (last);
    729 
    730       block = gimple_bind_block (scope);
    731       gcc_assert (!block || TREE_CODE (block) == BLOCK);
    732       if (!block || !debug_info)
    733 	{
    734 	  DECL_CHAIN (last) = gimple_bind_vars (scope);
    735 	  gimple_bind_set_vars (scope, temps);
    736 	}
    737       else
    738 	{
    739 	  /* We need to attach the nodes both to the BIND_EXPR and to its
    740 	     associated BLOCK for debugging purposes.  The key point here
    741 	     is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
    742 	     is a subchain of the BIND_EXPR_VARS of the BIND_EXPR.  */
    743 	  if (BLOCK_VARS (block))
    744 	    BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
    745 	  else
    746 	    {
    747 	      gimple_bind_set_vars (scope,
    748 	      			    chainon (gimple_bind_vars (scope), temps));
    749 	      BLOCK_VARS (block) = temps;
    750 	    }
    751 	}
    752     }
    753 }
    754 
    755 /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
    756    for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly.  Abort if
    757    no such upper bound can be obtained.  */
    758 
    759 static void
    760 force_constant_size (tree var)
    761 {
    762   /* The only attempt we make is by querying the maximum size of objects
    763      of the variable's type.  */
    764 
    765   HOST_WIDE_INT max_size;
    766 
    767   gcc_assert (VAR_P (var));
    768 
    769   max_size = max_int_size_in_bytes (TREE_TYPE (var));
    770 
    771   gcc_assert (max_size >= 0);
    772 
    773   DECL_SIZE_UNIT (var)
    774     = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
    775   DECL_SIZE (var)
    776     = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
    777 }
    778 
    779 /* Push the temporary variable TMP into the current binding.  */
    780 
    781 void
    782 gimple_add_tmp_var_fn (struct function *fn, tree tmp)
    783 {
    784   gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
    785 
    786   /* Later processing assumes that the object size is constant, which might
    787      not be true at this point.  Force the use of a constant upper bound in
    788      this case.  */
    789   if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
    790     force_constant_size (tmp);
    791 
    792   DECL_CONTEXT (tmp) = fn->decl;
    793   DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
    794 
    795   record_vars_into (tmp, fn->decl);
    796 }
    797 
    798 /* Push the temporary variable TMP into the current binding.  */
    799 
    800 void
    801 gimple_add_tmp_var (tree tmp)
    802 {
    803   gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
    804 
    805   /* Later processing assumes that the object size is constant, which might
    806      not be true at this point.  Force the use of a constant upper bound in
    807      this case.  */
    808   if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
    809     force_constant_size (tmp);
    810 
    811   DECL_CONTEXT (tmp) = current_function_decl;
    812   DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
    813 
    814   if (gimplify_ctxp)
    815     {
    816       DECL_CHAIN (tmp) = gimplify_ctxp->temps;
    817       gimplify_ctxp->temps = tmp;
    818 
    819       /* Mark temporaries local within the nearest enclosing parallel.  */
    820       if (gimplify_omp_ctxp)
    821 	{
    822 	  struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
    823 	  int flag = GOVD_LOCAL | GOVD_SEEN;
    824 	  while (ctx
    825 		 && (ctx->region_type == ORT_WORKSHARE
    826 		     || ctx->region_type == ORT_TASKGROUP
    827 		     || ctx->region_type == ORT_SIMD
    828 		     || ctx->region_type == ORT_ACC))
    829 	    {
    830 	      if (ctx->region_type == ORT_SIMD
    831 		  && TREE_ADDRESSABLE (tmp)
    832 		  && !TREE_STATIC (tmp))
    833 		{
    834 		  if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
    835 		    ctx->add_safelen1 = true;
    836 		  else if (ctx->in_for_exprs)
    837 		    flag = GOVD_PRIVATE;
    838 		  else
    839 		    flag = GOVD_PRIVATE | GOVD_SEEN;
    840 		  break;
    841 		}
    842 	      ctx = ctx->outer_context;
    843 	    }
    844 	  if (ctx)
    845 	    omp_add_variable (ctx, tmp, flag);
    846 	}
    847     }
    848   else if (cfun)
    849     record_vars (tmp);
    850   else
    851     {
    852       gimple_seq body_seq;
    853 
    854       /* This case is for nested functions.  We need to expose the locals
    855 	 they create.  */
    856       body_seq = gimple_body (current_function_decl);
    857       declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
    858     }
    859 }
    860 
    861 
    862 
    863 /* This page contains routines to unshare tree nodes, i.e. to duplicate tree
    865    nodes that are referenced more than once in GENERIC functions.  This is
    866    necessary because gimplification (translation into GIMPLE) is performed
    867    by modifying tree nodes in-place, so gimplication of a shared node in a
    868    first context could generate an invalid GIMPLE form in a second context.
    869 
    870    This is achieved with a simple mark/copy/unmark algorithm that walks the
    871    GENERIC representation top-down, marks nodes with TREE_VISITED the first
    872    time it encounters them, duplicates them if they already have TREE_VISITED
    873    set, and finally removes the TREE_VISITED marks it has set.
    874 
    875    The algorithm works only at the function level, i.e. it generates a GENERIC
    876    representation of a function with no nodes shared within the function when
    877    passed a GENERIC function (except for nodes that are allowed to be shared).
    878 
    879    At the global level, it is also necessary to unshare tree nodes that are
    880    referenced in more than one function, for the same aforementioned reason.
    881    This requires some cooperation from the front-end.  There are 2 strategies:
    882 
    883      1. Manual unsharing.  The front-end needs to call unshare_expr on every
    884         expression that might end up being shared across functions.
    885 
    886      2. Deep unsharing.  This is an extension of regular unsharing.  Instead
    887         of calling unshare_expr on expressions that might be shared across
    888         functions, the front-end pre-marks them with TREE_VISITED.  This will
    889         ensure that they are unshared on the first reference within functions
    890         when the regular unsharing algorithm runs.  The counterpart is that
    891         this algorithm must look deeper than for manual unsharing, which is
    892         specified by LANG_HOOKS_DEEP_UNSHARING.
    893 
    894   If there are only few specific cases of node sharing across functions, it is
    895   probably easier for a front-end to unshare the expressions manually.  On the
    896   contrary, if the expressions generated at the global level are as widespread
    897   as expressions generated within functions, deep unsharing is very likely the
    898   way to go.  */
    899 
    900 /* Similar to copy_tree_r but do not copy SAVE_EXPR or TARGET_EXPR nodes.
    901    These nodes model computations that must be done once.  If we were to
    902    unshare something like SAVE_EXPR(i++), the gimplification process would
    903    create wrong code.  However, if DATA is non-null, it must hold a pointer
    904    set that is used to unshare the subtrees of these nodes.  */
    905 
    906 static tree
    907 mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
    908 {
    909   tree t = *tp;
    910   enum tree_code code = TREE_CODE (t);
    911 
    912   /* Do not copy SAVE_EXPR, TARGET_EXPR or BIND_EXPR nodes themselves, but
    913      copy their subtrees if we can make sure to do it only once.  */
    914   if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
    915     {
    916       if (data && !((hash_set<tree> *)data)->add (t))
    917 	;
    918       else
    919 	*walk_subtrees = 0;
    920     }
    921 
    922   /* Stop at types, decls, constants like copy_tree_r.  */
    923   else if (TREE_CODE_CLASS (code) == tcc_type
    924 	   || TREE_CODE_CLASS (code) == tcc_declaration
    925 	   || TREE_CODE_CLASS (code) == tcc_constant)
    926     *walk_subtrees = 0;
    927 
    928   /* Cope with the statement expression extension.  */
    929   else if (code == STATEMENT_LIST)
    930     ;
    931 
    932   /* Leave the bulk of the work to copy_tree_r itself.  */
    933   else
    934     copy_tree_r (tp, walk_subtrees, NULL);
    935 
    936   return NULL_TREE;
    937 }
    938 
    939 /* Callback for walk_tree to unshare most of the shared trees rooted at *TP.
    940    If *TP has been visited already, then *TP is deeply copied by calling
    941    mostly_copy_tree_r.  DATA is passed to mostly_copy_tree_r unmodified.  */
    942 
    943 static tree
    944 copy_if_shared_r (tree *tp, int *walk_subtrees, void *data)
    945 {
    946   tree t = *tp;
    947   enum tree_code code = TREE_CODE (t);
    948 
    949   /* Skip types, decls, and constants.  But we do want to look at their
    950      types and the bounds of types.  Mark them as visited so we properly
    951      unmark their subtrees on the unmark pass.  If we've already seen them,
    952      don't look down further.  */
    953   if (TREE_CODE_CLASS (code) == tcc_type
    954       || TREE_CODE_CLASS (code) == tcc_declaration
    955       || TREE_CODE_CLASS (code) == tcc_constant)
    956     {
    957       if (TREE_VISITED (t))
    958 	*walk_subtrees = 0;
    959       else
    960 	TREE_VISITED (t) = 1;
    961     }
    962 
    963   /* If this node has been visited already, unshare it and don't look
    964      any deeper.  */
    965   else if (TREE_VISITED (t))
    966     {
    967       walk_tree (tp, mostly_copy_tree_r, data, NULL);
    968       *walk_subtrees = 0;
    969     }
    970 
    971   /* Otherwise, mark the node as visited and keep looking.  */
    972   else
    973     TREE_VISITED (t) = 1;
    974 
    975   return NULL_TREE;
    976 }
    977 
    978 /* Unshare most of the shared trees rooted at *TP.  DATA is passed to the
    979    copy_if_shared_r callback unmodified.  */
    980 
    981 void
    982 copy_if_shared (tree *tp, void *data)
    983 {
    984   walk_tree (tp, copy_if_shared_r, data, NULL);
    985 }
    986 
    987 /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
    988    any nested functions.  */
    989 
    990 static void
    991 unshare_body (tree fndecl)
    992 {
    993   struct cgraph_node *cgn = cgraph_node::get (fndecl);
    994   /* If the language requires deep unsharing, we need a pointer set to make
    995      sure we don't repeatedly unshare subtrees of unshareable nodes.  */
    996   hash_set<tree> *visited
    997     = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
    998 
    999   copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
   1000   copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
   1001   copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
   1002 
   1003   delete visited;
   1004 
   1005   if (cgn)
   1006     for (cgn = first_nested_function (cgn); cgn;
   1007 	 cgn = next_nested_function (cgn))
   1008       unshare_body (cgn->decl);
   1009 }
   1010 
   1011 /* Callback for walk_tree to unmark the visited trees rooted at *TP.
   1012    Subtrees are walked until the first unvisited node is encountered.  */
   1013 
   1014 static tree
   1015 unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
   1016 {
   1017   tree t = *tp;
   1018 
   1019   /* If this node has been visited, unmark it and keep looking.  */
   1020   if (TREE_VISITED (t))
   1021     TREE_VISITED (t) = 0;
   1022 
   1023   /* Otherwise, don't look any deeper.  */
   1024   else
   1025     *walk_subtrees = 0;
   1026 
   1027   return NULL_TREE;
   1028 }
   1029 
   1030 /* Unmark the visited trees rooted at *TP.  */
   1031 
   1032 static inline void
   1033 unmark_visited (tree *tp)
   1034 {
   1035   walk_tree (tp, unmark_visited_r, NULL, NULL);
   1036 }
   1037 
   1038 /* Likewise, but mark all trees as not visited.  */
   1039 
   1040 static void
   1041 unvisit_body (tree fndecl)
   1042 {
   1043   struct cgraph_node *cgn = cgraph_node::get (fndecl);
   1044 
   1045   unmark_visited (&DECL_SAVED_TREE (fndecl));
   1046   unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
   1047   unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
   1048 
   1049   if (cgn)
   1050     for (cgn = first_nested_function (cgn);
   1051 	 cgn; cgn = next_nested_function (cgn))
   1052       unvisit_body (cgn->decl);
   1053 }
   1054 
   1055 /* Unconditionally make an unshared copy of EXPR.  This is used when using
   1056    stored expressions which span multiple functions, such as BINFO_VTABLE,
   1057    as the normal unsharing process can't tell that they're shared.  */
   1058 
   1059 tree
   1060 unshare_expr (tree expr)
   1061 {
   1062   walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
   1063   return expr;
   1064 }
   1065 
   1066 /* Worker for unshare_expr_without_location.  */
   1067 
   1068 static tree
   1069 prune_expr_location (tree *tp, int *walk_subtrees, void *)
   1070 {
   1071   if (EXPR_P (*tp))
   1072     SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
   1073   else
   1074     *walk_subtrees = 0;
   1075   return NULL_TREE;
   1076 }
   1077 
   1078 /* Similar to unshare_expr but also prune all expression locations
   1079    from EXPR.  */
   1080 
   1081 tree
   1082 unshare_expr_without_location (tree expr)
   1083 {
   1084   walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
   1085   if (EXPR_P (expr))
   1086     walk_tree (&expr, prune_expr_location, NULL, NULL);
   1087   return expr;
   1088 }
   1089 
   1090 /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
   1091    one, OR_ELSE otherwise.  The location of a STATEMENT_LISTs
   1092    comprising at least one DEBUG_BEGIN_STMT followed by exactly one
   1093    EXPR is the location of the EXPR.  */
   1094 
   1095 static location_t
   1096 rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION)
   1097 {
   1098   if (!expr)
   1099     return or_else;
   1100 
   1101   if (EXPR_HAS_LOCATION (expr))
   1102     return EXPR_LOCATION (expr);
   1103 
   1104   if (TREE_CODE (expr) != STATEMENT_LIST)
   1105     return or_else;
   1106 
   1107   tree_stmt_iterator i = tsi_start (expr);
   1108 
   1109   bool found = false;
   1110   while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
   1111     {
   1112       found = true;
   1113       tsi_next (&i);
   1114     }
   1115 
   1116   if (!found || !tsi_one_before_end_p (i))
   1117     return or_else;
   1118 
   1119   return rexpr_location (tsi_stmt (i), or_else);
   1120 }
   1121 
   1122 /* Return TRUE iff EXPR (maybe recursively) has a location; see
   1123    rexpr_location for the potential recursion.  */
   1124 
   1125 static inline bool
   1126 rexpr_has_location (tree expr)
   1127 {
   1128   return rexpr_location (expr) != UNKNOWN_LOCATION;
   1129 }
   1130 
   1131 
   1132 /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
   1134    contain statements and have a value.  Assign its value to a temporary
   1135    and give it void_type_node.  Return the temporary, or NULL_TREE if
   1136    WRAPPER was already void.  */
   1137 
   1138 tree
   1139 voidify_wrapper_expr (tree wrapper, tree temp)
   1140 {
   1141   tree type = TREE_TYPE (wrapper);
   1142   if (type && !VOID_TYPE_P (type))
   1143     {
   1144       tree *p;
   1145 
   1146       /* Set p to point to the body of the wrapper.  Loop until we find
   1147 	 something that isn't a wrapper.  */
   1148       for (p = &wrapper; p && *p; )
   1149 	{
   1150 	  switch (TREE_CODE (*p))
   1151 	    {
   1152 	    case BIND_EXPR:
   1153 	      TREE_SIDE_EFFECTS (*p) = 1;
   1154 	      TREE_TYPE (*p) = void_type_node;
   1155 	      /* For a BIND_EXPR, the body is operand 1.  */
   1156 	      p = &BIND_EXPR_BODY (*p);
   1157 	      break;
   1158 
   1159 	    case CLEANUP_POINT_EXPR:
   1160 	    case TRY_FINALLY_EXPR:
   1161 	    case TRY_CATCH_EXPR:
   1162 	      TREE_SIDE_EFFECTS (*p) = 1;
   1163 	      TREE_TYPE (*p) = void_type_node;
   1164 	      p = &TREE_OPERAND (*p, 0);
   1165 	      break;
   1166 
   1167 	    case STATEMENT_LIST:
   1168 	      {
   1169 		tree_stmt_iterator i = tsi_last (*p);
   1170 		TREE_SIDE_EFFECTS (*p) = 1;
   1171 		TREE_TYPE (*p) = void_type_node;
   1172 		p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
   1173 	      }
   1174 	      break;
   1175 
   1176 	    case COMPOUND_EXPR:
   1177 	      /* Advance to the last statement.  Set all container types to
   1178 		 void.  */
   1179 	      for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
   1180 		{
   1181 		  TREE_SIDE_EFFECTS (*p) = 1;
   1182 		  TREE_TYPE (*p) = void_type_node;
   1183 		}
   1184 	      break;
   1185 
   1186 	    case TRANSACTION_EXPR:
   1187 	      TREE_SIDE_EFFECTS (*p) = 1;
   1188 	      TREE_TYPE (*p) = void_type_node;
   1189 	      p = &TRANSACTION_EXPR_BODY (*p);
   1190 	      break;
   1191 
   1192 	    default:
   1193 	      /* Assume that any tree upon which voidify_wrapper_expr is
   1194 		 directly called is a wrapper, and that its body is op0.  */
   1195 	      if (p == &wrapper)
   1196 		{
   1197 		  TREE_SIDE_EFFECTS (*p) = 1;
   1198 		  TREE_TYPE (*p) = void_type_node;
   1199 		  p = &TREE_OPERAND (*p, 0);
   1200 		  break;
   1201 		}
   1202 	      goto out;
   1203 	    }
   1204 	}
   1205 
   1206     out:
   1207       if (p == NULL || IS_EMPTY_STMT (*p))
   1208 	temp = NULL_TREE;
   1209       else if (temp)
   1210 	{
   1211 	  /* The wrapper is on the RHS of an assignment that we're pushing
   1212 	     down.  */
   1213 	  gcc_assert (TREE_CODE (temp) == INIT_EXPR
   1214 		      || TREE_CODE (temp) == MODIFY_EXPR);
   1215 	  TREE_OPERAND (temp, 1) = *p;
   1216 	  *p = temp;
   1217 	}
   1218       else
   1219 	{
   1220 	  temp = create_tmp_var (type, "retval");
   1221 	  *p = build2 (INIT_EXPR, type, temp, *p);
   1222 	}
   1223 
   1224       return temp;
   1225     }
   1226 
   1227   return NULL_TREE;
   1228 }
   1229 
   1230 /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
   1231    a temporary through which they communicate.  */
   1232 
   1233 static void
   1234 build_stack_save_restore (gcall **save, gcall **restore)
   1235 {
   1236   tree tmp_var;
   1237 
   1238   *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
   1239   tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
   1240   gimple_call_set_lhs (*save, tmp_var);
   1241 
   1242   *restore
   1243     = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
   1244 			 1, tmp_var);
   1245 }
   1246 
   1247 /* Generate IFN_ASAN_MARK call that poisons shadow of a for DECL variable.  */
   1248 
   1249 static tree
   1250 build_asan_poison_call_expr (tree decl)
   1251 {
   1252   /* Do not poison variables that have size equal to zero.  */
   1253   tree unit_size = DECL_SIZE_UNIT (decl);
   1254   if (zerop (unit_size))
   1255     return NULL_TREE;
   1256 
   1257   tree base = build_fold_addr_expr (decl);
   1258 
   1259   return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
   1260 				       void_type_node, 3,
   1261 				       build_int_cst (integer_type_node,
   1262 						      ASAN_MARK_POISON),
   1263 				       base, unit_size);
   1264 }
   1265 
   1266 /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
   1267    on POISON flag, shadow memory of a DECL variable.  The call will be
   1268    put on location identified by IT iterator, where BEFORE flag drives
   1269    position where the stmt will be put.  */
   1270 
   1271 static void
   1272 asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
   1273 		      bool before)
   1274 {
   1275   tree unit_size = DECL_SIZE_UNIT (decl);
   1276   tree base = build_fold_addr_expr (decl);
   1277 
   1278   /* Do not poison variables that have size equal to zero.  */
   1279   if (zerop (unit_size))
   1280     return;
   1281 
   1282   /* It's necessary to have all stack variables aligned to ASAN granularity
   1283      bytes.  */
   1284   gcc_assert (!hwasan_sanitize_p () || hwasan_sanitize_stack_p ());
   1285   unsigned shadow_granularity
   1286     = hwasan_sanitize_p () ? HWASAN_TAG_GRANULE_SIZE : ASAN_SHADOW_GRANULARITY;
   1287   if (DECL_ALIGN_UNIT (decl) <= shadow_granularity)
   1288     SET_DECL_ALIGN (decl, BITS_PER_UNIT * shadow_granularity);
   1289 
   1290   HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
   1291 
   1292   gimple *g
   1293     = gimple_build_call_internal (IFN_ASAN_MARK, 3,
   1294 				  build_int_cst (integer_type_node, flags),
   1295 				  base, unit_size);
   1296 
   1297   if (before)
   1298     gsi_insert_before (it, g, GSI_NEW_STMT);
   1299   else
   1300     gsi_insert_after (it, g, GSI_NEW_STMT);
   1301 }
   1302 
   1303 /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
   1304    either poisons or unpoisons a DECL.  Created statement is appended
   1305    to SEQ_P gimple sequence.  */
   1306 
   1307 static void
   1308 asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
   1309 {
   1310   gimple_stmt_iterator it = gsi_last (*seq_p);
   1311   bool before = false;
   1312 
   1313   if (gsi_end_p (it))
   1314     before = true;
   1315 
   1316   asan_poison_variable (decl, poison, &it, before);
   1317 }
   1318 
   1319 /* Sort pair of VAR_DECLs A and B by DECL_UID.  */
   1320 
   1321 static int
   1322 sort_by_decl_uid (const void *a, const void *b)
   1323 {
   1324   const tree *t1 = (const tree *)a;
   1325   const tree *t2 = (const tree *)b;
   1326 
   1327   int uid1 = DECL_UID (*t1);
   1328   int uid2 = DECL_UID (*t2);
   1329 
   1330   if (uid1 < uid2)
   1331     return -1;
   1332   else if (uid1 > uid2)
   1333     return 1;
   1334   else
   1335     return 0;
   1336 }
   1337 
   1338 /* Generate IFN_ASAN_MARK internal call for all VARIABLES
   1339    depending on POISON flag.  Created statement is appended
   1340    to SEQ_P gimple sequence.  */
   1341 
   1342 static void
   1343 asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
   1344 {
   1345   unsigned c = variables->elements ();
   1346   if (c == 0)
   1347     return;
   1348 
   1349   auto_vec<tree> sorted_variables (c);
   1350 
   1351   for (hash_set<tree>::iterator it = variables->begin ();
   1352        it != variables->end (); ++it)
   1353     sorted_variables.safe_push (*it);
   1354 
   1355   sorted_variables.qsort (sort_by_decl_uid);
   1356 
   1357   unsigned i;
   1358   tree var;
   1359   FOR_EACH_VEC_ELT (sorted_variables, i, var)
   1360     {
   1361       asan_poison_variable (var, poison, seq_p);
   1362 
   1363       /* Add use_after_scope_memory attribute for the variable in order
   1364 	 to prevent re-written into SSA.  */
   1365       if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
   1366 			     DECL_ATTRIBUTES (var)))
   1367 	DECL_ATTRIBUTES (var)
   1368 	  = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
   1369 		       integer_one_node,
   1370 		       DECL_ATTRIBUTES (var));
   1371     }
   1372 }
   1373 
   1374 /* Gimplify a BIND_EXPR.  Just voidify and recurse.  */
   1375 
   1376 static enum gimplify_status
   1377 gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
   1378 {
   1379   tree bind_expr = *expr_p;
   1380   bool old_keep_stack = gimplify_ctxp->keep_stack;
   1381   bool old_save_stack = gimplify_ctxp->save_stack;
   1382   tree t;
   1383   gbind *bind_stmt;
   1384   gimple_seq body, cleanup;
   1385   gcall *stack_save;
   1386   location_t start_locus = 0, end_locus = 0;
   1387   tree ret_clauses = NULL;
   1388 
   1389   tree temp = voidify_wrapper_expr (bind_expr, NULL);
   1390 
   1391   /* Mark variables seen in this bind expr.  */
   1392   for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
   1393     {
   1394       if (VAR_P (t))
   1395 	{
   1396 	  struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   1397 	  tree attr;
   1398 
   1399 	  if (flag_openmp
   1400 	      && !is_global_var (t)
   1401 	      && DECL_CONTEXT (t) == current_function_decl
   1402 	      && TREE_USED (t)
   1403 	      && (attr = lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t)))
   1404 		 != NULL_TREE)
   1405 	    {
   1406 	      gcc_assert (!DECL_HAS_VALUE_EXPR_P (t));
   1407 	      tree alloc = TREE_PURPOSE (TREE_VALUE (attr));
   1408 	      tree align = TREE_VALUE (TREE_VALUE (attr));
   1409 	      /* Allocate directives that appear in a target region must specify
   1410 		 an allocator clause unless a requires directive with the
   1411 		 dynamic_allocators clause is present in the same compilation
   1412 		 unit.  */
   1413 	      bool missing_dyn_alloc = false;
   1414 	      if (alloc == NULL_TREE
   1415 		  && ((omp_requires_mask & OMP_REQUIRES_DYNAMIC_ALLOCATORS)
   1416 		      == 0))
   1417 		{
   1418 		  /* This comes too early for omp_discover_declare_target...,
   1419 		     but should at least catch the most common cases.  */
   1420 		  missing_dyn_alloc
   1421 		    = cgraph_node::get (current_function_decl)->offloadable;
   1422 		  for (struct gimplify_omp_ctx *ctx2 = ctx;
   1423 		       ctx2 && !missing_dyn_alloc; ctx2 = ctx2->outer_context)
   1424 		    if (ctx2->code == OMP_TARGET)
   1425 		      missing_dyn_alloc = true;
   1426 		}
   1427 	      if (missing_dyn_alloc)
   1428 		error_at (DECL_SOURCE_LOCATION (t),
   1429 			  "%<allocate%> directive for %qD inside a target "
   1430 			  "region must specify an %<allocator%> clause", t);
   1431 	      /* Skip for omp_default_mem_alloc (= 1),
   1432 		 unless align is present. */
   1433 	      else if (!errorcount
   1434 		       && (align != NULL_TREE
   1435 			   || alloc == NULL_TREE
   1436 			   || !integer_onep (alloc)))
   1437 		{
   1438 		  /* Fortran might already use a pointer type internally;
   1439 		     use that pointer except for type(C_ptr) and type(C_funptr);
   1440 		     note that normal proc pointers are rejected.  */
   1441 		  tree type = TREE_TYPE (t);
   1442 		  tree tmp, v;
   1443 		  if (lang_GNU_Fortran ()
   1444 		      && POINTER_TYPE_P (type)
   1445 		      && TREE_TYPE (type) != void_type_node
   1446 		      && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
   1447 		    {
   1448 		      type = TREE_TYPE (type);
   1449 		      v = t;
   1450 		    }
   1451 		  else
   1452 		    {
   1453 		      tmp = build_pointer_type (type);
   1454 		      v = create_tmp_var (tmp, get_name (t));
   1455 		      DECL_IGNORED_P (v) = 0;
   1456 		      DECL_ATTRIBUTES (v)
   1457 			= tree_cons (get_identifier ("omp allocate var"),
   1458 				     build_tree_list (NULL_TREE, t),
   1459 				     remove_attribute ("omp allocate",
   1460 						       DECL_ATTRIBUTES (t)));
   1461 		      tmp = build_fold_indirect_ref (v);
   1462 		      TREE_THIS_NOTRAP (tmp) = 1;
   1463 		      SET_DECL_VALUE_EXPR (t, tmp);
   1464 		      DECL_HAS_VALUE_EXPR_P (t) = 1;
   1465 		    }
   1466 		  tree sz = TYPE_SIZE_UNIT (type);
   1467 		  /* The size to use in Fortran might not match TYPE_SIZE_UNIT;
   1468 		     hence, for some decls, a size variable is saved in the
   1469 		     attributes; use it, if available.  */
   1470 		  if (TREE_CHAIN (TREE_VALUE (attr))
   1471 		      && TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)))
   1472 		      && TREE_PURPOSE (
   1473 			   TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)))))
   1474 		    {
   1475 		      sz = TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)));
   1476 		      sz = TREE_PURPOSE (sz);
   1477 		    }
   1478 		  if (alloc == NULL_TREE)
   1479 		    alloc = build_zero_cst (ptr_type_node);
   1480 		  if (align == NULL_TREE)
   1481 		    align = build_int_cst (size_type_node, DECL_ALIGN_UNIT (t));
   1482 		  else
   1483 		    align = build_int_cst (size_type_node,
   1484 					   MAX (tree_to_uhwi (align),
   1485 						DECL_ALIGN_UNIT (t)));
   1486 		  location_t loc = DECL_SOURCE_LOCATION (t);
   1487 		  tmp = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC);
   1488 		  tmp = build_call_expr_loc (loc, tmp, 3, align, sz, alloc);
   1489 		  tmp = fold_build2_loc (loc, MODIFY_EXPR, TREE_TYPE (v), v,
   1490 					 fold_convert (TREE_TYPE (v), tmp));
   1491 		  gcc_assert (BIND_EXPR_BODY (bind_expr) != NULL_TREE);
   1492 		  /* Ensure that either TREE_CHAIN (TREE_VALUE (attr) is set
   1493 		     and GOMP_FREE added here or that DECL_HAS_VALUE_EXPR_P (t)
   1494 		     is set, using in a condition much further below.  */
   1495 		  gcc_assert (DECL_HAS_VALUE_EXPR_P (t)
   1496 			      || TREE_CHAIN (TREE_VALUE (attr)));
   1497 		  if (TREE_CHAIN (TREE_VALUE (attr)))
   1498 		    {
   1499 		      /* Fortran is special as it does not have properly nest
   1500 			 declarations in blocks.  And as there is no
   1501 			 initializer, there is also no expression to look for.
   1502 			 Hence, the FE makes the statement list of the
   1503 			 try-finally block available. We can put the GOMP_alloc
   1504 			 at the top, unless an allocator or size expression
   1505 			 requires to put it afterward; note that the size is
   1506 			 always later in generated code; for strings, no
   1507 			 size expr but still an expr might be available.
   1508 			 As LTO does not handle a statement list, 'sl' has
   1509 			 to be removed; done so by removing the attribute.  */
   1510 		      DECL_ATTRIBUTES (t)
   1511 			= remove_attribute ("omp allocate",
   1512 					    DECL_ATTRIBUTES (t));
   1513 		      tree sl = TREE_PURPOSE (TREE_CHAIN (TREE_VALUE (attr)));
   1514 		      tree_stmt_iterator e = tsi_start (sl);
   1515 		      tree needle = NULL_TREE;
   1516 		      if (TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr))))
   1517 			{
   1518 			  needle = TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)));
   1519 			  needle = (TREE_VALUE (needle) ? TREE_VALUE (needle)
   1520 							: sz);
   1521 			}
   1522 		      else if (TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr))))
   1523 			needle = sz;
   1524 		      else if (DECL_P (alloc) && DECL_ARTIFICIAL (alloc))
   1525 			needle = alloc;
   1526 
   1527 		      if (needle != NULL_TREE)
   1528 			{
   1529 			  while (!tsi_end_p (e))
   1530 			    {
   1531 			      if (*e == needle
   1532 				  || (TREE_CODE (*e) == MODIFY_EXPR
   1533 				      && TREE_OPERAND (*e, 0) == needle))
   1534 				break;
   1535 			      ++e;
   1536 			    }
   1537 			  gcc_assert (!tsi_end_p (e));
   1538 			}
   1539 		      tsi_link_after (&e, tmp, TSI_SAME_STMT);
   1540 
   1541 		      /* As the cleanup is in BIND_EXPR_BODY, GOMP_free is added
   1542 			 here; for C/C++ it will be added in the 'cleanup'
   1543 			 section after gimplification. But Fortran already has
   1544 			 a try-finally block.  */
   1545 		      sl = TREE_VALUE (TREE_CHAIN (TREE_VALUE (attr)));
   1546 		      e = tsi_last (sl);
   1547 		      tmp = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
   1548 		      tmp = build_call_expr_loc (EXPR_LOCATION (*e), tmp, 2, v,
   1549 						 build_zero_cst (ptr_type_node));
   1550 		      tsi_link_after (&e, tmp, TSI_SAME_STMT);
   1551 		      tmp = build_clobber (TREE_TYPE (v), CLOBBER_STORAGE_END);
   1552 		      tmp = fold_build2_loc (loc, MODIFY_EXPR, TREE_TYPE (v), v,
   1553 					     fold_convert (TREE_TYPE (v), tmp));
   1554 		      ++e;
   1555 		      tsi_link_after (&e, tmp, TSI_SAME_STMT);
   1556 		    }
   1557 		  else
   1558 		    {
   1559 		      gcc_assert (TREE_CODE (BIND_EXPR_BODY (bind_expr))
   1560 				  == STATEMENT_LIST);
   1561 		      tree_stmt_iterator e;
   1562 		      e = tsi_start (BIND_EXPR_BODY (bind_expr));
   1563 		      while (!tsi_end_p (e))
   1564 			{
   1565 			  if ((TREE_CODE (*e) == DECL_EXPR
   1566 			       && TREE_OPERAND (*e, 0) == t)
   1567 			      || (TREE_CODE (*e) == CLEANUP_POINT_EXPR
   1568 				  && (TREE_CODE (TREE_OPERAND (*e, 0))
   1569 				      == DECL_EXPR)
   1570 				  && (TREE_OPERAND (TREE_OPERAND (*e, 0), 0)
   1571 				      == t)))
   1572 			    break;
   1573 			  ++e;
   1574 			}
   1575 		      gcc_assert (!tsi_end_p (e));
   1576 		      tsi_link_before (&e, tmp, TSI_SAME_STMT);
   1577 		   }
   1578 		}
   1579 	    }
   1580 
   1581 	  /* Mark variable as local.  */
   1582 	  if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t))
   1583 	    {
   1584 	      if (! DECL_SEEN_IN_BIND_EXPR_P (t)
   1585 		  || splay_tree_lookup (ctx->variables,
   1586 					(splay_tree_key) t) == NULL)
   1587 		{
   1588 		  int flag = GOVD_LOCAL;
   1589 		  if (ctx->region_type == ORT_SIMD
   1590 		      && TREE_ADDRESSABLE (t)
   1591 		      && !TREE_STATIC (t))
   1592 		    {
   1593 		      if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST)
   1594 			ctx->add_safelen1 = true;
   1595 		      else
   1596 			flag = GOVD_PRIVATE;
   1597 		    }
   1598 		  omp_add_variable (ctx, t, flag | GOVD_SEEN);
   1599 		}
   1600 	      /* Static locals inside of target construct or offloaded
   1601 		 routines need to be "omp declare target".  */
   1602 	      if (TREE_STATIC (t))
   1603 		for (; ctx; ctx = ctx->outer_context)
   1604 		  if ((ctx->region_type & ORT_TARGET) != 0)
   1605 		    {
   1606 		      if (!lookup_attribute ("omp declare target",
   1607 					     DECL_ATTRIBUTES (t)))
   1608 			{
   1609 			  tree id = get_identifier ("omp declare target");
   1610 			  DECL_ATTRIBUTES (t)
   1611 			    = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
   1612 			  varpool_node *node = varpool_node::get (t);
   1613 			  if (node)
   1614 			    {
   1615 			      node->offloadable = 1;
   1616 			      if (ENABLE_OFFLOADING && !DECL_EXTERNAL (t))
   1617 				{
   1618 				  g->have_offload = true;
   1619 				  if (!in_lto_p)
   1620 				    vec_safe_push (offload_vars, t);
   1621 				}
   1622 			    }
   1623 			}
   1624 		      break;
   1625 		    }
   1626 	    }
   1627 
   1628 	  DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
   1629 
   1630 	  if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
   1631 	    cfun->has_local_explicit_reg_vars = true;
   1632 	}
   1633     }
   1634 
   1635   bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
   1636 				 BIND_EXPR_BLOCK (bind_expr));
   1637   gimple_push_bind_expr (bind_stmt);
   1638 
   1639   gimplify_ctxp->keep_stack = false;
   1640   gimplify_ctxp->save_stack = false;
   1641 
   1642   /* Gimplify the body into the GIMPLE_BIND tuple's body.  */
   1643   body = NULL;
   1644   gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
   1645   gimple_bind_set_body (bind_stmt, body);
   1646 
   1647   /* Source location wise, the cleanup code (stack_restore and clobbers)
   1648      belongs to the end of the block, so propagate what we have.  The
   1649      stack_save operation belongs to the beginning of block, which we can
   1650      infer from the bind_expr directly if the block has no explicit
   1651      assignment.  */
   1652   if (BIND_EXPR_BLOCK (bind_expr))
   1653     {
   1654       end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
   1655       start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
   1656     }
   1657   if (start_locus == 0)
   1658     start_locus = EXPR_LOCATION (bind_expr);
   1659 
   1660   cleanup = NULL;
   1661   stack_save = NULL;
   1662 
   1663   /* Add clobbers for all variables that go out of scope.  */
   1664   for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
   1665     {
   1666       if (VAR_P (t)
   1667 	  && !is_global_var (t)
   1668 	  && DECL_CONTEXT (t) == current_function_decl)
   1669 	{
   1670 	  if (flag_openmp
   1671 	      && DECL_HAS_VALUE_EXPR_P (t)
   1672 	      && TREE_USED (t)
   1673 	      && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t)))
   1674 	    {
   1675 	      /* For Fortran, TREE_CHAIN (TREE_VALUE (attr)) is set, which
   1676 		 causes that the GOMP_free call is already added above;
   1677 		 and "omp allocate" is removed from DECL_ATTRIBUTES.  */
   1678 	      tree v = TREE_OPERAND (DECL_VALUE_EXPR (t), 0);
   1679 	      tree tmp = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
   1680 	      tmp = build_call_expr_loc (end_locus, tmp, 2, v,
   1681 					 build_zero_cst (ptr_type_node));
   1682 	      gimplify_and_add (tmp, &cleanup);
   1683 	      gimple *clobber_stmt;
   1684 	      tmp = build_clobber (TREE_TYPE (v), CLOBBER_STORAGE_END);
   1685 	      clobber_stmt = gimple_build_assign (v, tmp);
   1686 	      gimple_set_location (clobber_stmt, end_locus);
   1687 	      gimplify_seq_add_stmt (&cleanup, clobber_stmt);
   1688 	    }
   1689 	  if (!DECL_HARD_REGISTER (t)
   1690 	      && !TREE_THIS_VOLATILE (t)
   1691 	      && !DECL_HAS_VALUE_EXPR_P (t)
   1692 	      /* Only care for variables that have to be in memory.  Others
   1693 		 will be rewritten into SSA names, hence moved to the
   1694 		 top-level.  */
   1695 	      && !is_gimple_reg (t)
   1696 	      && flag_stack_reuse != SR_NONE)
   1697 	    {
   1698 	      tree clobber = build_clobber (TREE_TYPE (t), CLOBBER_STORAGE_END);
   1699 	      gimple *clobber_stmt;
   1700 	      clobber_stmt = gimple_build_assign (t, clobber);
   1701 	      gimple_set_location (clobber_stmt, end_locus);
   1702 	      gimplify_seq_add_stmt (&cleanup, clobber_stmt);
   1703 	    }
   1704 
   1705 	  if (flag_openacc && oacc_declare_returns != NULL)
   1706 	    {
   1707 	      tree key = t;
   1708 	      if (DECL_HAS_VALUE_EXPR_P (key))
   1709 		{
   1710 		  key = DECL_VALUE_EXPR (key);
   1711 		  if (INDIRECT_REF_P (key))
   1712 		    key = TREE_OPERAND (key, 0);
   1713 		}
   1714 	      tree *c = oacc_declare_returns->get (key);
   1715 	      if (c != NULL)
   1716 		{
   1717 		  if (ret_clauses)
   1718 		    OMP_CLAUSE_CHAIN (*c) = ret_clauses;
   1719 
   1720 		  ret_clauses = unshare_expr (*c);
   1721 
   1722 		  oacc_declare_returns->remove (key);
   1723 
   1724 		  if (oacc_declare_returns->is_empty ())
   1725 		    {
   1726 		      delete oacc_declare_returns;
   1727 		      oacc_declare_returns = NULL;
   1728 		    }
   1729 		}
   1730 	    }
   1731 	}
   1732 
   1733       if (asan_poisoned_variables != NULL
   1734 	  && asan_poisoned_variables->contains (t))
   1735 	{
   1736 	  asan_poisoned_variables->remove (t);
   1737 	  asan_poison_variable (t, true, &cleanup);
   1738 	}
   1739 
   1740       if (gimplify_ctxp->live_switch_vars != NULL
   1741 	  && gimplify_ctxp->live_switch_vars->contains (t))
   1742 	gimplify_ctxp->live_switch_vars->remove (t);
   1743     }
   1744 
   1745   /* If the code both contains VLAs and calls alloca, then we cannot reclaim
   1746      the stack space allocated to the VLAs.  */
   1747   if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
   1748     {
   1749       gcall *stack_restore;
   1750 
   1751       /* Save stack on entry and restore it on exit.  Add a try_finally
   1752 	 block to achieve this.  */
   1753       build_stack_save_restore (&stack_save, &stack_restore);
   1754 
   1755       gimple_set_location (stack_save, start_locus);
   1756       gimple_set_location (stack_restore, end_locus);
   1757 
   1758       gimplify_seq_add_stmt (&cleanup, stack_restore);
   1759     }
   1760 
   1761   if (ret_clauses)
   1762     {
   1763       gomp_target *stmt;
   1764       gimple_stmt_iterator si = gsi_start (cleanup);
   1765 
   1766       stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
   1767 				      ret_clauses);
   1768       gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
   1769     }
   1770 
   1771   if (cleanup)
   1772     {
   1773       gtry *gs;
   1774       gimple_seq new_body;
   1775 
   1776       new_body = NULL;
   1777       gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
   1778 	  		     GIMPLE_TRY_FINALLY);
   1779 
   1780       if (stack_save)
   1781 	gimplify_seq_add_stmt (&new_body, stack_save);
   1782       gimplify_seq_add_stmt (&new_body, gs);
   1783       gimple_bind_set_body (bind_stmt, new_body);
   1784     }
   1785 
   1786   /* keep_stack propagates all the way up to the outermost BIND_EXPR.  */
   1787   if (!gimplify_ctxp->keep_stack)
   1788     gimplify_ctxp->keep_stack = old_keep_stack;
   1789   gimplify_ctxp->save_stack = old_save_stack;
   1790 
   1791   gimple_pop_bind_expr ();
   1792 
   1793   gimplify_seq_add_stmt (pre_p, bind_stmt);
   1794 
   1795   if (temp)
   1796     {
   1797       *expr_p = temp;
   1798       return GS_OK;
   1799     }
   1800 
   1801   *expr_p = NULL_TREE;
   1802   return GS_ALL_DONE;
   1803 }
   1804 
   1805 /* Maybe add early return predict statement to PRE_P sequence.  */
   1806 
   1807 static void
   1808 maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
   1809 {
   1810   /* If we are not in a conditional context, add PREDICT statement.  */
   1811   if (gimple_conditional_context ())
   1812     {
   1813       gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
   1814 					      NOT_TAKEN);
   1815       gimplify_seq_add_stmt (pre_p, predict);
   1816     }
   1817 }
   1818 
   1819 /* Gimplify a RETURN_EXPR.  If the expression to be returned is not a
   1820    GIMPLE value, it is assigned to a new temporary and the statement is
   1821    re-written to return the temporary.
   1822 
   1823    PRE_P points to the sequence where side effects that must happen before
   1824    STMT should be stored.  */
   1825 
   1826 static enum gimplify_status
   1827 gimplify_return_expr (tree stmt, gimple_seq *pre_p)
   1828 {
   1829   greturn *ret;
   1830   tree ret_expr = TREE_OPERAND (stmt, 0);
   1831   tree result_decl, result;
   1832 
   1833   if (ret_expr == error_mark_node)
   1834     return GS_ERROR;
   1835 
   1836   if (!ret_expr
   1837       || TREE_CODE (ret_expr) == RESULT_DECL)
   1838     {
   1839       maybe_add_early_return_predict_stmt (pre_p);
   1840       greturn *ret = gimple_build_return (ret_expr);
   1841       copy_warning (ret, stmt);
   1842       gimplify_seq_add_stmt (pre_p, ret);
   1843       return GS_ALL_DONE;
   1844     }
   1845 
   1846   if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
   1847     result_decl = NULL_TREE;
   1848   else if (TREE_CODE (ret_expr) == COMPOUND_EXPR)
   1849     {
   1850       /* Used in C++ for handling EH cleanup of the return value if a local
   1851 	 cleanup throws.  Assume the front-end knows what it's doing.  */
   1852       result_decl = DECL_RESULT (current_function_decl);
   1853       /* But crash if we end up trying to modify ret_expr below.  */
   1854       ret_expr = NULL_TREE;
   1855     }
   1856   else
   1857     {
   1858       result_decl = TREE_OPERAND (ret_expr, 0);
   1859 
   1860       /* See through a return by reference.  */
   1861       if (INDIRECT_REF_P (result_decl))
   1862 	result_decl = TREE_OPERAND (result_decl, 0);
   1863 
   1864       gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
   1865 		   || TREE_CODE (ret_expr) == INIT_EXPR)
   1866 		  && TREE_CODE (result_decl) == RESULT_DECL);
   1867     }
   1868 
   1869   /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
   1870      Recall that aggregate_value_p is FALSE for any aggregate type that is
   1871      returned in registers.  If we're returning values in registers, then
   1872      we don't want to extend the lifetime of the RESULT_DECL, particularly
   1873      across another call.  In addition, for those aggregates for which
   1874      hard_function_value generates a PARALLEL, we'll die during normal
   1875      expansion of structure assignments; there's special code in expand_return
   1876      to handle this case that does not exist in expand_expr.  */
   1877   if (!result_decl)
   1878     result = NULL_TREE;
   1879   else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
   1880     {
   1881       if (!poly_int_tree_p (DECL_SIZE (result_decl)))
   1882 	{
   1883 	  if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
   1884 	    gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
   1885 	  /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
   1886 	     should be effectively allocated by the caller, i.e. all calls to
   1887 	     this function must be subject to the Return Slot Optimization.  */
   1888 	  gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
   1889 	  gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
   1890 	}
   1891       result = result_decl;
   1892     }
   1893   else if (gimplify_ctxp->return_temp)
   1894     result = gimplify_ctxp->return_temp;
   1895   else
   1896     {
   1897       result = create_tmp_reg (TREE_TYPE (result_decl));
   1898 
   1899       /* ??? With complex control flow (usually involving abnormal edges),
   1900 	 we can wind up warning about an uninitialized value for this.  Due
   1901 	 to how this variable is constructed and initialized, this is never
   1902 	 true.  Give up and never warn.  */
   1903       suppress_warning (result, OPT_Wuninitialized);
   1904 
   1905       gimplify_ctxp->return_temp = result;
   1906     }
   1907 
   1908   /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
   1909      Then gimplify the whole thing.  */
   1910   if (result != result_decl)
   1911     TREE_OPERAND (ret_expr, 0) = result;
   1912 
   1913   gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
   1914 
   1915   maybe_add_early_return_predict_stmt (pre_p);
   1916   ret = gimple_build_return (result);
   1917   copy_warning (ret, stmt);
   1918   gimplify_seq_add_stmt (pre_p, ret);
   1919 
   1920   return GS_ALL_DONE;
   1921 }
   1922 
   1923 /* Gimplify a variable-length array DECL.  */
   1924 
   1925 static void
   1926 gimplify_vla_decl (tree decl, gimple_seq *seq_p)
   1927 {
   1928   /* This is a variable-sized decl.  Simplify its size and mark it
   1929      for deferred expansion.  */
   1930   tree t, addr, ptr_type;
   1931 
   1932   gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
   1933   gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
   1934 
   1935   /* Don't mess with a DECL_VALUE_EXPR set by the front-end.  */
   1936   if (DECL_HAS_VALUE_EXPR_P (decl))
   1937     return;
   1938 
   1939   /* All occurrences of this decl in final gimplified code will be
   1940      replaced by indirection.  Setting DECL_VALUE_EXPR does two
   1941      things: First, it lets the rest of the gimplifier know what
   1942      replacement to use.  Second, it lets the debug info know
   1943      where to find the value.  */
   1944   ptr_type = build_pointer_type (TREE_TYPE (decl));
   1945   addr = create_tmp_var (ptr_type, get_name (decl));
   1946   DECL_IGNORED_P (addr) = 0;
   1947   t = build_fold_indirect_ref (addr);
   1948   TREE_THIS_NOTRAP (t) = 1;
   1949   SET_DECL_VALUE_EXPR (decl, t);
   1950   DECL_HAS_VALUE_EXPR_P (decl) = 1;
   1951 
   1952   t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
   1953 			      max_int_size_in_bytes (TREE_TYPE (decl)));
   1954   /* The call has been built for a variable-sized object.  */
   1955   CALL_ALLOCA_FOR_VAR_P (t) = 1;
   1956   t = fold_convert (ptr_type, t);
   1957   t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
   1958 
   1959   gimplify_and_add (t, seq_p);
   1960 
   1961   /* Record the dynamic allocation associated with DECL if requested.  */
   1962   if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)
   1963     record_dynamic_alloc (decl);
   1964 }
   1965 
   1966 /* A helper function to be called via walk_tree.  Mark all labels under *TP
   1967    as being forced.  To be called for DECL_INITIAL of static variables.  */
   1968 
   1969 static tree
   1970 force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
   1971 {
   1972   if (TYPE_P (*tp))
   1973     *walk_subtrees = 0;
   1974   if (TREE_CODE (*tp) == LABEL_DECL)
   1975     {
   1976       FORCED_LABEL (*tp) = 1;
   1977       cfun->has_forced_label_in_static = 1;
   1978     }
   1979 
   1980   return NULL_TREE;
   1981 }
   1982 
   1983 /* Generate an initialization to automatic variable DECL based on INIT_TYPE.
   1984    Build a call to internal const function DEFERRED_INIT:
   1985    1st argument: SIZE of the DECL;
   1986    2nd argument: INIT_TYPE;
   1987    3rd argument: NAME of the DECL;
   1988 
   1989    as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, NAME of the DECL).  */
   1990 
   1991 static void
   1992 gimple_add_init_for_auto_var (tree decl,
   1993 			      enum auto_init_type init_type,
   1994 			      gimple_seq *seq_p)
   1995 {
   1996   gcc_assert (auto_var_p (decl));
   1997   gcc_assert (init_type > AUTO_INIT_UNINITIALIZED);
   1998   location_t loc = EXPR_LOCATION (decl);
   1999   tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl));
   2000 
   2001   tree init_type_node
   2002     = build_int_cst (integer_type_node, (int) init_type);
   2003 
   2004   tree decl_name = NULL_TREE;
   2005   if (DECL_NAME (decl))
   2006 
   2007     decl_name = build_string_literal (DECL_NAME (decl));
   2008 
   2009   else
   2010     {
   2011       char decl_name_anonymous[3 + (HOST_BITS_PER_INT + 2) / 3];
   2012       sprintf (decl_name_anonymous, "D.%u", DECL_UID (decl));
   2013       decl_name = build_string_literal (decl_name_anonymous);
   2014     }
   2015 
   2016   tree call = build_call_expr_internal_loc (loc, IFN_DEFERRED_INIT,
   2017 		 			    TREE_TYPE (decl), 3,
   2018 					    decl_size, init_type_node,
   2019 					    decl_name);
   2020 
   2021   gimplify_assign (decl, call, seq_p);
   2022 }
   2023 
   2024 /* Generate padding initialization for automatic vairable DECL.
   2025    C guarantees that brace-init with fewer initializers than members
   2026    aggregate will initialize the rest of the aggregate as-if it were
   2027    static initialization.  In turn static initialization guarantees
   2028    that padding is initialized to zero. So, we always initialize paddings
   2029    to zeroes regardless INIT_TYPE.
   2030    To do the padding initialization, we insert a call to
   2031    __builtin_clear_padding (&decl, 0, for_auto_init = true).
   2032    Note, we add an additional dummy argument for __builtin_clear_padding,
   2033    'for_auto_init' to distinguish whether this call is for automatic
   2034    variable initialization or not.
   2035    */
   2036 static void
   2037 gimple_add_padding_init_for_auto_var (tree decl, bool is_vla,
   2038 				      gimple_seq *seq_p)
   2039 {
   2040   tree addr_of_decl = NULL_TREE;
   2041   tree fn = builtin_decl_explicit (BUILT_IN_CLEAR_PADDING);
   2042 
   2043   if (is_vla)
   2044     {
   2045       /* The temporary address variable for this vla should be
   2046 	 created in gimplify_vla_decl.  */
   2047       gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
   2048       gcc_assert (INDIRECT_REF_P (DECL_VALUE_EXPR (decl)));
   2049       addr_of_decl = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
   2050     }
   2051   else
   2052     {
   2053       mark_addressable (decl);
   2054       addr_of_decl = build_fold_addr_expr (decl);
   2055     }
   2056 
   2057   gimple *call = gimple_build_call (fn, 2, addr_of_decl,
   2058 				    build_one_cst (TREE_TYPE (addr_of_decl)));
   2059   gimplify_seq_add_stmt (seq_p, call);
   2060 }
   2061 
   2062 /* Return true if the DECL need to be automaticly initialized by the
   2063    compiler.  */
   2064 static bool
   2065 is_var_need_auto_init (tree decl)
   2066 {
   2067   if (auto_var_p (decl)
   2068       && (TREE_CODE (decl) != VAR_DECL
   2069 	  || !DECL_HARD_REGISTER (decl))
   2070       && (flag_auto_var_init > AUTO_INIT_UNINITIALIZED)
   2071       && (!lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl)))
   2072       && !OPAQUE_TYPE_P (TREE_TYPE (decl))
   2073       && !is_empty_type (TREE_TYPE (decl)))
   2074     return true;
   2075   return false;
   2076 }
   2077 
   2078 /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
   2079    and initialization explicit.  */
   2080 
   2081 static enum gimplify_status
   2082 gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
   2083 {
   2084   tree stmt = *stmt_p;
   2085   tree decl = DECL_EXPR_DECL (stmt);
   2086 
   2087   *stmt_p = NULL_TREE;
   2088 
   2089   if (TREE_TYPE (decl) == error_mark_node)
   2090     return GS_ERROR;
   2091 
   2092   if ((TREE_CODE (decl) == TYPE_DECL
   2093        || VAR_P (decl))
   2094       && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
   2095     {
   2096       gimplify_type_sizes (TREE_TYPE (decl), seq_p);
   2097       if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
   2098 	gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
   2099     }
   2100 
   2101   /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
   2102      in case its size expressions contain problematic nodes like CALL_EXPR.  */
   2103   if (TREE_CODE (decl) == TYPE_DECL
   2104       && DECL_ORIGINAL_TYPE (decl)
   2105       && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
   2106     {
   2107       gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
   2108       if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
   2109 	gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
   2110     }
   2111 
   2112   if (VAR_P (decl) && !DECL_EXTERNAL (decl))
   2113     {
   2114       tree init = DECL_INITIAL (decl);
   2115       bool is_vla = false;
   2116       /* Check whether a decl has FE created VALUE_EXPR here BEFORE
   2117 	 gimplify_vla_decl creates VALUE_EXPR for a vla decl.
   2118 	 If the decl has VALUE_EXPR that was created by FE (usually
   2119 	 C++FE), it's a proxy varaible, and FE already initialized
   2120 	 the VALUE_EXPR of it, we should not initialize it anymore.  */
   2121       bool decl_had_value_expr_p = DECL_HAS_VALUE_EXPR_P (decl);
   2122 
   2123       poly_uint64 size;
   2124       if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
   2125 	  || (!TREE_STATIC (decl)
   2126 	      && flag_stack_check == GENERIC_STACK_CHECK
   2127 	      && maybe_gt (size,
   2128 			   (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
   2129 	{
   2130 	  gimplify_vla_decl (decl, seq_p);
   2131 	  is_vla = true;
   2132 	}
   2133 
   2134       if (asan_poisoned_variables
   2135 	  && !is_vla
   2136 	  && TREE_ADDRESSABLE (decl)
   2137 	  && !TREE_STATIC (decl)
   2138 	  && !DECL_HAS_VALUE_EXPR_P (decl)
   2139 	  && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
   2140 	  && dbg_cnt (asan_use_after_scope)
   2141 	  && !gimplify_omp_ctxp
   2142 	  /* GNAT introduces temporaries to hold return values of calls in
   2143 	     initializers of variables defined in other units, so the
   2144 	     declaration of the variable is discarded completely.  We do not
   2145 	     want to issue poison calls for such dropped variables.  */
   2146 	  && (DECL_SEEN_IN_BIND_EXPR_P (decl)
   2147 	      || (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)))
   2148 	{
   2149 	  asan_poisoned_variables->add (decl);
   2150 	  asan_poison_variable (decl, false, seq_p);
   2151 	  if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
   2152 	    gimplify_ctxp->live_switch_vars->add (decl);
   2153 	}
   2154 
   2155       /* Some front ends do not explicitly declare all anonymous
   2156 	 artificial variables.  We compensate here by declaring the
   2157 	 variables, though it would be better if the front ends would
   2158 	 explicitly declare them.  */
   2159       if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
   2160 	  && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
   2161 	gimple_add_tmp_var (decl);
   2162 
   2163       if (init && init != error_mark_node)
   2164 	{
   2165 	  if (!TREE_STATIC (decl))
   2166 	    {
   2167 	      DECL_INITIAL (decl) = NULL_TREE;
   2168 	      init = build2 (INIT_EXPR, void_type_node, decl, init);
   2169 	      gimplify_and_add (init, seq_p);
   2170 	      ggc_free (init);
   2171 	      /* Clear TREE_READONLY if we really have an initialization.  */
   2172 	      if (!DECL_INITIAL (decl)
   2173 		  && !omp_privatize_by_reference (decl))
   2174 		TREE_READONLY (decl) = 0;
   2175 	    }
   2176 	  else
   2177 	    /* We must still examine initializers for static variables
   2178 	       as they may contain a label address.  */
   2179 	    walk_tree (&init, force_labels_r, NULL, NULL);
   2180 	}
   2181       /* When there is no explicit initializer, if the user requested,
   2182 	 We should insert an artifical initializer for this automatic
   2183 	 variable.  */
   2184       else if (is_var_need_auto_init (decl)
   2185 	       && !decl_had_value_expr_p)
   2186 	{
   2187 	  gimple_add_init_for_auto_var (decl,
   2188 					flag_auto_var_init,
   2189 					seq_p);
   2190 	  /* The expanding of a call to the above .DEFERRED_INIT will apply
   2191 	     block initialization to the whole space covered by this variable.
   2192 	     As a result, all the paddings will be initialized to zeroes
   2193 	     for zero initialization and 0xFE byte-repeatable patterns for
   2194 	     pattern initialization.
   2195 	     In order to make the paddings as zeroes for pattern init, We
   2196 	     should add a call to __builtin_clear_padding to clear the
   2197 	     paddings to zero in compatiple with CLANG.
   2198 	     We cannot insert this call if the variable is a gimple register
   2199 	     since __builtin_clear_padding will take the address of the
   2200 	     variable.  As a result, if a long double/_Complex long double
   2201 	     variable will spilled into stack later, its padding is 0XFE.  */
   2202 	  if (flag_auto_var_init == AUTO_INIT_PATTERN
   2203 	      && !is_gimple_reg (decl)
   2204 	      && clear_padding_type_may_have_padding_p (TREE_TYPE (decl)))
   2205 	    gimple_add_padding_init_for_auto_var (decl, is_vla, seq_p);
   2206 	}
   2207     }
   2208 
   2209   return GS_ALL_DONE;
   2210 }
   2211 
   2212 /* Gimplify a LOOP_EXPR.  Normally this just involves gimplifying the body
   2213    and replacing the LOOP_EXPR with goto, but if the loop contains an
   2214    EXIT_EXPR, we need to append a label for it to jump to.  */
   2215 
   2216 static enum gimplify_status
   2217 gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
   2218 {
   2219   tree saved_label = gimplify_ctxp->exit_label;
   2220   tree start_label = create_artificial_label (UNKNOWN_LOCATION);
   2221 
   2222   gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
   2223 
   2224   gimplify_ctxp->exit_label = NULL_TREE;
   2225 
   2226   gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
   2227 
   2228   gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
   2229 
   2230   if (gimplify_ctxp->exit_label)
   2231     gimplify_seq_add_stmt (pre_p,
   2232 			   gimple_build_label (gimplify_ctxp->exit_label));
   2233 
   2234   gimplify_ctxp->exit_label = saved_label;
   2235 
   2236   *expr_p = NULL;
   2237   return GS_ALL_DONE;
   2238 }
   2239 
   2240 /* Gimplify a statement list onto a sequence.  These may be created either
   2241    by an enlightened front-end, or by shortcut_cond_expr.  */
   2242 
   2243 static enum gimplify_status
   2244 gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
   2245 {
   2246   tree temp = voidify_wrapper_expr (*expr_p, NULL);
   2247 
   2248   tree_stmt_iterator i = tsi_start (*expr_p);
   2249 
   2250   while (!tsi_end_p (i))
   2251     {
   2252       gimplify_stmt (tsi_stmt_ptr (i), pre_p);
   2253       tsi_delink (&i);
   2254     }
   2255 
   2256   if (temp)
   2257     {
   2258       *expr_p = temp;
   2259       return GS_OK;
   2260     }
   2261 
   2262   return GS_ALL_DONE;
   2263 }
   2264 
   2265 
   2266 /* Emit warning for the unreachable statment STMT if needed.
   2267    Return the gimple itself when the warning is emitted, otherwise
   2268    return NULL.  */
   2269 static gimple *
   2270 emit_warn_switch_unreachable (gimple *stmt)
   2271 {
   2272   if (gimple_code (stmt) == GIMPLE_GOTO
   2273       && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
   2274       && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
   2275   /* Don't warn for compiler-generated gotos.  These occur
   2276      in Duff's devices, for example.  */
   2277     return NULL;
   2278   else if ((flag_auto_var_init > AUTO_INIT_UNINITIALIZED)
   2279 	   && ((gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
   2280 		|| (gimple_call_builtin_p (stmt, BUILT_IN_CLEAR_PADDING)
   2281 		    && (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 1)))
   2282 		|| (is_gimple_assign (stmt)
   2283 		    && gimple_assign_single_p (stmt)
   2284 		    && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
   2285 		    && gimple_call_internal_p (
   2286 			 SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt)),
   2287 			 IFN_DEFERRED_INIT))))
   2288   /* Don't warn for compiler-generated initializations for
   2289      -ftrivial-auto-var-init.
   2290      There are 3 cases:
   2291 	case 1: a call to .DEFERRED_INIT;
   2292 	case 2: a call to __builtin_clear_padding with the 2nd argument is
   2293 		present and non-zero;
   2294 	case 3: a gimple assign store right after the call to .DEFERRED_INIT
   2295 		that has the LHS of .DEFERRED_INIT as the RHS as following:
   2296 		  _1 = .DEFERRED_INIT (4, 2, &"i1"[0]);
   2297 		  i1 = _1.  */
   2298     return NULL;
   2299   else
   2300     warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
   2301 		"statement will never be executed");
   2302   return stmt;
   2303 }
   2304 
   2305 /* Callback for walk_gimple_seq.  */
   2306 
   2307 static tree
   2308 warn_switch_unreachable_and_auto_init_r (gimple_stmt_iterator *gsi_p,
   2309 					 bool *handled_ops_p,
   2310 					 struct walk_stmt_info *wi)
   2311 {
   2312   gimple *stmt = gsi_stmt (*gsi_p);
   2313   bool unreachable_issued = wi->info != NULL;
   2314 
   2315   *handled_ops_p = true;
   2316   switch (gimple_code (stmt))
   2317     {
   2318     case GIMPLE_TRY:
   2319       /* A compiler-generated cleanup or a user-written try block.
   2320 	 If it's empty, don't dive into it--that would result in
   2321 	 worse location info.  */
   2322       if (gimple_try_eval (stmt) == NULL)
   2323 	{
   2324 	  if (warn_switch_unreachable && !unreachable_issued)
   2325 	    wi->info = emit_warn_switch_unreachable (stmt);
   2326 
   2327 	  /* Stop when auto var init warning is not on.  */
   2328 	  if (!warn_trivial_auto_var_init)
   2329 	    return integer_zero_node;
   2330 	}
   2331       /* Fall through.  */
   2332     case GIMPLE_BIND:
   2333     case GIMPLE_CATCH:
   2334     case GIMPLE_EH_FILTER:
   2335     case GIMPLE_TRANSACTION:
   2336       /* Walk the sub-statements.  */
   2337       *handled_ops_p = false;
   2338       break;
   2339 
   2340     case GIMPLE_DEBUG:
   2341       /* Ignore these.  We may generate them before declarations that
   2342 	 are never executed.  If there's something to warn about,
   2343 	 there will be non-debug stmts too, and we'll catch those.  */
   2344       break;
   2345 
   2346     case GIMPLE_LABEL:
   2347       /* Stop till the first Label.  */
   2348       return integer_zero_node;
   2349     case GIMPLE_CALL:
   2350       if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
   2351 	{
   2352 	  *handled_ops_p = false;
   2353 	  break;
   2354 	}
   2355       if (warn_trivial_auto_var_init
   2356 	  && flag_auto_var_init > AUTO_INIT_UNINITIALIZED
   2357 	  && gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
   2358 	{
   2359 	  /* Get the variable name from the 3rd argument of call.  */
   2360 	  tree var_name = gimple_call_arg (stmt, 2);
   2361 	  var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0);
   2362 	  const char *var_name_str = TREE_STRING_POINTER (var_name);
   2363 
   2364 	  warning_at (gimple_location (stmt), OPT_Wtrivial_auto_var_init,
   2365 		      "%qs cannot be initialized with "
   2366 		      "%<-ftrivial-auto-var_init%>",
   2367 		      var_name_str);
   2368 	  break;
   2369        }
   2370 
   2371       /* Fall through.  */
   2372     default:
   2373       /* check the first "real" statement (not a decl/lexical scope/...), issue
   2374 	 warning if needed.  */
   2375       if (warn_switch_unreachable && !unreachable_issued)
   2376 	wi->info = emit_warn_switch_unreachable (stmt);
   2377       /* Stop when auto var init warning is not on.  */
   2378       if (!warn_trivial_auto_var_init)
   2379 	return integer_zero_node;
   2380       break;
   2381     }
   2382   return NULL_TREE;
   2383 }
   2384 
   2385 
   2386 /* Possibly warn about unreachable statements between switch's controlling
   2387    expression and the first case.  Also warn about -ftrivial-auto-var-init
   2388    cannot initialize the auto variable under such situation.
   2389    SEQ is the body of a switch expression.  */
   2390 
   2391 static void
   2392 maybe_warn_switch_unreachable_and_auto_init (gimple_seq seq)
   2393 {
   2394   if ((!warn_switch_unreachable && !warn_trivial_auto_var_init)
   2395       /* This warning doesn't play well with Fortran when optimizations
   2396 	 are on.  */
   2397       || lang_GNU_Fortran ()
   2398       || seq == NULL)
   2399     return;
   2400 
   2401   struct walk_stmt_info wi;
   2402 
   2403   memset (&wi, 0, sizeof (wi));
   2404   walk_gimple_seq (seq, warn_switch_unreachable_and_auto_init_r, NULL, &wi);
   2405 }
   2406 
   2407 
   2408 /* A label entry that pairs label and a location.  */
   2409 struct label_entry
   2410 {
   2411   tree label;
   2412   location_t loc;
   2413 };
   2414 
   2415 /* Find LABEL in vector of label entries VEC.  */
   2416 
   2417 static struct label_entry *
   2418 find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
   2419 {
   2420   unsigned int i;
   2421   struct label_entry *l;
   2422 
   2423   FOR_EACH_VEC_ELT (*vec, i, l)
   2424     if (l->label == label)
   2425       return l;
   2426   return NULL;
   2427 }
   2428 
   2429 /* Return true if LABEL, a LABEL_DECL, represents a case label
   2430    in a vector of labels CASES.  */
   2431 
   2432 static bool
   2433 case_label_p (const vec<tree> *cases, tree label)
   2434 {
   2435   unsigned int i;
   2436   tree l;
   2437 
   2438   FOR_EACH_VEC_ELT (*cases, i, l)
   2439     if (CASE_LABEL (l) == label)
   2440       return true;
   2441   return false;
   2442 }
   2443 
   2444 /* Find the last nondebug statement in a scope STMT.  */
   2445 
   2446 static gimple *
   2447 last_stmt_in_scope (gimple *stmt)
   2448 {
   2449   if (!stmt)
   2450     return NULL;
   2451 
   2452   switch (gimple_code (stmt))
   2453     {
   2454     case GIMPLE_BIND:
   2455       {
   2456 	gbind *bind = as_a <gbind *> (stmt);
   2457 	stmt = gimple_seq_last_nondebug_stmt (gimple_bind_body (bind));
   2458 	return last_stmt_in_scope (stmt);
   2459       }
   2460 
   2461     case GIMPLE_TRY:
   2462       {
   2463 	gtry *try_stmt = as_a <gtry *> (stmt);
   2464 	stmt = gimple_seq_last_nondebug_stmt (gimple_try_eval (try_stmt));
   2465 	gimple *last_eval = last_stmt_in_scope (stmt);
   2466 	if (gimple_stmt_may_fallthru (last_eval)
   2467 	    && (last_eval == NULL
   2468 		|| !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
   2469 	    && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
   2470 	  {
   2471 	    stmt = gimple_seq_last_nondebug_stmt (gimple_try_cleanup (try_stmt));
   2472 	    return last_stmt_in_scope (stmt);
   2473 	  }
   2474 	else
   2475 	  return last_eval;
   2476       }
   2477 
   2478     case GIMPLE_DEBUG:
   2479       gcc_unreachable ();
   2480 
   2481     default:
   2482       return stmt;
   2483     }
   2484 }
   2485 
   2486 /* Collect labels that may fall through into LABELS and return the statement
   2487    preceding another case label, or a user-defined label.  Store a location
   2488    useful to give warnings at *PREVLOC (usually the location of the returned
   2489    statement or of its surrounding scope).  */
   2490 
   2491 static gimple *
   2492 collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
   2493 			    auto_vec <struct label_entry> *labels,
   2494 			    location_t *prevloc)
   2495 {
   2496   gimple *prev = NULL;
   2497 
   2498   *prevloc = UNKNOWN_LOCATION;
   2499   do
   2500     {
   2501       if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
   2502 	{
   2503 	  /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
   2504 	     which starts on a GIMPLE_SWITCH and ends with a break label.
   2505 	     Handle that as a single statement that can fall through.  */
   2506 	  gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
   2507 	  gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
   2508 	  gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
   2509 	  if (last
   2510 	      && gimple_code (first) == GIMPLE_SWITCH
   2511 	      && gimple_code (last) == GIMPLE_LABEL)
   2512 	    {
   2513 	      tree label = gimple_label_label (as_a <glabel *> (last));
   2514 	      if (SWITCH_BREAK_LABEL_P (label))
   2515 		{
   2516 		  prev = bind;
   2517 		  gsi_next (gsi_p);
   2518 		  continue;
   2519 		}
   2520 	    }
   2521 	}
   2522       if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
   2523 	  || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
   2524 	{
   2525 	  /* Nested scope.  Only look at the last statement of
   2526 	     the innermost scope.  */
   2527 	  location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
   2528 	  gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
   2529 	  if (last)
   2530 	    {
   2531 	      prev = last;
   2532 	      /* It might be a label without a location.  Use the
   2533 		 location of the scope then.  */
   2534 	      if (!gimple_has_location (prev))
   2535 		*prevloc = bind_loc;
   2536 	    }
   2537 	  gsi_next (gsi_p);
   2538 	  continue;
   2539 	}
   2540 
   2541       /* Ifs are tricky.  */
   2542       if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
   2543 	{
   2544 	  gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
   2545 	  tree false_lab = gimple_cond_false_label (cond_stmt);
   2546 	  location_t if_loc = gimple_location (cond_stmt);
   2547 
   2548 	  /* If we have e.g.
   2549 	       if (i > 1) goto <D.2259>; else goto D;
   2550 	     we can't do much with the else-branch.  */
   2551 	  if (!DECL_ARTIFICIAL (false_lab))
   2552 	    break;
   2553 
   2554 	  /* Go on until the false label, then one step back.  */
   2555 	  for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
   2556 	    {
   2557 	      gimple *stmt = gsi_stmt (*gsi_p);
   2558 	      if (gimple_code (stmt) == GIMPLE_LABEL
   2559 		  && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
   2560 		break;
   2561 	    }
   2562 
   2563 	  /* Not found?  Oops.  */
   2564 	  if (gsi_end_p (*gsi_p))
   2565 	    break;
   2566 
   2567 	  /* A dead label can't fall through.  */
   2568 	  if (!UNUSED_LABEL_P (false_lab))
   2569 	    {
   2570 	      struct label_entry l = { false_lab, if_loc };
   2571 	      labels->safe_push (l);
   2572 	    }
   2573 
   2574 	  /* Go to the last statement of the then branch.  */
   2575 	  gsi_prev (gsi_p);
   2576 
   2577 	  /* if (i != 0) goto <D.1759>; else goto <D.1760>;
   2578 	     <D.1759>:
   2579 	     <stmt>;
   2580 	     goto <D.1761>;
   2581 	     <D.1760>:
   2582 	   */
   2583 	  if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
   2584 	      && !gimple_has_location (gsi_stmt (*gsi_p)))
   2585 	    {
   2586 	      /* Look at the statement before, it might be
   2587 		 attribute fallthrough, in which case don't warn.  */
   2588 	      gsi_prev (gsi_p);
   2589 	      bool fallthru_before_dest
   2590 		= gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
   2591 	      gsi_next (gsi_p);
   2592 	      tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
   2593 	      if (!fallthru_before_dest)
   2594 		{
   2595 		  struct label_entry l = { goto_dest, if_loc };
   2596 		  labels->safe_push (l);
   2597 		}
   2598 	    }
   2599 	  /* This case is about
   2600 	      if (1 != 0) goto <D.2022>; else goto <D.2023>;
   2601 	      <D.2022>:
   2602 	      n = n + 1; // #1
   2603 	      <D.2023>:  // #2
   2604 	      <D.1988>:  // #3
   2605 	     where #2 is UNUSED_LABEL_P and we want to warn about #1 falling
   2606 	     through to #3.  So set PREV to #1.  */
   2607 	  else if (UNUSED_LABEL_P (false_lab))
   2608 	    prev = gsi_stmt (*gsi_p);
   2609 
   2610 	  /* And move back.  */
   2611 	  gsi_next (gsi_p);
   2612 	}
   2613 
   2614       /* Remember the last statement.  Skip labels that are of no interest
   2615 	 to us.  */
   2616       if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
   2617 	{
   2618 	  tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
   2619 	  if (find_label_entry (labels, label))
   2620 	    prev = gsi_stmt (*gsi_p);
   2621 	}
   2622       else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
   2623 	;
   2624       else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
   2625 	;
   2626       else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
   2627 	prev = gsi_stmt (*gsi_p);
   2628       gsi_next (gsi_p);
   2629     }
   2630   while (!gsi_end_p (*gsi_p)
   2631 	 /* Stop if we find a case or a user-defined label.  */
   2632 	 && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
   2633 	     || !gimple_has_location (gsi_stmt (*gsi_p))));
   2634 
   2635   if (prev && gimple_has_location (prev))
   2636     *prevloc = gimple_location (prev);
   2637   return prev;
   2638 }
   2639 
   2640 /* Return true if the switch fallthough warning should occur.  LABEL is
   2641    the label statement that we're falling through to.  */
   2642 
   2643 static bool
   2644 should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
   2645 {
   2646   gimple_stmt_iterator gsi = *gsi_p;
   2647 
   2648   /* Don't warn if the label is marked with a "falls through" comment.  */
   2649   if (FALLTHROUGH_LABEL_P (label))
   2650     return false;
   2651 
   2652   /* Don't warn for non-case labels followed by a statement:
   2653        case 0:
   2654 	 foo ();
   2655        label:
   2656 	 bar ();
   2657      as these are likely intentional.  */
   2658   if (!case_label_p (&gimplify_ctxp->case_labels, label))
   2659     {
   2660       tree l;
   2661       while (!gsi_end_p (gsi)
   2662 	     && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
   2663 	     && (l = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
   2664 	     && !case_label_p (&gimplify_ctxp->case_labels, l))
   2665 	gsi_next_nondebug (&gsi);
   2666       if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
   2667 	return false;
   2668     }
   2669 
   2670   /* Don't warn for terminated branches, i.e. when the subsequent case labels
   2671      immediately breaks.  */
   2672   gsi = *gsi_p;
   2673 
   2674   /* Skip all immediately following labels.  */
   2675   while (!gsi_end_p (gsi)
   2676 	 && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
   2677 	     || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT))
   2678     gsi_next_nondebug (&gsi);
   2679 
   2680   /* { ... something; default:; } */
   2681   if (gsi_end_p (gsi)
   2682       /* { ... something; default: break; } or
   2683 	 { ... something; default: goto L; } */
   2684       || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
   2685       /* { ... something; default: return; } */
   2686       || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
   2687     return false;
   2688 
   2689   return true;
   2690 }
   2691 
   2692 /* Callback for walk_gimple_seq.  */
   2693 
   2694 static tree
   2695 warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
   2696 			     struct walk_stmt_info *)
   2697 {
   2698   gimple *stmt = gsi_stmt (*gsi_p);
   2699 
   2700   *handled_ops_p = true;
   2701   switch (gimple_code (stmt))
   2702     {
   2703     case GIMPLE_TRY:
   2704     case GIMPLE_BIND:
   2705     case GIMPLE_CATCH:
   2706     case GIMPLE_EH_FILTER:
   2707     case GIMPLE_TRANSACTION:
   2708       /* Walk the sub-statements.  */
   2709       *handled_ops_p = false;
   2710       break;
   2711 
   2712     /* Find a sequence of form:
   2713 
   2714        GIMPLE_LABEL
   2715        [...]
   2716        <may fallthru stmt>
   2717        GIMPLE_LABEL
   2718 
   2719        and possibly warn.  */
   2720     case GIMPLE_LABEL:
   2721       {
   2722 	/* Found a label.  Skip all immediately following labels.  */
   2723 	while (!gsi_end_p (*gsi_p)
   2724 	       && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
   2725 	  gsi_next_nondebug (gsi_p);
   2726 
   2727 	/* There might be no more statements.  */
   2728 	if (gsi_end_p (*gsi_p))
   2729 	  return integer_zero_node;
   2730 
   2731 	/* Vector of labels that fall through.  */
   2732 	auto_vec <struct label_entry> labels;
   2733 	location_t prevloc;
   2734 	gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
   2735 
   2736 	/* There might be no more statements.  */
   2737 	if (gsi_end_p (*gsi_p))
   2738 	  return integer_zero_node;
   2739 
   2740 	gimple *next = gsi_stmt (*gsi_p);
   2741 	tree label;
   2742 	/* If what follows is a label, then we may have a fallthrough.  */
   2743 	if (gimple_code (next) == GIMPLE_LABEL
   2744 	    && gimple_has_location (next)
   2745 	    && (label = gimple_label_label (as_a <glabel *> (next)))
   2746 	    && prev != NULL)
   2747 	  {
   2748 	    struct label_entry *l;
   2749 	    bool warned_p = false;
   2750 	    auto_diagnostic_group d;
   2751 	    if (!should_warn_for_implicit_fallthrough (gsi_p, label))
   2752 	      /* Quiet.  */;
   2753 	    else if (gimple_code (prev) == GIMPLE_LABEL
   2754 		     && (label = gimple_label_label (as_a <glabel *> (prev)))
   2755 		     && (l = find_label_entry (&labels, label)))
   2756 	      warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
   2757 				     "this statement may fall through");
   2758 	    else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
   2759 		     /* Try to be clever and don't warn when the statement
   2760 			can't actually fall through.  */
   2761 		     && gimple_stmt_may_fallthru (prev)
   2762 		     && prevloc != UNKNOWN_LOCATION)
   2763 	      warned_p = warning_at (prevloc,
   2764 				     OPT_Wimplicit_fallthrough_,
   2765 				     "this statement may fall through");
   2766 	    if (warned_p)
   2767 	      inform (gimple_location (next), "here");
   2768 
   2769 	    /* Mark this label as processed so as to prevent multiple
   2770 	       warnings in nested switches.  */
   2771 	    FALLTHROUGH_LABEL_P (label) = true;
   2772 
   2773 	    /* So that next warn_implicit_fallthrough_r will start looking for
   2774 	       a new sequence starting with this label.  */
   2775 	    gsi_prev (gsi_p);
   2776 	  }
   2777       }
   2778       break;
   2779    default:
   2780       break;
   2781     }
   2782   return NULL_TREE;
   2783 }
   2784 
   2785 /* Warn when a switch case falls through.  */
   2786 
   2787 static void
   2788 maybe_warn_implicit_fallthrough (gimple_seq seq)
   2789 {
   2790   if (!warn_implicit_fallthrough)
   2791     return;
   2792 
   2793   /* This warning is meant for C/C++/ObjC/ObjC++ only.  */
   2794   if (!(lang_GNU_C ()
   2795 	|| lang_GNU_CXX ()
   2796 	|| lang_GNU_OBJC ()))
   2797     return;
   2798 
   2799   struct walk_stmt_info wi;
   2800   memset (&wi, 0, sizeof (wi));
   2801   walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
   2802 }
   2803 
   2804 /* Callback for walk_gimple_seq.  */
   2805 
   2806 static tree
   2807 expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
   2808 		      struct walk_stmt_info *wi)
   2809 {
   2810   gimple *stmt = gsi_stmt (*gsi_p);
   2811 
   2812   *handled_ops_p = true;
   2813   switch (gimple_code (stmt))
   2814     {
   2815     case GIMPLE_TRY:
   2816     case GIMPLE_BIND:
   2817     case GIMPLE_CATCH:
   2818     case GIMPLE_EH_FILTER:
   2819     case GIMPLE_TRANSACTION:
   2820       /* Walk the sub-statements.  */
   2821       *handled_ops_p = false;
   2822       break;
   2823     case GIMPLE_CALL:
   2824       static_cast<location_t *>(wi->info)[0] = UNKNOWN_LOCATION;
   2825       if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
   2826 	{
   2827 	  location_t loc = gimple_location (stmt);
   2828 	  gsi_remove (gsi_p, true);
   2829 	  wi->removed_stmt = true;
   2830 
   2831 	  /* nothrow flag is added by genericize_c_loop to mark fallthrough
   2832 	     statement at the end of some loop's body.  Those should be
   2833 	     always diagnosed, either because they indeed don't precede
   2834 	     a case label or default label, or because the next statement
   2835 	     is not within the same iteration statement.  */
   2836 	  if ((stmt->subcode & GF_CALL_NOTHROW) != 0)
   2837 	    {
   2838 	      pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
   2839 			       "a case label or default label");
   2840 	      break;
   2841 	    }
   2842 
   2843 	  if (gsi_end_p (*gsi_p))
   2844 	    {
   2845 	      static_cast<location_t *>(wi->info)[0] = BUILTINS_LOCATION;
   2846 	      static_cast<location_t *>(wi->info)[1] = loc;
   2847 	      break;
   2848 	    }
   2849 
   2850 	  bool found = false;
   2851 
   2852 	  gimple_stmt_iterator gsi2 = *gsi_p;
   2853 	  stmt = gsi_stmt (gsi2);
   2854 	  if (gimple_code (stmt) == GIMPLE_GOTO && !gimple_has_location (stmt))
   2855 	    {
   2856 	      /* Go on until the artificial label.  */
   2857 	      tree goto_dest = gimple_goto_dest (stmt);
   2858 	      for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
   2859 		{
   2860 		  if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
   2861 		      && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
   2862 			   == goto_dest)
   2863 		    break;
   2864 		}
   2865 
   2866 	      /* Not found?  Stop.  */
   2867 	      if (gsi_end_p (gsi2))
   2868 		break;
   2869 
   2870 	      /* Look one past it.  */
   2871 	      gsi_next (&gsi2);
   2872 	    }
   2873 
   2874 	  /* We're looking for a case label or default label here.  */
   2875 	  while (!gsi_end_p (gsi2))
   2876 	    {
   2877 	      stmt = gsi_stmt (gsi2);
   2878 	      if (gimple_code (stmt) == GIMPLE_LABEL)
   2879 		{
   2880 		  tree label = gimple_label_label (as_a <glabel *> (stmt));
   2881 		  if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
   2882 		    {
   2883 		      found = true;
   2884 		      break;
   2885 		    }
   2886 		}
   2887 	      else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
   2888 		;
   2889 	      else if (!is_gimple_debug (stmt))
   2890 		/* Anything else is not expected.  */
   2891 		break;
   2892 	      gsi_next (&gsi2);
   2893 	    }
   2894 	  if (!found)
   2895 	    pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
   2896 		     "a case label or default label");
   2897 	}
   2898       break;
   2899     default:
   2900       static_cast<location_t *>(wi->info)[0] = UNKNOWN_LOCATION;
   2901       break;
   2902     }
   2903   return NULL_TREE;
   2904 }
   2905 
   2906 /* Expand all FALLTHROUGH () calls in SEQ.  */
   2907 
   2908 static void
   2909 expand_FALLTHROUGH (gimple_seq *seq_p)
   2910 {
   2911   struct walk_stmt_info wi;
   2912   location_t loc[2];
   2913   memset (&wi, 0, sizeof (wi));
   2914   loc[0] = UNKNOWN_LOCATION;
   2915   loc[1] = UNKNOWN_LOCATION;
   2916   wi.info = (void *) &loc[0];
   2917   walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
   2918   if (loc[0] != UNKNOWN_LOCATION)
   2919     /* We've found [[fallthrough]]; at the end of a switch, which the C++
   2920        standard says is ill-formed; see [dcl.attr.fallthrough].  */
   2921     pedwarn (loc[1], 0, "attribute %<fallthrough%> not preceding "
   2922 	     "a case label or default label");
   2923 }
   2924 
   2925 
   2926 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
   2928    branch to.  */
   2929 
   2930 static enum gimplify_status
   2931 gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
   2932 {
   2933   tree switch_expr = *expr_p;
   2934   gimple_seq switch_body_seq = NULL;
   2935   enum gimplify_status ret;
   2936   tree index_type = TREE_TYPE (switch_expr);
   2937   if (index_type == NULL_TREE)
   2938     index_type = TREE_TYPE (SWITCH_COND (switch_expr));
   2939 
   2940   ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
   2941                        fb_rvalue);
   2942   if (ret == GS_ERROR || ret == GS_UNHANDLED)
   2943     return ret;
   2944 
   2945   if (SWITCH_BODY (switch_expr))
   2946     {
   2947       vec<tree> labels;
   2948       vec<tree> saved_labels;
   2949       hash_set<tree> *saved_live_switch_vars = NULL;
   2950       tree default_case = NULL_TREE;
   2951       gswitch *switch_stmt;
   2952 
   2953       /* Save old labels, get new ones from body, then restore the old
   2954          labels.  Save all the things from the switch body to append after.  */
   2955       saved_labels = gimplify_ctxp->case_labels;
   2956       gimplify_ctxp->case_labels.create (8);
   2957 
   2958       /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR.  */
   2959       saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
   2960       tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
   2961       if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
   2962 	gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
   2963       else
   2964 	gimplify_ctxp->live_switch_vars = NULL;
   2965 
   2966       bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
   2967       gimplify_ctxp->in_switch_expr = true;
   2968 
   2969       gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
   2970 
   2971       gimplify_ctxp->in_switch_expr = old_in_switch_expr;
   2972       maybe_warn_switch_unreachable_and_auto_init (switch_body_seq);
   2973       maybe_warn_implicit_fallthrough (switch_body_seq);
   2974       /* Only do this for the outermost GIMPLE_SWITCH.  */
   2975       if (!gimplify_ctxp->in_switch_expr)
   2976 	expand_FALLTHROUGH (&switch_body_seq);
   2977 
   2978       labels = gimplify_ctxp->case_labels;
   2979       gimplify_ctxp->case_labels = saved_labels;
   2980 
   2981       if (gimplify_ctxp->live_switch_vars)
   2982 	{
   2983 	  gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
   2984 	  delete gimplify_ctxp->live_switch_vars;
   2985 	}
   2986       gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
   2987 
   2988       preprocess_case_label_vec_for_gimple (labels, index_type,
   2989 					    &default_case);
   2990 
   2991       bool add_bind = false;
   2992       if (!default_case)
   2993 	{
   2994 	  glabel *new_default;
   2995 
   2996 	  default_case
   2997 	    = build_case_label (NULL_TREE, NULL_TREE,
   2998 				create_artificial_label (UNKNOWN_LOCATION));
   2999 	  if (old_in_switch_expr)
   3000 	    {
   3001 	      SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
   3002 	      add_bind = true;
   3003 	    }
   3004 	  new_default = gimple_build_label (CASE_LABEL (default_case));
   3005 	  gimplify_seq_add_stmt (&switch_body_seq, new_default);
   3006 	}
   3007       else if (old_in_switch_expr)
   3008 	{
   3009 	  gimple *last = gimple_seq_last_stmt (switch_body_seq);
   3010 	  if (last && gimple_code (last) == GIMPLE_LABEL)
   3011 	    {
   3012 	      tree label = gimple_label_label (as_a <glabel *> (last));
   3013 	      if (SWITCH_BREAK_LABEL_P (label))
   3014 		add_bind = true;
   3015 	    }
   3016 	}
   3017 
   3018       switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
   3019 					 default_case, labels);
   3020       gimple_set_location (switch_stmt, EXPR_LOCATION (switch_expr));
   3021       /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
   3022 	 ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
   3023 	 wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
   3024 	 so that we can easily find the start and end of the switch
   3025 	 statement.  */
   3026       if (add_bind)
   3027 	{
   3028 	  gimple_seq bind_body = NULL;
   3029 	  gimplify_seq_add_stmt (&bind_body, switch_stmt);
   3030 	  gimple_seq_add_seq (&bind_body, switch_body_seq);
   3031 	  gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
   3032 	  gimple_set_location (bind, EXPR_LOCATION (switch_expr));
   3033 	  gimplify_seq_add_stmt (pre_p, bind);
   3034 	}
   3035       else
   3036 	{
   3037 	  gimplify_seq_add_stmt (pre_p, switch_stmt);
   3038 	  gimplify_seq_add_seq (pre_p, switch_body_seq);
   3039 	}
   3040       labels.release ();
   3041     }
   3042   else
   3043     gcc_unreachable ();
   3044 
   3045   return GS_ALL_DONE;
   3046 }
   3047 
   3048 /* Gimplify the LABEL_EXPR pointed to by EXPR_P.  */
   3049 
   3050 static enum gimplify_status
   3051 gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
   3052 {
   3053   gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
   3054 	      == current_function_decl);
   3055 
   3056   tree label = LABEL_EXPR_LABEL (*expr_p);
   3057   glabel *label_stmt = gimple_build_label (label);
   3058   gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
   3059   gimplify_seq_add_stmt (pre_p, label_stmt);
   3060 
   3061   if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
   3062     gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
   3063 						      NOT_TAKEN));
   3064   else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
   3065     gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
   3066 						      TAKEN));
   3067 
   3068   return GS_ALL_DONE;
   3069 }
   3070 
   3071 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P.  */
   3072 
   3073 static enum gimplify_status
   3074 gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
   3075 {
   3076   struct gimplify_ctx *ctxp;
   3077   glabel *label_stmt;
   3078 
   3079   /* Invalid programs can play Duff's Device type games with, for example,
   3080      #pragma omp parallel.  At least in the C front end, we don't
   3081      detect such invalid branches until after gimplification, in the
   3082      diagnose_omp_blocks pass.  */
   3083   for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
   3084     if (ctxp->case_labels.exists ())
   3085       break;
   3086 
   3087   tree label = CASE_LABEL (*expr_p);
   3088   label_stmt = gimple_build_label (label);
   3089   gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
   3090   ctxp->case_labels.safe_push (*expr_p);
   3091   gimplify_seq_add_stmt (pre_p, label_stmt);
   3092 
   3093   if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
   3094     gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
   3095 						      NOT_TAKEN));
   3096   else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
   3097     gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
   3098 						      TAKEN));
   3099 
   3100   return GS_ALL_DONE;
   3101 }
   3102 
   3103 /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
   3104    if necessary.  */
   3105 
   3106 tree
   3107 build_and_jump (tree *label_p)
   3108 {
   3109   if (label_p == NULL)
   3110     /* If there's nowhere to jump, just fall through.  */
   3111     return NULL_TREE;
   3112 
   3113   if (*label_p == NULL_TREE)
   3114     {
   3115       tree label = create_artificial_label (UNKNOWN_LOCATION);
   3116       *label_p = label;
   3117     }
   3118 
   3119   return build1 (GOTO_EXPR, void_type_node, *label_p);
   3120 }
   3121 
   3122 /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
   3123    This also involves building a label to jump to and communicating it to
   3124    gimplify_loop_expr through gimplify_ctxp->exit_label.  */
   3125 
   3126 static enum gimplify_status
   3127 gimplify_exit_expr (tree *expr_p)
   3128 {
   3129   tree cond = TREE_OPERAND (*expr_p, 0);
   3130   tree expr;
   3131 
   3132   expr = build_and_jump (&gimplify_ctxp->exit_label);
   3133   expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
   3134   *expr_p = expr;
   3135 
   3136   return GS_OK;
   3137 }
   3138 
   3139 /* *EXPR_P is a COMPONENT_REF being used as an rvalue.  If its type is
   3140    different from its canonical type, wrap the whole thing inside a
   3141    NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
   3142    type.
   3143 
   3144    The canonical type of a COMPONENT_REF is the type of the field being
   3145    referenced--unless the field is a bit-field which can be read directly
   3146    in a smaller mode, in which case the canonical type is the
   3147    sign-appropriate type corresponding to that mode.  */
   3148 
   3149 static void
   3150 canonicalize_component_ref (tree *expr_p)
   3151 {
   3152   tree expr = *expr_p;
   3153   tree type;
   3154 
   3155   gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
   3156 
   3157   if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
   3158     type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
   3159   else
   3160     type = TREE_TYPE (TREE_OPERAND (expr, 1));
   3161 
   3162   /* One could argue that all the stuff below is not necessary for
   3163      the non-bitfield case and declare it a FE error if type
   3164      adjustment would be needed.  */
   3165   if (TREE_TYPE (expr) != type)
   3166     {
   3167 #ifdef ENABLE_TYPES_CHECKING
   3168       tree old_type = TREE_TYPE (expr);
   3169 #endif
   3170       int type_quals;
   3171 
   3172       /* We need to preserve qualifiers and propagate them from
   3173 	 operand 0.  */
   3174       type_quals = TYPE_QUALS (type)
   3175 	| TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
   3176       if (TYPE_QUALS (type) != type_quals)
   3177 	type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
   3178 
   3179       /* Set the type of the COMPONENT_REF to the underlying type.  */
   3180       TREE_TYPE (expr) = type;
   3181 
   3182 #ifdef ENABLE_TYPES_CHECKING
   3183       /* It is now a FE error, if the conversion from the canonical
   3184 	 type to the original expression type is not useless.  */
   3185       gcc_assert (useless_type_conversion_p (old_type, type));
   3186 #endif
   3187     }
   3188 }
   3189 
   3190 /* If a NOP conversion is changing a pointer to array of foo to a pointer
   3191    to foo, embed that change in the ADDR_EXPR by converting
   3192       T array[U];
   3193       (T *)&array
   3194    ==>
   3195       &array[L]
   3196    where L is the lower bound.  For simplicity, only do this for constant
   3197    lower bound.
   3198    The constraint is that the type of &array[L] is trivially convertible
   3199    to T *.  */
   3200 
   3201 static void
   3202 canonicalize_addr_expr (tree *expr_p)
   3203 {
   3204   tree expr = *expr_p;
   3205   tree addr_expr = TREE_OPERAND (expr, 0);
   3206   tree datype, ddatype, pddatype;
   3207 
   3208   /* We simplify only conversions from an ADDR_EXPR to a pointer type.  */
   3209   if (!POINTER_TYPE_P (TREE_TYPE (expr))
   3210       || TREE_CODE (addr_expr) != ADDR_EXPR)
   3211     return;
   3212 
   3213   /* The addr_expr type should be a pointer to an array.  */
   3214   datype = TREE_TYPE (TREE_TYPE (addr_expr));
   3215   if (TREE_CODE (datype) != ARRAY_TYPE)
   3216     return;
   3217 
   3218   /* The pointer to element type shall be trivially convertible to
   3219      the expression pointer type.  */
   3220   ddatype = TREE_TYPE (datype);
   3221   pddatype = build_pointer_type (ddatype);
   3222   if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
   3223 				  pddatype))
   3224     return;
   3225 
   3226   /* The lower bound and element sizes must be constant.  */
   3227   if (!TYPE_SIZE_UNIT (ddatype)
   3228       || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
   3229       || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
   3230       || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
   3231     return;
   3232 
   3233   /* All checks succeeded.  Build a new node to merge the cast.  */
   3234   *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
   3235 		    TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
   3236 		    NULL_TREE, NULL_TREE);
   3237   *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
   3238 
   3239   /* We can have stripped a required restrict qualifier above.  */
   3240   if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
   3241     *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
   3242 }
   3243 
   3244 /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR.  Remove it and/or other conversions
   3245    underneath as appropriate.  */
   3246 
   3247 static enum gimplify_status
   3248 gimplify_conversion (tree *expr_p)
   3249 {
   3250   location_t loc = EXPR_LOCATION (*expr_p);
   3251   gcc_assert (CONVERT_EXPR_P (*expr_p));
   3252 
   3253   /* Then strip away all but the outermost conversion.  */
   3254   STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
   3255 
   3256   /* And remove the outermost conversion if it's useless.  */
   3257   if (tree_ssa_useless_type_conversion (*expr_p))
   3258     *expr_p = TREE_OPERAND (*expr_p, 0);
   3259 
   3260   /* If we still have a conversion at the toplevel,
   3261      then canonicalize some constructs.  */
   3262   if (CONVERT_EXPR_P (*expr_p))
   3263     {
   3264       tree sub = TREE_OPERAND (*expr_p, 0);
   3265 
   3266       /* If a NOP conversion is changing the type of a COMPONENT_REF
   3267 	 expression, then canonicalize its type now in order to expose more
   3268 	 redundant conversions.  */
   3269       if (TREE_CODE (sub) == COMPONENT_REF)
   3270 	canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
   3271 
   3272       /* If a NOP conversion is changing a pointer to array of foo
   3273 	 to a pointer to foo, embed that change in the ADDR_EXPR.  */
   3274       else if (TREE_CODE (sub) == ADDR_EXPR)
   3275 	canonicalize_addr_expr (expr_p);
   3276     }
   3277 
   3278   /* If we have a conversion to a non-register type force the
   3279      use of a VIEW_CONVERT_EXPR instead.  */
   3280   if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
   3281     *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
   3282 			       TREE_OPERAND (*expr_p, 0));
   3283 
   3284   /* Canonicalize CONVERT_EXPR to NOP_EXPR.  */
   3285   if (TREE_CODE (*expr_p) == CONVERT_EXPR)
   3286     TREE_SET_CODE (*expr_p, NOP_EXPR);
   3287 
   3288   return GS_OK;
   3289 }
   3290 
   3291 /* Gimplify a VAR_DECL or PARM_DECL.  Return GS_OK if we expanded a
   3292    DECL_VALUE_EXPR, and it's worth re-examining things.  */
   3293 
   3294 static enum gimplify_status
   3295 gimplify_var_or_parm_decl (tree *expr_p)
   3296 {
   3297   tree decl = *expr_p;
   3298 
   3299   /* ??? If this is a local variable, and it has not been seen in any
   3300      outer BIND_EXPR, then it's probably the result of a duplicate
   3301      declaration, for which we've already issued an error.  It would
   3302      be really nice if the front end wouldn't leak these at all.
   3303      Currently the only known culprit is C++ destructors, as seen
   3304      in g++.old-deja/g++.jason/binding.C.
   3305      Another possible culpit are size expressions for variably modified
   3306      types which are lost in the FE or not gimplified correctly.  */
   3307   if (VAR_P (decl)
   3308       && !DECL_SEEN_IN_BIND_EXPR_P (decl)
   3309       && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
   3310       && decl_function_context (decl) == current_function_decl)
   3311     {
   3312       gcc_assert (seen_error ());
   3313       return GS_ERROR;
   3314     }
   3315 
   3316   /* When within an OMP context, notice uses of variables.  */
   3317   if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
   3318     return GS_ALL_DONE;
   3319 
   3320   /* If the decl is an alias for another expression, substitute it now.  */
   3321   if (DECL_HAS_VALUE_EXPR_P (decl))
   3322     {
   3323       *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
   3324       return GS_OK;
   3325     }
   3326 
   3327   return GS_ALL_DONE;
   3328 }
   3329 
   3330 /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T.  */
   3331 
   3332 static void
   3333 recalculate_side_effects (tree t)
   3334 {
   3335   enum tree_code code = TREE_CODE (t);
   3336   int len = TREE_OPERAND_LENGTH (t);
   3337   int i;
   3338 
   3339   switch (TREE_CODE_CLASS (code))
   3340     {
   3341     case tcc_expression:
   3342       switch (code)
   3343 	{
   3344 	case INIT_EXPR:
   3345 	case MODIFY_EXPR:
   3346 	case VA_ARG_EXPR:
   3347 	case PREDECREMENT_EXPR:
   3348 	case PREINCREMENT_EXPR:
   3349 	case POSTDECREMENT_EXPR:
   3350 	case POSTINCREMENT_EXPR:
   3351 	  /* All of these have side-effects, no matter what their
   3352 	     operands are.  */
   3353 	  return;
   3354 
   3355 	default:
   3356 	  break;
   3357 	}
   3358       /* Fall through.  */
   3359 
   3360     case tcc_comparison:  /* a comparison expression */
   3361     case tcc_unary:       /* a unary arithmetic expression */
   3362     case tcc_binary:      /* a binary arithmetic expression */
   3363     case tcc_reference:   /* a reference */
   3364     case tcc_vl_exp:        /* a function call */
   3365       TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
   3366       for (i = 0; i < len; ++i)
   3367 	{
   3368 	  tree op = TREE_OPERAND (t, i);
   3369 	  if (op && TREE_SIDE_EFFECTS (op))
   3370 	    TREE_SIDE_EFFECTS (t) = 1;
   3371 	}
   3372       break;
   3373 
   3374     case tcc_constant:
   3375       /* No side-effects.  */
   3376       return;
   3377 
   3378     default:
   3379       if (code == SSA_NAME)
   3380 	/* No side-effects.  */
   3381 	return;
   3382       gcc_unreachable ();
   3383    }
   3384 }
   3385 
   3386 /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
   3387    node *EXPR_P.
   3388 
   3389       compound_lval
   3390 	      : min_lval '[' val ']'
   3391 	      | min_lval '.' ID
   3392 	      | compound_lval '[' val ']'
   3393 	      | compound_lval '.' ID
   3394 
   3395    This is not part of the original SIMPLE definition, which separates
   3396    array and member references, but it seems reasonable to handle them
   3397    together.  Also, this way we don't run into problems with union
   3398    aliasing; gcc requires that for accesses through a union to alias, the
   3399    union reference must be explicit, which was not always the case when we
   3400    were splitting up array and member refs.
   3401 
   3402    PRE_P points to the sequence where side effects that must happen before
   3403      *EXPR_P should be stored.
   3404 
   3405    POST_P points to the sequence where side effects that must happen after
   3406      *EXPR_P should be stored.  */
   3407 
   3408 static enum gimplify_status
   3409 gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   3410 			fallback_t fallback)
   3411 {
   3412   tree *p;
   3413   enum gimplify_status ret = GS_ALL_DONE, tret;
   3414   int i;
   3415   location_t loc = EXPR_LOCATION (*expr_p);
   3416   tree expr = *expr_p;
   3417 
   3418   /* Create a stack of the subexpressions so later we can walk them in
   3419      order from inner to outer.  */
   3420   auto_vec<tree, 10> expr_stack;
   3421 
   3422   /* We can handle anything that get_inner_reference can deal with.  */
   3423   for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
   3424     {
   3425     restart:
   3426       /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs.  */
   3427       if (TREE_CODE (*p) == INDIRECT_REF)
   3428 	*p = fold_indirect_ref_loc (loc, *p);
   3429 
   3430       if (handled_component_p (*p))
   3431 	;
   3432       /* Expand DECL_VALUE_EXPR now.  In some cases that may expose
   3433 	 additional COMPONENT_REFs.  */
   3434       else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
   3435 	       && gimplify_var_or_parm_decl (p) == GS_OK)
   3436 	goto restart;
   3437       else
   3438 	break;
   3439 
   3440       expr_stack.safe_push (*p);
   3441     }
   3442 
   3443   gcc_assert (expr_stack.length ());
   3444 
   3445   /* Now EXPR_STACK is a stack of pointers to all the refs we've
   3446      walked through and P points to the innermost expression.
   3447 
   3448      Java requires that we elaborated nodes in source order.  That
   3449      means we must gimplify the inner expression followed by each of
   3450      the indices, in order.  But we can't gimplify the inner
   3451      expression until we deal with any variable bounds, sizes, or
   3452      positions in order to deal with PLACEHOLDER_EXPRs.
   3453 
   3454      The base expression may contain a statement expression that
   3455      has declarations used in size expressions, so has to be
   3456      gimplified before gimplifying the size expressions.
   3457 
   3458      So we do this in three steps.  First we deal with variable
   3459      bounds, sizes, and positions, then we gimplify the base and
   3460      ensure it is memory if needed, then we deal with the annotations
   3461      for any variables in the components and any indices, from left
   3462      to right.  */
   3463 
   3464   bool need_non_reg = false;
   3465   for (i = expr_stack.length () - 1; i >= 0; i--)
   3466     {
   3467       tree t = expr_stack[i];
   3468 
   3469       if (error_operand_p (TREE_OPERAND (t, 0)))
   3470 	return GS_ERROR;
   3471 
   3472       if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
   3473 	{
   3474 	  /* Deal with the low bound and element type size and put them into
   3475 	     the ARRAY_REF.  If these values are set, they have already been
   3476 	     gimplified.  */
   3477 	  if (TREE_OPERAND (t, 2) == NULL_TREE)
   3478 	    {
   3479 	      tree low = unshare_expr (array_ref_low_bound (t));
   3480 	      if (!is_gimple_min_invariant (low))
   3481 		{
   3482 		  TREE_OPERAND (t, 2) = low;
   3483 		}
   3484 	    }
   3485 
   3486 	  if (TREE_OPERAND (t, 3) == NULL_TREE)
   3487 	    {
   3488 	      tree elmt_size = array_ref_element_size (t);
   3489 	      if (!is_gimple_min_invariant (elmt_size))
   3490 		{
   3491 		  elmt_size = unshare_expr (elmt_size);
   3492 		  tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
   3493 		  tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
   3494 
   3495 		  /* Divide the element size by the alignment of the element
   3496 		     type (above).  */
   3497 		  elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR,
   3498 					      elmt_size, factor);
   3499 
   3500 		  TREE_OPERAND (t, 3) = elmt_size;
   3501 		}
   3502 	    }
   3503 	  need_non_reg = true;
   3504 	}
   3505       else if (TREE_CODE (t) == COMPONENT_REF)
   3506 	{
   3507 	  /* Set the field offset into T and gimplify it.  */
   3508 	  if (TREE_OPERAND (t, 2) == NULL_TREE)
   3509 	    {
   3510 	      tree offset = component_ref_field_offset (t);
   3511 	      if (!is_gimple_min_invariant (offset))
   3512 		{
   3513 		  offset = unshare_expr (offset);
   3514 		  tree field = TREE_OPERAND (t, 1);
   3515 		  tree factor
   3516 		    = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
   3517 
   3518 		  /* Divide the offset by its alignment.  */
   3519 		  offset = size_binop_loc (loc, EXACT_DIV_EXPR,
   3520 					   offset, factor);
   3521 
   3522 		  TREE_OPERAND (t, 2) = offset;
   3523 		}
   3524 	    }
   3525 	  need_non_reg = true;
   3526 	}
   3527       else if (!is_gimple_reg_type (TREE_TYPE (t)))
   3528 	/* When the result of an operation, in particular a VIEW_CONVERT_EXPR
   3529 	   is a non-register type then require the base object to be a
   3530 	   non-register as well.  */
   3531 	need_non_reg = true;
   3532     }
   3533 
   3534   /* Step 2 is to gimplify the base expression.  Make sure lvalue is set
   3535      so as to match the min_lval predicate.  Failure to do so may result
   3536      in the creation of large aggregate temporaries.  */
   3537   tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
   3538 			fallback | fb_lvalue);
   3539   ret = MIN (ret, tret);
   3540   if (ret == GS_ERROR)
   3541     return GS_ERROR;
   3542 
   3543   /* Step 2a: if we have component references we do not support on
   3544      registers then make sure the base isn't a register.  Of course
   3545      we can only do so if an rvalue is OK.  */
   3546   if (need_non_reg && (fallback & fb_rvalue))
   3547     prepare_gimple_addressable (p, pre_p);
   3548 
   3549 
   3550   /* Step 3: gimplify size expressions and the indices and operands of
   3551      ARRAY_REF.  During this loop we also remove any useless conversions.
   3552      If we operate on a register also make sure to properly gimplify
   3553      to individual operations.  */
   3554 
   3555   bool reg_operations = is_gimple_reg (*p);
   3556   for (; expr_stack.length () > 0; )
   3557     {
   3558       tree t = expr_stack.pop ();
   3559 
   3560       if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
   3561 	{
   3562 	  gcc_assert (!reg_operations);
   3563 
   3564 	  /* Gimplify the low bound and element type size. */
   3565 	  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
   3566 				is_gimple_reg, fb_rvalue);
   3567 	  ret = MIN (ret, tret);
   3568 
   3569 	  tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
   3570 				is_gimple_reg, fb_rvalue);
   3571 	  ret = MIN (ret, tret);
   3572 
   3573 	  /* Gimplify the dimension.  */
   3574 	  tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
   3575 				is_gimple_val, fb_rvalue);
   3576 	  ret = MIN (ret, tret);
   3577 	}
   3578       else if (TREE_CODE (t) == COMPONENT_REF)
   3579 	{
   3580 	  gcc_assert (!reg_operations);
   3581 
   3582 	  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
   3583 				is_gimple_reg, fb_rvalue);
   3584 	  ret = MIN (ret, tret);
   3585 	}
   3586       else if (reg_operations)
   3587 	{
   3588 	  tret = gimplify_expr (&TREE_OPERAND (t, 0), pre_p, post_p,
   3589 				is_gimple_val, fb_rvalue);
   3590 	  ret = MIN (ret, tret);
   3591 	}
   3592 
   3593       STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
   3594 
   3595       /* The innermost expression P may have originally had
   3596 	 TREE_SIDE_EFFECTS set which would have caused all the outer
   3597 	 expressions in *EXPR_P leading to P to also have had
   3598 	 TREE_SIDE_EFFECTS set.  */
   3599       recalculate_side_effects (t);
   3600     }
   3601 
   3602   /* If the outermost expression is a COMPONENT_REF, canonicalize its type.  */
   3603   if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
   3604     {
   3605       canonicalize_component_ref (expr_p);
   3606     }
   3607 
   3608   expr_stack.release ();
   3609 
   3610   gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
   3611 
   3612   return ret;
   3613 }
   3614 
   3615 /*  Gimplify the self modifying expression pointed to by EXPR_P
   3616     (++, --, +=, -=).
   3617 
   3618     PRE_P points to the list where side effects that must happen before
   3619 	*EXPR_P should be stored.
   3620 
   3621     POST_P points to the list where side effects that must happen after
   3622 	*EXPR_P should be stored.
   3623 
   3624     WANT_VALUE is nonzero iff we want to use the value of this expression
   3625 	in another expression.
   3626 
   3627     ARITH_TYPE is the type the computation should be performed in.  */
   3628 
   3629 enum gimplify_status
   3630 gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   3631 			bool want_value, tree arith_type)
   3632 {
   3633   enum tree_code code;
   3634   tree lhs, lvalue, rhs, t1;
   3635   gimple_seq post = NULL, *orig_post_p = post_p;
   3636   bool postfix;
   3637   enum tree_code arith_code;
   3638   enum gimplify_status ret;
   3639   location_t loc = EXPR_LOCATION (*expr_p);
   3640 
   3641   code = TREE_CODE (*expr_p);
   3642 
   3643   gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
   3644 	      || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
   3645 
   3646   /* Prefix or postfix?  */
   3647   if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
   3648     /* Faster to treat as prefix if result is not used.  */
   3649     postfix = want_value;
   3650   else
   3651     postfix = false;
   3652 
   3653   /* For postfix, make sure the inner expression's post side effects
   3654      are executed after side effects from this expression.  */
   3655   if (postfix)
   3656     post_p = &post;
   3657 
   3658   /* Add or subtract?  */
   3659   if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
   3660     arith_code = PLUS_EXPR;
   3661   else
   3662     arith_code = MINUS_EXPR;
   3663 
   3664   /* Gimplify the LHS into a GIMPLE lvalue.  */
   3665   lvalue = TREE_OPERAND (*expr_p, 0);
   3666   ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
   3667   if (ret == GS_ERROR)
   3668     return ret;
   3669 
   3670   /* Extract the operands to the arithmetic operation.  */
   3671   lhs = lvalue;
   3672   rhs = TREE_OPERAND (*expr_p, 1);
   3673 
   3674   /* For postfix operator, we evaluate the LHS to an rvalue and then use
   3675      that as the result value and in the postqueue operation.  */
   3676   if (postfix)
   3677     {
   3678       ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
   3679       if (ret == GS_ERROR)
   3680 	return ret;
   3681 
   3682       lhs = get_initialized_tmp_var (lhs, pre_p);
   3683     }
   3684 
   3685   /* For POINTERs increment, use POINTER_PLUS_EXPR.  */
   3686   if (POINTER_TYPE_P (TREE_TYPE (lhs)))
   3687     {
   3688       rhs = convert_to_ptrofftype_loc (loc, rhs);
   3689       if (arith_code == MINUS_EXPR)
   3690 	rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
   3691       t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
   3692     }
   3693   else
   3694     t1 = fold_convert (TREE_TYPE (*expr_p),
   3695 		       fold_build2 (arith_code, arith_type,
   3696 				    fold_convert (arith_type, lhs),
   3697 				    fold_convert (arith_type, rhs)));
   3698 
   3699   if (postfix)
   3700     {
   3701       gimplify_assign (lvalue, t1, pre_p);
   3702       gimplify_seq_add_seq (orig_post_p, post);
   3703       *expr_p = lhs;
   3704       return GS_ALL_DONE;
   3705     }
   3706   else
   3707     {
   3708       *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
   3709       return GS_OK;
   3710     }
   3711 }
   3712 
   3713 /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR.  */
   3714 
   3715 static void
   3716 maybe_with_size_expr (tree *expr_p)
   3717 {
   3718   tree expr = *expr_p;
   3719   tree type = TREE_TYPE (expr);
   3720   tree size;
   3721 
   3722   /* If we've already wrapped this or the type is error_mark_node, we can't do
   3723      anything.  */
   3724   if (TREE_CODE (expr) == WITH_SIZE_EXPR
   3725       || type == error_mark_node)
   3726     return;
   3727 
   3728   /* If the size isn't known or is a constant, we have nothing to do.  */
   3729   size = TYPE_SIZE_UNIT (type);
   3730   if (!size || poly_int_tree_p (size))
   3731     return;
   3732 
   3733   /* Otherwise, make a WITH_SIZE_EXPR.  */
   3734   size = unshare_expr (size);
   3735   size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
   3736   *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
   3737 }
   3738 
   3739 /* Helper for gimplify_call_expr.  Gimplify a single argument *ARG_P
   3740    Store any side-effects in PRE_P.  CALL_LOCATION is the location of
   3741    the CALL_EXPR.  If ALLOW_SSA is set the actual parameter may be
   3742    gimplified to an SSA name.  */
   3743 
   3744 enum gimplify_status
   3745 gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
   3746 	      bool allow_ssa)
   3747 {
   3748   bool (*test) (tree);
   3749   fallback_t fb;
   3750 
   3751   /* In general, we allow lvalues for function arguments to avoid
   3752      extra overhead of copying large aggregates out of even larger
   3753      aggregates into temporaries only to copy the temporaries to
   3754      the argument list.  Make optimizers happy by pulling out to
   3755      temporaries those types that fit in registers.  */
   3756   if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
   3757     test = is_gimple_val, fb = fb_rvalue;
   3758   else
   3759     {
   3760       test = is_gimple_lvalue, fb = fb_either;
   3761       /* Also strip a TARGET_EXPR that would force an extra copy.  */
   3762       if (TREE_CODE (*arg_p) == TARGET_EXPR)
   3763 	{
   3764 	  tree init = TARGET_EXPR_INITIAL (*arg_p);
   3765 	  if (init
   3766 	      && !VOID_TYPE_P (TREE_TYPE (init)))
   3767 	    *arg_p = init;
   3768 	}
   3769     }
   3770 
   3771   /* If this is a variable sized type, we must remember the size.  */
   3772   maybe_with_size_expr (arg_p);
   3773 
   3774   /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c.  */
   3775   /* Make sure arguments have the same location as the function call
   3776      itself.  */
   3777   protected_set_expr_location (*arg_p, call_location);
   3778 
   3779   /* There is a sequence point before a function call.  Side effects in
   3780      the argument list must occur before the actual call. So, when
   3781      gimplifying arguments, force gimplify_expr to use an internal
   3782      post queue which is then appended to the end of PRE_P.  */
   3783   return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
   3784 }
   3785 
   3786 /* Don't fold inside offloading or taskreg regions: it can break code by
   3787    adding decl references that weren't in the source.  We'll do it during
   3788    omplower pass instead.  */
   3789 
   3790 static bool
   3791 maybe_fold_stmt (gimple_stmt_iterator *gsi)
   3792 {
   3793   struct gimplify_omp_ctx *ctx;
   3794   for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
   3795     if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
   3796       return false;
   3797     else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
   3798       return false;
   3799   /* Delay folding of builtins until the IL is in consistent state
   3800      so the diagnostic machinery can do a better job.  */
   3801   if (gimple_call_builtin_p (gsi_stmt (*gsi)))
   3802     return false;
   3803   return fold_stmt (gsi);
   3804 }
   3805 
   3806 /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
   3807    WANT_VALUE is true if the result of the call is desired.  */
   3808 
   3809 static enum gimplify_status
   3810 gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
   3811 {
   3812   tree fndecl, parms, p, fnptrtype;
   3813   enum gimplify_status ret;
   3814   int i, nargs;
   3815   gcall *call;
   3816   bool builtin_va_start_p = false;
   3817   location_t loc = EXPR_LOCATION (*expr_p);
   3818 
   3819   gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
   3820 
   3821   /* For reliable diagnostics during inlining, it is necessary that
   3822      every call_expr be annotated with file and line.  */
   3823   if (! EXPR_HAS_LOCATION (*expr_p))
   3824     SET_EXPR_LOCATION (*expr_p, input_location);
   3825 
   3826   /* Gimplify internal functions created in the FEs.  */
   3827   if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
   3828     {
   3829       if (want_value)
   3830 	return GS_ALL_DONE;
   3831 
   3832       nargs = call_expr_nargs (*expr_p);
   3833       enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
   3834       auto_vec<tree> vargs (nargs);
   3835 
   3836       if (ifn == IFN_ASSUME)
   3837 	{
   3838 	  if (simple_condition_p (CALL_EXPR_ARG (*expr_p, 0)))
   3839 	    {
   3840 	      /* If the [[assume (cond)]]; condition is simple
   3841 		 enough and can be evaluated unconditionally
   3842 		 without side-effects, expand it as
   3843 		 if (!cond) __builtin_unreachable ();  */
   3844 	      tree fndecl = builtin_decl_explicit (BUILT_IN_UNREACHABLE);
   3845 	      *expr_p = build3 (COND_EXPR, void_type_node,
   3846 				CALL_EXPR_ARG (*expr_p, 0), void_node,
   3847 				build_call_expr_loc (EXPR_LOCATION (*expr_p),
   3848 						     fndecl, 0));
   3849 	      return GS_OK;
   3850 	    }
   3851 	  /* If not optimizing, ignore the assumptions.  */
   3852 	  if (!optimize || seen_error ())
   3853 	    {
   3854 	      *expr_p = NULL_TREE;
   3855 	      return GS_ALL_DONE;
   3856 	    }
   3857 	  /* Temporarily, until gimple lowering, transform
   3858 	     .ASSUME (cond);
   3859 	     into:
   3860 	     [[assume (guard)]]
   3861 	     {
   3862 	       guard = cond;
   3863 	     }
   3864 	     such that gimple lowering can outline the condition into
   3865 	     a separate function easily.  */
   3866 	  tree guard = create_tmp_var (boolean_type_node);
   3867 	  *expr_p = build2 (MODIFY_EXPR, void_type_node, guard,
   3868 			    gimple_boolify (CALL_EXPR_ARG (*expr_p, 0)));
   3869 	  *expr_p = build3 (BIND_EXPR, void_type_node, NULL, *expr_p, NULL);
   3870 	  push_gimplify_context ();
   3871 	  gimple_seq body = NULL;
   3872 	  gimple *g = gimplify_and_return_first (*expr_p, &body);
   3873 	  pop_gimplify_context (g);
   3874 	  g = gimple_build_assume (guard, body);
   3875 	  gimple_set_location (g, loc);
   3876 	  gimplify_seq_add_stmt (pre_p, g);
   3877 	  *expr_p = NULL_TREE;
   3878 	  return GS_ALL_DONE;
   3879 	}
   3880       else if (ifn == IFN_UBSAN_BOUNDS
   3881 	       && nargs == 3
   3882 	       && integer_onep (CALL_EXPR_ARG (*expr_p, 0)))
   3883 	{
   3884 	  /* If first argument is one, add TYPE_MAX_VALUE (TYPE_DOMAIN (t))
   3885 	     to 3rd argument and change first argument to 0.  This is
   3886 	     done by ubsan_instrument_bounds so that we can use the
   3887 	     max value from gimplify_type_sizes here instead of original
   3888 	     expression for VLAs.  */
   3889 	  tree type = TREE_TYPE (CALL_EXPR_ARG (*expr_p, 0));
   3890 	  CALL_EXPR_ARG (*expr_p, 0) = build_int_cst (type, 0);
   3891 	  gcc_assert (TREE_CODE (type) == POINTER_TYPE);
   3892 	  type = TREE_TYPE (type);
   3893 	  gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
   3894 	  tree maxv = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
   3895 	  gcc_assert (maxv);
   3896 	  tree arg3 = CALL_EXPR_ARG (*expr_p, 2);
   3897 	  CALL_EXPR_ARG (*expr_p, 2)
   3898 	    = fold_build2 (PLUS_EXPR, TREE_TYPE (arg3), maxv, arg3);
   3899 	}
   3900 
   3901       for (i = 0; i < nargs; i++)
   3902 	{
   3903 	  gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
   3904 			EXPR_LOCATION (*expr_p));
   3905 	  vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
   3906 	}
   3907 
   3908       gcall *call = gimple_build_call_internal_vec (ifn, vargs);
   3909       gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
   3910       gimplify_seq_add_stmt (pre_p, call);
   3911       return GS_ALL_DONE;
   3912     }
   3913 
   3914   /* This may be a call to a builtin function.
   3915 
   3916      Builtin function calls may be transformed into different
   3917      (and more efficient) builtin function calls under certain
   3918      circumstances.  Unfortunately, gimplification can muck things
   3919      up enough that the builtin expanders are not aware that certain
   3920      transformations are still valid.
   3921 
   3922      So we attempt transformation/gimplification of the call before
   3923      we gimplify the CALL_EXPR.  At this time we do not manage to
   3924      transform all calls in the same manner as the expanders do, but
   3925      we do transform most of them.  */
   3926   fndecl = get_callee_fndecl (*expr_p);
   3927   if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
   3928     switch (DECL_FUNCTION_CODE (fndecl))
   3929       {
   3930       CASE_BUILT_IN_ALLOCA:
   3931 	/* If the call has been built for a variable-sized object, then we
   3932 	   want to restore the stack level when the enclosing BIND_EXPR is
   3933 	   exited to reclaim the allocated space; otherwise, we precisely
   3934 	   need to do the opposite and preserve the latest stack level.  */
   3935 	if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
   3936 	  gimplify_ctxp->save_stack = true;
   3937 	else
   3938 	  gimplify_ctxp->keep_stack = true;
   3939 	break;
   3940 
   3941       case BUILT_IN_VA_START:
   3942         {
   3943 	  builtin_va_start_p = true;
   3944 	  if (call_expr_nargs (*expr_p) < 2)
   3945 	    {
   3946 	      error ("too few arguments to function %<va_start%>");
   3947 	      *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
   3948 	      return GS_OK;
   3949 	    }
   3950 
   3951 	  if (fold_builtin_next_arg (*expr_p, true))
   3952 	    {
   3953 	      *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
   3954 	      return GS_OK;
   3955 	    }
   3956 	  break;
   3957 	}
   3958 
   3959       case BUILT_IN_EH_RETURN:
   3960 	cfun->calls_eh_return = true;
   3961 	break;
   3962 
   3963       case BUILT_IN_CLEAR_PADDING:
   3964 	if (call_expr_nargs (*expr_p) == 1)
   3965 	  {
   3966 	    /* Remember the original type of the argument in an internal
   3967 	       dummy second argument, as in GIMPLE pointer conversions are
   3968 	       useless.  Also mark this call as not for automatic
   3969 	       initialization in the internal dummy third argument.  */
   3970 	    p = CALL_EXPR_ARG (*expr_p, 0);
   3971 	    *expr_p
   3972 	      = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p,
   3973 				     build_zero_cst (TREE_TYPE (p)));
   3974 	    return GS_OK;
   3975 	  }
   3976 	break;
   3977 
   3978       default:
   3979         ;
   3980       }
   3981   if (fndecl && fndecl_built_in_p (fndecl))
   3982     {
   3983       tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
   3984       if (new_tree && new_tree != *expr_p)
   3985 	{
   3986 	  /* There was a transformation of this call which computes the
   3987 	     same value, but in a more efficient way.  Return and try
   3988 	     again.  */
   3989 	  *expr_p = new_tree;
   3990 	  return GS_OK;
   3991 	}
   3992     }
   3993 
   3994   /* Remember the original function pointer type.  */
   3995   fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
   3996 
   3997   if (flag_openmp
   3998       && fndecl
   3999       && cfun
   4000       && (cfun->curr_properties & PROP_gimple_any) == 0)
   4001     {
   4002       tree variant = omp_resolve_declare_variant (fndecl);
   4003       if (variant != fndecl)
   4004 	CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
   4005     }
   4006 
   4007   /* There is a sequence point before the call, so any side effects in
   4008      the calling expression must occur before the actual call.  Force
   4009      gimplify_expr to use an internal post queue.  */
   4010   ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
   4011 		       is_gimple_call_addr, fb_rvalue);
   4012 
   4013   if (ret == GS_ERROR)
   4014     return GS_ERROR;
   4015 
   4016   nargs = call_expr_nargs (*expr_p);
   4017 
   4018   /* Get argument types for verification.  */
   4019   fndecl = get_callee_fndecl (*expr_p);
   4020   parms = NULL_TREE;
   4021   if (fndecl)
   4022     parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
   4023   else
   4024     parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
   4025 
   4026   if (fndecl && DECL_ARGUMENTS (fndecl))
   4027     p = DECL_ARGUMENTS (fndecl);
   4028   else if (parms)
   4029     p = parms;
   4030   else
   4031     p = NULL_TREE;
   4032   for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
   4033     ;
   4034 
   4035   /* If the last argument is __builtin_va_arg_pack () and it is not
   4036      passed as a named argument, decrease the number of CALL_EXPR
   4037      arguments and set instead the CALL_EXPR_VA_ARG_PACK flag.  */
   4038   if (!p
   4039       && i < nargs
   4040       && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
   4041     {
   4042       tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
   4043       tree last_arg_fndecl = get_callee_fndecl (last_arg);
   4044 
   4045       if (last_arg_fndecl
   4046 	  && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
   4047 	{
   4048 	  tree call = *expr_p;
   4049 
   4050 	  --nargs;
   4051 	  *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
   4052 					  CALL_EXPR_FN (call),
   4053 					  nargs, CALL_EXPR_ARGP (call));
   4054 
   4055 	  /* Copy all CALL_EXPR flags, location and block, except
   4056 	     CALL_EXPR_VA_ARG_PACK flag.  */
   4057 	  CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
   4058 	  CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
   4059 	  CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
   4060 	    = CALL_EXPR_RETURN_SLOT_OPT (call);
   4061 	  CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
   4062 	  SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
   4063 
   4064 	  /* Set CALL_EXPR_VA_ARG_PACK.  */
   4065 	  CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
   4066 	}
   4067     }
   4068 
   4069   /* If the call returns twice then after building the CFG the call
   4070      argument computations will no longer dominate the call because
   4071      we add an abnormal incoming edge to the call.  So do not use SSA
   4072      vars there.  */
   4073   bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
   4074 
   4075   /* Gimplify the function arguments.  */
   4076   if (nargs > 0)
   4077     {
   4078       for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
   4079            PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
   4080            PUSH_ARGS_REVERSED ? i-- : i++)
   4081         {
   4082           enum gimplify_status t;
   4083 
   4084           /* Avoid gimplifying the second argument to va_start, which needs to
   4085              be the plain PARM_DECL.  */
   4086           if ((i != 1) || !builtin_va_start_p)
   4087             {
   4088               t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
   4089 				EXPR_LOCATION (*expr_p), ! returns_twice);
   4090 
   4091               if (t == GS_ERROR)
   4092                 ret = GS_ERROR;
   4093             }
   4094         }
   4095     }
   4096 
   4097   /* Gimplify the static chain.  */
   4098   if (CALL_EXPR_STATIC_CHAIN (*expr_p))
   4099     {
   4100       if (fndecl && !DECL_STATIC_CHAIN (fndecl))
   4101 	CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
   4102       else
   4103 	{
   4104 	  enum gimplify_status t;
   4105 	  t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
   4106 			    EXPR_LOCATION (*expr_p), ! returns_twice);
   4107 	  if (t == GS_ERROR)
   4108 	    ret = GS_ERROR;
   4109 	}
   4110     }
   4111 
   4112   /* Verify the function result.  */
   4113   if (want_value && fndecl
   4114       && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
   4115     {
   4116       error_at (loc, "using result of function returning %<void%>");
   4117       ret = GS_ERROR;
   4118     }
   4119 
   4120   /* Try this again in case gimplification exposed something.  */
   4121   if (ret != GS_ERROR)
   4122     {
   4123       tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
   4124 
   4125       if (new_tree && new_tree != *expr_p)
   4126 	{
   4127 	  /* There was a transformation of this call which computes the
   4128 	     same value, but in a more efficient way.  Return and try
   4129 	     again.  */
   4130 	  *expr_p = new_tree;
   4131 	  return GS_OK;
   4132 	}
   4133     }
   4134   else
   4135     {
   4136       *expr_p = error_mark_node;
   4137       return GS_ERROR;
   4138     }
   4139 
   4140   /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
   4141      decl.  This allows us to eliminate redundant or useless
   4142      calls to "const" functions.  */
   4143   if (TREE_CODE (*expr_p) == CALL_EXPR)
   4144     {
   4145       int flags = call_expr_flags (*expr_p);
   4146       if (flags & (ECF_CONST | ECF_PURE)
   4147 	  /* An infinite loop is considered a side effect.  */
   4148 	  && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
   4149 	TREE_SIDE_EFFECTS (*expr_p) = 0;
   4150     }
   4151 
   4152   /* If the value is not needed by the caller, emit a new GIMPLE_CALL
   4153      and clear *EXPR_P.  Otherwise, leave *EXPR_P in its gimplified
   4154      form and delegate the creation of a GIMPLE_CALL to
   4155      gimplify_modify_expr.  This is always possible because when
   4156      WANT_VALUE is true, the caller wants the result of this call into
   4157      a temporary, which means that we will emit an INIT_EXPR in
   4158      internal_get_tmp_var which will then be handled by
   4159      gimplify_modify_expr.  */
   4160   if (!want_value)
   4161     {
   4162       /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
   4163 	 have to do is replicate it as a GIMPLE_CALL tuple.  */
   4164       gimple_stmt_iterator gsi;
   4165       call = gimple_build_call_from_tree (*expr_p, fnptrtype);
   4166       notice_special_calls (call);
   4167       gimplify_seq_add_stmt (pre_p, call);
   4168       gsi = gsi_last (*pre_p);
   4169       maybe_fold_stmt (&gsi);
   4170       *expr_p = NULL_TREE;
   4171     }
   4172   else
   4173     /* Remember the original function type.  */
   4174     CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
   4175 				     CALL_EXPR_FN (*expr_p));
   4176 
   4177   return ret;
   4178 }
   4179 
   4180 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
   4181    rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
   4182 
   4183    TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
   4184    condition is true or false, respectively.  If null, we should generate
   4185    our own to skip over the evaluation of this specific expression.
   4186 
   4187    LOCUS is the source location of the COND_EXPR.
   4188 
   4189    The condition_uid is a discriminator tag for condition coverage used to map
   4190    conditions to its corresponding full Boolean function.
   4191 
   4192    This function is the tree equivalent of do_jump.
   4193 
   4194    shortcut_cond_r should only be called by shortcut_cond_expr.  */
   4195 
   4196 static tree
   4197 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
   4198 		 location_t locus, unsigned condition_uid)
   4199 {
   4200   tree local_label = NULL_TREE;
   4201   tree t, expr = NULL;
   4202 
   4203   /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
   4204      retain the shortcut semantics.  Just insert the gotos here;
   4205      shortcut_cond_expr will append the real blocks later.  */
   4206   if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
   4207     {
   4208       location_t new_locus;
   4209 
   4210       /* Turn if (a && b) into
   4211 
   4212 	 if (a); else goto no;
   4213 	 if (b) goto yes; else goto no;
   4214 	 (no:) */
   4215 
   4216       if (false_label_p == NULL)
   4217 	false_label_p = &local_label;
   4218 
   4219       /* Keep the original source location on the first 'if'.  */
   4220       t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus,
   4221 			   condition_uid);
   4222       append_to_statement_list (t, &expr);
   4223 
   4224       /* Set the source location of the && on the second 'if'.  */
   4225       new_locus = rexpr_location (pred, locus);
   4226       t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
   4227 			   new_locus, condition_uid);
   4228       append_to_statement_list (t, &expr);
   4229     }
   4230   else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
   4231     {
   4232       location_t new_locus;
   4233 
   4234       /* Turn if (a || b) into
   4235 
   4236 	 if (a) goto yes;
   4237 	 if (b) goto yes; else goto no;
   4238 	 (yes:) */
   4239 
   4240       if (true_label_p == NULL)
   4241 	true_label_p = &local_label;
   4242 
   4243       /* Keep the original source location on the first 'if'.  */
   4244       t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus,
   4245 			   condition_uid);
   4246       append_to_statement_list (t, &expr);
   4247 
   4248       /* Set the source location of the || on the second 'if'.  */
   4249       new_locus = rexpr_location (pred, locus);
   4250       t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
   4251 			   new_locus, condition_uid);
   4252       append_to_statement_list (t, &expr);
   4253     }
   4254   else if (TREE_CODE (pred) == COND_EXPR
   4255 	   && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
   4256 	   && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
   4257     {
   4258       location_t new_locus;
   4259 
   4260       /* As long as we're messing with gotos, turn if (a ? b : c) into
   4261 	 if (a)
   4262 	   if (b) goto yes; else goto no;
   4263 	 else
   4264 	   if (c) goto yes; else goto no;
   4265 
   4266 	 Don't do this if one of the arms has void type, which can happen
   4267 	 in C++ when the arm is throw.  */
   4268 
   4269       /* Keep the original source location on the first 'if'.  Set the source
   4270 	 location of the ? on the second 'if'.  */
   4271       new_locus = rexpr_location (pred, locus);
   4272       expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
   4273 		     shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
   4274 				      false_label_p, locus, condition_uid),
   4275 		     shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
   4276 				      false_label_p, new_locus,
   4277 				      condition_uid));
   4278       SET_EXPR_UID (expr, condition_uid);
   4279     }
   4280   else
   4281     {
   4282       expr = build3 (COND_EXPR, void_type_node, pred,
   4283 		     build_and_jump (true_label_p),
   4284 		     build_and_jump (false_label_p));
   4285       SET_EXPR_LOCATION (expr, locus);
   4286       SET_EXPR_UID (expr, condition_uid);
   4287     }
   4288 
   4289   if (local_label)
   4290     {
   4291       t = build1 (LABEL_EXPR, void_type_node, local_label);
   4292       append_to_statement_list (t, &expr);
   4293     }
   4294 
   4295   return expr;
   4296 }
   4297 
   4298 /* If EXPR is a GOTO_EXPR, return it.  If it is a STATEMENT_LIST, skip
   4299    any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
   4300    statement, if it is the last one.  Otherwise, return NULL.  */
   4301 
   4302 static tree
   4303 find_goto (tree expr)
   4304 {
   4305   if (!expr)
   4306     return NULL_TREE;
   4307 
   4308   if (TREE_CODE (expr) == GOTO_EXPR)
   4309     return expr;
   4310 
   4311   if (TREE_CODE (expr) != STATEMENT_LIST)
   4312     return NULL_TREE;
   4313 
   4314   tree_stmt_iterator i = tsi_start (expr);
   4315 
   4316   while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
   4317     tsi_next (&i);
   4318 
   4319   if (!tsi_one_before_end_p (i))
   4320     return NULL_TREE;
   4321 
   4322   return find_goto (tsi_stmt (i));
   4323 }
   4324 
   4325 /* Same as find_goto, except that it returns NULL if the destination
   4326    is not a LABEL_DECL.  */
   4327 
   4328 static inline tree
   4329 find_goto_label (tree expr)
   4330 {
   4331   tree dest = find_goto (expr);
   4332   if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
   4333     return dest;
   4334   return NULL_TREE;
   4335 }
   4336 
   4337 
   4338 /* Given a multi-term condition (ANDIF, ORIF), walk the predicate PRED and tag
   4339    every basic condition with CONDITION_UID.  Two basic conditions share the
   4340    CONDITION_UID discriminator when they belong to the same predicate, which is
   4341    used by the condition coverage.  Doing this as an explicit step makes for a
   4342    simpler implementation than weaving it into the splitting code as the
   4343    splitting code eventually calls the entry point gimplfiy_expr which makes
   4344    bookkeeping complicated.  */
   4345 static void
   4346 tag_shortcut_cond (tree pred, unsigned condition_uid)
   4347 {
   4348   if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR
   4349       || TREE_CODE (pred) == TRUTH_ORIF_EXPR)
   4350     {
   4351       tree fst = TREE_OPERAND (pred, 0);
   4352       tree lst = TREE_OPERAND (pred, 1);
   4353 
   4354       if (TREE_CODE (fst) == TRUTH_ANDIF_EXPR
   4355 	  || TREE_CODE (fst) == TRUTH_ORIF_EXPR)
   4356 	tag_shortcut_cond (fst, condition_uid);
   4357       else if (TREE_CODE (fst) == COND_EXPR)
   4358 	SET_EXPR_UID (fst, condition_uid);
   4359 
   4360       if (TREE_CODE (lst) == TRUTH_ANDIF_EXPR
   4361 	  || TREE_CODE (lst) == TRUTH_ORIF_EXPR)
   4362 	tag_shortcut_cond (lst, condition_uid);
   4363       else if (TREE_CODE (lst) == COND_EXPR)
   4364 	SET_EXPR_UID (lst, condition_uid);
   4365     }
   4366 }
   4367 
   4368 /* Given a conditional expression EXPR with short-circuit boolean
   4369    predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
   4370    predicate apart into the equivalent sequence of conditionals.  CONDITION_UID
   4371    is a the tag/discriminator for this EXPR - all basic conditions in the
   4372    expression will be given the same CONDITION_UID.  */
   4373 static tree
   4374 shortcut_cond_expr (tree expr, unsigned condition_uid)
   4375 {
   4376   tree pred = TREE_OPERAND (expr, 0);
   4377   tree then_ = TREE_OPERAND (expr, 1);
   4378   tree else_ = TREE_OPERAND (expr, 2);
   4379   tree true_label, false_label, end_label, t;
   4380   tree *true_label_p;
   4381   tree *false_label_p;
   4382   bool emit_end, emit_false, jump_over_else;
   4383   bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
   4384   bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
   4385 
   4386   tag_shortcut_cond (pred, condition_uid);
   4387 
   4388   /* First do simple transformations.  */
   4389   if (!else_se)
   4390     {
   4391       /* If there is no 'else', turn
   4392 	   if (a && b) then c
   4393 	 into
   4394 	   if (a) if (b) then c.  */
   4395       while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
   4396 	{
   4397 	  /* Keep the original source location on the first 'if'.  */
   4398 	  location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
   4399 	  TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
   4400 	  /* Set the source location of the && on the second 'if'.  */
   4401 	  if (rexpr_has_location (pred))
   4402 	    SET_EXPR_LOCATION (expr, rexpr_location (pred));
   4403 	  then_ = shortcut_cond_expr (expr, condition_uid);
   4404 	  then_se = then_ && TREE_SIDE_EFFECTS (then_);
   4405 	  pred = TREE_OPERAND (pred, 0);
   4406 	  expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
   4407 	  SET_EXPR_LOCATION (expr, locus);
   4408 	}
   4409     }
   4410 
   4411   if (!then_se)
   4412     {
   4413       /* If there is no 'then', turn
   4414 	   if (a || b); else d
   4415 	 into
   4416 	   if (a); else if (b); else d.  */
   4417       while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
   4418 	{
   4419 	  /* Keep the original source location on the first 'if'.  */
   4420 	  location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
   4421 	  TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
   4422 	  /* Set the source location of the || on the second 'if'.  */
   4423 	  if (rexpr_has_location (pred))
   4424 	    SET_EXPR_LOCATION (expr, rexpr_location (pred));
   4425 	  else_ = shortcut_cond_expr (expr, condition_uid);
   4426 	  else_se = else_ && TREE_SIDE_EFFECTS (else_);
   4427 	  pred = TREE_OPERAND (pred, 0);
   4428 	  expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
   4429 	  SET_EXPR_LOCATION (expr, locus);
   4430 	}
   4431     }
   4432 
   4433   /* The expr tree should also have the expression id set.  */
   4434   SET_EXPR_UID (expr, condition_uid);
   4435 
   4436   /* If we're done, great.  */
   4437   if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
   4438       && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
   4439     return expr;
   4440 
   4441   /* Otherwise we need to mess with gotos.  Change
   4442        if (a) c; else d;
   4443      to
   4444        if (a); else goto no;
   4445        c; goto end;
   4446        no: d; end:
   4447      and recursively gimplify the condition.  */
   4448 
   4449   true_label = false_label = end_label = NULL_TREE;
   4450 
   4451   /* If our arms just jump somewhere, hijack those labels so we don't
   4452      generate jumps to jumps.  */
   4453 
   4454   if (tree then_goto = find_goto_label (then_))
   4455     {
   4456       true_label = GOTO_DESTINATION (then_goto);
   4457       then_ = NULL;
   4458       then_se = false;
   4459     }
   4460 
   4461   if (tree else_goto = find_goto_label (else_))
   4462     {
   4463       false_label = GOTO_DESTINATION (else_goto);
   4464       else_ = NULL;
   4465       else_se = false;
   4466     }
   4467 
   4468   /* If we aren't hijacking a label for the 'then' branch, it falls through.  */
   4469   if (true_label)
   4470     true_label_p = &true_label;
   4471   else
   4472     true_label_p = NULL;
   4473 
   4474   /* The 'else' branch also needs a label if it contains interesting code.  */
   4475   if (false_label || else_se)
   4476     false_label_p = &false_label;
   4477   else
   4478     false_label_p = NULL;
   4479 
   4480   /* If there was nothing else in our arms, just forward the label(s).  */
   4481   if (!then_se && !else_se)
   4482     return shortcut_cond_r (pred, true_label_p, false_label_p,
   4483 			    EXPR_LOC_OR_LOC (expr, input_location), condition_uid);
   4484 
   4485   /* If our last subexpression already has a terminal label, reuse it.  */
   4486   if (else_se)
   4487     t = expr_last (else_);
   4488   else if (then_se)
   4489     t = expr_last (then_);
   4490   else
   4491     t = NULL;
   4492   if (t && TREE_CODE (t) == LABEL_EXPR)
   4493     end_label = LABEL_EXPR_LABEL (t);
   4494 
   4495   /* If we don't care about jumping to the 'else' branch, jump to the end
   4496      if the condition is false.  */
   4497   if (!false_label_p)
   4498     false_label_p = &end_label;
   4499 
   4500   /* We only want to emit these labels if we aren't hijacking them.  */
   4501   emit_end = (end_label == NULL_TREE);
   4502   emit_false = (false_label == NULL_TREE);
   4503 
   4504   /* We only emit the jump over the else clause if we have to--if the
   4505      then clause may fall through.  Otherwise we can wind up with a
   4506      useless jump and a useless label at the end of gimplified code,
   4507      which will cause us to think that this conditional as a whole
   4508      falls through even if it doesn't.  If we then inline a function
   4509      which ends with such a condition, that can cause us to issue an
   4510      inappropriate warning about control reaching the end of a
   4511      non-void function.  */
   4512   jump_over_else = block_may_fallthru (then_);
   4513 
   4514   pred = shortcut_cond_r (pred, true_label_p, false_label_p,
   4515 			  EXPR_LOC_OR_LOC (expr, input_location),
   4516 			  condition_uid);
   4517 
   4518   expr = NULL;
   4519   append_to_statement_list (pred, &expr);
   4520 
   4521   append_to_statement_list (then_, &expr);
   4522   if (else_se)
   4523     {
   4524       if (jump_over_else)
   4525 	{
   4526 	  tree last = expr_last (expr);
   4527 	  t = build_and_jump (&end_label);
   4528 	  if (rexpr_has_location (last))
   4529 	    SET_EXPR_LOCATION (t, rexpr_location (last));
   4530 	  append_to_statement_list (t, &expr);
   4531 	}
   4532       if (emit_false)
   4533 	{
   4534 	  t = build1 (LABEL_EXPR, void_type_node, false_label);
   4535 	  append_to_statement_list (t, &expr);
   4536 	}
   4537       append_to_statement_list (else_, &expr);
   4538     }
   4539   if (emit_end && end_label)
   4540     {
   4541       t = build1 (LABEL_EXPR, void_type_node, end_label);
   4542       append_to_statement_list (t, &expr);
   4543     }
   4544 
   4545   return expr;
   4546 }
   4547 
   4548 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE.  */
   4549 
   4550 tree
   4551 gimple_boolify (tree expr)
   4552 {
   4553   tree type = TREE_TYPE (expr);
   4554   location_t loc = EXPR_LOCATION (expr);
   4555 
   4556   if (TREE_CODE (expr) == NE_EXPR
   4557       && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
   4558       && integer_zerop (TREE_OPERAND (expr, 1)))
   4559     {
   4560       tree call = TREE_OPERAND (expr, 0);
   4561       tree fn = get_callee_fndecl (call);
   4562 
   4563       /* For __builtin_expect ((long) (x), y) recurse into x as well
   4564 	 if x is truth_value_p.  */
   4565       if (fn
   4566 	  && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
   4567 	  && call_expr_nargs (call) == 2)
   4568 	{
   4569 	  tree arg = CALL_EXPR_ARG (call, 0);
   4570 	  if (arg)
   4571 	    {
   4572 	      if (TREE_CODE (arg) == NOP_EXPR
   4573 		  && TREE_TYPE (arg) == TREE_TYPE (call))
   4574 		arg = TREE_OPERAND (arg, 0);
   4575 	      if (truth_value_p (TREE_CODE (arg)))
   4576 		{
   4577 		  arg = gimple_boolify (arg);
   4578 		  CALL_EXPR_ARG (call, 0)
   4579 		    = fold_convert_loc (loc, TREE_TYPE (call), arg);
   4580 		}
   4581 	    }
   4582 	}
   4583     }
   4584 
   4585   switch (TREE_CODE (expr))
   4586     {
   4587     case TRUTH_AND_EXPR:
   4588     case TRUTH_OR_EXPR:
   4589     case TRUTH_XOR_EXPR:
   4590     case TRUTH_ANDIF_EXPR:
   4591     case TRUTH_ORIF_EXPR:
   4592       /* Also boolify the arguments of truth exprs.  */
   4593       TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
   4594       /* FALLTHRU */
   4595 
   4596     case TRUTH_NOT_EXPR:
   4597       TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
   4598 
   4599       /* These expressions always produce boolean results.  */
   4600       if (TREE_CODE (type) != BOOLEAN_TYPE)
   4601 	TREE_TYPE (expr) = boolean_type_node;
   4602       return expr;
   4603 
   4604     case ANNOTATE_EXPR:
   4605       switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
   4606 	{
   4607 	case annot_expr_ivdep_kind:
   4608 	case annot_expr_unroll_kind:
   4609 	case annot_expr_no_vector_kind:
   4610 	case annot_expr_vector_kind:
   4611 	case annot_expr_parallel_kind:
   4612 	case annot_expr_maybe_infinite_kind:
   4613 	  TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
   4614 	  if (TREE_CODE (type) != BOOLEAN_TYPE)
   4615 	    TREE_TYPE (expr) = boolean_type_node;
   4616 	  return expr;
   4617 	default:
   4618 	  gcc_unreachable ();
   4619 	}
   4620 
   4621     default:
   4622       if (COMPARISON_CLASS_P (expr))
   4623 	{
   4624 	  /* These expressions always produce boolean results.  */
   4625 	  if (TREE_CODE (type) != BOOLEAN_TYPE)
   4626 	    TREE_TYPE (expr) = boolean_type_node;
   4627 	  return expr;
   4628 	}
   4629       /* Other expressions that get here must have boolean values, but
   4630 	 might need to be converted to the appropriate mode.  */
   4631       if (TREE_CODE (type) == BOOLEAN_TYPE)
   4632 	return expr;
   4633       return fold_convert_loc (loc, boolean_type_node, expr);
   4634     }
   4635 }
   4636 
   4637 /* Given a conditional expression *EXPR_P without side effects, gimplify
   4638    its operands.  New statements are inserted to PRE_P.  */
   4639 
   4640 static enum gimplify_status
   4641 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
   4642 {
   4643   tree expr = *expr_p, cond;
   4644   enum gimplify_status ret, tret;
   4645   enum tree_code code;
   4646 
   4647   cond = gimple_boolify (COND_EXPR_COND (expr));
   4648 
   4649   /* We need to handle && and || specially, as their gimplification
   4650      creates pure cond_expr, thus leading to an infinite cycle otherwise.  */
   4651   code = TREE_CODE (cond);
   4652   if (code == TRUTH_ANDIF_EXPR)
   4653     TREE_SET_CODE (cond, TRUTH_AND_EXPR);
   4654   else if (code == TRUTH_ORIF_EXPR)
   4655     TREE_SET_CODE (cond, TRUTH_OR_EXPR);
   4656   ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_val, fb_rvalue);
   4657   COND_EXPR_COND (*expr_p) = cond;
   4658 
   4659   tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
   4660 			is_gimple_val, fb_rvalue);
   4661   ret = MIN (ret, tret);
   4662   tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
   4663 			is_gimple_val, fb_rvalue);
   4664 
   4665   return MIN (ret, tret);
   4666 }
   4667 
   4668 /* Return true if evaluating EXPR could trap.
   4669    EXPR is GENERIC, while tree_could_trap_p can be called
   4670    only on GIMPLE.  */
   4671 
   4672 bool
   4673 generic_expr_could_trap_p (tree expr)
   4674 {
   4675   unsigned i, n;
   4676 
   4677   if (!expr || is_gimple_val (expr))
   4678     return false;
   4679 
   4680   if (!EXPR_P (expr) || tree_could_trap_p (expr))
   4681     return true;
   4682 
   4683   n = TREE_OPERAND_LENGTH (expr);
   4684   for (i = 0; i < n; i++)
   4685     if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
   4686       return true;
   4687 
   4688   return false;
   4689 }
   4690 
   4691 /* Associate the condition STMT with the discriminator UID.  STMTs that are
   4692    broken down with ANDIF/ORIF from the same Boolean expression should be given
   4693    the same UID; 'if (a && b && c) { if (d || e) ... } ...' should yield the
   4694    { a: 1, b: 1, c: 1, d: 2, e: 2 } when gimplification is done.  This is used
   4695    for condition coverage.  */
   4696 static void
   4697 gimple_associate_condition_with_expr (struct function *fn, gcond *stmt,
   4698 				      unsigned uid)
   4699 {
   4700   if (!condition_coverage_flag)
   4701     return;
   4702 
   4703   if (!fn->cond_uids)
   4704     fn->cond_uids = new hash_map <gcond*, unsigned> ();
   4705 
   4706   fn->cond_uids->put (stmt, uid);
   4707 }
   4708 
   4709 /*  Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
   4710     into
   4711 
   4712     if (p)			if (p)
   4713       t1 = a;			  a;
   4714     else		or	else
   4715       t1 = b;			  b;
   4716     t1;
   4717 
   4718     The second form is used when *EXPR_P is of type void.
   4719 
   4720     PRE_P points to the list where side effects that must happen before
   4721       *EXPR_P should be stored.  */
   4722 
   4723 static enum gimplify_status
   4724 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
   4725 {
   4726   tree expr = *expr_p;
   4727   tree type = TREE_TYPE (expr);
   4728   location_t loc = EXPR_LOCATION (expr);
   4729   tree tmp, arm1, arm2;
   4730   enum gimplify_status ret;
   4731   tree label_true, label_false, label_cont;
   4732   bool have_then_clause_p, have_else_clause_p;
   4733   gcond *cond_stmt;
   4734   enum tree_code pred_code;
   4735   gimple_seq seq = NULL;
   4736 
   4737   /* If this COND_EXPR has a value, copy the values into a temporary within
   4738      the arms.  */
   4739   if (!VOID_TYPE_P (type))
   4740     {
   4741       tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
   4742       tree result;
   4743 
   4744       /* If either an rvalue is ok or we do not require an lvalue, create the
   4745 	 temporary.  But we cannot do that if the type is addressable.  */
   4746       if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
   4747 	  && !TREE_ADDRESSABLE (type))
   4748 	{
   4749 	  if (gimplify_ctxp->allow_rhs_cond_expr
   4750 	      /* If either branch has side effects or could trap, it can't be
   4751 		 evaluated unconditionally.  */
   4752 	      && !TREE_SIDE_EFFECTS (then_)
   4753 	      && !generic_expr_could_trap_p (then_)
   4754 	      && !TREE_SIDE_EFFECTS (else_)
   4755 	      && !generic_expr_could_trap_p (else_))
   4756 	    return gimplify_pure_cond_expr (expr_p, pre_p);
   4757 
   4758 	  tmp = create_tmp_var (type, "iftmp");
   4759 	  result = tmp;
   4760 	}
   4761 
   4762       /* Otherwise, only create and copy references to the values.  */
   4763       else
   4764 	{
   4765 	  type = build_pointer_type (type);
   4766 
   4767 	  if (!VOID_TYPE_P (TREE_TYPE (then_)))
   4768 	    then_ = build_fold_addr_expr_loc (loc, then_);
   4769 
   4770 	  if (!VOID_TYPE_P (TREE_TYPE (else_)))
   4771 	    else_ = build_fold_addr_expr_loc (loc, else_);
   4772 
   4773 	  expr
   4774 	    = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
   4775 
   4776 	  tmp = create_tmp_var (type, "iftmp");
   4777 	  result = build_simple_mem_ref_loc (loc, tmp);
   4778 	}
   4779 
   4780       /* Build the new then clause, `tmp = then_;'.  But don't build the
   4781 	 assignment if the value is void; in C++ it can be if it's a throw.  */
   4782       if (!VOID_TYPE_P (TREE_TYPE (then_)))
   4783 	TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
   4784 
   4785       /* Similarly, build the new else clause, `tmp = else_;'.  */
   4786       if (!VOID_TYPE_P (TREE_TYPE (else_)))
   4787 	TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
   4788 
   4789       TREE_TYPE (expr) = void_type_node;
   4790       recalculate_side_effects (expr);
   4791 
   4792       /* Move the COND_EXPR to the prequeue.  */
   4793       gimplify_stmt (&expr, pre_p);
   4794 
   4795       *expr_p = result;
   4796       return GS_ALL_DONE;
   4797     }
   4798 
   4799   /* Remove any COMPOUND_EXPR so the following cases will be caught.  */
   4800   STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
   4801   if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
   4802     gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
   4803 
   4804   /* Make sure the condition has BOOLEAN_TYPE.  */
   4805   TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
   4806 
   4807   /* Break apart && and || conditions.  */
   4808   if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
   4809       || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
   4810     {
   4811       expr = shortcut_cond_expr (expr, next_cond_uid ());
   4812 
   4813       if (expr != *expr_p)
   4814 	{
   4815 	  *expr_p = expr;
   4816 
   4817 	  /* We can't rely on gimplify_expr to re-gimplify the expanded
   4818 	     form properly, as cleanups might cause the target labels to be
   4819 	     wrapped in a TRY_FINALLY_EXPR.  To prevent that, we need to
   4820 	     set up a conditional context.  */
   4821 	  gimple_push_condition ();
   4822 	  gimplify_stmt (expr_p, &seq);
   4823 	  gimple_pop_condition (pre_p);
   4824 	  gimple_seq_add_seq (pre_p, seq);
   4825 
   4826 	  return GS_ALL_DONE;
   4827 	}
   4828     }
   4829 
   4830   /* Now do the normal gimplification.  */
   4831 
   4832   /* Gimplify condition.  */
   4833   ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
   4834 		       is_gimple_condexpr_for_cond, fb_rvalue);
   4835   if (ret == GS_ERROR)
   4836     return GS_ERROR;
   4837   gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
   4838 
   4839   gimple_push_condition ();
   4840 
   4841   have_then_clause_p = have_else_clause_p = false;
   4842   label_true = find_goto_label (TREE_OPERAND (expr, 1));
   4843   if (label_true
   4844       && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
   4845       /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
   4846 	 have different locations, otherwise we end up with incorrect
   4847 	 location information on the branches.  */
   4848       && (optimize
   4849 	  || !EXPR_HAS_LOCATION (expr)
   4850 	  || !rexpr_has_location (label_true)
   4851 	  || EXPR_LOCATION (expr) == rexpr_location (label_true)))
   4852     {
   4853       have_then_clause_p = true;
   4854       label_true = GOTO_DESTINATION (label_true);
   4855     }
   4856   else
   4857     label_true = create_artificial_label (UNKNOWN_LOCATION);
   4858   label_false = find_goto_label (TREE_OPERAND (expr, 2));
   4859   if (label_false
   4860       && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
   4861       /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
   4862 	 have different locations, otherwise we end up with incorrect
   4863 	 location information on the branches.  */
   4864       && (optimize
   4865 	  || !EXPR_HAS_LOCATION (expr)
   4866 	  || !rexpr_has_location (label_false)
   4867 	  || EXPR_LOCATION (expr) == rexpr_location (label_false)))
   4868     {
   4869       have_else_clause_p = true;
   4870       label_false = GOTO_DESTINATION (label_false);
   4871     }
   4872   else
   4873     label_false = create_artificial_label (UNKNOWN_LOCATION);
   4874 
   4875   unsigned cond_uid = EXPR_COND_UID (expr);
   4876   if (cond_uid == 0)
   4877     cond_uid = next_cond_uid ();
   4878 
   4879   gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
   4880 				 &arm2);
   4881   cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
   4882 				 label_false);
   4883   gimple_set_location (cond_stmt, EXPR_LOCATION (expr));
   4884   gimple_associate_condition_with_expr (cfun, cond_stmt, cond_uid);
   4885   copy_warning (cond_stmt, COND_EXPR_COND (expr));
   4886   gimplify_seq_add_stmt (&seq, cond_stmt);
   4887   gimple_stmt_iterator gsi = gsi_last (seq);
   4888   maybe_fold_stmt (&gsi);
   4889 
   4890   label_cont = NULL_TREE;
   4891   if (!have_then_clause_p)
   4892     {
   4893       /* For if (...) {} else { code; } put label_true after
   4894 	 the else block.  */
   4895       if (TREE_OPERAND (expr, 1) == NULL_TREE
   4896 	  && !have_else_clause_p
   4897 	  && TREE_OPERAND (expr, 2) != NULL_TREE)
   4898 	{
   4899 	  /* For if (0) {} else { code; } tell -Wimplicit-fallthrough
   4900 	     handling that label_cont == label_true can be only reached
   4901 	     through fallthrough from { code; }.  */
   4902 	  if (integer_zerop (COND_EXPR_COND (expr)))
   4903 	    UNUSED_LABEL_P (label_true) = 1;
   4904 	  label_cont = label_true;
   4905 	}
   4906       else
   4907 	{
   4908 	  bool then_side_effects
   4909 	    = (TREE_OPERAND (expr, 1)
   4910 	       && TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)));
   4911 	  gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
   4912 	  have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
   4913 	  /* For if (...) { code; } else {} or
   4914 	     if (...) { code; } else goto label; or
   4915 	     if (...) { code; return; } else { ... }
   4916 	     label_cont isn't needed.  */
   4917 	  if (!have_else_clause_p
   4918 	      && TREE_OPERAND (expr, 2) != NULL_TREE
   4919 	      && gimple_seq_may_fallthru (seq))
   4920 	    {
   4921 	      gimple *g;
   4922 	      label_cont = create_artificial_label (UNKNOWN_LOCATION);
   4923 
   4924 	      /* For if (0) { non-side-effect-code } else { code }
   4925 		 tell -Wimplicit-fallthrough handling that label_cont can
   4926 		 be only reached through fallthrough from { code }.  */
   4927 	      if (integer_zerop (COND_EXPR_COND (expr)))
   4928 		{
   4929 		  UNUSED_LABEL_P (label_true) = 1;
   4930 		  if (!then_side_effects)
   4931 		    UNUSED_LABEL_P (label_cont) = 1;
   4932 		}
   4933 
   4934 	      g = gimple_build_goto (label_cont);
   4935 
   4936 	      /* GIMPLE_COND's are very low level; they have embedded
   4937 		 gotos.  This particular embedded goto should not be marked
   4938 		 with the location of the original COND_EXPR, as it would
   4939 		 correspond to the COND_EXPR's condition, not the ELSE or the
   4940 		 THEN arms.  To avoid marking it with the wrong location, flag
   4941 		 it as "no location".  */
   4942 	      gimple_set_do_not_emit_location (g);
   4943 
   4944 	      gimplify_seq_add_stmt (&seq, g);
   4945 	    }
   4946 	}
   4947     }
   4948   if (!have_else_clause_p)
   4949     {
   4950       /* For if (1) { code } or if (1) { code } else { non-side-effect-code }
   4951 	 tell -Wimplicit-fallthrough handling that label_false can be only
   4952 	 reached through fallthrough from { code }.  */
   4953       if (integer_nonzerop (COND_EXPR_COND (expr))
   4954 	  && (TREE_OPERAND (expr, 2) == NULL_TREE
   4955 	      || !TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2))))
   4956 	UNUSED_LABEL_P (label_false) = 1;
   4957       gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
   4958       have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
   4959     }
   4960   if (label_cont)
   4961     gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
   4962 
   4963   gimple_pop_condition (pre_p);
   4964   gimple_seq_add_seq (pre_p, seq);
   4965 
   4966   if (ret == GS_ERROR)
   4967     ; /* Do nothing.  */
   4968   else if (have_then_clause_p || have_else_clause_p)
   4969     ret = GS_ALL_DONE;
   4970   else
   4971     {
   4972       /* Both arms are empty; replace the COND_EXPR with its predicate.  */
   4973       expr = TREE_OPERAND (expr, 0);
   4974       gimplify_stmt (&expr, pre_p);
   4975     }
   4976 
   4977   *expr_p = NULL;
   4978   return ret;
   4979 }
   4980 
   4981 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
   4982    to be marked addressable.
   4983 
   4984    We cannot rely on such an expression being directly markable if a temporary
   4985    has been created by the gimplification.  In this case, we create another
   4986    temporary and initialize it with a copy, which will become a store after we
   4987    mark it addressable.  This can happen if the front-end passed us something
   4988    that it could not mark addressable yet, like a Fortran pass-by-reference
   4989    parameter (int) floatvar.  */
   4990 
   4991 static void
   4992 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
   4993 {
   4994   while (handled_component_p (*expr_p))
   4995     expr_p = &TREE_OPERAND (*expr_p, 0);
   4996 
   4997   /* Do not allow an SSA name as the temporary.  */
   4998   if (is_gimple_reg (*expr_p))
   4999     *expr_p = internal_get_tmp_var (*expr_p, seq_p, NULL, false, false, true);
   5000 }
   5001 
   5002 /* A subroutine of gimplify_modify_expr.  Replace a MODIFY_EXPR with
   5003    a call to __builtin_memcpy.  */
   5004 
   5005 static enum gimplify_status
   5006 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
   5007     				gimple_seq *seq_p)
   5008 {
   5009   tree t, to, to_ptr, from, from_ptr;
   5010   gcall *gs;
   5011   location_t loc = EXPR_LOCATION (*expr_p);
   5012 
   5013   to = TREE_OPERAND (*expr_p, 0);
   5014   from = TREE_OPERAND (*expr_p, 1);
   5015   gcc_assert (ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (to)))
   5016 	      && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (from))));
   5017 
   5018   /* Mark the RHS addressable.  Beware that it may not be possible to do so
   5019      directly if a temporary has been created by the gimplification.  */
   5020   prepare_gimple_addressable (&from, seq_p);
   5021 
   5022   mark_addressable (from);
   5023   from_ptr = build_fold_addr_expr_loc (loc, from);
   5024   gimplify_arg (&from_ptr, seq_p, loc);
   5025 
   5026   mark_addressable (to);
   5027   to_ptr = build_fold_addr_expr_loc (loc, to);
   5028   gimplify_arg (&to_ptr, seq_p, loc);
   5029 
   5030   t = builtin_decl_implicit (BUILT_IN_MEMCPY);
   5031 
   5032   gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
   5033   gimple_call_set_alloca_for_var (gs, true);
   5034 
   5035   if (want_value)
   5036     {
   5037       /* tmp = memcpy() */
   5038       t = create_tmp_var (TREE_TYPE (to_ptr));
   5039       gimple_call_set_lhs (gs, t);
   5040       gimplify_seq_add_stmt (seq_p, gs);
   5041 
   5042       *expr_p = build_simple_mem_ref (t);
   5043       return GS_ALL_DONE;
   5044     }
   5045 
   5046   gimplify_seq_add_stmt (seq_p, gs);
   5047   *expr_p = NULL;
   5048   return GS_ALL_DONE;
   5049 }
   5050 
   5051 /* A subroutine of gimplify_modify_expr.  Replace a MODIFY_EXPR with
   5052    a call to __builtin_memset.  In this case we know that the RHS is
   5053    a CONSTRUCTOR with an empty element list.  */
   5054 
   5055 static enum gimplify_status
   5056 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
   5057     				gimple_seq *seq_p)
   5058 {
   5059   tree t, from, to, to_ptr;
   5060   gcall *gs;
   5061   location_t loc = EXPR_LOCATION (*expr_p);
   5062 
   5063   /* Assert our assumptions, to abort instead of producing wrong code
   5064      silently if they are not met.  Beware that the RHS CONSTRUCTOR might
   5065      not be immediately exposed.  */
   5066   from = TREE_OPERAND (*expr_p, 1);
   5067   if (TREE_CODE (from) == WITH_SIZE_EXPR)
   5068     from = TREE_OPERAND (from, 0);
   5069 
   5070   gcc_assert (TREE_CODE (from) == CONSTRUCTOR
   5071 	      && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
   5072 
   5073   /* Now proceed.  */
   5074   to = TREE_OPERAND (*expr_p, 0);
   5075   gcc_assert (ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (to))));
   5076 
   5077   to_ptr = build_fold_addr_expr_loc (loc, to);
   5078   gimplify_arg (&to_ptr, seq_p, loc);
   5079   t = builtin_decl_implicit (BUILT_IN_MEMSET);
   5080 
   5081   gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
   5082 
   5083   if (want_value)
   5084     {
   5085       /* tmp = memset() */
   5086       t = create_tmp_var (TREE_TYPE (to_ptr));
   5087       gimple_call_set_lhs (gs, t);
   5088       gimplify_seq_add_stmt (seq_p, gs);
   5089 
   5090       *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
   5091       return GS_ALL_DONE;
   5092     }
   5093 
   5094   gimplify_seq_add_stmt (seq_p, gs);
   5095   *expr_p = NULL;
   5096   return GS_ALL_DONE;
   5097 }
   5098 
   5099 /* A subroutine of gimplify_init_ctor_preeval.  Called via walk_tree,
   5100    determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
   5101    assignment.  Return non-null if we detect a potential overlap.  */
   5102 
   5103 struct gimplify_init_ctor_preeval_data
   5104 {
   5105   /* The base decl of the lhs object.  May be NULL, in which case we
   5106      have to assume the lhs is indirect.  */
   5107   tree lhs_base_decl;
   5108 
   5109   /* The alias set of the lhs object.  */
   5110   alias_set_type lhs_alias_set;
   5111 };
   5112 
   5113 static tree
   5114 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
   5115 {
   5116   struct gimplify_init_ctor_preeval_data *data
   5117     = (struct gimplify_init_ctor_preeval_data *) xdata;
   5118   tree t = *tp;
   5119 
   5120   /* If we find the base object, obviously we have overlap.  */
   5121   if (data->lhs_base_decl == t)
   5122     return t;
   5123 
   5124   /* If the constructor component is indirect, determine if we have a
   5125      potential overlap with the lhs.  The only bits of information we
   5126      have to go on at this point are addressability and alias sets.  */
   5127   if ((INDIRECT_REF_P (t)
   5128        || TREE_CODE (t) == MEM_REF)
   5129       && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
   5130       && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
   5131     return t;
   5132 
   5133   /* If the constructor component is a call, determine if it can hide a
   5134      potential overlap with the lhs through an INDIRECT_REF like above.
   5135      ??? Ugh - this is completely broken.  In fact this whole analysis
   5136      doesn't look conservative.  */
   5137   if (TREE_CODE (t) == CALL_EXPR)
   5138     {
   5139       tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
   5140 
   5141       for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
   5142 	if (POINTER_TYPE_P (TREE_VALUE (type))
   5143 	    && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
   5144 	    && alias_sets_conflict_p (data->lhs_alias_set,
   5145 				      get_alias_set
   5146 				        (TREE_TYPE (TREE_VALUE (type)))))
   5147 	  return t;
   5148     }
   5149 
   5150   if (IS_TYPE_OR_DECL_P (t))
   5151     *walk_subtrees = 0;
   5152   return NULL;
   5153 }
   5154 
   5155 /* A subroutine of gimplify_init_constructor.  Pre-evaluate EXPR,
   5156    force values that overlap with the lhs (as described by *DATA)
   5157    into temporaries.  */
   5158 
   5159 static void
   5160 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   5161 			    struct gimplify_init_ctor_preeval_data *data)
   5162 {
   5163   enum gimplify_status one;
   5164 
   5165   /* If the value is constant, then there's nothing to pre-evaluate.  */
   5166   if (TREE_CONSTANT (*expr_p))
   5167     {
   5168       /* Ensure it does not have side effects, it might contain a reference to
   5169 	 the object we're initializing.  */
   5170       gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
   5171       return;
   5172     }
   5173 
   5174   /* If the type has non-trivial constructors, we can't pre-evaluate.  */
   5175   if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
   5176     return;
   5177 
   5178   /* Recurse for nested constructors.  */
   5179   if (TREE_CODE (*expr_p) == CONSTRUCTOR)
   5180     {
   5181       unsigned HOST_WIDE_INT ix;
   5182       constructor_elt *ce;
   5183       vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
   5184 
   5185       FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
   5186 	gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
   5187 
   5188       return;
   5189     }
   5190 
   5191   /* If this is a variable sized type, we must remember the size.  */
   5192   maybe_with_size_expr (expr_p);
   5193 
   5194   /* Gimplify the constructor element to something appropriate for the rhs
   5195      of a MODIFY_EXPR.  Given that we know the LHS is an aggregate, we know
   5196      the gimplifier will consider this a store to memory.  Doing this
   5197      gimplification now means that we won't have to deal with complicated
   5198      language-specific trees, nor trees like SAVE_EXPR that can induce
   5199      exponential search behavior.  */
   5200   one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
   5201   if (one == GS_ERROR)
   5202     {
   5203       *expr_p = NULL;
   5204       return;
   5205     }
   5206 
   5207   /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
   5208      with the lhs, since "a = { .x=a }" doesn't make sense.  This will
   5209      always be true for all scalars, since is_gimple_mem_rhs insists on a
   5210      temporary variable for them.  */
   5211   if (DECL_P (*expr_p))
   5212     return;
   5213 
   5214   /* If this is of variable size, we have no choice but to assume it doesn't
   5215      overlap since we can't make a temporary for it.  */
   5216   if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
   5217     return;
   5218 
   5219   /* Otherwise, we must search for overlap ...  */
   5220   if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
   5221     return;
   5222 
   5223   /* ... and if found, force the value into a temporary.  */
   5224   *expr_p = get_formal_tmp_var (*expr_p, pre_p);
   5225 }
   5226 
   5227 /* A subroutine of gimplify_init_ctor_eval.  Create a loop for
   5228    a RANGE_EXPR in a CONSTRUCTOR for an array.
   5229 
   5230       var = lower;
   5231     loop_entry:
   5232       object[var] = value;
   5233       if (var == upper)
   5234 	goto loop_exit;
   5235       var = var + 1;
   5236       goto loop_entry;
   5237     loop_exit:
   5238 
   5239    We increment var _after_ the loop exit check because we might otherwise
   5240    fail if upper == TYPE_MAX_VALUE (type for upper).
   5241 
   5242    Note that we never have to deal with SAVE_EXPRs here, because this has
   5243    already been taken care of for us, in gimplify_init_ctor_preeval().  */
   5244 
   5245 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
   5246 				     gimple_seq *, bool);
   5247 
   5248 static void
   5249 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
   5250 			       tree value, tree array_elt_type,
   5251 			       gimple_seq *pre_p, bool cleared)
   5252 {
   5253   tree loop_entry_label, loop_exit_label, fall_thru_label;
   5254   tree var, var_type, cref, tmp;
   5255 
   5256   loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
   5257   loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
   5258   fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
   5259 
   5260   /* Create and initialize the index variable.  */
   5261   var_type = TREE_TYPE (upper);
   5262   var = create_tmp_var (var_type);
   5263   gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
   5264 
   5265   /* Add the loop entry label.  */
   5266   gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
   5267 
   5268   /* Build the reference.  */
   5269   cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
   5270 		 var, NULL_TREE, NULL_TREE);
   5271 
   5272   /* If we are a constructor, just call gimplify_init_ctor_eval to do
   5273      the store.  Otherwise just assign value to the reference.  */
   5274 
   5275   if (TREE_CODE (value) == CONSTRUCTOR)
   5276     /* NB we might have to call ourself recursively through
   5277        gimplify_init_ctor_eval if the value is a constructor.  */
   5278     gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
   5279 			     pre_p, cleared);
   5280   else
   5281     {
   5282       if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue)
   5283 	  != GS_ERROR)
   5284 	gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
   5285     }
   5286 
   5287   /* We exit the loop when the index var is equal to the upper bound.  */
   5288   gimplify_seq_add_stmt (pre_p,
   5289 			 gimple_build_cond (EQ_EXPR, var, upper,
   5290 					    loop_exit_label, fall_thru_label));
   5291 
   5292   gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
   5293 
   5294   /* Otherwise, increment the index var...  */
   5295   tmp = build2 (PLUS_EXPR, var_type, var,
   5296 		fold_convert (var_type, integer_one_node));
   5297   gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
   5298 
   5299   /* ...and jump back to the loop entry.  */
   5300   gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
   5301 
   5302   /* Add the loop exit label.  */
   5303   gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
   5304 }
   5305 
   5306 /* A subroutine of gimplify_init_constructor.  Generate individual
   5307    MODIFY_EXPRs for a CONSTRUCTOR.  OBJECT is the LHS against which the
   5308    assignments should happen.  ELTS is the CONSTRUCTOR_ELTS of the
   5309    CONSTRUCTOR.  CLEARED is true if the entire LHS object has been
   5310    zeroed first.  */
   5311 
   5312 static void
   5313 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
   5314 			 gimple_seq *pre_p, bool cleared)
   5315 {
   5316   tree array_elt_type = NULL;
   5317   unsigned HOST_WIDE_INT ix;
   5318   tree purpose, value;
   5319 
   5320   if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
   5321     array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
   5322 
   5323   FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
   5324     {
   5325       tree cref;
   5326 
   5327       /* NULL values are created above for gimplification errors.  */
   5328       if (value == NULL)
   5329 	continue;
   5330 
   5331       if (cleared && initializer_zerop (value))
   5332 	continue;
   5333 
   5334       /* ??? Here's to hoping the front end fills in all of the indices,
   5335 	 so we don't have to figure out what's missing ourselves.  */
   5336       gcc_assert (purpose);
   5337 
   5338       /* Skip zero-sized fields, unless value has side-effects.  This can
   5339 	 happen with calls to functions returning a empty type, which
   5340 	 we shouldn't discard.  As a number of downstream passes don't
   5341 	 expect sets of empty type fields, we rely on the gimplification of
   5342 	 the MODIFY_EXPR we make below to drop the assignment statement.  */
   5343       if (!TREE_SIDE_EFFECTS (value)
   5344 	  && TREE_CODE (purpose) == FIELD_DECL
   5345 	  && is_empty_type (TREE_TYPE (purpose)))
   5346 	continue;
   5347 
   5348       /* If we have a RANGE_EXPR, we have to build a loop to assign the
   5349 	 whole range.  */
   5350       if (TREE_CODE (purpose) == RANGE_EXPR)
   5351 	{
   5352 	  tree lower = TREE_OPERAND (purpose, 0);
   5353 	  tree upper = TREE_OPERAND (purpose, 1);
   5354 
   5355 	  /* If the lower bound is equal to upper, just treat it as if
   5356 	     upper was the index.  */
   5357 	  if (simple_cst_equal (lower, upper))
   5358 	    purpose = upper;
   5359 	  else
   5360 	    {
   5361 	      gimplify_init_ctor_eval_range (object, lower, upper, value,
   5362 					     array_elt_type, pre_p, cleared);
   5363 	      continue;
   5364 	    }
   5365 	}
   5366 
   5367       if (array_elt_type)
   5368 	{
   5369 	  /* Do not use bitsizetype for ARRAY_REF indices.  */
   5370 	  if (TYPE_DOMAIN (TREE_TYPE (object)))
   5371 	    purpose
   5372 	      = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
   5373 			      purpose);
   5374 	  cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
   5375 			 purpose, NULL_TREE, NULL_TREE);
   5376 	}
   5377       else
   5378 	{
   5379 	  gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
   5380 	  cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
   5381 			 unshare_expr (object), purpose, NULL_TREE);
   5382 	}
   5383 
   5384       if (TREE_CODE (value) == CONSTRUCTOR
   5385 	  && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
   5386 	gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
   5387 				 pre_p, cleared);
   5388       else
   5389 	{
   5390 	  tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
   5391 	  gimplify_and_add (init, pre_p);
   5392 	  ggc_free (init);
   5393 	}
   5394     }
   5395 }
   5396 
   5397 /* Return the appropriate RHS predicate for this LHS.  */
   5398 
   5399 gimple_predicate
   5400 rhs_predicate_for (tree lhs)
   5401 {
   5402   if (is_gimple_reg (lhs))
   5403     return is_gimple_reg_rhs_or_call;
   5404   else
   5405     return is_gimple_mem_rhs_or_call;
   5406 }
   5407 
   5408 /* Return the initial guess for an appropriate RHS predicate for this LHS,
   5409    before the LHS has been gimplified.  */
   5410 
   5411 static gimple_predicate
   5412 initial_rhs_predicate_for (tree lhs)
   5413 {
   5414   if (is_gimple_reg_type (TREE_TYPE (lhs)))
   5415     return is_gimple_reg_rhs_or_call;
   5416   else
   5417     return is_gimple_mem_rhs_or_call;
   5418 }
   5419 
   5420 /* Gimplify a C99 compound literal expression.  This just means adding
   5421    the DECL_EXPR before the current statement and using its anonymous
   5422    decl instead.  */
   5423 
   5424 static enum gimplify_status
   5425 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
   5426 				bool (*gimple_test_f) (tree),
   5427 				fallback_t fallback)
   5428 {
   5429   tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
   5430   tree decl = DECL_EXPR_DECL (decl_s);
   5431   tree init = DECL_INITIAL (decl);
   5432   /* Mark the decl as addressable if the compound literal
   5433      expression is addressable now, otherwise it is marked too late
   5434      after we gimplify the initialization expression.  */
   5435   if (TREE_ADDRESSABLE (*expr_p))
   5436     TREE_ADDRESSABLE (decl) = 1;
   5437   /* Otherwise, if we don't need an lvalue and have a literal directly
   5438      substitute it.  Check if it matches the gimple predicate, as
   5439      otherwise we'd generate a new temporary, and we can as well just
   5440      use the decl we already have.  */
   5441   else if (!TREE_ADDRESSABLE (decl)
   5442 	   && !TREE_THIS_VOLATILE (decl)
   5443 	   && init
   5444 	   && (fallback & fb_lvalue) == 0
   5445 	   && gimple_test_f (init))
   5446     {
   5447       *expr_p = init;
   5448       return GS_OK;
   5449     }
   5450 
   5451   /* If the decl is not addressable, then it is being used in some
   5452      expression or on the right hand side of a statement, and it can
   5453      be put into a readonly data section.  */
   5454   if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
   5455     TREE_READONLY (decl) = 1;
   5456 
   5457   /* This decl isn't mentioned in the enclosing block, so add it to the
   5458      list of temps.  FIXME it seems a bit of a kludge to say that
   5459      anonymous artificial vars aren't pushed, but everything else is.  */
   5460   if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
   5461     gimple_add_tmp_var (decl);
   5462 
   5463   gimplify_and_add (decl_s, pre_p);
   5464   *expr_p = decl;
   5465   return GS_OK;
   5466 }
   5467 
   5468 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
   5469    return a new CONSTRUCTOR if something changed.  */
   5470 
   5471 static tree
   5472 optimize_compound_literals_in_ctor (tree orig_ctor)
   5473 {
   5474   tree ctor = orig_ctor;
   5475   vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
   5476   unsigned int idx, num = vec_safe_length (elts);
   5477 
   5478   for (idx = 0; idx < num; idx++)
   5479     {
   5480       tree value = (*elts)[idx].value;
   5481       tree newval = value;
   5482       if (TREE_CODE (value) == CONSTRUCTOR)
   5483 	newval = optimize_compound_literals_in_ctor (value);
   5484       else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
   5485 	{
   5486 	  tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
   5487 	  tree decl = DECL_EXPR_DECL (decl_s);
   5488 	  tree init = DECL_INITIAL (decl);
   5489 
   5490 	  if (!TREE_ADDRESSABLE (value)
   5491 	      && !TREE_ADDRESSABLE (decl)
   5492 	      && init
   5493 	      && TREE_CODE (init) == CONSTRUCTOR)
   5494 	    newval = optimize_compound_literals_in_ctor (init);
   5495 	}
   5496       if (newval == value)
   5497 	continue;
   5498 
   5499       if (ctor == orig_ctor)
   5500 	{
   5501 	  ctor = copy_node (orig_ctor);
   5502 	  CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
   5503 	  elts = CONSTRUCTOR_ELTS (ctor);
   5504 	}
   5505       (*elts)[idx].value = newval;
   5506     }
   5507   return ctor;
   5508 }
   5509 
   5510 /* A subroutine of gimplify_modify_expr.  Break out elements of a
   5511    CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
   5512 
   5513    Note that we still need to clear any elements that don't have explicit
   5514    initializers, so if not all elements are initialized we keep the
   5515    original MODIFY_EXPR, we just remove all of the constructor elements.
   5516 
   5517    If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
   5518    GS_ERROR if we would have to create a temporary when gimplifying
   5519    this constructor.  Otherwise, return GS_OK.
   5520 
   5521    If NOTIFY_TEMP_CREATION is false, just do the gimplification.  */
   5522 
   5523 static enum gimplify_status
   5524 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   5525 			   bool want_value, bool notify_temp_creation)
   5526 {
   5527   tree object, ctor, type;
   5528   enum gimplify_status ret;
   5529   vec<constructor_elt, va_gc> *elts;
   5530   bool cleared = false;
   5531   bool is_empty_ctor = false;
   5532   bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR);
   5533 
   5534   gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
   5535 
   5536   if (!notify_temp_creation)
   5537     {
   5538       ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   5539 			   is_gimple_lvalue, fb_lvalue);
   5540       if (ret == GS_ERROR)
   5541 	return ret;
   5542     }
   5543 
   5544   object = TREE_OPERAND (*expr_p, 0);
   5545   ctor = TREE_OPERAND (*expr_p, 1)
   5546     = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
   5547   type = TREE_TYPE (ctor);
   5548   elts = CONSTRUCTOR_ELTS (ctor);
   5549   ret = GS_ALL_DONE;
   5550 
   5551   switch (TREE_CODE (type))
   5552     {
   5553     case RECORD_TYPE:
   5554     case UNION_TYPE:
   5555     case QUAL_UNION_TYPE:
   5556     case ARRAY_TYPE:
   5557       {
   5558 	/* Use readonly data for initializers of this or smaller size
   5559 	   regardless of the num_nonzero_elements / num_unique_nonzero_elements
   5560 	   ratio.  */
   5561 	const HOST_WIDE_INT min_unique_size = 64;
   5562 	/* If num_nonzero_elements / num_unique_nonzero_elements ratio
   5563 	   is smaller than this, use readonly data.  */
   5564 	const int unique_nonzero_ratio = 8;
   5565 	/* True if a single access of the object must be ensured.  This is the
   5566 	   case if the target is volatile, the type is non-addressable and more
   5567 	   than one field need to be assigned.  */
   5568 	const bool ensure_single_access
   5569 	  = TREE_THIS_VOLATILE (object)
   5570 	    && !TREE_ADDRESSABLE (type)
   5571 	    && vec_safe_length (elts) > 1;
   5572 	struct gimplify_init_ctor_preeval_data preeval_data;
   5573 	HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
   5574 	HOST_WIDE_INT num_unique_nonzero_elements;
   5575 	bool complete_p, valid_const_initializer;
   5576 
   5577 	/* Aggregate types must lower constructors to initialization of
   5578 	   individual elements.  The exception is that a CONSTRUCTOR node
   5579 	   with no elements indicates zero-initialization of the whole.  */
   5580 	if (vec_safe_is_empty (elts))
   5581 	  {
   5582 	    if (notify_temp_creation)
   5583 	      return GS_OK;
   5584 
   5585 	    /* The var will be initialized and so appear on lhs of
   5586 	       assignment, it can't be TREE_READONLY anymore.  */
   5587 	    if (VAR_P (object))
   5588 	      TREE_READONLY (object) = 0;
   5589 
   5590 	    is_empty_ctor = true;
   5591 	    break;
   5592 	  }
   5593 
   5594 	/* Fetch information about the constructor to direct later processing.
   5595 	   We might want to make static versions of it in various cases, and
   5596 	   can only do so if it known to be a valid constant initializer.  */
   5597 	valid_const_initializer
   5598 	  = categorize_ctor_elements (ctor, &num_nonzero_elements,
   5599 				      &num_unique_nonzero_elements,
   5600 				      &num_ctor_elements, &complete_p);
   5601 
   5602 	/* If a const aggregate variable is being initialized, then it
   5603 	   should never be a lose to promote the variable to be static.  */
   5604 	if (valid_const_initializer
   5605 	    && num_nonzero_elements > 1
   5606 	    && TREE_READONLY (object)
   5607 	    && VAR_P (object)
   5608 	    && !DECL_REGISTER (object)
   5609 	    && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)
   5610 		|| DECL_MERGEABLE (object))
   5611 	    /* For ctors that have many repeated nonzero elements
   5612 	       represented through RANGE_EXPRs, prefer initializing
   5613 	       those through runtime loops over copies of large amounts
   5614 	       of data from readonly data section.  */
   5615 	    && (num_unique_nonzero_elements
   5616 		> num_nonzero_elements / unique_nonzero_ratio
   5617 		|| ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
   5618 		    <= (unsigned HOST_WIDE_INT) min_unique_size)))
   5619 	  {
   5620 	    if (notify_temp_creation)
   5621 	      return GS_ERROR;
   5622 
   5623 	    DECL_INITIAL (object) = ctor;
   5624 	    TREE_STATIC (object) = 1;
   5625 	    if (!DECL_NAME (object) || DECL_NAMELESS (object))
   5626 	      DECL_NAME (object) = create_tmp_var_name ("C");
   5627 	    walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
   5628 
   5629 	    /* ??? C++ doesn't automatically append a .<number> to the
   5630 	       assembler name, and even when it does, it looks at FE private
   5631 	       data structures to figure out what that number should be,
   5632 	       which are not set for this variable.  I suppose this is
   5633 	       important for local statics for inline functions, which aren't
   5634 	       "local" in the object file sense.  So in order to get a unique
   5635 	       TU-local symbol, we must invoke the lhd version now.  */
   5636 	    lhd_set_decl_assembler_name (object);
   5637 
   5638 	    *expr_p = NULL_TREE;
   5639 	    break;
   5640 	  }
   5641 
   5642 	/* The var will be initialized and so appear on lhs of
   5643 	   assignment, it can't be TREE_READONLY anymore.  */
   5644 	if (VAR_P (object) && !notify_temp_creation)
   5645 	  TREE_READONLY (object) = 0;
   5646 
   5647 	/* If there are "lots" of initialized elements, even discounting
   5648 	   those that are not address constants (and thus *must* be
   5649 	   computed at runtime), then partition the constructor into
   5650 	   constant and non-constant parts.  Block copy the constant
   5651 	   parts in, then generate code for the non-constant parts.  */
   5652 	/* TODO.  There's code in cp/typeck.cc to do this.  */
   5653 
   5654 	if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
   5655 	  /* store_constructor will ignore the clearing of variable-sized
   5656 	     objects.  Initializers for such objects must explicitly set
   5657 	     every field that needs to be set.  */
   5658 	  cleared = false;
   5659 	else if (!complete_p)
   5660 	  /* If the constructor isn't complete, clear the whole object
   5661 	     beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
   5662 
   5663 	     ??? This ought not to be needed.  For any element not present
   5664 	     in the initializer, we should simply set them to zero.  Except
   5665 	     we'd need to *find* the elements that are not present, and that
   5666 	     requires trickery to avoid quadratic compile-time behavior in
   5667 	     large cases or excessive memory use in small cases.  */
   5668 	  cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
   5669 	else if (num_ctor_elements - num_nonzero_elements
   5670 		 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
   5671 		 && num_nonzero_elements < num_ctor_elements / 4)
   5672 	  /* If there are "lots" of zeros, it's more efficient to clear
   5673 	     the memory and then set the nonzero elements.  */
   5674 	  cleared = true;
   5675 	else if (ensure_single_access && num_nonzero_elements == 0)
   5676 	  /* If a single access to the target must be ensured and all elements
   5677 	     are zero, then it's optimal to clear whatever their number.  */
   5678 	  cleared = true;
   5679 	else
   5680 	  cleared = false;
   5681 
   5682 	/* If there are "lots" of initialized elements, and all of them
   5683 	   are valid address constants, then the entire initializer can
   5684 	   be dropped to memory, and then memcpy'd out.  Don't do this
   5685 	   for sparse arrays, though, as it's more efficient to follow
   5686 	   the standard CONSTRUCTOR behavior of memset followed by
   5687 	   individual element initialization.  Also don't do this for small
   5688 	   all-zero initializers (which aren't big enough to merit
   5689 	   clearing), and don't try to make bitwise copies of
   5690 	   TREE_ADDRESSABLE types.  */
   5691 	if (valid_const_initializer
   5692 	    && complete_p
   5693 	    && !(cleared || num_nonzero_elements == 0)
   5694 	    && !TREE_ADDRESSABLE (type))
   5695 	  {
   5696 	    HOST_WIDE_INT size = int_size_in_bytes (type);
   5697 	    unsigned int align;
   5698 
   5699 	    /* ??? We can still get unbounded array types, at least
   5700 	       from the C++ front end.  This seems wrong, but attempt
   5701 	       to work around it for now.  */
   5702 	    if (size < 0)
   5703 	      {
   5704 		size = int_size_in_bytes (TREE_TYPE (object));
   5705 		if (size >= 0)
   5706 		  TREE_TYPE (ctor) = type = TREE_TYPE (object);
   5707 	      }
   5708 
   5709 	    /* Find the maximum alignment we can assume for the object.  */
   5710 	    /* ??? Make use of DECL_OFFSET_ALIGN.  */
   5711 	    if (DECL_P (object))
   5712 	      align = DECL_ALIGN (object);
   5713 	    else
   5714 	      align = TYPE_ALIGN (type);
   5715 
   5716 	    /* Do a block move either if the size is so small as to make
   5717 	       each individual move a sub-unit move on average, or if it
   5718 	       is so large as to make individual moves inefficient.  */
   5719 	    if (size > 0
   5720 		&& num_nonzero_elements > 1
   5721 		/* For ctors that have many repeated nonzero elements
   5722 		   represented through RANGE_EXPRs, prefer initializing
   5723 		   those through runtime loops over copies of large amounts
   5724 		   of data from readonly data section.  */
   5725 		&& (num_unique_nonzero_elements
   5726 		    > num_nonzero_elements / unique_nonzero_ratio
   5727 		    || size <= min_unique_size)
   5728 		&& (size < num_nonzero_elements
   5729 		    || !can_move_by_pieces (size, align)))
   5730 	      {
   5731 		if (notify_temp_creation)
   5732 		  return GS_ERROR;
   5733 
   5734 		walk_tree (&ctor, force_labels_r, NULL, NULL);
   5735 		ctor = tree_output_constant_def (ctor);
   5736 		if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
   5737 		  ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
   5738 		TREE_OPERAND (*expr_p, 1) = ctor;
   5739 
   5740 		/* This is no longer an assignment of a CONSTRUCTOR, but
   5741 		   we still may have processing to do on the LHS.  So
   5742 		   pretend we didn't do anything here to let that happen.  */
   5743 		return GS_UNHANDLED;
   5744 	      }
   5745 	  }
   5746 
   5747 	/* If a single access to the target must be ensured and there are
   5748 	   nonzero elements or the zero elements are not assigned en masse,
   5749 	   initialize the target from a temporary.  */
   5750 	if (ensure_single_access && (num_nonzero_elements > 0 || !cleared))
   5751 	  {
   5752 	    if (notify_temp_creation)
   5753 	      return GS_ERROR;
   5754 
   5755 	    tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
   5756 	    TREE_OPERAND (*expr_p, 0) = temp;
   5757 	    *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
   5758 			      *expr_p,
   5759 			      build2 (MODIFY_EXPR, void_type_node,
   5760 				      object, temp));
   5761 	    return GS_OK;
   5762 	  }
   5763 
   5764 	if (notify_temp_creation)
   5765 	  return GS_OK;
   5766 
   5767 	/* If there are nonzero elements and if needed, pre-evaluate to capture
   5768 	   elements overlapping with the lhs into temporaries.  We must do this
   5769 	   before clearing to fetch the values before they are zeroed-out.  */
   5770 	if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
   5771 	  {
   5772 	    preeval_data.lhs_base_decl = get_base_address (object);
   5773 	    if (!DECL_P (preeval_data.lhs_base_decl))
   5774 	      preeval_data.lhs_base_decl = NULL;
   5775 	    preeval_data.lhs_alias_set = get_alias_set (object);
   5776 
   5777 	    gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
   5778 					pre_p, post_p, &preeval_data);
   5779 	  }
   5780 
   5781 	bool ctor_has_side_effects_p
   5782 	  = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
   5783 
   5784 	if (cleared)
   5785 	  {
   5786 	    /* Zap the CONSTRUCTOR element list, which simplifies this case.
   5787 	       Note that we still have to gimplify, in order to handle the
   5788 	       case of variable sized types.  Avoid shared tree structures.  */
   5789 	    CONSTRUCTOR_ELTS (ctor) = NULL;
   5790 	    TREE_SIDE_EFFECTS (ctor) = 0;
   5791 	    object = unshare_expr (object);
   5792 	    gimplify_stmt (expr_p, pre_p);
   5793 	  }
   5794 
   5795 	/* If we have not block cleared the object, or if there are nonzero
   5796 	   elements in the constructor, or if the constructor has side effects,
   5797 	   add assignments to the individual scalar fields of the object.  */
   5798 	if (!cleared
   5799 	    || num_nonzero_elements > 0
   5800 	    || ctor_has_side_effects_p)
   5801 	  gimplify_init_ctor_eval (object, elts, pre_p, cleared);
   5802 
   5803 	*expr_p = NULL_TREE;
   5804       }
   5805       break;
   5806 
   5807     case COMPLEX_TYPE:
   5808       {
   5809 	tree r, i;
   5810 
   5811 	if (notify_temp_creation)
   5812 	  return GS_OK;
   5813 
   5814 	/* Extract the real and imaginary parts out of the ctor.  */
   5815 	gcc_assert (elts->length () == 2);
   5816 	r = (*elts)[0].value;
   5817 	i = (*elts)[1].value;
   5818 	if (r == NULL || i == NULL)
   5819 	  {
   5820 	    tree zero = build_zero_cst (TREE_TYPE (type));
   5821 	    if (r == NULL)
   5822 	      r = zero;
   5823 	    if (i == NULL)
   5824 	      i = zero;
   5825 	  }
   5826 
   5827 	/* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
   5828 	   represent creation of a complex value.  */
   5829 	if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
   5830 	  {
   5831 	    ctor = build_complex (type, r, i);
   5832 	    TREE_OPERAND (*expr_p, 1) = ctor;
   5833 	  }
   5834 	else
   5835 	  {
   5836 	    ctor = build2 (COMPLEX_EXPR, type, r, i);
   5837 	    TREE_OPERAND (*expr_p, 1) = ctor;
   5838 	    ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
   5839 				 pre_p,
   5840 				 post_p,
   5841 				 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
   5842 				 fb_rvalue);
   5843 	  }
   5844       }
   5845       break;
   5846 
   5847     case VECTOR_TYPE:
   5848       {
   5849 	unsigned HOST_WIDE_INT ix;
   5850 	constructor_elt *ce;
   5851 
   5852 	if (notify_temp_creation)
   5853 	  return GS_OK;
   5854 
   5855 	/* Vector types use CONSTRUCTOR all the way through gimple
   5856 	   compilation as a general initializer.  */
   5857 	FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
   5858 	  {
   5859 	    enum gimplify_status tret;
   5860 	    tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
   5861 				  fb_rvalue);
   5862 	    if (tret == GS_ERROR)
   5863 	      ret = GS_ERROR;
   5864 	    else if (TREE_STATIC (ctor)
   5865 		     && !initializer_constant_valid_p (ce->value,
   5866 						       TREE_TYPE (ce->value)))
   5867 	      TREE_STATIC (ctor) = 0;
   5868 	  }
   5869 	recompute_constructor_flags (ctor);
   5870 
   5871 	/* Go ahead and simplify constant constructors to VECTOR_CST.  */
   5872 	if (TREE_CONSTANT (ctor))
   5873 	  {
   5874 	    bool constant_p = true;
   5875 	    tree value;
   5876 
   5877 	    /* Even when ctor is constant, it might contain non-*_CST
   5878 	       elements, such as addresses or trapping values like
   5879 	       1.0/0.0 - 1.0/0.0.  Such expressions don't belong
   5880 	       in VECTOR_CST nodes.  */
   5881 	    FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
   5882 	      if (!CONSTANT_CLASS_P (value))
   5883 		{
   5884 		  constant_p = false;
   5885 		  break;
   5886 		}
   5887 
   5888 	    if (constant_p)
   5889 	      {
   5890 		TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
   5891 		break;
   5892 	      }
   5893 	  }
   5894 
   5895 	if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
   5896 	  TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
   5897       }
   5898       break;
   5899 
   5900     default:
   5901       /* So how did we get a CONSTRUCTOR for a scalar type?  */
   5902       gcc_unreachable ();
   5903     }
   5904 
   5905   if (ret == GS_ERROR)
   5906     return GS_ERROR;
   5907   /* If we have gimplified both sides of the initializer but have
   5908      not emitted an assignment, do so now.   */
   5909   if (*expr_p
   5910       /* If the type is an empty type, we don't need to emit the
   5911 	 assignment. */
   5912       && !is_empty_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
   5913     {
   5914       tree lhs = TREE_OPERAND (*expr_p, 0);
   5915       tree rhs = TREE_OPERAND (*expr_p, 1);
   5916       if (want_value && object == lhs)
   5917 	lhs = unshare_expr (lhs);
   5918       gassign *init = gimple_build_assign (lhs, rhs);
   5919       gimplify_seq_add_stmt (pre_p, init);
   5920     }
   5921   if (want_value)
   5922     {
   5923       *expr_p = object;
   5924       ret = GS_OK;
   5925     }
   5926   else
   5927     {
   5928       *expr_p = NULL;
   5929       ret = GS_ALL_DONE;
   5930     }
   5931 
   5932   /* If the user requests to initialize automatic variables, we
   5933      should initialize paddings inside the variable.  Add a call to
   5934      __builtin_clear_pading (&object, 0, for_auto_init = true) to
   5935      initialize paddings of object always to zero regardless of
   5936      INIT_TYPE.  Note, we will not insert this call if the aggregate
   5937      variable has be completely cleared already or it's initialized
   5938      with an empty constructor.  We cannot insert this call if the
   5939      variable is a gimple register since __builtin_clear_padding will take
   5940      the address of the variable.  As a result, if a long double/_Complex long
   5941      double variable will be spilled into stack later, its padding cannot
   5942      be cleared with __builtin_clear_padding.  We should clear its padding
   5943      when it is spilled into memory.  */
   5944   if (is_init_expr
   5945       && !is_gimple_reg (object)
   5946       && clear_padding_type_may_have_padding_p (type)
   5947       && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor)
   5948 	  || !AGGREGATE_TYPE_P (type))
   5949       && is_var_need_auto_init (object))
   5950     gimple_add_padding_init_for_auto_var (object, false, pre_p);
   5951 
   5952   return ret;
   5953 }
   5954 
   5955 /* Given a pointer value OP0, return a simplified version of an
   5956    indirection through OP0, or NULL_TREE if no simplification is
   5957    possible.  This may only be applied to a rhs of an expression.
   5958    Note that the resulting type may be different from the type pointed
   5959    to in the sense that it is still compatible from the langhooks
   5960    point of view. */
   5961 
   5962 static tree
   5963 gimple_fold_indirect_ref_rhs (tree t)
   5964 {
   5965   return gimple_fold_indirect_ref (t);
   5966 }
   5967 
   5968 /* Subroutine of gimplify_modify_expr to do simplifications of
   5969    MODIFY_EXPRs based on the code of the RHS.  We loop for as long as
   5970    something changes.  */
   5971 
   5972 static enum gimplify_status
   5973 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
   5974 			  gimple_seq *pre_p, gimple_seq *post_p,
   5975 			  bool want_value)
   5976 {
   5977   enum gimplify_status ret = GS_UNHANDLED;
   5978   bool changed;
   5979 
   5980   do
   5981     {
   5982       changed = false;
   5983       switch (TREE_CODE (*from_p))
   5984 	{
   5985 	case VAR_DECL:
   5986 	  /* If we're assigning from a read-only variable initialized with
   5987 	     a constructor and not volatile, do the direct assignment from
   5988 	     the constructor, but only if the target is not volatile either
   5989 	     since this latter assignment might end up being done on a per
   5990 	     field basis.  However, if the target is volatile and the type
   5991 	     is aggregate and non-addressable, gimplify_init_constructor
   5992 	     knows that it needs to ensure a single access to the target
   5993 	     and it will return GS_OK only in this case.  */
   5994 	  if (TREE_READONLY (*from_p)
   5995 	      && DECL_INITIAL (*from_p)
   5996 	      && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR
   5997 	      && !TREE_THIS_VOLATILE (*from_p)
   5998 	      && (!TREE_THIS_VOLATILE (*to_p)
   5999 		  || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p))
   6000 		      && !TREE_ADDRESSABLE (TREE_TYPE (*to_p)))))
   6001 	    {
   6002 	      tree old_from = *from_p;
   6003 	      enum gimplify_status subret;
   6004 
   6005 	      /* Move the constructor into the RHS.  */
   6006 	      *from_p = unshare_expr (DECL_INITIAL (*from_p));
   6007 
   6008 	      /* Let's see if gimplify_init_constructor will need to put
   6009 		 it in memory.  */
   6010 	      subret = gimplify_init_constructor (expr_p, NULL, NULL,
   6011 						  false, true);
   6012 	      if (subret == GS_ERROR)
   6013 		{
   6014 		  /* If so, revert the change.  */
   6015 		  *from_p = old_from;
   6016 		}
   6017 	      else
   6018 		{
   6019 		  ret = GS_OK;
   6020 		  changed = true;
   6021 		}
   6022 	    }
   6023 	  break;
   6024 	case INDIRECT_REF:
   6025 	  if (!TREE_ADDRESSABLE (TREE_TYPE (*from_p)))
   6026 	    /* If we have code like
   6027 
   6028 	     *(const A*)(A*)&x
   6029 
   6030 	     where the type of "x" is a (possibly cv-qualified variant
   6031 	     of "A"), treat the entire expression as identical to "x".
   6032 	     This kind of code arises in C++ when an object is bound
   6033 	     to a const reference, and if "x" is a TARGET_EXPR we want
   6034 	     to take advantage of the optimization below.  But not if
   6035 	     the type is TREE_ADDRESSABLE; then C++17 says that the
   6036 	     TARGET_EXPR needs to be a temporary.  */
   6037 	    if (tree t
   6038 		= gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0)))
   6039 	      {
   6040 		bool volatile_p = TREE_THIS_VOLATILE (*from_p);
   6041 		if (TREE_THIS_VOLATILE (t) != volatile_p)
   6042 		  {
   6043 		    if (DECL_P (t))
   6044 		      t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
   6045 						    build_fold_addr_expr (t));
   6046 		    if (REFERENCE_CLASS_P (t))
   6047 		      TREE_THIS_VOLATILE (t) = volatile_p;
   6048 		  }
   6049 		*from_p = t;
   6050 		ret = GS_OK;
   6051 		changed = true;
   6052 	      }
   6053 	  break;
   6054 
   6055 	case TARGET_EXPR:
   6056 	  {
   6057 	    /* If we are initializing something from a TARGET_EXPR, strip the
   6058 	       TARGET_EXPR and initialize it directly, if possible.  This can't
   6059 	       be done if the initializer is void, since that implies that the
   6060 	       temporary is set in some non-trivial way.
   6061 
   6062 	       ??? What about code that pulls out the temp and uses it
   6063 	       elsewhere? I think that such code never uses the TARGET_EXPR as
   6064 	       an initializer.  If I'm wrong, we'll die because the temp won't
   6065 	       have any RTL.  In that case, I guess we'll need to replace
   6066 	       references somehow.  */
   6067 	    tree init = TARGET_EXPR_INITIAL (*from_p);
   6068 
   6069 	    if (init
   6070 		&& (TREE_CODE (*expr_p) != MODIFY_EXPR
   6071 		    || !TARGET_EXPR_NO_ELIDE (*from_p))
   6072 		&& !VOID_TYPE_P (TREE_TYPE (init)))
   6073 	      {
   6074 		*from_p = init;
   6075 		ret = GS_OK;
   6076 		changed = true;
   6077 	      }
   6078 	  }
   6079 	  break;
   6080 
   6081 	case COMPOUND_EXPR:
   6082 	  /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
   6083 	     caught.  */
   6084 	  gimplify_compound_expr (from_p, pre_p, true);
   6085 	  ret = GS_OK;
   6086 	  changed = true;
   6087 	  break;
   6088 
   6089 	case CONSTRUCTOR:
   6090 	  /* If we already made some changes, let the front end have a
   6091 	     crack at this before we break it down.  */
   6092 	  if (ret != GS_UNHANDLED)
   6093 	    break;
   6094 
   6095 	  /* If we're initializing from a CONSTRUCTOR, break this into
   6096 	     individual MODIFY_EXPRs.  */
   6097 	  ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
   6098 					   false);
   6099 	  return ret;
   6100 
   6101 	case COND_EXPR:
   6102 	  /* If we're assigning to a non-register type, push the assignment
   6103 	     down into the branches.  This is mandatory for ADDRESSABLE types,
   6104 	     since we cannot generate temporaries for such, but it saves a
   6105 	     copy in other cases as well.  */
   6106 	  if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
   6107 	    {
   6108 	      /* This code should mirror the code in gimplify_cond_expr. */
   6109 	      enum tree_code code = TREE_CODE (*expr_p);
   6110 	      tree cond = *from_p;
   6111 	      tree result = *to_p;
   6112 
   6113 	      ret = gimplify_expr (&result, pre_p, post_p,
   6114 				   is_gimple_lvalue, fb_lvalue);
   6115 	      if (ret != GS_ERROR)
   6116 		ret = GS_OK;
   6117 
   6118 	      /* If we are going to write RESULT more than once, clear
   6119 		 TREE_READONLY flag, otherwise we might incorrectly promote
   6120 		 the variable to static const and initialize it at compile
   6121 		 time in one of the branches.  */
   6122 	      if (VAR_P (result)
   6123 		  && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
   6124 		  && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
   6125 		TREE_READONLY (result) = 0;
   6126 	      if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
   6127 		TREE_OPERAND (cond, 1)
   6128 		  = build2 (code, void_type_node, result,
   6129 			    TREE_OPERAND (cond, 1));
   6130 	      if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
   6131 		TREE_OPERAND (cond, 2)
   6132 		  = build2 (code, void_type_node, unshare_expr (result),
   6133 			    TREE_OPERAND (cond, 2));
   6134 
   6135 	      TREE_TYPE (cond) = void_type_node;
   6136 	      recalculate_side_effects (cond);
   6137 
   6138 	      if (want_value)
   6139 		{
   6140 		  gimplify_and_add (cond, pre_p);
   6141 		  *expr_p = unshare_expr (result);
   6142 		}
   6143 	      else
   6144 		*expr_p = cond;
   6145 	      return ret;
   6146 	    }
   6147 	  break;
   6148 
   6149 	case CALL_EXPR:
   6150 	  /* For calls that return in memory, give *to_p as the CALL_EXPR's
   6151 	     return slot so that we don't generate a temporary.  */
   6152 	  if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
   6153 	      && aggregate_value_p (*from_p, *from_p))
   6154 	    {
   6155 	      bool use_target;
   6156 
   6157 	      if (!(rhs_predicate_for (*to_p))(*from_p))
   6158 		/* If we need a temporary, *to_p isn't accurate.  */
   6159 		use_target = false;
   6160 	      /* It's OK to use the return slot directly unless it's an NRV. */
   6161 	      else if (TREE_CODE (*to_p) == RESULT_DECL
   6162 		       && DECL_NAME (*to_p) == NULL_TREE
   6163 		       && needs_to_live_in_memory (*to_p))
   6164 		use_target = true;
   6165 	      else if (is_gimple_reg_type (TREE_TYPE (*to_p))
   6166 		       || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
   6167 		/* Don't force regs into memory.  */
   6168 		use_target = false;
   6169 	      else if (TREE_CODE (*expr_p) == INIT_EXPR)
   6170 		/* It's OK to use the target directly if it's being
   6171 		   initialized. */
   6172 		use_target = true;
   6173 	      else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
   6174 		       != INTEGER_CST)
   6175 		/* Always use the target and thus RSO for variable-sized types.
   6176 		   GIMPLE cannot deal with a variable-sized assignment
   6177 		   embedded in a call statement.  */
   6178 		use_target = true;
   6179 	      else if (TREE_CODE (*to_p) != SSA_NAME
   6180 		      && (!is_gimple_variable (*to_p)
   6181 			  || needs_to_live_in_memory (*to_p)))
   6182 		/* Don't use the original target if it's already addressable;
   6183 		   if its address escapes, and the called function uses the
   6184 		   NRV optimization, a conforming program could see *to_p
   6185 		   change before the called function returns; see c++/19317.
   6186 		   When optimizing, the return_slot pass marks more functions
   6187 		   as safe after we have escape info.  */
   6188 		use_target = false;
   6189 	      else
   6190 		use_target = true;
   6191 
   6192 	      if (use_target)
   6193 		{
   6194 		  CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
   6195 		  mark_addressable (*to_p);
   6196 		}
   6197 	    }
   6198 	  break;
   6199 
   6200 	case WITH_SIZE_EXPR:
   6201 	  /* Likewise for calls that return an aggregate of non-constant size,
   6202 	     since we would not be able to generate a temporary at all.  */
   6203 	  if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
   6204 	    {
   6205 	      *from_p = TREE_OPERAND (*from_p, 0);
   6206 	      /* We don't change ret in this case because the
   6207 		 WITH_SIZE_EXPR might have been added in
   6208 		 gimplify_modify_expr, so returning GS_OK would lead to an
   6209 		 infinite loop.  */
   6210 	      changed = true;
   6211 	    }
   6212 	  break;
   6213 
   6214 	  /* If we're initializing from a container, push the initialization
   6215 	     inside it.  */
   6216 	case CLEANUP_POINT_EXPR:
   6217 	case BIND_EXPR:
   6218 	case STATEMENT_LIST:
   6219 	  {
   6220 	    tree wrap = *from_p;
   6221 	    tree t;
   6222 
   6223 	    ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
   6224 				 fb_lvalue);
   6225 	    if (ret != GS_ERROR)
   6226 	      ret = GS_OK;
   6227 
   6228 	    t = voidify_wrapper_expr (wrap, *expr_p);
   6229 	    gcc_assert (t == *expr_p);
   6230 
   6231 	    if (want_value)
   6232 	      {
   6233 		gimplify_and_add (wrap, pre_p);
   6234 		*expr_p = unshare_expr (*to_p);
   6235 	      }
   6236 	    else
   6237 	      *expr_p = wrap;
   6238 	    return GS_OK;
   6239 	  }
   6240 
   6241 	case NOP_EXPR:
   6242 	  /* Pull out compound literal expressions from a NOP_EXPR.
   6243 	     Those are created in the C FE to drop qualifiers during
   6244 	     lvalue conversion.  */
   6245 	  if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
   6246 	      && tree_ssa_useless_type_conversion (*from_p))
   6247 	    {
   6248 	      *from_p = TREE_OPERAND (*from_p, 0);
   6249 	      ret = GS_OK;
   6250 	      changed = true;
   6251 	    }
   6252 	  break;
   6253 
   6254 	case COMPOUND_LITERAL_EXPR:
   6255 	  {
   6256 	    tree complit = TREE_OPERAND (*expr_p, 1);
   6257 	    tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
   6258 	    tree decl = DECL_EXPR_DECL (decl_s);
   6259 	    tree init = DECL_INITIAL (decl);
   6260 
   6261 	    /* struct T x = (struct T) { 0, 1, 2 } can be optimized
   6262 	       into struct T x = { 0, 1, 2 } if the address of the
   6263 	       compound literal has never been taken.  */
   6264 	    if (!TREE_ADDRESSABLE (complit)
   6265 		&& !TREE_ADDRESSABLE (decl)
   6266 		&& init)
   6267 	      {
   6268 		*expr_p = copy_node (*expr_p);
   6269 		TREE_OPERAND (*expr_p, 1) = init;
   6270 		return GS_OK;
   6271 	      }
   6272 	  }
   6273 
   6274 	default:
   6275 	  break;
   6276 	}
   6277     }
   6278   while (changed);
   6279 
   6280   return ret;
   6281 }
   6282 
   6283 
   6284 /* Return true if T looks like a valid GIMPLE statement.  */
   6285 
   6286 static bool
   6287 is_gimple_stmt (tree t)
   6288 {
   6289   const enum tree_code code = TREE_CODE (t);
   6290 
   6291   switch (code)
   6292     {
   6293     case NOP_EXPR:
   6294       /* The only valid NOP_EXPR is the empty statement.  */
   6295       return IS_EMPTY_STMT (t);
   6296 
   6297     case BIND_EXPR:
   6298     case COND_EXPR:
   6299       /* These are only valid if they're void.  */
   6300       return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
   6301 
   6302     case SWITCH_EXPR:
   6303     case GOTO_EXPR:
   6304     case RETURN_EXPR:
   6305     case LABEL_EXPR:
   6306     case CASE_LABEL_EXPR:
   6307     case TRY_CATCH_EXPR:
   6308     case TRY_FINALLY_EXPR:
   6309     case EH_FILTER_EXPR:
   6310     case CATCH_EXPR:
   6311     case ASM_EXPR:
   6312     case STATEMENT_LIST:
   6313     case OACC_PARALLEL:
   6314     case OACC_KERNELS:
   6315     case OACC_SERIAL:
   6316     case OACC_DATA:
   6317     case OACC_HOST_DATA:
   6318     case OACC_DECLARE:
   6319     case OACC_UPDATE:
   6320     case OACC_ENTER_DATA:
   6321     case OACC_EXIT_DATA:
   6322     case OACC_CACHE:
   6323     case OMP_PARALLEL:
   6324     case OMP_FOR:
   6325     case OMP_SIMD:
   6326     case OMP_DISTRIBUTE:
   6327     case OMP_LOOP:
   6328     case OACC_LOOP:
   6329     case OMP_SCAN:
   6330     case OMP_SCOPE:
   6331     case OMP_SECTIONS:
   6332     case OMP_SECTION:
   6333     case OMP_STRUCTURED_BLOCK:
   6334     case OMP_SINGLE:
   6335     case OMP_MASTER:
   6336     case OMP_MASKED:
   6337     case OMP_TASKGROUP:
   6338     case OMP_ORDERED:
   6339     case OMP_CRITICAL:
   6340     case OMP_TASK:
   6341     case OMP_TARGET:
   6342     case OMP_TARGET_DATA:
   6343     case OMP_TARGET_UPDATE:
   6344     case OMP_TARGET_ENTER_DATA:
   6345     case OMP_TARGET_EXIT_DATA:
   6346     case OMP_TASKLOOP:
   6347     case OMP_TEAMS:
   6348       /* These are always void.  */
   6349       return true;
   6350 
   6351     case CALL_EXPR:
   6352     case MODIFY_EXPR:
   6353     case PREDICT_EXPR:
   6354       /* These are valid regardless of their type.  */
   6355       return true;
   6356 
   6357     default:
   6358       return false;
   6359     }
   6360 }
   6361 
   6362 
   6363 /* Promote partial stores to COMPLEX variables to total stores.  *EXPR_P is
   6364    a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
   6365 
   6366    IMPORTANT NOTE: This promotion is performed by introducing a load of the
   6367    other, unmodified part of the complex object just before the total store.
   6368    As a consequence, if the object is still uninitialized, an undefined value
   6369    will be loaded into a register, which may result in a spurious exception
   6370    if the register is floating-point and the value happens to be a signaling
   6371    NaN for example.  Then the fully-fledged complex operations lowering pass
   6372    followed by a DCE pass are necessary in order to fix things up.  */
   6373 
   6374 static enum gimplify_status
   6375 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
   6376                                    bool want_value)
   6377 {
   6378   enum tree_code code, ocode;
   6379   tree lhs, rhs, new_rhs, other, realpart, imagpart;
   6380 
   6381   lhs = TREE_OPERAND (*expr_p, 0);
   6382   rhs = TREE_OPERAND (*expr_p, 1);
   6383   code = TREE_CODE (lhs);
   6384   lhs = TREE_OPERAND (lhs, 0);
   6385 
   6386   ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
   6387   other = build1 (ocode, TREE_TYPE (rhs), lhs);
   6388   suppress_warning (other);
   6389   other = get_formal_tmp_var (other, pre_p);
   6390 
   6391   realpart = code == REALPART_EXPR ? rhs : other;
   6392   imagpart = code == REALPART_EXPR ? other : rhs;
   6393 
   6394   if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
   6395     new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
   6396   else
   6397     new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
   6398 
   6399   gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
   6400   *expr_p = (want_value) ? rhs : NULL_TREE;
   6401 
   6402   return GS_ALL_DONE;
   6403 }
   6404 
   6405 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
   6406 
   6407       modify_expr
   6408 	      : varname '=' rhs
   6409 	      | '*' ID '=' rhs
   6410 
   6411     PRE_P points to the list where side effects that must happen before
   6412 	*EXPR_P should be stored.
   6413 
   6414     POST_P points to the list where side effects that must happen after
   6415 	*EXPR_P should be stored.
   6416 
   6417     WANT_VALUE is nonzero iff we want to use the value of this expression
   6418 	in another expression.  */
   6419 
   6420 static enum gimplify_status
   6421 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   6422 		      bool want_value)
   6423 {
   6424   tree *from_p = &TREE_OPERAND (*expr_p, 1);
   6425   tree *to_p = &TREE_OPERAND (*expr_p, 0);
   6426   enum gimplify_status ret = GS_UNHANDLED;
   6427   gimple *assign;
   6428   location_t loc = EXPR_LOCATION (*expr_p);
   6429   gimple_stmt_iterator gsi;
   6430 
   6431   if (error_operand_p (*from_p) || error_operand_p (*to_p))
   6432     return GS_ERROR;
   6433 
   6434   gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
   6435 	      || TREE_CODE (*expr_p) == INIT_EXPR);
   6436 
   6437   /* Trying to simplify a clobber using normal logic doesn't work,
   6438      so handle it here.  */
   6439   if (TREE_CLOBBER_P (*from_p))
   6440     {
   6441       ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
   6442       if (ret == GS_ERROR)
   6443 	return ret;
   6444       gcc_assert (!want_value);
   6445       if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
   6446 	{
   6447 	  tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
   6448 					       pre_p, post_p);
   6449 	  *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
   6450 	}
   6451       gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
   6452       *expr_p = NULL;
   6453       return GS_ALL_DONE;
   6454     }
   6455 
   6456   /* Convert initialization from an empty variable-size CONSTRUCTOR to
   6457      memset.  */
   6458   if (TREE_TYPE (*from_p) != error_mark_node
   6459       && TYPE_SIZE_UNIT (TREE_TYPE (*from_p))
   6460       && !poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (*from_p)))
   6461       && TREE_CODE (*from_p) == CONSTRUCTOR
   6462       && CONSTRUCTOR_NELTS (*from_p) == 0)
   6463     {
   6464       maybe_with_size_expr (from_p);
   6465       gcc_assert (TREE_CODE (*from_p) == WITH_SIZE_EXPR);
   6466       return gimplify_modify_expr_to_memset (expr_p,
   6467 					     TREE_OPERAND (*from_p, 1),
   6468 					     want_value, pre_p);
   6469     }
   6470 
   6471   /* Insert pointer conversions required by the middle-end that are not
   6472      required by the frontend.  This fixes middle-end type checking for
   6473      for example gcc.dg/redecl-6.c.  */
   6474   if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
   6475     {
   6476       STRIP_USELESS_TYPE_CONVERSION (*from_p);
   6477       if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
   6478 	*from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
   6479     }
   6480 
   6481   /* See if any simplifications can be done based on what the RHS is.  */
   6482   ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
   6483 				  want_value);
   6484   if (ret != GS_UNHANDLED)
   6485     return ret;
   6486 
   6487   /* For empty types only gimplify the left hand side and right hand
   6488      side as statements and throw away the assignment.  Do this after
   6489      gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
   6490      types properly.  */
   6491   if (is_empty_type (TREE_TYPE (*from_p))
   6492       && !want_value
   6493       /* Don't do this for calls that return addressable types, expand_call
   6494 	 relies on those having a lhs.  */
   6495       && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
   6496 	   && TREE_CODE (*from_p) == CALL_EXPR))
   6497     {
   6498       gimplify_stmt (from_p, pre_p);
   6499       gimplify_stmt (to_p, pre_p);
   6500       *expr_p = NULL_TREE;
   6501       return GS_ALL_DONE;
   6502     }
   6503 
   6504   /* If the value being copied is of variable width, compute the length
   6505      of the copy into a WITH_SIZE_EXPR.   Note that we need to do this
   6506      before gimplifying any of the operands so that we can resolve any
   6507      PLACEHOLDER_EXPRs in the size.  Also note that the RTL expander uses
   6508      the size of the expression to be copied, not of the destination, so
   6509      that is what we must do here.  */
   6510   maybe_with_size_expr (from_p);
   6511 
   6512   /* As a special case, we have to temporarily allow for assignments
   6513      with a CALL_EXPR on the RHS.  Since in GIMPLE a function call is
   6514      a toplevel statement, when gimplifying the GENERIC expression
   6515      MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
   6516      GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
   6517 
   6518      Instead, we need to create the tuple GIMPLE_CALL <a, foo>.  To
   6519      prevent gimplify_expr from trying to create a new temporary for
   6520      foo's LHS, we tell it that it should only gimplify until it
   6521      reaches the CALL_EXPR.  On return from gimplify_expr, the newly
   6522      created GIMPLE_CALL <foo> will be the last statement in *PRE_P
   6523      and all we need to do here is set 'a' to be its LHS.  */
   6524 
   6525   /* Gimplify the RHS first for C++17 and bug 71104.  */
   6526   gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
   6527   ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
   6528   if (ret == GS_ERROR)
   6529     return ret;
   6530 
   6531   /* Then gimplify the LHS.  */
   6532   /* If we gimplified the RHS to a CALL_EXPR and that call may return
   6533      twice we have to make sure to gimplify into non-SSA as otherwise
   6534      the abnormal edge added later will make those defs not dominate
   6535      their uses.
   6536      ???  Technically this applies only to the registers used in the
   6537      resulting non-register *TO_P.  */
   6538   bool saved_into_ssa = gimplify_ctxp->into_ssa;
   6539   if (saved_into_ssa
   6540       && TREE_CODE (*from_p) == CALL_EXPR
   6541       && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
   6542     gimplify_ctxp->into_ssa = false;
   6543   ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
   6544   gimplify_ctxp->into_ssa = saved_into_ssa;
   6545   if (ret == GS_ERROR)
   6546     return ret;
   6547 
   6548   /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
   6549      guess for the predicate was wrong.  */
   6550   gimple_predicate final_pred = rhs_predicate_for (*to_p);
   6551   if (final_pred != initial_pred)
   6552     {
   6553       ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
   6554       if (ret == GS_ERROR)
   6555 	return ret;
   6556     }
   6557 
   6558   /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
   6559      size as argument to the call.  */
   6560   if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
   6561     {
   6562       tree call = TREE_OPERAND (*from_p, 0);
   6563       tree vlasize = TREE_OPERAND (*from_p, 1);
   6564 
   6565       if (TREE_CODE (call) == CALL_EXPR
   6566 	  && CALL_EXPR_IFN (call) == IFN_VA_ARG)
   6567 	{
   6568 	  int nargs = call_expr_nargs (call);
   6569 	  tree type = TREE_TYPE (call);
   6570 	  tree ap = CALL_EXPR_ARG (call, 0);
   6571 	  tree tag = CALL_EXPR_ARG (call, 1);
   6572 	  tree aptag = CALL_EXPR_ARG (call, 2);
   6573 	  tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
   6574 						       IFN_VA_ARG, type,
   6575 						       nargs + 1, ap, tag,
   6576 						       aptag, vlasize);
   6577 	  TREE_OPERAND (*from_p, 0) = newcall;
   6578 	}
   6579     }
   6580 
   6581   /* Now see if the above changed *from_p to something we handle specially.  */
   6582   ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
   6583 				  want_value);
   6584   if (ret != GS_UNHANDLED)
   6585     return ret;
   6586 
   6587   /* If we've got a variable sized assignment between two lvalues (i.e. does
   6588      not involve a call), then we can make things a bit more straightforward
   6589      by converting the assignment to memcpy or memset.  */
   6590   if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
   6591     {
   6592       tree from = TREE_OPERAND (*from_p, 0);
   6593       tree size = TREE_OPERAND (*from_p, 1);
   6594 
   6595       if (TREE_CODE (from) == CONSTRUCTOR)
   6596 	return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
   6597       else if (is_gimple_addressable (from)
   6598 	       && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (*to_p)))
   6599 	       && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (from))))
   6600 	{
   6601 	  *from_p = from;
   6602 	  return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
   6603 	      					 pre_p);
   6604 	}
   6605     }
   6606 
   6607   /* Transform partial stores to non-addressable complex variables into
   6608      total stores.  This allows us to use real instead of virtual operands
   6609      for these variables, which improves optimization.  */
   6610   if ((TREE_CODE (*to_p) == REALPART_EXPR
   6611        || TREE_CODE (*to_p) == IMAGPART_EXPR)
   6612       && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
   6613     return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
   6614 
   6615   /* Try to alleviate the effects of the gimplification creating artificial
   6616      temporaries (see for example is_gimple_reg_rhs) on the debug info, but
   6617      make sure not to create DECL_DEBUG_EXPR links across functions.  */
   6618   if (!gimplify_ctxp->into_ssa
   6619       && VAR_P (*from_p)
   6620       && DECL_IGNORED_P (*from_p)
   6621       && DECL_P (*to_p)
   6622       && !DECL_IGNORED_P (*to_p)
   6623       && decl_function_context (*to_p) == current_function_decl
   6624       && decl_function_context (*from_p) == current_function_decl)
   6625     {
   6626       if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
   6627 	DECL_NAME (*from_p)
   6628 	  = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
   6629       DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
   6630       SET_DECL_DEBUG_EXPR (*from_p, *to_p);
   6631    }
   6632 
   6633   if (want_value && TREE_THIS_VOLATILE (*to_p))
   6634     *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
   6635 
   6636   if (TREE_CODE (*from_p) == CALL_EXPR)
   6637     {
   6638       /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
   6639 	 instead of a GIMPLE_ASSIGN.  */
   6640       gcall *call_stmt;
   6641       if (CALL_EXPR_FN (*from_p) == NULL_TREE)
   6642 	{
   6643 	  /* Gimplify internal functions created in the FEs.  */
   6644 	  int nargs = call_expr_nargs (*from_p), i;
   6645 	  enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
   6646 	  auto_vec<tree> vargs (nargs);
   6647 
   6648 	  for (i = 0; i < nargs; i++)
   6649 	    {
   6650 	      gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
   6651 			    EXPR_LOCATION (*from_p));
   6652 	      vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
   6653 	    }
   6654 	  call_stmt = gimple_build_call_internal_vec (ifn, vargs);
   6655 	  gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
   6656 	  gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
   6657 	}
   6658       else
   6659 	{
   6660 	  tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
   6661 	  CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
   6662 	  STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
   6663 	  tree fndecl = get_callee_fndecl (*from_p);
   6664 	  if (fndecl
   6665 	      && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
   6666 	      && call_expr_nargs (*from_p) == 3)
   6667 	    call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
   6668 						    CALL_EXPR_ARG (*from_p, 0),
   6669 						    CALL_EXPR_ARG (*from_p, 1),
   6670 						    CALL_EXPR_ARG (*from_p, 2));
   6671 	  else
   6672 	    {
   6673 	      call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
   6674 	    }
   6675 	}
   6676       notice_special_calls (call_stmt);
   6677       if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
   6678 	gimple_call_set_lhs (call_stmt, *to_p);
   6679       else if (TREE_CODE (*to_p) == SSA_NAME)
   6680 	/* The above is somewhat premature, avoid ICEing later for a
   6681 	   SSA name w/o a definition.  We may have uses in the GIMPLE IL.
   6682 	   ???  This doesn't make it a default-def.  */
   6683 	SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
   6684 
   6685       assign = call_stmt;
   6686     }
   6687   else
   6688     {
   6689       assign = gimple_build_assign (*to_p, *from_p);
   6690       gimple_set_location (assign, EXPR_LOCATION (*expr_p));
   6691       if (COMPARISON_CLASS_P (*from_p))
   6692 	copy_warning (assign, *from_p);
   6693     }
   6694 
   6695   if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
   6696     {
   6697       /* We should have got an SSA name from the start.  */
   6698       gcc_assert (TREE_CODE (*to_p) == SSA_NAME
   6699 		  || ! gimple_in_ssa_p (cfun));
   6700     }
   6701 
   6702   gimplify_seq_add_stmt (pre_p, assign);
   6703   gsi = gsi_last (*pre_p);
   6704   maybe_fold_stmt (&gsi);
   6705 
   6706   if (want_value)
   6707     {
   6708       *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
   6709       return GS_OK;
   6710     }
   6711   else
   6712     *expr_p = NULL;
   6713 
   6714   return GS_ALL_DONE;
   6715 }
   6716 
   6717 /* Gimplify a comparison between two variable-sized objects.  Do this
   6718    with a call to BUILT_IN_MEMCMP.  */
   6719 
   6720 static enum gimplify_status
   6721 gimplify_variable_sized_compare (tree *expr_p)
   6722 {
   6723   location_t loc = EXPR_LOCATION (*expr_p);
   6724   tree op0 = TREE_OPERAND (*expr_p, 0);
   6725   tree op1 = TREE_OPERAND (*expr_p, 1);
   6726   tree t, arg, dest, src, expr;
   6727 
   6728   arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
   6729   arg = unshare_expr (arg);
   6730   arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
   6731   src = build_fold_addr_expr_loc (loc, op1);
   6732   dest = build_fold_addr_expr_loc (loc, op0);
   6733   t = builtin_decl_implicit (BUILT_IN_MEMCMP);
   6734   t = build_call_expr_loc (loc, t, 3, dest, src, arg);
   6735 
   6736   expr
   6737     = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
   6738   SET_EXPR_LOCATION (expr, loc);
   6739   *expr_p = expr;
   6740 
   6741   return GS_OK;
   6742 }
   6743 
   6744 /* Gimplify a comparison between two aggregate objects of integral scalar
   6745    mode as a comparison between the bitwise equivalent scalar values.  */
   6746 
   6747 static enum gimplify_status
   6748 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
   6749 {
   6750   location_t loc = EXPR_LOCATION (*expr_p);
   6751   tree op0 = TREE_OPERAND (*expr_p, 0);
   6752   tree op1 = TREE_OPERAND (*expr_p, 1);
   6753 
   6754   tree type = TREE_TYPE (op0);
   6755   tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
   6756 
   6757   op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
   6758   op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
   6759 
   6760   *expr_p
   6761     = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
   6762 
   6763   return GS_OK;
   6764 }
   6765 
   6766 /* Gimplify an expression sequence.  This function gimplifies each
   6767    expression and rewrites the original expression with the last
   6768    expression of the sequence in GIMPLE form.
   6769 
   6770    PRE_P points to the list where the side effects for all the
   6771        expressions in the sequence will be emitted.
   6772 
   6773    WANT_VALUE is true when the result of the last COMPOUND_EXPR is used.  */
   6774 
   6775 static enum gimplify_status
   6776 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
   6777 {
   6778   tree t = *expr_p;
   6779 
   6780   do
   6781     {
   6782       tree *sub_p = &TREE_OPERAND (t, 0);
   6783 
   6784       if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
   6785 	gimplify_compound_expr (sub_p, pre_p, false);
   6786       else
   6787 	gimplify_stmt (sub_p, pre_p);
   6788 
   6789       t = TREE_OPERAND (t, 1);
   6790     }
   6791   while (TREE_CODE (t) == COMPOUND_EXPR);
   6792 
   6793   *expr_p = t;
   6794   if (want_value)
   6795     return GS_OK;
   6796   else
   6797     {
   6798       gimplify_stmt (expr_p, pre_p);
   6799       return GS_ALL_DONE;
   6800     }
   6801 }
   6802 
   6803 /* Gimplify a SAVE_EXPR node.  EXPR_P points to the expression to
   6804    gimplify.  After gimplification, EXPR_P will point to a new temporary
   6805    that holds the original value of the SAVE_EXPR node.
   6806 
   6807    PRE_P points to the list where side effects that must happen before
   6808    *EXPR_P should be stored.  */
   6809 
   6810 static enum gimplify_status
   6811 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
   6812 {
   6813   enum gimplify_status ret = GS_ALL_DONE;
   6814   tree val;
   6815 
   6816   gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
   6817   val = TREE_OPERAND (*expr_p, 0);
   6818 
   6819   if (val && TREE_TYPE (val) == error_mark_node)
   6820     return GS_ERROR;
   6821 
   6822   /* If the SAVE_EXPR has not been resolved, then evaluate it once.  */
   6823   if (!SAVE_EXPR_RESOLVED_P (*expr_p))
   6824     {
   6825       /* The operand may be a void-valued expression.  It is
   6826 	 being executed only for its side-effects.  */
   6827       if (TREE_TYPE (val) == void_type_node)
   6828 	{
   6829 	  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   6830 			       is_gimple_stmt, fb_none);
   6831 	  val = NULL;
   6832 	}
   6833       else
   6834 	/* The temporary may not be an SSA name as later abnormal and EH
   6835 	   control flow may invalidate use/def domination.  When in SSA
   6836 	   form then assume there are no such issues and SAVE_EXPRs only
   6837 	   appear via GENERIC foldings.  */
   6838 	val = get_initialized_tmp_var (val, pre_p, post_p,
   6839 				       gimple_in_ssa_p (cfun));
   6840 
   6841       TREE_OPERAND (*expr_p, 0) = val;
   6842       SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
   6843     }
   6844 
   6845   *expr_p = val;
   6846 
   6847   return ret;
   6848 }
   6849 
   6850 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
   6851 
   6852       unary_expr
   6853 	      : ...
   6854 	      | '&' varname
   6855 	      ...
   6856 
   6857     PRE_P points to the list where side effects that must happen before
   6858 	*EXPR_P should be stored.
   6859 
   6860     POST_P points to the list where side effects that must happen after
   6861 	*EXPR_P should be stored.  */
   6862 
   6863 static enum gimplify_status
   6864 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
   6865 {
   6866   tree expr = *expr_p;
   6867   tree op0 = TREE_OPERAND (expr, 0);
   6868   enum gimplify_status ret;
   6869   location_t loc = EXPR_LOCATION (*expr_p);
   6870 
   6871   switch (TREE_CODE (op0))
   6872     {
   6873     case INDIRECT_REF:
   6874     do_indirect_ref:
   6875       /* Check if we are dealing with an expression of the form '&*ptr'.
   6876 	 While the front end folds away '&*ptr' into 'ptr', these
   6877 	 expressions may be generated internally by the compiler (e.g.,
   6878 	 builtins like __builtin_va_end).  */
   6879       /* Caution: the silent array decomposition semantics we allow for
   6880 	 ADDR_EXPR means we can't always discard the pair.  */
   6881       /* Gimplification of the ADDR_EXPR operand may drop
   6882 	 cv-qualification conversions, so make sure we add them if
   6883 	 needed.  */
   6884       {
   6885 	tree op00 = TREE_OPERAND (op0, 0);
   6886 	tree t_expr = TREE_TYPE (expr);
   6887 	tree t_op00 = TREE_TYPE (op00);
   6888 
   6889         if (!useless_type_conversion_p (t_expr, t_op00))
   6890 	  op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
   6891         *expr_p = op00;
   6892         ret = GS_OK;
   6893       }
   6894       break;
   6895 
   6896     case VIEW_CONVERT_EXPR:
   6897       /* Take the address of our operand and then convert it to the type of
   6898 	 this ADDR_EXPR.
   6899 
   6900 	 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
   6901 	 all clear.  The impact of this transformation is even less clear.  */
   6902 
   6903       /* If the operand is a useless conversion, look through it.  Doing so
   6904 	 guarantees that the ADDR_EXPR and its operand will remain of the
   6905 	 same type.  */
   6906       if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
   6907 	op0 = TREE_OPERAND (op0, 0);
   6908 
   6909       *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
   6910 				  build_fold_addr_expr_loc (loc,
   6911 							TREE_OPERAND (op0, 0)));
   6912       ret = GS_OK;
   6913       break;
   6914 
   6915     case MEM_REF:
   6916       if (integer_zerop (TREE_OPERAND (op0, 1)))
   6917 	goto do_indirect_ref;
   6918 
   6919       /* fall through */
   6920 
   6921     default:
   6922       /* If we see a call to a declared builtin or see its address
   6923 	 being taken (we can unify those cases here) then we can mark
   6924 	 the builtin for implicit generation by GCC.  */
   6925       if (TREE_CODE (op0) == FUNCTION_DECL
   6926 	  && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
   6927 	  && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
   6928 	set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
   6929 
   6930       /* We use fb_either here because the C frontend sometimes takes
   6931 	 the address of a call that returns a struct; see
   6932 	 gcc.dg/c99-array-lval-1.c.  The gimplifier will correctly make
   6933 	 the implied temporary explicit.  */
   6934 
   6935       /* Make the operand addressable.  */
   6936       ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
   6937 			   is_gimple_addressable, fb_either);
   6938       if (ret == GS_ERROR)
   6939 	break;
   6940 
   6941       /* Then mark it.  Beware that it may not be possible to do so directly
   6942 	 if a temporary has been created by the gimplification.  */
   6943       prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
   6944 
   6945       op0 = TREE_OPERAND (expr, 0);
   6946 
   6947       /* For various reasons, the gimplification of the expression
   6948 	 may have made a new INDIRECT_REF.  */
   6949       if (INDIRECT_REF_P (op0)
   6950 	  || (TREE_CODE (op0) == MEM_REF
   6951 	      && integer_zerop (TREE_OPERAND (op0, 1))))
   6952 	goto do_indirect_ref;
   6953 
   6954       mark_addressable (TREE_OPERAND (expr, 0));
   6955 
   6956       /* The FEs may end up building ADDR_EXPRs early on a decl with
   6957 	 an incomplete type.  Re-build ADDR_EXPRs in canonical form
   6958 	 here.  */
   6959       if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
   6960 	*expr_p = build_fold_addr_expr (op0);
   6961 
   6962       /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly.  */
   6963       if (TREE_CODE (*expr_p) == ADDR_EXPR)
   6964 	recompute_tree_invariant_for_addr_expr (*expr_p);
   6965 
   6966       /* If we re-built the ADDR_EXPR add a conversion to the original type
   6967          if required.  */
   6968       if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
   6969 	*expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
   6970 
   6971       break;
   6972     }
   6973 
   6974   return ret;
   6975 }
   6976 
   6977 /* Gimplify the operands of an ASM_EXPR.  Input operands should be a gimple
   6978    value; output operands should be a gimple lvalue.  */
   6979 
   6980 static enum gimplify_status
   6981 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
   6982 {
   6983   tree expr;
   6984   int noutputs;
   6985   const char **oconstraints;
   6986   int i;
   6987   tree link;
   6988   const char *constraint;
   6989   bool allows_mem, allows_reg, is_inout;
   6990   enum gimplify_status ret, tret;
   6991   gasm *stmt;
   6992   vec<tree, va_gc> *inputs;
   6993   vec<tree, va_gc> *outputs;
   6994   vec<tree, va_gc> *clobbers;
   6995   vec<tree, va_gc> *labels;
   6996   tree link_next;
   6997 
   6998   expr = *expr_p;
   6999   noutputs = list_length (ASM_OUTPUTS (expr));
   7000   oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
   7001 
   7002   inputs = NULL;
   7003   outputs = NULL;
   7004   clobbers = NULL;
   7005   labels = NULL;
   7006 
   7007   ret = GS_ALL_DONE;
   7008   link_next = NULL_TREE;
   7009   for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
   7010     {
   7011       bool ok;
   7012       size_t constraint_len;
   7013 
   7014       link_next = TREE_CHAIN (link);
   7015 
   7016       oconstraints[i]
   7017 	= constraint
   7018 	= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
   7019       constraint_len = strlen (constraint);
   7020       if (constraint_len == 0)
   7021         continue;
   7022 
   7023       ok = parse_output_constraint (&constraint, i, 0, 0,
   7024 				    &allows_mem, &allows_reg, &is_inout);
   7025       if (!ok)
   7026 	{
   7027 	  ret = GS_ERROR;
   7028 	  is_inout = false;
   7029 	}
   7030 
   7031       /* If we can't make copies, we can only accept memory.
   7032 	 Similarly for VLAs.  */
   7033       tree outtype = TREE_TYPE (TREE_VALUE (link));
   7034       if (outtype != error_mark_node
   7035 	  && (TREE_ADDRESSABLE (outtype)
   7036 	      || !COMPLETE_TYPE_P (outtype)
   7037 	      || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
   7038 	{
   7039 	  if (allows_mem)
   7040 	    allows_reg = 0;
   7041 	  else
   7042 	    {
   7043 	      error ("impossible constraint in %<asm%>");
   7044 	      error ("non-memory output %d must stay in memory", i);
   7045 	      return GS_ERROR;
   7046 	    }
   7047 	}
   7048 
   7049       if (!allows_reg && allows_mem)
   7050 	mark_addressable (TREE_VALUE (link));
   7051 
   7052       tree orig = TREE_VALUE (link);
   7053       tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
   7054 			    is_inout ? is_gimple_min_lval : is_gimple_lvalue,
   7055 			    fb_lvalue | fb_mayfail);
   7056       if (tret == GS_ERROR)
   7057 	{
   7058 	  if (orig != error_mark_node)
   7059 	    error ("invalid lvalue in %<asm%> output %d", i);
   7060 	  ret = tret;
   7061 	}
   7062 
   7063       /* If the gimplified operand is a register we do not allow memory.  */
   7064       if (allows_reg
   7065 	  && allows_mem
   7066 	  && (is_gimple_reg (TREE_VALUE (link))
   7067 	      || (handled_component_p (TREE_VALUE (link))
   7068 		  && is_gimple_reg (TREE_OPERAND (TREE_VALUE (link), 0)))))
   7069 	allows_mem = 0;
   7070 
   7071       /* If the constraint does not allow memory make sure we gimplify
   7072          it to a register if it is not already but its base is.  This
   7073 	 happens for complex and vector components.  */
   7074       if (!allows_mem)
   7075 	{
   7076 	  tree op = TREE_VALUE (link);
   7077 	  if (! is_gimple_val (op)
   7078 	      && is_gimple_reg_type (TREE_TYPE (op))
   7079 	      && is_gimple_reg (get_base_address (op)))
   7080 	    {
   7081 	      tree tem = create_tmp_reg (TREE_TYPE (op));
   7082 	      tree ass;
   7083 	      if (is_inout)
   7084 		{
   7085 		  ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
   7086 				tem, unshare_expr (op));
   7087 		  gimplify_and_add (ass, pre_p);
   7088 		}
   7089 	      ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
   7090 	      gimplify_and_add (ass, post_p);
   7091 
   7092 	      TREE_VALUE (link) = tem;
   7093 	      tret = GS_OK;
   7094 	    }
   7095 	}
   7096 
   7097       vec_safe_push (outputs, link);
   7098       TREE_CHAIN (link) = NULL_TREE;
   7099 
   7100       if (is_inout)
   7101 	{
   7102 	  /* An input/output operand.  To give the optimizers more
   7103 	     flexibility, split it into separate input and output
   7104  	     operands.  */
   7105 	  tree input;
   7106 	  /* Buffer big enough to format a 32-bit UINT_MAX into.  */
   7107 	  char buf[11];
   7108 
   7109 	  /* Turn the in/out constraint into an output constraint.  */
   7110 	  char *p = xstrdup (constraint);
   7111 	  p[0] = '=';
   7112 	  TREE_PURPOSE (link) = unshare_expr (TREE_PURPOSE (link));
   7113 	  TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
   7114 
   7115 	  /* And add a matching input constraint.  */
   7116 	  if (allows_reg)
   7117 	    {
   7118 	      sprintf (buf, "%u", i);
   7119 
   7120 	      /* If there are multiple alternatives in the constraint,
   7121 		 handle each of them individually.  Those that allow register
   7122 		 will be replaced with operand number, the others will stay
   7123 		 unchanged.  */
   7124 	      if (strchr (p, ',') != NULL)
   7125 		{
   7126 		  size_t len = 0, buflen = strlen (buf);
   7127 		  char *beg, *end, *str, *dst;
   7128 
   7129 		  for (beg = p + 1;;)
   7130 		    {
   7131 		      end = strchr (beg, ',');
   7132 		      if (end == NULL)
   7133 			end = strchr (beg, '\0');
   7134 		      if ((size_t) (end - beg) < buflen)
   7135 			len += buflen + 1;
   7136 		      else
   7137 			len += end - beg + 1;
   7138 		      if (*end)
   7139 			beg = end + 1;
   7140 		      else
   7141 			break;
   7142 		    }
   7143 
   7144 		  str = (char *) alloca (len);
   7145 		  for (beg = p + 1, dst = str;;)
   7146 		    {
   7147 		      const char *tem;
   7148 		      bool mem_p, reg_p, inout_p;
   7149 
   7150 		      end = strchr (beg, ',');
   7151 		      if (end)
   7152 			*end = '\0';
   7153 		      beg[-1] = '=';
   7154 		      tem = beg - 1;
   7155 		      parse_output_constraint (&tem, i, 0, 0,
   7156 					       &mem_p, &reg_p, &inout_p);
   7157 		      if (dst != str)
   7158 			*dst++ = ',';
   7159 		      if (reg_p)
   7160 			{
   7161 			  memcpy (dst, buf, buflen);
   7162 			  dst += buflen;
   7163 			}
   7164 		      else
   7165 			{
   7166 			  if (end)
   7167 			    len = end - beg;
   7168 			  else
   7169 			    len = strlen (beg);
   7170 			  memcpy (dst, beg, len);
   7171 			  dst += len;
   7172 			}
   7173 		      if (end)
   7174 			beg = end + 1;
   7175 		      else
   7176 			break;
   7177 		    }
   7178 		  *dst = '\0';
   7179 		  input = build_string (dst - str, str);
   7180 		}
   7181 	      else
   7182 		input = build_string (strlen (buf), buf);
   7183 	    }
   7184 	  else
   7185 	    input = build_string (constraint_len - 1, constraint + 1);
   7186 
   7187 	  free (p);
   7188 
   7189 	  input = build_tree_list (build_tree_list (NULL_TREE, input),
   7190 				   unshare_expr (TREE_VALUE (link)));
   7191 	  ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
   7192 	}
   7193     }
   7194 
   7195   link_next = NULL_TREE;
   7196   for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
   7197     {
   7198       link_next = TREE_CHAIN (link);
   7199       constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
   7200       parse_input_constraint (&constraint, 0, 0, noutputs, 0,
   7201 			      oconstraints, &allows_mem, &allows_reg);
   7202 
   7203       /* If we can't make copies, we can only accept memory.  */
   7204       tree intype = TREE_TYPE (TREE_VALUE (link));
   7205       if (intype != error_mark_node
   7206 	  && (TREE_ADDRESSABLE (intype)
   7207 	      || !COMPLETE_TYPE_P (intype)
   7208 	      || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
   7209 	{
   7210 	  if (allows_mem)
   7211 	    allows_reg = 0;
   7212 	  else
   7213 	    {
   7214 	      error ("impossible constraint in %<asm%>");
   7215 	      error ("non-memory input %d must stay in memory", i);
   7216 	      return GS_ERROR;
   7217 	    }
   7218 	}
   7219 
   7220       /* If the operand is a memory input, it should be an lvalue.  */
   7221       if (!allows_reg && allows_mem)
   7222 	{
   7223 	  tree inputv = TREE_VALUE (link);
   7224 	  STRIP_NOPS (inputv);
   7225 	  if (TREE_CODE (inputv) == PREDECREMENT_EXPR
   7226 	      || TREE_CODE (inputv) == PREINCREMENT_EXPR
   7227 	      || TREE_CODE (inputv) == POSTDECREMENT_EXPR
   7228 	      || TREE_CODE (inputv) == POSTINCREMENT_EXPR
   7229 	      || TREE_CODE (inputv) == MODIFY_EXPR)
   7230 	    TREE_VALUE (link) = error_mark_node;
   7231 	  tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
   7232 				is_gimple_lvalue, fb_lvalue | fb_mayfail);
   7233 	  if (tret != GS_ERROR)
   7234 	    {
   7235 	      /* Unlike output operands, memory inputs are not guaranteed
   7236 		 to be lvalues by the FE, and while the expressions are
   7237 		 marked addressable there, if it is e.g. a statement
   7238 		 expression, temporaries in it might not end up being
   7239 		 addressable.  They might be already used in the IL and thus
   7240 		 it is too late to make them addressable now though.  */
   7241 	      tree x = TREE_VALUE (link);
   7242 	      while (handled_component_p (x))
   7243 		x = TREE_OPERAND (x, 0);
   7244 	      if (TREE_CODE (x) == MEM_REF
   7245 		  && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
   7246 		x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
   7247 	      if ((VAR_P (x)
   7248 		   || TREE_CODE (x) == PARM_DECL
   7249 		   || TREE_CODE (x) == RESULT_DECL)
   7250 		  && !TREE_ADDRESSABLE (x)
   7251 		  && is_gimple_reg (x))
   7252 		{
   7253 		  warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
   7254 					       input_location), 0,
   7255 			      "memory input %d is not directly addressable",
   7256 			      i);
   7257 		  prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
   7258 		}
   7259 	    }
   7260 	  mark_addressable (TREE_VALUE (link));
   7261 	  if (tret == GS_ERROR)
   7262 	    {
   7263 	      if (inputv != error_mark_node)
   7264 		error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
   7265 			  "memory input %d is not directly addressable", i);
   7266 	      ret = tret;
   7267 	    }
   7268 	}
   7269       else
   7270 	{
   7271 	  tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
   7272 				is_gimple_asm_val, fb_rvalue);
   7273 	  if (tret == GS_ERROR)
   7274 	    ret = tret;
   7275 	}
   7276 
   7277       TREE_CHAIN (link) = NULL_TREE;
   7278       vec_safe_push (inputs, link);
   7279     }
   7280 
   7281   link_next = NULL_TREE;
   7282   for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
   7283     {
   7284       link_next = TREE_CHAIN (link);
   7285       TREE_CHAIN (link) = NULL_TREE;
   7286       vec_safe_push (clobbers, link);
   7287     }
   7288 
   7289   link_next = NULL_TREE;
   7290   for (link = ASM_LABELS (expr); link; ++i, link = link_next)
   7291     {
   7292       link_next = TREE_CHAIN (link);
   7293       TREE_CHAIN (link) = NULL_TREE;
   7294       vec_safe_push (labels, link);
   7295     }
   7296 
   7297   /* Do not add ASMs with errors to the gimple IL stream.  */
   7298   if (ret != GS_ERROR)
   7299     {
   7300       stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
   7301 				   inputs, outputs, clobbers, labels);
   7302 
   7303       /* asm is volatile if it was marked by the user as volatile or
   7304 	 there are no outputs or this is an asm goto.  */
   7305       gimple_asm_set_volatile (stmt,
   7306 			       ASM_VOLATILE_P (expr)
   7307 			       || noutputs == 0
   7308 			       || labels);
   7309       gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
   7310       gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
   7311 
   7312       gimplify_seq_add_stmt (pre_p, stmt);
   7313     }
   7314 
   7315   return ret;
   7316 }
   7317 
   7318 /* Gimplify a CLEANUP_POINT_EXPR.  Currently this works by adding
   7319    GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
   7320    gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
   7321    return to this function.
   7322 
   7323    FIXME should we complexify the prequeue handling instead?  Or use flags
   7324    for all the cleanups and let the optimizer tighten them up?  The current
   7325    code seems pretty fragile; it will break on a cleanup within any
   7326    non-conditional nesting.  But any such nesting would be broken, anyway;
   7327    we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
   7328    and continues out of it.  We can do that at the RTL level, though, so
   7329    having an optimizer to tighten up try/finally regions would be a Good
   7330    Thing.  */
   7331 
   7332 static enum gimplify_status
   7333 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
   7334 {
   7335   gimple_stmt_iterator iter;
   7336   gimple_seq body_sequence = NULL;
   7337 
   7338   tree temp = voidify_wrapper_expr (*expr_p, NULL);
   7339 
   7340   /* We only care about the number of conditions between the innermost
   7341      CLEANUP_POINT_EXPR and the cleanup.  So save and reset the count and
   7342      any cleanups collected outside the CLEANUP_POINT_EXPR.  */
   7343   int old_conds = gimplify_ctxp->conditions;
   7344   gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
   7345   bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
   7346   gimplify_ctxp->conditions = 0;
   7347   gimplify_ctxp->conditional_cleanups = NULL;
   7348   gimplify_ctxp->in_cleanup_point_expr = true;
   7349 
   7350   gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
   7351 
   7352   gimplify_ctxp->conditions = old_conds;
   7353   gimplify_ctxp->conditional_cleanups = old_cleanups;
   7354   gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
   7355 
   7356   for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
   7357     {
   7358       gimple *wce = gsi_stmt (iter);
   7359 
   7360       if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
   7361 	{
   7362 	  if (gsi_one_before_end_p (iter))
   7363 	    {
   7364               /* Note that gsi_insert_seq_before and gsi_remove do not
   7365                  scan operands, unlike some other sequence mutators.  */
   7366 	      if (!gimple_wce_cleanup_eh_only (wce))
   7367 		gsi_insert_seq_before_without_update (&iter,
   7368 						      gimple_wce_cleanup (wce),
   7369 						      GSI_SAME_STMT);
   7370 	      gsi_remove (&iter, true);
   7371 	      break;
   7372 	    }
   7373 	  else
   7374 	    {
   7375 	      gtry *gtry;
   7376 	      gimple_seq seq;
   7377 	      enum gimple_try_flags kind;
   7378 
   7379 	      if (gimple_wce_cleanup_eh_only (wce))
   7380 		kind = GIMPLE_TRY_CATCH;
   7381 	      else
   7382 		kind = GIMPLE_TRY_FINALLY;
   7383 	      seq = gsi_split_seq_after (iter);
   7384 
   7385 	      gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
   7386               /* Do not use gsi_replace here, as it may scan operands.
   7387                  We want to do a simple structural modification only.  */
   7388 	      gsi_set_stmt (&iter, gtry);
   7389 	      iter = gsi_start (gtry->eval);
   7390 	    }
   7391 	}
   7392       else
   7393 	gsi_next (&iter);
   7394     }
   7395 
   7396   gimplify_seq_add_seq (pre_p, body_sequence);
   7397   if (temp)
   7398     {
   7399       *expr_p = temp;
   7400       return GS_OK;
   7401     }
   7402   else
   7403     {
   7404       *expr_p = NULL;
   7405       return GS_ALL_DONE;
   7406     }
   7407 }
   7408 
   7409 /* Insert a cleanup marker for gimplify_cleanup_point_expr.  CLEANUP
   7410    is the cleanup action required.  EH_ONLY is true if the cleanup should
   7411    only be executed if an exception is thrown, not on normal exit.
   7412    If FORCE_UNCOND is true perform the cleanup unconditionally;  this is
   7413    only valid for clobbers.  */
   7414 
   7415 static void
   7416 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
   7417 		     bool force_uncond = false)
   7418 {
   7419   gimple *wce;
   7420   gimple_seq cleanup_stmts = NULL;
   7421 
   7422   /* Errors can result in improperly nested cleanups.  Which results in
   7423      confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR.  */
   7424   if (seen_error ())
   7425     return;
   7426 
   7427   if (gimple_conditional_context ())
   7428     {
   7429       /* If we're in a conditional context, this is more complex.  We only
   7430 	 want to run the cleanup if we actually ran the initialization that
   7431 	 necessitates it, but we want to run it after the end of the
   7432 	 conditional context.  So we wrap the try/finally around the
   7433 	 condition and use a flag to determine whether or not to actually
   7434 	 run the destructor.  Thus
   7435 
   7436 	   test ? f(A()) : 0
   7437 
   7438 	 becomes (approximately)
   7439 
   7440 	   flag = 0;
   7441 	   try {
   7442 	     if (test) { A::A(temp); flag = 1; val = f(temp); }
   7443 	     else { val = 0; }
   7444 	   } finally {
   7445 	     if (flag) A::~A(temp);
   7446 	   }
   7447 	   val
   7448       */
   7449       if (force_uncond)
   7450 	{
   7451 	  gimplify_stmt (&cleanup, &cleanup_stmts);
   7452 	  wce = gimple_build_wce (cleanup_stmts);
   7453 	  gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
   7454 	}
   7455       else
   7456 	{
   7457 	  tree flag = create_tmp_var (boolean_type_node, "cleanup");
   7458 	  gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
   7459 	  gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
   7460 
   7461 	  cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
   7462 	  gimplify_stmt (&cleanup, &cleanup_stmts);
   7463 	  wce = gimple_build_wce (cleanup_stmts);
   7464 	  gimple_wce_set_cleanup_eh_only (wce, eh_only);
   7465 
   7466 	  gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
   7467 	  gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
   7468 	  gimplify_seq_add_stmt (pre_p, ftrue);
   7469 
   7470 	  /* Because of this manipulation, and the EH edges that jump
   7471 	     threading cannot redirect, the temporary (VAR) will appear
   7472 	     to be used uninitialized.  Don't warn.  */
   7473 	  suppress_warning (var, OPT_Wuninitialized);
   7474 	}
   7475     }
   7476   else
   7477     {
   7478       gimplify_stmt (&cleanup, &cleanup_stmts);
   7479       wce = gimple_build_wce (cleanup_stmts);
   7480       gimple_wce_set_cleanup_eh_only (wce, eh_only);
   7481       gimplify_seq_add_stmt (pre_p, wce);
   7482     }
   7483 }
   7484 
   7485 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR.  */
   7486 
   7487 static enum gimplify_status
   7488 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
   7489 {
   7490   tree targ = *expr_p;
   7491   tree temp = TARGET_EXPR_SLOT (targ);
   7492   tree init = TARGET_EXPR_INITIAL (targ);
   7493   enum gimplify_status ret;
   7494 
   7495   bool unpoison_empty_seq = false;
   7496   gimple_stmt_iterator unpoison_it;
   7497 
   7498   if (init)
   7499     {
   7500       gimple_seq init_pre_p = NULL;
   7501 
   7502       /* TARGET_EXPR temps aren't part of the enclosing block, so add it
   7503 	 to the temps list.  Handle also variable length TARGET_EXPRs.  */
   7504       if (!poly_int_tree_p (DECL_SIZE (temp)))
   7505 	{
   7506 	  if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
   7507 	    gimplify_type_sizes (TREE_TYPE (temp), &init_pre_p);
   7508 	  /* FIXME: this is correct only when the size of the type does
   7509 	     not depend on expressions evaluated in init.  */
   7510 	  gimplify_vla_decl (temp, &init_pre_p);
   7511 	}
   7512       else
   7513 	{
   7514 	  /* Save location where we need to place unpoisoning.  It's possible
   7515 	     that a variable will be converted to needs_to_live_in_memory.  */
   7516 	  unpoison_it = gsi_last (*pre_p);
   7517 	  unpoison_empty_seq = gsi_end_p (unpoison_it);
   7518 
   7519 	  gimple_add_tmp_var (temp);
   7520 	}
   7521 
   7522       /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
   7523 	 expression is supposed to initialize the slot.  */
   7524       if (VOID_TYPE_P (TREE_TYPE (init)))
   7525 	ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
   7526 			     fb_none);
   7527       else
   7528 	{
   7529 	  tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
   7530 	  init = init_expr;
   7531 	  ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
   7532 			       fb_none);
   7533 	  init = NULL;
   7534 	  ggc_free (init_expr);
   7535 	}
   7536       if (ret == GS_ERROR)
   7537 	{
   7538 	  /* PR c++/28266 Make sure this is expanded only once. */
   7539 	  TARGET_EXPR_INITIAL (targ) = NULL_TREE;
   7540 	  return GS_ERROR;
   7541 	}
   7542 
   7543       if (init)
   7544 	gimplify_and_add (init, &init_pre_p);
   7545 
   7546       /* Add a clobber for the temporary going out of scope, like
   7547 	 gimplify_bind_expr.  But only if we did not promote the
   7548 	 temporary to static storage.  */
   7549       if (gimplify_ctxp->in_cleanup_point_expr
   7550 	  && !TREE_STATIC (temp)
   7551 	  && needs_to_live_in_memory (temp))
   7552 	{
   7553 	  if (flag_stack_reuse == SR_ALL)
   7554 	    {
   7555 	      tree clobber = build_clobber (TREE_TYPE (temp),
   7556 					    CLOBBER_STORAGE_END);
   7557 	      clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
   7558 	      gimple_push_cleanup (temp, clobber, false, pre_p, true);
   7559 	    }
   7560 	  if (asan_poisoned_variables
   7561 	      && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
   7562 	      && !TREE_STATIC (temp)
   7563 	      && dbg_cnt (asan_use_after_scope)
   7564 	      && !gimplify_omp_ctxp)
   7565 	    {
   7566 	      tree asan_cleanup = build_asan_poison_call_expr (temp);
   7567 	      if (asan_cleanup)
   7568 		{
   7569 		  if (unpoison_empty_seq)
   7570 		    unpoison_it = gsi_start (*pre_p);
   7571 
   7572 		  asan_poison_variable (temp, false, &unpoison_it,
   7573 					unpoison_empty_seq);
   7574 		  gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
   7575 		}
   7576 	    }
   7577 	}
   7578 
   7579       gimple_seq_add_seq (pre_p, init_pre_p);
   7580 
   7581       /* If needed, push the cleanup for the temp.  */
   7582       if (TARGET_EXPR_CLEANUP (targ))
   7583 	gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
   7584 			     CLEANUP_EH_ONLY (targ), pre_p);
   7585 
   7586       /* Only expand this once.  */
   7587       TREE_OPERAND (targ, 3) = init;
   7588       TARGET_EXPR_INITIAL (targ) = NULL_TREE;
   7589     }
   7590   else
   7591     /* We should have expanded this before.  */
   7592     gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
   7593 
   7594   *expr_p = temp;
   7595   return GS_OK;
   7596 }
   7597 
   7598 /* Gimplification of expression trees.  */
   7599 
   7600 /* Gimplify an expression which appears at statement context.  The
   7601    corresponding GIMPLE statements are added to *SEQ_P.  If *SEQ_P is
   7602    NULL, a new sequence is allocated.
   7603 
   7604    Return true if we actually added a statement to the queue.  */
   7605 
   7606 bool
   7607 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
   7608 {
   7609   gimple_seq_node last;
   7610 
   7611   last = gimple_seq_last (*seq_p);
   7612   gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
   7613   return last != gimple_seq_last (*seq_p);
   7614 }
   7615 
   7616 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
   7617    to CTX.  If entries already exist, force them to be some flavor of private.
   7618    If there is no enclosing parallel, do nothing.  */
   7619 
   7620 void
   7621 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
   7622 {
   7623   splay_tree_node n;
   7624 
   7625   if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
   7626     return;
   7627 
   7628   do
   7629     {
   7630       n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
   7631       if (n != NULL)
   7632 	{
   7633 	  if (n->value & GOVD_SHARED)
   7634 	    n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
   7635 	  else if (n->value & GOVD_MAP)
   7636 	    n->value |= GOVD_MAP_TO_ONLY;
   7637 	  else
   7638 	    return;
   7639 	}
   7640       else if ((ctx->region_type & ORT_TARGET) != 0)
   7641 	{
   7642 	  if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
   7643 	    omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
   7644 	  else
   7645 	    omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
   7646 	}
   7647       else if (ctx->region_type != ORT_WORKSHARE
   7648 	       && ctx->region_type != ORT_TASKGROUP
   7649 	       && ctx->region_type != ORT_SIMD
   7650 	       && ctx->region_type != ORT_ACC
   7651 	       && !(ctx->region_type & ORT_TARGET_DATA))
   7652 	omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
   7653 
   7654       ctx = ctx->outer_context;
   7655     }
   7656   while (ctx);
   7657 }
   7658 
   7659 /* Similarly for each of the type sizes of TYPE.  */
   7660 
   7661 static void
   7662 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
   7663 {
   7664   if (type == NULL || type == error_mark_node)
   7665     return;
   7666   type = TYPE_MAIN_VARIANT (type);
   7667 
   7668   if (ctx->privatized_types->add (type))
   7669     return;
   7670 
   7671   switch (TREE_CODE (type))
   7672     {
   7673     case INTEGER_TYPE:
   7674     case ENUMERAL_TYPE:
   7675     case BOOLEAN_TYPE:
   7676     case REAL_TYPE:
   7677     case FIXED_POINT_TYPE:
   7678       omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
   7679       omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
   7680       break;
   7681 
   7682     case ARRAY_TYPE:
   7683       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
   7684       omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
   7685       break;
   7686 
   7687     case RECORD_TYPE:
   7688     case UNION_TYPE:
   7689     case QUAL_UNION_TYPE:
   7690       {
   7691 	tree field;
   7692 	for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
   7693 	  if (TREE_CODE (field) == FIELD_DECL)
   7694 	    {
   7695 	      omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
   7696 	      omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
   7697 	    }
   7698       }
   7699       break;
   7700 
   7701     case POINTER_TYPE:
   7702     case REFERENCE_TYPE:
   7703       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
   7704       break;
   7705 
   7706     default:
   7707       break;
   7708     }
   7709 
   7710   omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
   7711   omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
   7712   lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
   7713 }
   7714 
   7715 /* Add an entry for DECL in the OMP context CTX with FLAGS.  */
   7716 
   7717 static void
   7718 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
   7719 {
   7720   splay_tree_node n;
   7721   unsigned int nflags;
   7722   tree t;
   7723 
   7724   if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
   7725     return;
   7726 
   7727   /* Never elide decls whose type has TREE_ADDRESSABLE set.  This means
   7728      there are constructors involved somewhere.  Exception is a shared clause,
   7729      there is nothing privatized in that case.  */
   7730   if ((flags & GOVD_SHARED) == 0
   7731       && (TREE_ADDRESSABLE (TREE_TYPE (decl))
   7732 	  || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
   7733     flags |= GOVD_SEEN;
   7734 
   7735   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
   7736   if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
   7737     {
   7738       /* We shouldn't be re-adding the decl with the same data
   7739 	 sharing class.  */
   7740       gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
   7741       nflags = n->value | flags;
   7742       /* The only combination of data sharing classes we should see is
   7743 	 FIRSTPRIVATE and LASTPRIVATE.  However, OpenACC permits
   7744 	 reduction variables to be used in data sharing clauses.  */
   7745       gcc_assert ((ctx->region_type & ORT_ACC) != 0
   7746 		  || ((nflags & GOVD_DATA_SHARE_CLASS)
   7747 		      == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
   7748 		  || (flags & GOVD_DATA_SHARE_CLASS) == 0);
   7749       n->value = nflags;
   7750       return;
   7751     }
   7752 
   7753   /* When adding a variable-sized variable, we have to handle all sorts
   7754      of additional bits of data: the pointer replacement variable, and
   7755      the parameters of the type.  */
   7756   if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
   7757     {
   7758       /* Add the pointer replacement variable as PRIVATE if the variable
   7759 	 replacement is private, else FIRSTPRIVATE since we'll need the
   7760 	 address of the original variable either for SHARED, or for the
   7761 	 copy into or out of the context.  */
   7762       if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
   7763 	{
   7764 	  if (flags & GOVD_MAP)
   7765 	    nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
   7766 	  else if (flags & GOVD_PRIVATE)
   7767 	    nflags = GOVD_PRIVATE;
   7768 	  else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
   7769 		    && (flags & GOVD_FIRSTPRIVATE))
   7770 		   || (ctx->region_type == ORT_TARGET_DATA
   7771 		       && (flags & GOVD_DATA_SHARE_CLASS) == 0))
   7772 	    nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
   7773 	  else
   7774 	    nflags = GOVD_FIRSTPRIVATE;
   7775 	  nflags |= flags & GOVD_SEEN;
   7776 	  t = DECL_VALUE_EXPR (decl);
   7777 	  gcc_assert (INDIRECT_REF_P (t));
   7778 	  t = TREE_OPERAND (t, 0);
   7779 	  gcc_assert (DECL_P (t));
   7780 	  omp_add_variable (ctx, t, nflags);
   7781 	}
   7782 
   7783       /* Add all of the variable and type parameters (which should have
   7784 	 been gimplified to a formal temporary) as FIRSTPRIVATE.  */
   7785       omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
   7786       omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
   7787       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
   7788 
   7789       /* The variable-sized variable itself is never SHARED, only some form
   7790 	 of PRIVATE.  The sharing would take place via the pointer variable
   7791 	 which we remapped above.  */
   7792       if (flags & GOVD_SHARED)
   7793 	flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
   7794 		| (flags & (GOVD_SEEN | GOVD_EXPLICIT));
   7795 
   7796       /* We're going to make use of the TYPE_SIZE_UNIT at least in the
   7797 	 alloca statement we generate for the variable, so make sure it
   7798 	 is available.  This isn't automatically needed for the SHARED
   7799 	 case, since we won't be allocating local storage then.
   7800 	 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
   7801 	 in this case omp_notice_variable will be called later
   7802 	 on when it is gimplified.  */
   7803       else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
   7804 	       && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
   7805 	omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
   7806     }
   7807   else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
   7808 	   && omp_privatize_by_reference (decl))
   7809     {
   7810       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
   7811 
   7812       /* Similar to the direct variable sized case above, we'll need the
   7813 	 size of references being privatized.  */
   7814       if ((flags & GOVD_SHARED) == 0)
   7815 	{
   7816 	  t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
   7817 	  if (t && DECL_P (t))
   7818 	    omp_notice_variable (ctx, t, true);
   7819 	}
   7820     }
   7821 
   7822   if (n != NULL)
   7823     n->value |= flags;
   7824   else
   7825     splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
   7826 
   7827   /* For reductions clauses in OpenACC loop directives, by default create a
   7828      copy clause on the enclosing parallel construct for carrying back the
   7829      results.  */
   7830   if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
   7831     {
   7832       struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
   7833       while (outer_ctx)
   7834 	{
   7835 	  n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
   7836 	  if (n != NULL)
   7837 	    {
   7838 	      /* Ignore local variables and explicitly declared clauses.  */
   7839 	      if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
   7840 		break;
   7841 	      else if (outer_ctx->region_type == ORT_ACC_KERNELS)
   7842 		{
   7843 		  /* According to the OpenACC spec, such a reduction variable
   7844 		     should already have a copy map on a kernels construct,
   7845 		     verify that here.  */
   7846 		  gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
   7847 			      && (n->value & GOVD_MAP));
   7848 		}
   7849 	      else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
   7850 		{
   7851 		  /* Remove firstprivate and make it a copy map.  */
   7852 		  n->value &= ~GOVD_FIRSTPRIVATE;
   7853 		  n->value |= GOVD_MAP;
   7854 		}
   7855 	    }
   7856 	  else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
   7857 	    {
   7858 	      splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
   7859 				 GOVD_MAP | GOVD_SEEN);
   7860 	      break;
   7861 	    }
   7862 	  outer_ctx = outer_ctx->outer_context;
   7863 	}
   7864     }
   7865 }
   7866 
   7867 /* Notice a threadprivate variable DECL used in OMP context CTX.
   7868    This just prints out diagnostics about threadprivate variable uses
   7869    in untied tasks.  If DECL2 is non-NULL, prevent this warning
   7870    on that variable.  */
   7871 
   7872 static bool
   7873 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
   7874 				   tree decl2)
   7875 {
   7876   splay_tree_node n;
   7877   struct gimplify_omp_ctx *octx;
   7878 
   7879   for (octx = ctx; octx; octx = octx->outer_context)
   7880     if ((octx->region_type & ORT_TARGET) != 0
   7881 	|| octx->order_concurrent)
   7882       {
   7883 	n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
   7884 	if (n == NULL)
   7885 	  {
   7886 	    if (octx->order_concurrent)
   7887 	      {
   7888 		error ("threadprivate variable %qE used in a region with"
   7889 		       " %<order(concurrent)%> clause", DECL_NAME (decl));
   7890 		inform (octx->location, "enclosing region");
   7891 	      }
   7892 	    else
   7893 	      {
   7894 		error ("threadprivate variable %qE used in target region",
   7895 		       DECL_NAME (decl));
   7896 		inform (octx->location, "enclosing target region");
   7897 	      }
   7898 	    splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
   7899 	  }
   7900 	if (decl2)
   7901 	  splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
   7902       }
   7903 
   7904   if (ctx->region_type != ORT_UNTIED_TASK)
   7905     return false;
   7906   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
   7907   if (n == NULL)
   7908     {
   7909       error ("threadprivate variable %qE used in untied task",
   7910 	     DECL_NAME (decl));
   7911       inform (ctx->location, "enclosing task");
   7912       splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
   7913     }
   7914   if (decl2)
   7915     splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
   7916   return false;
   7917 }
   7918 
   7919 /* Return true if global var DECL is device resident.  */
   7920 
   7921 static bool
   7922 device_resident_p (tree decl)
   7923 {
   7924   tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
   7925 
   7926   if (!attr)
   7927     return false;
   7928 
   7929   for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
   7930     {
   7931       tree c = TREE_VALUE (t);
   7932       if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
   7933 	return true;
   7934     }
   7935 
   7936   return false;
   7937 }
   7938 
   7939 /* Return true if DECL has an ACC DECLARE attribute.  */
   7940 
   7941 static bool
   7942 is_oacc_declared (tree decl)
   7943 {
   7944   tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
   7945   tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
   7946   return declared != NULL_TREE;
   7947 }
   7948 
   7949 /* Determine outer default flags for DECL mentioned in an OMP region
   7950    but not declared in an enclosing clause.
   7951 
   7952    ??? Some compiler-generated variables (like SAVE_EXPRs) could be
   7953    remapped firstprivate instead of shared.  To some extent this is
   7954    addressed in omp_firstprivatize_type_sizes, but not
   7955    effectively.  */
   7956 
   7957 static unsigned
   7958 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
   7959 		    bool in_code, unsigned flags)
   7960 {
   7961   enum omp_clause_default_kind default_kind = ctx->default_kind;
   7962   enum omp_clause_default_kind kind;
   7963 
   7964   kind = lang_hooks.decls.omp_predetermined_sharing (decl);
   7965   if (ctx->region_type & ORT_TASK)
   7966     {
   7967       tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH);
   7968 
   7969       /* The event-handle specified by a detach clause should always be firstprivate,
   7970 	 regardless of the current default.  */
   7971       if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl)
   7972 	kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
   7973     }
   7974   if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
   7975     default_kind = kind;
   7976   else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
   7977     default_kind = OMP_CLAUSE_DEFAULT_SHARED;
   7978   /* For C/C++ default({,first}private), variables with static storage duration
   7979      declared in a namespace or global scope and referenced in construct
   7980      must be explicitly specified, i.e. acts as default(none).  */
   7981   else if ((default_kind == OMP_CLAUSE_DEFAULT_PRIVATE
   7982 	    || default_kind == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
   7983 	   && VAR_P (decl)
   7984 	   && is_global_var (decl)
   7985 	   && (DECL_FILE_SCOPE_P (decl)
   7986 	       || (DECL_CONTEXT (decl)
   7987 		   && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
   7988 	   && !lang_GNU_Fortran ())
   7989     default_kind = OMP_CLAUSE_DEFAULT_NONE;
   7990 
   7991   switch (default_kind)
   7992     {
   7993     case OMP_CLAUSE_DEFAULT_NONE:
   7994       {
   7995 	const char *rtype;
   7996 
   7997 	if (ctx->region_type & ORT_PARALLEL)
   7998 	  rtype = "parallel";
   7999 	else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
   8000 	  rtype = "taskloop";
   8001 	else if (ctx->region_type & ORT_TASK)
   8002 	  rtype = "task";
   8003 	else if (ctx->region_type & ORT_TEAMS)
   8004 	  rtype = "teams";
   8005 	else
   8006 	  gcc_unreachable ();
   8007 
   8008 	error ("%qE not specified in enclosing %qs",
   8009 	       DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
   8010 	inform (ctx->location, "enclosing %qs", rtype);
   8011       }
   8012       /* FALLTHRU */
   8013     case OMP_CLAUSE_DEFAULT_SHARED:
   8014       flags |= GOVD_SHARED;
   8015       break;
   8016     case OMP_CLAUSE_DEFAULT_PRIVATE:
   8017       flags |= GOVD_PRIVATE;
   8018       break;
   8019     case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
   8020       flags |= GOVD_FIRSTPRIVATE;
   8021       break;
   8022     case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
   8023       /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED.  */
   8024       gcc_assert ((ctx->region_type & ORT_TASK) != 0);
   8025       if (struct gimplify_omp_ctx *octx = ctx->outer_context)
   8026 	{
   8027 	  omp_notice_variable (octx, decl, in_code);
   8028 	  for (; octx; octx = octx->outer_context)
   8029 	    {
   8030 	      splay_tree_node n2;
   8031 
   8032 	      n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
   8033 	      if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
   8034 		  && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
   8035 		continue;
   8036 	      if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
   8037 		{
   8038 		  flags |= GOVD_FIRSTPRIVATE;
   8039 		  goto found_outer;
   8040 		}
   8041 	      if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
   8042 		{
   8043 		  flags |= GOVD_SHARED;
   8044 		  goto found_outer;
   8045 		}
   8046 	    }
   8047 	}
   8048 
   8049       if (TREE_CODE (decl) == PARM_DECL
   8050 	  || (!is_global_var (decl)
   8051 	      && DECL_CONTEXT (decl) == current_function_decl))
   8052 	flags |= GOVD_FIRSTPRIVATE;
   8053       else
   8054 	flags |= GOVD_SHARED;
   8055     found_outer:
   8056       break;
   8057 
   8058     default:
   8059       gcc_unreachable ();
   8060     }
   8061 
   8062   return flags;
   8063 }
   8064 
   8065 /* Return string name for types of OpenACC constructs from ORT_* values.  */
   8066 
   8067 static const char *
   8068 oacc_region_type_name (enum omp_region_type region_type)
   8069 {
   8070   switch (region_type)
   8071     {
   8072     case ORT_ACC_DATA:
   8073       return "data";
   8074     case ORT_ACC_PARALLEL:
   8075       return "parallel";
   8076     case ORT_ACC_KERNELS:
   8077       return "kernels";
   8078     case ORT_ACC_SERIAL:
   8079       return "serial";
   8080     default:
   8081       gcc_unreachable ();
   8082     }
   8083 }
   8084 
   8085 /* Determine outer default flags for DECL mentioned in an OACC region
   8086    but not declared in an enclosing clause.  */
   8087 
   8088 static unsigned
   8089 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
   8090 {
   8091   struct gimplify_omp_ctx *ctx_default = ctx;
   8092   /* If no 'default' clause appears on this compute construct...  */
   8093   if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_SHARED)
   8094     {
   8095       /* ..., see if one appears on a lexically containing 'data'
   8096 	 construct.  */
   8097       while ((ctx_default = ctx_default->outer_context))
   8098 	{
   8099 	  if (ctx_default->region_type == ORT_ACC_DATA
   8100 	      && ctx_default->default_kind != OMP_CLAUSE_DEFAULT_SHARED)
   8101 	    break;
   8102 	}
   8103       /* If not, reset.  */
   8104       if (!ctx_default)
   8105 	ctx_default = ctx;
   8106     }
   8107 
   8108   bool on_device = false;
   8109   bool is_private = false;
   8110   bool declared = is_oacc_declared (decl);
   8111   tree type = TREE_TYPE (decl);
   8112 
   8113   if (omp_privatize_by_reference (decl))
   8114     type = TREE_TYPE (type);
   8115 
   8116   /* For Fortran COMMON blocks, only used variables in those blocks are
   8117      transfered and remapped.  The block itself will have a private clause to
   8118      avoid transfering the data twice.
   8119      The hook evaluates to false by default.  For a variable in Fortran's COMMON
   8120      or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
   8121      the variables in such a COMMON/EQUIVALENCE block shall be privatized not
   8122      the whole block.  For C++ and Fortran, it can also be true under certain
   8123      other conditions, if DECL_HAS_VALUE_EXPR.  */
   8124   if (RECORD_OR_UNION_TYPE_P (type))
   8125     is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
   8126 
   8127   if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
   8128       && is_global_var (decl)
   8129       && device_resident_p (decl)
   8130       && !is_private)
   8131     {
   8132       on_device = true;
   8133       flags |= GOVD_MAP_TO_ONLY;
   8134     }
   8135 
   8136   switch (ctx->region_type)
   8137     {
   8138     case ORT_ACC_KERNELS:
   8139       if (is_private)
   8140 	flags |= GOVD_FIRSTPRIVATE;
   8141       else if (AGGREGATE_TYPE_P (type))
   8142 	{
   8143 	  /* Aggregates default to 'present_or_copy', or 'present'.  */
   8144 	  if (ctx_default->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
   8145 	    flags |= GOVD_MAP;
   8146 	  else
   8147 	    flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
   8148 	}
   8149       else
   8150 	/* Scalars default to 'copy'.  */
   8151 	flags |= GOVD_MAP | GOVD_MAP_FORCE;
   8152 
   8153       break;
   8154 
   8155     case ORT_ACC_PARALLEL:
   8156     case ORT_ACC_SERIAL:
   8157       if (is_private)
   8158 	flags |= GOVD_FIRSTPRIVATE;
   8159       else if (on_device || declared)
   8160 	flags |= GOVD_MAP;
   8161       else if (AGGREGATE_TYPE_P (type))
   8162 	{
   8163 	  /* Aggregates default to 'present_or_copy', or 'present'.  */
   8164 	  if (ctx_default->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
   8165 	    flags |= GOVD_MAP;
   8166 	  else
   8167 	    flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
   8168 	}
   8169       else
   8170 	/* Scalars default to 'firstprivate'.  */
   8171 	flags |= GOVD_FIRSTPRIVATE;
   8172 
   8173       break;
   8174 
   8175     default:
   8176       gcc_unreachable ();
   8177     }
   8178 
   8179   if (DECL_ARTIFICIAL (decl))
   8180     ; /* We can get compiler-generated decls, and should not complain
   8181 	 about them.  */
   8182   else if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_NONE)
   8183     {
   8184       error ("%qE not specified in enclosing OpenACC %qs construct",
   8185 	     DECL_NAME (lang_hooks.decls.omp_report_decl (decl)),
   8186 	     oacc_region_type_name (ctx->region_type));
   8187       if (ctx_default != ctx)
   8188 	inform (ctx->location, "enclosing OpenACC %qs construct and",
   8189 		oacc_region_type_name (ctx->region_type));
   8190       inform (ctx_default->location,
   8191 	      "enclosing OpenACC %qs construct with %qs clause",
   8192 	      oacc_region_type_name (ctx_default->region_type),
   8193 	      "default(none)");
   8194     }
   8195   else if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
   8196     ; /* Handled above.  */
   8197   else
   8198     gcc_checking_assert (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
   8199 
   8200   return flags;
   8201 }
   8202 
   8203 /* Record the fact that DECL was used within the OMP context CTX.
   8204    IN_CODE is true when real code uses DECL, and false when we should
   8205    merely emit default(none) errors.  Return true if DECL is going to
   8206    be remapped and thus DECL shouldn't be gimplified into its
   8207    DECL_VALUE_EXPR (if any).  */
   8208 
   8209 static bool
   8210 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
   8211 {
   8212   splay_tree_node n;
   8213   unsigned flags = in_code ? GOVD_SEEN : 0;
   8214   bool ret = false, shared;
   8215 
   8216   if (error_operand_p (decl))
   8217     return false;
   8218 
   8219   if (DECL_ARTIFICIAL (decl))
   8220     {
   8221       tree attr = lookup_attribute ("omp allocate var", DECL_ATTRIBUTES (decl));
   8222       if (attr)
   8223 	decl = TREE_VALUE (TREE_VALUE (attr));
   8224     }
   8225 
   8226   if (ctx->region_type == ORT_NONE)
   8227     return lang_hooks.decls.omp_disregard_value_expr (decl, false);
   8228 
   8229   if (is_global_var (decl))
   8230     {
   8231       /* Threadprivate variables are predetermined.  */
   8232       if (DECL_THREAD_LOCAL_P (decl))
   8233 	return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
   8234 
   8235       if (DECL_HAS_VALUE_EXPR_P (decl))
   8236 	{
   8237 	  if (ctx->region_type & ORT_ACC)
   8238 	    /* For OpenACC, defer expansion of value to avoid transfering
   8239 	       privatized common block data instead of im-/explicitly transfered
   8240 	       variables which are in common blocks.  */
   8241 	    ;
   8242 	  else
   8243 	    {
   8244 	      tree value = get_base_address (DECL_VALUE_EXPR (decl));
   8245 
   8246 	      if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
   8247 		return omp_notice_threadprivate_variable (ctx, decl, value);
   8248 	    }
   8249 	}
   8250 
   8251       if (gimplify_omp_ctxp->outer_context == NULL
   8252 	  && VAR_P (decl)
   8253 	  && oacc_get_fn_attrib (current_function_decl))
   8254 	{
   8255 	  location_t loc = DECL_SOURCE_LOCATION (decl);
   8256 
   8257 	  if (lookup_attribute ("omp declare target link",
   8258 				DECL_ATTRIBUTES (decl)))
   8259 	    {
   8260 	      error_at (loc,
   8261 			"%qE with %<link%> clause used in %<routine%> function",
   8262 			DECL_NAME (decl));
   8263 	      return false;
   8264 	    }
   8265 	  else if (!lookup_attribute ("omp declare target",
   8266 				      DECL_ATTRIBUTES (decl)))
   8267 	    {
   8268 	      error_at (loc,
   8269 			"%qE requires a %<declare%> directive for use "
   8270 			"in a %<routine%> function", DECL_NAME (decl));
   8271 	      return false;
   8272 	    }
   8273 	}
   8274     }
   8275 
   8276   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
   8277   if ((ctx->region_type & ORT_TARGET) != 0)
   8278     {
   8279       if (n == NULL)
   8280 	{
   8281 	  unsigned nflags = flags;
   8282 	  if ((ctx->region_type & ORT_ACC) == 0)
   8283 	    {
   8284 	      bool is_declare_target = false;
   8285 	      if (is_global_var (decl)
   8286 		  && varpool_node::get_create (decl)->offloadable)
   8287 		{
   8288 		  struct gimplify_omp_ctx *octx;
   8289 		  for (octx = ctx->outer_context;
   8290 		       octx; octx = octx->outer_context)
   8291 		    {
   8292 		      n = splay_tree_lookup (octx->variables,
   8293 					     (splay_tree_key)decl);
   8294 		      if (n
   8295 			  && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
   8296 			  && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
   8297 			break;
   8298 		    }
   8299 		  is_declare_target = octx == NULL;
   8300 		}
   8301 	      if (!is_declare_target)
   8302 		{
   8303 		  int gdmk;
   8304 		  enum omp_clause_defaultmap_kind kind;
   8305 		  if (lang_hooks.decls.omp_allocatable_p (decl))
   8306 		    gdmk = GDMK_ALLOCATABLE;
   8307 		  else if (lang_hooks.decls.omp_scalar_target_p (decl))
   8308 		    gdmk = GDMK_SCALAR_TARGET;
   8309 		  else if (lang_hooks.decls.omp_scalar_p (decl, false))
   8310 		    gdmk = GDMK_SCALAR;
   8311 		  else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
   8312 			   || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
   8313 			       && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
   8314 				   == POINTER_TYPE)))
   8315 		    gdmk = GDMK_POINTER;
   8316 		  else
   8317 		    gdmk = GDMK_AGGREGATE;
   8318 		  kind = lang_hooks.decls.omp_predetermined_mapping (decl);
   8319 		  if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
   8320 		    {
   8321 		      if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
   8322 			nflags |= GOVD_FIRSTPRIVATE;
   8323 		      else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
   8324 			nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
   8325 		      else
   8326 			gcc_unreachable ();
   8327 		    }
   8328 		  else if (ctx->defaultmap[gdmk] == 0)
   8329 		    {
   8330 		      tree d = lang_hooks.decls.omp_report_decl (decl);
   8331 		      error ("%qE not specified in enclosing %<target%>",
   8332 			     DECL_NAME (d));
   8333 		      inform (ctx->location, "enclosing %<target%>");
   8334 		    }
   8335 		  else if (ctx->defaultmap[gdmk]
   8336 			   & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
   8337 		    nflags |= ctx->defaultmap[gdmk];
   8338 		  else if (ctx->defaultmap[gdmk] & GOVD_MAP_FORCE_PRESENT)
   8339 		    {
   8340 		      gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
   8341 		      nflags |= ctx->defaultmap[gdmk] | GOVD_MAP_ALLOC_ONLY;
   8342 		    }
   8343 		  else
   8344 		    {
   8345 		      gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
   8346 		      nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
   8347 		    }
   8348 		}
   8349 	    }
   8350 
   8351 	  struct gimplify_omp_ctx *octx = ctx->outer_context;
   8352 	  if ((ctx->region_type & ORT_ACC) && octx)
   8353 	    {
   8354 	      /* Look in outer OpenACC contexts, to see if there's a
   8355 		 data attribute for this variable.  */
   8356 	      omp_notice_variable (octx, decl, in_code);
   8357 
   8358 	      for (; octx; octx = octx->outer_context)
   8359 		{
   8360 		  if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
   8361 		    break;
   8362 		  splay_tree_node n2
   8363 		    = splay_tree_lookup (octx->variables,
   8364 					 (splay_tree_key) decl);
   8365 		  if (n2)
   8366 		    {
   8367 		      if (octx->region_type == ORT_ACC_HOST_DATA)
   8368 		        error ("variable %qE declared in enclosing "
   8369 			       "%<host_data%> region", DECL_NAME (decl));
   8370 		      nflags |= GOVD_MAP;
   8371 		      if (octx->region_type == ORT_ACC_DATA
   8372 			  && (n2->value & GOVD_MAP_0LEN_ARRAY))
   8373 			nflags |= GOVD_MAP_0LEN_ARRAY;
   8374 		      goto found_outer;
   8375 		    }
   8376 		}
   8377 	    }
   8378 
   8379 	  if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
   8380 			  | GOVD_MAP_ALLOC_ONLY)) == flags)
   8381 	    {
   8382 	      tree type = TREE_TYPE (decl);
   8383 
   8384 	      if (gimplify_omp_ctxp->target_firstprivatize_array_bases
   8385 		  && omp_privatize_by_reference (decl))
   8386 		type = TREE_TYPE (type);
   8387 	      if (!omp_mappable_type (type))
   8388 		{
   8389 		  error ("%qD referenced in target region does not have "
   8390 			 "a mappable type", decl);
   8391 		  nflags |= GOVD_MAP | GOVD_EXPLICIT;
   8392 		}
   8393 	      else
   8394 		{
   8395 		  if ((ctx->region_type & ORT_ACC) != 0)
   8396 		    nflags = oacc_default_clause (ctx, decl, flags);
   8397 		  else
   8398 		    nflags |= GOVD_MAP;
   8399 		}
   8400 	    }
   8401 	found_outer:
   8402 	  omp_add_variable (ctx, decl, nflags);
   8403 	  if (ctx->region_type & ORT_ACC)
   8404 	    /* For OpenACC, as remarked above, defer expansion.  */
   8405 	    shared = false;
   8406 	  else
   8407 	    shared = (nflags & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0;
   8408 	  ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
   8409 	}
   8410       else
   8411 	{
   8412 	  if (ctx->region_type & ORT_ACC)
   8413 	    /* For OpenACC, as remarked above, defer expansion.  */
   8414 	    shared = false;
   8415 	  else
   8416 	    shared = ((n->value | flags)
   8417 		      & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0;
   8418 	  ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
   8419 	  /* If nothing changed, there's nothing left to do.  */
   8420 	  if ((n->value & flags) == flags)
   8421 	    return ret;
   8422 	  flags |= n->value;
   8423 	  n->value = flags;
   8424 	}
   8425       goto do_outer;
   8426     }
   8427 
   8428   if (n == NULL)
   8429     {
   8430       if (ctx->region_type == ORT_WORKSHARE
   8431 	  || ctx->region_type == ORT_TASKGROUP
   8432 	  || ctx->region_type == ORT_SIMD
   8433 	  || ctx->region_type == ORT_ACC
   8434 	  || (ctx->region_type & ORT_TARGET_DATA) != 0)
   8435 	goto do_outer;
   8436 
   8437       flags = omp_default_clause (ctx, decl, in_code, flags);
   8438 
   8439       if ((flags & GOVD_PRIVATE)
   8440 	  && lang_hooks.decls.omp_private_outer_ref (decl))
   8441 	flags |= GOVD_PRIVATE_OUTER_REF;
   8442 
   8443       omp_add_variable (ctx, decl, flags);
   8444 
   8445       shared = (flags & GOVD_SHARED) != 0;
   8446       ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
   8447       goto do_outer;
   8448     }
   8449 
   8450   /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
   8451      lb, b or incr expressions, those shouldn't be turned into simd arrays.  */
   8452   if (ctx->region_type == ORT_SIMD
   8453       && ctx->in_for_exprs
   8454       && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
   8455 	  == GOVD_PRIVATE))
   8456     flags &= ~GOVD_SEEN;
   8457 
   8458   if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
   8459       && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
   8460       && DECL_SIZE (decl))
   8461     {
   8462       if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
   8463 	{
   8464 	  splay_tree_node n2;
   8465 	  tree t = DECL_VALUE_EXPR (decl);
   8466 	  gcc_assert (INDIRECT_REF_P (t));
   8467 	  t = TREE_OPERAND (t, 0);
   8468 	  gcc_assert (DECL_P (t));
   8469 	  n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
   8470 	  n2->value |= GOVD_SEEN;
   8471 	}
   8472       else if (omp_privatize_by_reference (decl)
   8473 	       && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
   8474 	       && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
   8475 		   != INTEGER_CST))
   8476 	{
   8477 	  splay_tree_node n2;
   8478 	  tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
   8479 	  gcc_assert (DECL_P (t));
   8480 	  n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
   8481 	  if (n2)
   8482 	    omp_notice_variable (ctx, t, true);
   8483 	}
   8484     }
   8485 
   8486   if (ctx->region_type & ORT_ACC)
   8487     /* For OpenACC, as remarked above, defer expansion.  */
   8488     shared = false;
   8489   else
   8490     shared = ((flags | n->value) & GOVD_SHARED) != 0;
   8491   ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
   8492 
   8493   /* If nothing changed, there's nothing left to do.  */
   8494   if ((n->value & flags) == flags)
   8495     return ret;
   8496   flags |= n->value;
   8497   n->value = flags;
   8498 
   8499  do_outer:
   8500   /* If the variable is private in the current context, then we don't
   8501      need to propagate anything to an outer context.  */
   8502   if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
   8503     return ret;
   8504   if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
   8505       == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
   8506     return ret;
   8507   if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
   8508 		| GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
   8509       == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
   8510     return ret;
   8511   if (ctx->outer_context
   8512       && omp_notice_variable (ctx->outer_context, decl, in_code))
   8513     return true;
   8514   return ret;
   8515 }
   8516 
   8517 /* Verify that DECL is private within CTX.  If there's specific information
   8518    to the contrary in the innermost scope, generate an error.  */
   8519 
   8520 static bool
   8521 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
   8522 {
   8523   splay_tree_node n;
   8524 
   8525   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
   8526   if (n != NULL)
   8527     {
   8528       if (n->value & GOVD_SHARED)
   8529 	{
   8530 	  if (ctx == gimplify_omp_ctxp)
   8531 	    {
   8532 	      if (simd)
   8533 		error ("iteration variable %qE is predetermined linear",
   8534 		       DECL_NAME (decl));
   8535 	      else
   8536 		error ("iteration variable %qE should be private",
   8537 		       DECL_NAME (decl));
   8538 	      n->value = GOVD_PRIVATE;
   8539 	      return true;
   8540 	    }
   8541 	  else
   8542 	    return false;
   8543 	}
   8544       else if ((n->value & GOVD_EXPLICIT) != 0
   8545 	       && (ctx == gimplify_omp_ctxp
   8546 		   || (ctx->region_type == ORT_COMBINED_PARALLEL
   8547 		       && gimplify_omp_ctxp->outer_context == ctx)))
   8548 	{
   8549 	  if ((n->value & GOVD_FIRSTPRIVATE) != 0)
   8550 	    error ("iteration variable %qE should not be firstprivate",
   8551 		   DECL_NAME (decl));
   8552 	  else if ((n->value & GOVD_REDUCTION) != 0)
   8553 	    error ("iteration variable %qE should not be reduction",
   8554 		   DECL_NAME (decl));
   8555 	  else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
   8556 	    error ("iteration variable %qE should not be linear",
   8557 		   DECL_NAME (decl));
   8558 	}
   8559       return (ctx == gimplify_omp_ctxp
   8560 	      || (ctx->region_type == ORT_COMBINED_PARALLEL
   8561 		  && gimplify_omp_ctxp->outer_context == ctx));
   8562     }
   8563 
   8564   if (ctx->region_type != ORT_WORKSHARE
   8565       && ctx->region_type != ORT_TASKGROUP
   8566       && ctx->region_type != ORT_SIMD
   8567       && ctx->region_type != ORT_ACC)
   8568     return false;
   8569   else if (ctx->outer_context)
   8570     return omp_is_private (ctx->outer_context, decl, simd);
   8571   return false;
   8572 }
   8573 
   8574 /* Return true if DECL is private within a parallel region
   8575    that binds to the current construct's context or in parallel
   8576    region's REDUCTION clause.  */
   8577 
   8578 static bool
   8579 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
   8580 {
   8581   splay_tree_node n;
   8582 
   8583   do
   8584     {
   8585       ctx = ctx->outer_context;
   8586       if (ctx == NULL)
   8587 	{
   8588 	  if (is_global_var (decl))
   8589 	    return false;
   8590 
   8591 	  /* References might be private, but might be shared too,
   8592 	     when checking for copyprivate, assume they might be
   8593 	     private, otherwise assume they might be shared.  */
   8594 	  if (copyprivate)
   8595 	    return true;
   8596 
   8597 	  if (omp_privatize_by_reference (decl))
   8598 	    return false;
   8599 
   8600 	  /* Treat C++ privatized non-static data members outside
   8601 	     of the privatization the same.  */
   8602 	  if (omp_member_access_dummy_var (decl))
   8603 	    return false;
   8604 
   8605 	  return true;
   8606 	}
   8607 
   8608       n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   8609 
   8610       if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
   8611 	  && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
   8612 	{
   8613 	  if ((ctx->region_type & ORT_TARGET_DATA) != 0
   8614 	      || n == NULL
   8615 	      || (n->value & GOVD_MAP) == 0)
   8616 	    continue;
   8617 	  return false;
   8618 	}
   8619 
   8620       if (n != NULL)
   8621 	{
   8622 	  if ((n->value & GOVD_LOCAL) != 0
   8623 	      && omp_member_access_dummy_var (decl))
   8624 	    return false;
   8625 	  return (n->value & GOVD_SHARED) == 0;
   8626 	}
   8627 
   8628       if (ctx->region_type == ORT_WORKSHARE
   8629 	  || ctx->region_type == ORT_TASKGROUP
   8630 	  || ctx->region_type == ORT_SIMD
   8631 	  || ctx->region_type == ORT_ACC)
   8632 	continue;
   8633 
   8634       break;
   8635     }
   8636   while (1);
   8637   return false;
   8638 }
   8639 
   8640 /* Callback for walk_tree to find a DECL_EXPR for the given DECL.  */
   8641 
   8642 static tree
   8643 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
   8644 {
   8645   tree t = *tp;
   8646 
   8647   /* If this node has been visited, unmark it and keep looking.  */
   8648   if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
   8649     return t;
   8650 
   8651   if (IS_TYPE_OR_DECL_P (t))
   8652     *walk_subtrees = 0;
   8653   return NULL_TREE;
   8654 }
   8655 
   8656 
   8657 /* Gimplify the affinity clause but effectively ignore it.
   8658    Generate:
   8659      var = begin;
   8660      if ((step > 1) ? var <= end : var > end)
   8661        locatator_var_expr;  */
   8662 
   8663 static void
   8664 gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p)
   8665 {
   8666   tree last_iter = NULL_TREE;
   8667   tree last_bind = NULL_TREE;
   8668   tree label = NULL_TREE;
   8669   tree *last_body = NULL;
   8670   for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
   8671     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
   8672       {
   8673 	tree t = OMP_CLAUSE_DECL (c);
   8674 	if (TREE_CODE (t) == TREE_LIST
   8675 		    && TREE_PURPOSE (t)
   8676 		    && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
   8677 	  {
   8678 	    if (TREE_VALUE (t) == null_pointer_node)
   8679 	      continue;
   8680 	    if (TREE_PURPOSE (t) != last_iter)
   8681 	      {
   8682 		if (last_bind)
   8683 		  {
   8684 		    append_to_statement_list (label, last_body);
   8685 		    gimplify_and_add (last_bind, pre_p);
   8686 		    last_bind = NULL_TREE;
   8687 		  }
   8688 		for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
   8689 		  {
   8690 		    if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
   8691 				       is_gimple_val, fb_rvalue) == GS_ERROR
   8692 			|| gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
   8693 					  is_gimple_val, fb_rvalue) == GS_ERROR
   8694 			|| gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
   8695 					  is_gimple_val, fb_rvalue) == GS_ERROR
   8696 			|| (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
   8697 					   is_gimple_val, fb_rvalue)
   8698 			    == GS_ERROR))
   8699 		      return;
   8700 		  }
   8701 	    last_iter = TREE_PURPOSE (t);
   8702 	    tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
   8703 	    last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
   8704 				NULL, block);
   8705 	    last_body = &BIND_EXPR_BODY (last_bind);
   8706 	    tree cond = NULL_TREE;
   8707 	    location_t loc = OMP_CLAUSE_LOCATION (c);
   8708 	    for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
   8709 	      {
   8710 		tree var = TREE_VEC_ELT (it, 0);
   8711 		tree begin = TREE_VEC_ELT (it, 1);
   8712 		tree end = TREE_VEC_ELT (it, 2);
   8713 		tree step = TREE_VEC_ELT (it, 3);
   8714 		loc = DECL_SOURCE_LOCATION (var);
   8715 		tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
   8716 				       var, begin);
   8717 		append_to_statement_list_force (tem, last_body);
   8718 
   8719 		tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
   8720 			       step, build_zero_cst (TREE_TYPE (step)));
   8721 		tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node,
   8722 					      var, end);
   8723 		tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
   8724 					      var, end);
   8725 		cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node,
   8726 					 cond1, cond2, cond3);
   8727 		if (cond)
   8728 		  cond = fold_build2_loc (loc, TRUTH_AND_EXPR,
   8729 					  boolean_type_node, cond, cond1);
   8730 		else
   8731 		  cond = cond1;
   8732 	      }
   8733 	    tree cont_label = create_artificial_label (loc);
   8734 	    label = build1 (LABEL_EXPR, void_type_node, cont_label);
   8735 	    tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
   8736 					void_node,
   8737 					build_and_jump (&cont_label));
   8738 	    append_to_statement_list_force (tem, last_body);
   8739 	      }
   8740 	    if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
   8741 	      {
   8742 		append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0),
   8743 					  last_body);
   8744 		TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
   8745 	      }
   8746 	    if (error_operand_p (TREE_VALUE (t)))
   8747 	      return;
   8748 	    append_to_statement_list_force (TREE_VALUE (t), last_body);
   8749 	    TREE_VALUE (t) = null_pointer_node;
   8750 	  }
   8751 	else
   8752 	  {
   8753 	    if (last_bind)
   8754 	      {
   8755 		append_to_statement_list (label, last_body);
   8756 		gimplify_and_add (last_bind, pre_p);
   8757 		last_bind = NULL_TREE;
   8758 	      }
   8759 	    if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
   8760 	      {
   8761 		gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
   8762 			       NULL, is_gimple_val, fb_rvalue);
   8763 		OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
   8764 	      }
   8765 	    if (error_operand_p (OMP_CLAUSE_DECL (c)))
   8766 	      return;
   8767 	    if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
   8768 			       is_gimple_lvalue, fb_lvalue) == GS_ERROR)
   8769 	      return;
   8770 	    gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p);
   8771 	  }
   8772       }
   8773   if (last_bind)
   8774     {
   8775       append_to_statement_list (label, last_body);
   8776       gimplify_and_add (last_bind, pre_p);
   8777     }
   8778   return;
   8779 }
   8780 
   8781 /* If *LIST_P contains any OpenMP depend clauses with iterators,
   8782    lower all the depend clauses by populating corresponding depend
   8783    array.  Returns 0 if there are no such depend clauses, or
   8784    2 if all depend clauses should be removed, 1 otherwise.  */
   8785 
   8786 static int
   8787 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
   8788 {
   8789   tree c;
   8790   gimple *g;
   8791   size_t n[5] = { 0, 0, 0, 0, 0 };
   8792   bool unused[5];
   8793   tree counts[5] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
   8794   tree last_iter = NULL_TREE, last_count = NULL_TREE;
   8795   size_t i, j;
   8796   location_t first_loc = UNKNOWN_LOCATION;
   8797 
   8798   for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
   8799     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
   8800       {
   8801 	switch (OMP_CLAUSE_DEPEND_KIND (c))
   8802 	  {
   8803 	  case OMP_CLAUSE_DEPEND_IN:
   8804 	    i = 2;
   8805 	    break;
   8806 	  case OMP_CLAUSE_DEPEND_OUT:
   8807 	  case OMP_CLAUSE_DEPEND_INOUT:
   8808 	    i = 0;
   8809 	    break;
   8810 	  case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
   8811 	    i = 1;
   8812 	    break;
   8813 	  case OMP_CLAUSE_DEPEND_DEPOBJ:
   8814 	    i = 3;
   8815 	    break;
   8816 	  case OMP_CLAUSE_DEPEND_INOUTSET:
   8817 	    i = 4;
   8818 	    break;
   8819 	  default:
   8820 	    gcc_unreachable ();
   8821 	  }
   8822 	tree t = OMP_CLAUSE_DECL (c);
   8823 	if (first_loc == UNKNOWN_LOCATION)
   8824 	  first_loc = OMP_CLAUSE_LOCATION (c);
   8825 	if (TREE_CODE (t) == TREE_LIST
   8826 	    && TREE_PURPOSE (t)
   8827 	    && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
   8828 	  {
   8829 	    if (TREE_PURPOSE (t) != last_iter)
   8830 	      {
   8831 		tree tcnt = size_one_node;
   8832 		for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
   8833 		  {
   8834 		    if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
   8835 				       is_gimple_val, fb_rvalue) == GS_ERROR
   8836 			|| gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
   8837 					  is_gimple_val, fb_rvalue) == GS_ERROR
   8838 			|| gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
   8839 					  is_gimple_val, fb_rvalue) == GS_ERROR
   8840 			|| (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
   8841 					   is_gimple_val, fb_rvalue)
   8842 			    == GS_ERROR))
   8843 		      return 2;
   8844 		    tree var = TREE_VEC_ELT (it, 0);
   8845 		    tree begin = TREE_VEC_ELT (it, 1);
   8846 		    tree end = TREE_VEC_ELT (it, 2);
   8847 		    tree step = TREE_VEC_ELT (it, 3);
   8848 		    tree orig_step = TREE_VEC_ELT (it, 4);
   8849 		    tree type = TREE_TYPE (var);
   8850 		    tree stype = TREE_TYPE (step);
   8851 		    location_t loc = DECL_SOURCE_LOCATION (var);
   8852 		    tree endmbegin;
   8853 		    /* Compute count for this iterator as
   8854 		       orig_step > 0
   8855 		       ? (begin < end ? (end - begin + (step - 1)) / step : 0)
   8856 		       : (begin > end ? (end - begin + (step + 1)) / step : 0)
   8857 		       and compute product of those for the entire depend
   8858 		       clause.  */
   8859 		    if (POINTER_TYPE_P (type))
   8860 		      endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
   8861 						   stype, end, begin);
   8862 		    else
   8863 		      endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
   8864 						   end, begin);
   8865 		    tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
   8866 						   step,
   8867 						   build_int_cst (stype, 1));
   8868 		    tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
   8869 						   build_int_cst (stype, 1));
   8870 		    tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
   8871 						unshare_expr (endmbegin),
   8872 						stepm1);
   8873 		    pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
   8874 					   pos, step);
   8875 		    tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
   8876 						endmbegin, stepp1);
   8877 		    if (TYPE_UNSIGNED (stype))
   8878 		      {
   8879 			neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
   8880 			step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
   8881 		      }
   8882 		    neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
   8883 					   neg, step);
   8884 		    step = NULL_TREE;
   8885 		    tree cond = fold_build2_loc (loc, LT_EXPR,
   8886 						 boolean_type_node,
   8887 						 begin, end);
   8888 		    pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
   8889 					   build_int_cst (stype, 0));
   8890 		    cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
   8891 					    end, begin);
   8892 		    neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
   8893 					   build_int_cst (stype, 0));
   8894 		    tree osteptype = TREE_TYPE (orig_step);
   8895 		    cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
   8896 					    orig_step,
   8897 					    build_int_cst (osteptype, 0));
   8898 		    tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
   8899 						cond, pos, neg);
   8900 		    cnt = fold_convert_loc (loc, sizetype, cnt);
   8901 		    if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
   8902 				       fb_rvalue) == GS_ERROR)
   8903 		      return 2;
   8904 		    tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
   8905 		  }
   8906 		if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
   8907 				   fb_rvalue) == GS_ERROR)
   8908 		  return 2;
   8909 		last_iter = TREE_PURPOSE (t);
   8910 		last_count = tcnt;
   8911 	      }
   8912 	    if (counts[i] == NULL_TREE)
   8913 	      counts[i] = last_count;
   8914 	    else
   8915 	      counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
   8916 					  PLUS_EXPR, counts[i], last_count);
   8917 	  }
   8918 	else
   8919 	  n[i]++;
   8920       }
   8921   for (i = 0; i < 5; i++)
   8922     if (counts[i])
   8923       break;
   8924   if (i == 5)
   8925     return 0;
   8926 
   8927   tree total = size_zero_node;
   8928   for (i = 0; i < 5; i++)
   8929     {
   8930       unused[i] = counts[i] == NULL_TREE && n[i] == 0;
   8931       if (counts[i] == NULL_TREE)
   8932 	counts[i] = size_zero_node;
   8933       if (n[i])
   8934 	counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
   8935       if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
   8936 			 fb_rvalue) == GS_ERROR)
   8937 	return 2;
   8938       total = size_binop (PLUS_EXPR, total, counts[i]);
   8939     }
   8940 
   8941   if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
   8942       == GS_ERROR)
   8943     return 2;
   8944   bool is_old = unused[1] && unused[3] && unused[4];
   8945   tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
   8946 			     size_int (is_old ? 1 : 4));
   8947   if (!unused[4])
   8948     totalpx = size_binop (PLUS_EXPR, totalpx,
   8949 			  size_binop (MULT_EXPR, counts[4], size_int (2)));
   8950   tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
   8951   tree array = create_tmp_var_raw (type);
   8952   TREE_ADDRESSABLE (array) = 1;
   8953   if (!poly_int_tree_p (totalpx))
   8954     {
   8955       if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
   8956 	gimplify_type_sizes (TREE_TYPE (array), pre_p);
   8957       if (gimplify_omp_ctxp)
   8958 	{
   8959 	  struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   8960 	  while (ctx
   8961 		 && (ctx->region_type == ORT_WORKSHARE
   8962 		     || ctx->region_type == ORT_TASKGROUP
   8963 		     || ctx->region_type == ORT_SIMD
   8964 		     || ctx->region_type == ORT_ACC))
   8965 	    ctx = ctx->outer_context;
   8966 	  if (ctx)
   8967 	    omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
   8968 	}
   8969       gimplify_vla_decl (array, pre_p);
   8970     }
   8971   else
   8972     gimple_add_tmp_var (array);
   8973   tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
   8974 		   NULL_TREE);
   8975   tree tem;
   8976   if (!is_old)
   8977     {
   8978       tem = build2 (MODIFY_EXPR, void_type_node, r,
   8979 		    build_int_cst (ptr_type_node, 0));
   8980       gimplify_and_add (tem, pre_p);
   8981       r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
   8982 		  NULL_TREE);
   8983     }
   8984   tem = build2 (MODIFY_EXPR, void_type_node, r,
   8985 		fold_convert (ptr_type_node, total));
   8986   gimplify_and_add (tem, pre_p);
   8987   for (i = 1; i < (is_old ? 2 : 4); i++)
   8988     {
   8989       r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
   8990 		  NULL_TREE, NULL_TREE);
   8991       tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
   8992       gimplify_and_add (tem, pre_p);
   8993     }
   8994 
   8995   tree cnts[6];
   8996   for (j = 5; j; j--)
   8997     if (!unused[j - 1])
   8998       break;
   8999   for (i = 0; i < 5; i++)
   9000     {
   9001       if (i && (i >= j || unused[i - 1]))
   9002 	{
   9003 	  cnts[i] = cnts[i - 1];
   9004 	  continue;
   9005 	}
   9006       cnts[i] = create_tmp_var (sizetype);
   9007       if (i == 0)
   9008 	g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
   9009       else
   9010 	{
   9011 	  tree t;
   9012 	  if (is_old)
   9013 	    t = size_binop (PLUS_EXPR, counts[0], size_int (2));
   9014 	  else
   9015 	    t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
   9016 	  if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
   9017 	      == GS_ERROR)
   9018 	    return 2;
   9019 	  g = gimple_build_assign (cnts[i], t);
   9020 	}
   9021       gimple_seq_add_stmt (pre_p, g);
   9022     }
   9023   if (unused[4])
   9024     cnts[5] = NULL_TREE;
   9025   else
   9026     {
   9027       tree t = size_binop (PLUS_EXPR, total, size_int (5));
   9028       cnts[5] = create_tmp_var (sizetype);
   9029       g = gimple_build_assign (cnts[i], t);
   9030       gimple_seq_add_stmt (pre_p, g);
   9031     }
   9032 
   9033   last_iter = NULL_TREE;
   9034   tree last_bind = NULL_TREE;
   9035   tree *last_body = NULL;
   9036   for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
   9037     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
   9038       {
   9039 	switch (OMP_CLAUSE_DEPEND_KIND (c))
   9040 	  {
   9041 	  case OMP_CLAUSE_DEPEND_IN:
   9042 	    i = 2;
   9043 	    break;
   9044 	  case OMP_CLAUSE_DEPEND_OUT:
   9045 	  case OMP_CLAUSE_DEPEND_INOUT:
   9046 	    i = 0;
   9047 	    break;
   9048 	  case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
   9049 	    i = 1;
   9050 	    break;
   9051 	  case OMP_CLAUSE_DEPEND_DEPOBJ:
   9052 	    i = 3;
   9053 	    break;
   9054 	  case OMP_CLAUSE_DEPEND_INOUTSET:
   9055 	    i = 4;
   9056 	    break;
   9057 	  default:
   9058 	    gcc_unreachable ();
   9059 	  }
   9060 	tree t = OMP_CLAUSE_DECL (c);
   9061 	if (TREE_CODE (t) == TREE_LIST
   9062 	    && TREE_PURPOSE (t)
   9063 	    && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
   9064 	  {
   9065 	    if (TREE_PURPOSE (t) != last_iter)
   9066 	      {
   9067 		if (last_bind)
   9068 		  gimplify_and_add (last_bind, pre_p);
   9069 		tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
   9070 		last_bind = build3 (BIND_EXPR, void_type_node,
   9071 				    BLOCK_VARS (block), NULL, block);
   9072 		TREE_SIDE_EFFECTS (last_bind) = 1;
   9073 		SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
   9074 		tree *p = &BIND_EXPR_BODY (last_bind);
   9075 		for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
   9076 		  {
   9077 		    tree var = TREE_VEC_ELT (it, 0);
   9078 		    tree begin = TREE_VEC_ELT (it, 1);
   9079 		    tree end = TREE_VEC_ELT (it, 2);
   9080 		    tree step = TREE_VEC_ELT (it, 3);
   9081 		    tree orig_step = TREE_VEC_ELT (it, 4);
   9082 		    tree type = TREE_TYPE (var);
   9083 		    location_t loc = DECL_SOURCE_LOCATION (var);
   9084 		    /* Emit:
   9085 		       var = begin;
   9086 		       goto cond_label;
   9087 		       beg_label:
   9088 		       ...
   9089 		       var = var + step;
   9090 		       cond_label:
   9091 		       if (orig_step > 0) {
   9092 			 if (var < end) goto beg_label;
   9093 		       } else {
   9094 			 if (var > end) goto beg_label;
   9095 		       }
   9096 		       for each iterator, with inner iterators added to
   9097 		       the ... above.  */
   9098 		    tree beg_label = create_artificial_label (loc);
   9099 		    tree cond_label = NULL_TREE;
   9100 		    tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
   9101 				      var, begin);
   9102 		    append_to_statement_list_force (tem, p);
   9103 		    tem = build_and_jump (&cond_label);
   9104 		    append_to_statement_list_force (tem, p);
   9105 		    tem = build1 (LABEL_EXPR, void_type_node, beg_label);
   9106 		    append_to_statement_list (tem, p);
   9107 		    tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
   9108 					NULL_TREE, NULL_TREE);
   9109 		    TREE_SIDE_EFFECTS (bind) = 1;
   9110 		    SET_EXPR_LOCATION (bind, loc);
   9111 		    append_to_statement_list_force (bind, p);
   9112 		    if (POINTER_TYPE_P (type))
   9113 		      tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
   9114 					var, fold_convert_loc (loc, sizetype,
   9115 							       step));
   9116 		    else
   9117 		      tem = build2_loc (loc, PLUS_EXPR, type, var, step);
   9118 		    tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
   9119 				      var, tem);
   9120 		    append_to_statement_list_force (tem, p);
   9121 		    tem = build1 (LABEL_EXPR, void_type_node, cond_label);
   9122 		    append_to_statement_list (tem, p);
   9123 		    tree cond = fold_build2_loc (loc, LT_EXPR,
   9124 						 boolean_type_node,
   9125 						 var, end);
   9126 		    tree pos
   9127 		      = fold_build3_loc (loc, COND_EXPR, void_type_node,
   9128 					 cond, build_and_jump (&beg_label),
   9129 					 void_node);
   9130 		    cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
   9131 					    var, end);
   9132 		    tree neg
   9133 		      = fold_build3_loc (loc, COND_EXPR, void_type_node,
   9134 					 cond, build_and_jump (&beg_label),
   9135 					 void_node);
   9136 		    tree osteptype = TREE_TYPE (orig_step);
   9137 		    cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
   9138 					    orig_step,
   9139 					    build_int_cst (osteptype, 0));
   9140 		    tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
   9141 					   cond, pos, neg);
   9142 		    append_to_statement_list_force (tem, p);
   9143 		    p = &BIND_EXPR_BODY (bind);
   9144 		  }
   9145 		last_body = p;
   9146 	      }
   9147 	    last_iter = TREE_PURPOSE (t);
   9148 	    if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
   9149 	      {
   9150 		append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
   9151 					  0), last_body);
   9152 		TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
   9153 	      }
   9154 	    if (error_operand_p (TREE_VALUE (t)))
   9155 	      return 2;
   9156 	    if (TREE_VALUE (t) != null_pointer_node)
   9157 	      TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
   9158 	    if (i == 4)
   9159 	      {
   9160 		r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
   9161 			    NULL_TREE, NULL_TREE);
   9162 		tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5],
   9163 				  NULL_TREE, NULL_TREE);
   9164 		r2 = build_fold_addr_expr_with_type (r2, ptr_type_node);
   9165 		tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   9166 				  void_type_node, r, r2);
   9167 		append_to_statement_list_force (tem, last_body);
   9168 		tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   9169 				  void_type_node, cnts[i],
   9170 				  size_binop (PLUS_EXPR, cnts[i],
   9171 					      size_int (1)));
   9172 		append_to_statement_list_force (tem, last_body);
   9173 		i = 5;
   9174 	      }
   9175 	    r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
   9176 			NULL_TREE, NULL_TREE);
   9177 	    tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   9178 			      void_type_node, r, TREE_VALUE (t));
   9179 	    append_to_statement_list_force (tem, last_body);
   9180 	    if (i == 5)
   9181 	      {
   9182 		r = build4 (ARRAY_REF, ptr_type_node, array,
   9183 			    size_binop (PLUS_EXPR, cnts[i], size_int (1)),
   9184 			    NULL_TREE, NULL_TREE);
   9185 		tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
   9186 		tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   9187 				  void_type_node, r, tem);
   9188 		append_to_statement_list_force (tem, last_body);
   9189 	      }
   9190 	    tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   9191 			      void_type_node, cnts[i],
   9192 			      size_binop (PLUS_EXPR, cnts[i],
   9193 					  size_int (1 + (i == 5))));
   9194 	    append_to_statement_list_force (tem, last_body);
   9195 	    TREE_VALUE (t) = null_pointer_node;
   9196 	  }
   9197 	else
   9198 	  {
   9199 	    if (last_bind)
   9200 	      {
   9201 		gimplify_and_add (last_bind, pre_p);
   9202 		last_bind = NULL_TREE;
   9203 	      }
   9204 	    if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
   9205 	      {
   9206 		gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
   9207 			       NULL, is_gimple_val, fb_rvalue);
   9208 		OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
   9209 	      }
   9210 	    if (error_operand_p (OMP_CLAUSE_DECL (c)))
   9211 	      return 2;
   9212 	    if (OMP_CLAUSE_DECL (c) != null_pointer_node)
   9213 	      OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
   9214 	    if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
   9215 			       is_gimple_val, fb_rvalue) == GS_ERROR)
   9216 	      return 2;
   9217 	    if (i == 4)
   9218 	      {
   9219 		r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
   9220 			    NULL_TREE, NULL_TREE);
   9221 		tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5],
   9222 				  NULL_TREE, NULL_TREE);
   9223 		r2 = build_fold_addr_expr_with_type (r2, ptr_type_node);
   9224 		tem = build2 (MODIFY_EXPR, void_type_node, r, r2);
   9225 		gimplify_and_add (tem, pre_p);
   9226 		g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR,
   9227 							      cnts[i],
   9228 							      size_int (1)));
   9229 		gimple_seq_add_stmt (pre_p, g);
   9230 		i = 5;
   9231 	      }
   9232 	    r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
   9233 			NULL_TREE, NULL_TREE);
   9234 	    tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
   9235 	    gimplify_and_add (tem, pre_p);
   9236 	    if (i == 5)
   9237 	      {
   9238 		r = build4 (ARRAY_REF, ptr_type_node, array,
   9239 			    size_binop (PLUS_EXPR, cnts[i], size_int (1)),
   9240 			    NULL_TREE, NULL_TREE);
   9241 		tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
   9242 		tem = build2 (MODIFY_EXPR, void_type_node, r, tem);
   9243 		append_to_statement_list_force (tem, last_body);
   9244 		gimplify_and_add (tem, pre_p);
   9245 	      }
   9246 	    g = gimple_build_assign (cnts[i],
   9247 				     size_binop (PLUS_EXPR, cnts[i],
   9248 						 size_int (1 + (i == 5))));
   9249 	    gimple_seq_add_stmt (pre_p, g);
   9250 	  }
   9251       }
   9252   if (last_bind)
   9253     gimplify_and_add (last_bind, pre_p);
   9254   tree cond = boolean_false_node;
   9255   if (is_old)
   9256     {
   9257       if (!unused[0])
   9258 	cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
   9259 			   size_binop_loc (first_loc, PLUS_EXPR, counts[0],
   9260 					   size_int (2)));
   9261       if (!unused[2])
   9262 	cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
   9263 			   build2_loc (first_loc, NE_EXPR, boolean_type_node,
   9264 				       cnts[2],
   9265 				       size_binop_loc (first_loc, PLUS_EXPR,
   9266 						       totalpx,
   9267 						       size_int (1))));
   9268     }
   9269   else
   9270     {
   9271       tree prev = size_int (5);
   9272       for (i = 0; i < 5; i++)
   9273 	{
   9274 	  if (unused[i])
   9275 	    continue;
   9276 	  prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
   9277 	  cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
   9278 			     build2_loc (first_loc, NE_EXPR, boolean_type_node,
   9279 					 cnts[i], unshare_expr (prev)));
   9280 	}
   9281     }
   9282   tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
   9283 		    build_call_expr_loc (first_loc,
   9284 					 builtin_decl_explicit (BUILT_IN_TRAP),
   9285 					 0), void_node);
   9286   gimplify_and_add (tem, pre_p);
   9287   c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
   9288   OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
   9289   OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
   9290   OMP_CLAUSE_CHAIN (c) = *list_p;
   9291   *list_p = c;
   9292   return 1;
   9293 }
   9294 
   9295 /* True if mapping node C maps, or unmaps, a (Fortran) array descriptor.  */
   9296 
   9297 static bool
   9298 omp_map_clause_descriptor_p (tree c)
   9299 {
   9300   if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
   9301     return false;
   9302 
   9303   if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
   9304     return true;
   9305 
   9306   if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_RELEASE
   9307        || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DELETE)
   9308       && OMP_CLAUSE_RELEASE_DESCRIPTOR (c))
   9309     return true;
   9310 
   9311   return false;
   9312 }
   9313 
   9314 /* For a set of mappings describing an array section pointed to by a struct
   9315    (or derived type, etc.) component, create an "alloc" or "release" node to
   9316    insert into a list following a GOMP_MAP_STRUCT node.  For some types of
   9317    mapping (e.g. Fortran arrays with descriptors), an additional mapping may
   9318    be created that is inserted into the list of mapping nodes attached to the
   9319    directive being processed -- not part of the sorted list of nodes after
   9320    GOMP_MAP_STRUCT.
   9321 
   9322    CODE is the code of the directive being processed.  GRP_START and GRP_END
   9323    are the first and last of two or three nodes representing this array section
   9324    mapping (e.g. a data movement node like GOMP_MAP_{TO,FROM}, optionally a
   9325    GOMP_MAP_TO_PSET, and finally a GOMP_MAP_ALWAYS_POINTER).  EXTRA_NODE is
   9326    filled with the additional node described above, if needed.
   9327 
   9328    This function does not add the new nodes to any lists itself.  It is the
   9329    responsibility of the caller to do that.  */
   9330 
   9331 static tree
   9332 build_omp_struct_comp_nodes (enum tree_code code, tree grp_start, tree grp_end,
   9333 			     tree *extra_node)
   9334 {
   9335   enum gomp_map_kind mkind
   9336     = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
   9337       ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
   9338 
   9339   gcc_assert (grp_start != grp_end);
   9340 
   9341   tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
   9342   OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
   9343   OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (grp_end));
   9344   OMP_CLAUSE_CHAIN (c2) = NULL_TREE;
   9345   tree grp_mid = NULL_TREE;
   9346   if (OMP_CLAUSE_CHAIN (grp_start) != grp_end)
   9347     grp_mid = OMP_CLAUSE_CHAIN (grp_start);
   9348 
   9349   if (grp_mid && omp_map_clause_descriptor_p (grp_mid))
   9350     OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (grp_mid);
   9351   else
   9352     OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
   9353 
   9354   if (grp_mid
   9355       && OMP_CLAUSE_CODE (grp_mid) == OMP_CLAUSE_MAP
   9356       && OMP_CLAUSE_MAP_KIND (grp_mid) == GOMP_MAP_ALWAYS_POINTER)
   9357     {
   9358       tree c3
   9359 	= build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
   9360       OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
   9361       OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (grp_mid));
   9362       OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
   9363       OMP_CLAUSE_CHAIN (c3) = NULL_TREE;
   9364 
   9365       *extra_node = c3;
   9366     }
   9367   else
   9368     *extra_node = NULL_TREE;
   9369 
   9370   return c2;
   9371 }
   9372 
   9373 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
   9374    and set *BITPOSP and *POFFSETP to the bit offset of the access.
   9375    If BASE_REF is non-NULL and the containing object is a reference, set
   9376    *BASE_REF to that reference before dereferencing the object.
   9377    If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
   9378    has array type, else return NULL.  */
   9379 
   9380 static tree
   9381 extract_base_bit_offset (tree base, poly_int64 *bitposp,
   9382 			 poly_offset_int *poffsetp,
   9383 			 bool *variable_offset)
   9384 {
   9385   tree offset;
   9386   poly_int64 bitsize, bitpos;
   9387   machine_mode mode;
   9388   int unsignedp, reversep, volatilep = 0;
   9389   poly_offset_int poffset;
   9390 
   9391   STRIP_NOPS (base);
   9392 
   9393   base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
   9394 			      &unsignedp, &reversep, &volatilep);
   9395 
   9396   STRIP_NOPS (base);
   9397 
   9398   if (offset && poly_int_tree_p (offset))
   9399     {
   9400       poffset = wi::to_poly_offset (offset);
   9401       *variable_offset = false;
   9402     }
   9403   else
   9404     {
   9405       poffset = 0;
   9406       *variable_offset = (offset != NULL_TREE);
   9407     }
   9408 
   9409   if (maybe_ne (bitpos, 0))
   9410     poffset += bits_to_bytes_round_down (bitpos);
   9411 
   9412   *bitposp = bitpos;
   9413   *poffsetp = poffset;
   9414 
   9415   return base;
   9416 }
   9417 
   9418 /* Used for topological sorting of mapping groups.  UNVISITED means we haven't
   9419    started processing the group yet.  The TEMPORARY mark is used when we first
   9420    encounter a group on a depth-first traversal, and the PERMANENT mark is used
   9421    when we have processed all the group's children (i.e. all the base pointers
   9422    referred to by the group's mapping nodes, recursively).  */
   9423 
   9424 enum omp_tsort_mark {
   9425   UNVISITED,
   9426   TEMPORARY,
   9427   PERMANENT
   9428 };
   9429 
   9430 /* Hash for trees based on operand_equal_p.  Like tree_operand_hash
   9431    but ignores side effects in the equality comparisons.  */
   9432 
   9433 struct tree_operand_hash_no_se : tree_operand_hash
   9434 {
   9435   static inline bool equal (const value_type &,
   9436 			    const compare_type &);
   9437 };
   9438 
   9439 inline bool
   9440 tree_operand_hash_no_se::equal (const value_type &t1,
   9441 				const compare_type &t2)
   9442 {
   9443   return operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS);
   9444 }
   9445 
   9446 /* A group of OMP_CLAUSE_MAP nodes that correspond to a single "map"
   9447    clause.  */
   9448 
   9449 struct omp_mapping_group {
   9450   tree *grp_start;
   9451   tree grp_end;
   9452   omp_tsort_mark mark;
   9453   /* If we've removed the group but need to reindex, mark the group as
   9454      deleted.  */
   9455   bool deleted;
   9456   /* The group points to an already-created "GOMP_MAP_STRUCT
   9457      GOMP_MAP_ATTACH_DETACH" pair.  */
   9458   bool reprocess_struct;
   9459   /* The group should use "zero-length" allocations for pointers that are not
   9460      mapped "to" on the same directive.  */
   9461   bool fragile;
   9462   struct omp_mapping_group *sibling;
   9463   struct omp_mapping_group *next;
   9464 };
   9465 
   9466 DEBUG_FUNCTION void
   9467 debug_mapping_group (omp_mapping_group *grp)
   9468 {
   9469   tree tmp = OMP_CLAUSE_CHAIN (grp->grp_end);
   9470   OMP_CLAUSE_CHAIN (grp->grp_end) = NULL;
   9471   debug_generic_expr (*grp->grp_start);
   9472   OMP_CLAUSE_CHAIN (grp->grp_end) = tmp;
   9473 }
   9474 
   9475 /* Return the OpenMP "base pointer" of an expression EXPR, or NULL if there
   9476    isn't one.  */
   9477 
   9478 static tree
   9479 omp_get_base_pointer (tree expr)
   9480 {
   9481   while (TREE_CODE (expr) == ARRAY_REF
   9482 	 || TREE_CODE (expr) == COMPONENT_REF)
   9483     expr = TREE_OPERAND (expr, 0);
   9484 
   9485   if (INDIRECT_REF_P (expr)
   9486       || (TREE_CODE (expr) == MEM_REF
   9487 	  && integer_zerop (TREE_OPERAND (expr, 1))))
   9488     {
   9489       expr = TREE_OPERAND (expr, 0);
   9490       while (TREE_CODE (expr) == COMPOUND_EXPR)
   9491 	expr = TREE_OPERAND (expr, 1);
   9492       if (TREE_CODE (expr) == POINTER_PLUS_EXPR)
   9493 	expr = TREE_OPERAND (expr, 0);
   9494       if (TREE_CODE (expr) == SAVE_EXPR)
   9495 	expr = TREE_OPERAND (expr, 0);
   9496       STRIP_NOPS (expr);
   9497       return expr;
   9498     }
   9499 
   9500   return NULL_TREE;
   9501 }
   9502 
   9503 /* An attach or detach operation depends directly on the address being
   9504    attached/detached.  Return that address, or none if there are no
   9505    attachments/detachments.  */
   9506 
   9507 static tree
   9508 omp_get_attachment (omp_mapping_group *grp)
   9509 {
   9510   tree node = *grp->grp_start;
   9511 
   9512   switch (OMP_CLAUSE_MAP_KIND (node))
   9513     {
   9514     case GOMP_MAP_TO:
   9515     case GOMP_MAP_FROM:
   9516     case GOMP_MAP_TOFROM:
   9517     case GOMP_MAP_ALWAYS_FROM:
   9518     case GOMP_MAP_ALWAYS_TO:
   9519     case GOMP_MAP_ALWAYS_TOFROM:
   9520     case GOMP_MAP_FORCE_FROM:
   9521     case GOMP_MAP_FORCE_TO:
   9522     case GOMP_MAP_FORCE_TOFROM:
   9523     case GOMP_MAP_FORCE_PRESENT:
   9524     case GOMP_MAP_PRESENT_ALLOC:
   9525     case GOMP_MAP_PRESENT_FROM:
   9526     case GOMP_MAP_PRESENT_TO:
   9527     case GOMP_MAP_PRESENT_TOFROM:
   9528     case GOMP_MAP_ALWAYS_PRESENT_FROM:
   9529     case GOMP_MAP_ALWAYS_PRESENT_TO:
   9530     case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   9531     case GOMP_MAP_ALLOC:
   9532     case GOMP_MAP_RELEASE:
   9533     case GOMP_MAP_DELETE:
   9534     case GOMP_MAP_FORCE_ALLOC:
   9535       if (node == grp->grp_end)
   9536 	return NULL_TREE;
   9537 
   9538       node = OMP_CLAUSE_CHAIN (node);
   9539       if (node && omp_map_clause_descriptor_p (node))
   9540 	{
   9541 	  gcc_assert (node != grp->grp_end);
   9542 	  node = OMP_CLAUSE_CHAIN (node);
   9543 	}
   9544       if (node)
   9545 	switch (OMP_CLAUSE_MAP_KIND (node))
   9546 	  {
   9547 	  case GOMP_MAP_POINTER:
   9548 	  case GOMP_MAP_ALWAYS_POINTER:
   9549 	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
   9550 	  case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   9551 	  case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
   9552 	    return NULL_TREE;
   9553 
   9554 	  case GOMP_MAP_ATTACH_DETACH:
   9555 	  case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   9556 	  case GOMP_MAP_DETACH:
   9557 	    return OMP_CLAUSE_DECL (node);
   9558 
   9559 	  default:
   9560 	    internal_error ("unexpected mapping node");
   9561 	  }
   9562       return error_mark_node;
   9563 
   9564     case GOMP_MAP_TO_PSET:
   9565       gcc_assert (node != grp->grp_end);
   9566       node = OMP_CLAUSE_CHAIN (node);
   9567       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH
   9568 	  || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DETACH)
   9569 	return OMP_CLAUSE_DECL (node);
   9570       else
   9571 	internal_error ("unexpected mapping node");
   9572       return error_mark_node;
   9573 
   9574     case GOMP_MAP_ATTACH:
   9575     case GOMP_MAP_DETACH:
   9576       node = OMP_CLAUSE_CHAIN (node);
   9577       if (!node || *grp->grp_start == grp->grp_end)
   9578 	return OMP_CLAUSE_DECL (*grp->grp_start);
   9579       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
   9580 	  || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   9581 	return OMP_CLAUSE_DECL (*grp->grp_start);
   9582       else
   9583 	internal_error ("unexpected mapping node");
   9584       return error_mark_node;
   9585 
   9586     case GOMP_MAP_STRUCT:
   9587     case GOMP_MAP_STRUCT_UNORD:
   9588     case GOMP_MAP_FORCE_DEVICEPTR:
   9589     case GOMP_MAP_DEVICE_RESIDENT:
   9590     case GOMP_MAP_LINK:
   9591     case GOMP_MAP_IF_PRESENT:
   9592     case GOMP_MAP_FIRSTPRIVATE:
   9593     case GOMP_MAP_FIRSTPRIVATE_INT:
   9594     case GOMP_MAP_USE_DEVICE_PTR:
   9595     case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   9596       return NULL_TREE;
   9597 
   9598     default:
   9599       internal_error ("unexpected mapping node");
   9600     }
   9601 
   9602   return error_mark_node;
   9603 }
   9604 
   9605 /* Given a pointer START_P to the start of a group of related (e.g. pointer)
   9606    mappings, return the chain pointer to the end of that group in the list.  */
   9607 
   9608 static tree *
   9609 omp_group_last (tree *start_p)
   9610 {
   9611   tree c = *start_p, nc, *grp_last_p = start_p;
   9612 
   9613   gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP);
   9614 
   9615   nc = OMP_CLAUSE_CHAIN (c);
   9616 
   9617   if (!nc || OMP_CLAUSE_CODE (nc) != OMP_CLAUSE_MAP)
   9618     return grp_last_p;
   9619 
   9620   switch (OMP_CLAUSE_MAP_KIND (c))
   9621     {
   9622     default:
   9623       while (nc
   9624 	     && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
   9625 	     && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
   9626 		 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER
   9627 		 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH_DETACH
   9628 		 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_POINTER
   9629 		 || (OMP_CLAUSE_MAP_KIND (nc)
   9630 		     == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)
   9631 		 || (OMP_CLAUSE_MAP_KIND (nc)
   9632 		     == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)
   9633 		 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH
   9634 		 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ALWAYS_POINTER
   9635 		 || omp_map_clause_descriptor_p (nc)))
   9636 	{
   9637 	  tree nc2 = OMP_CLAUSE_CHAIN (nc);
   9638 	  if (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH)
   9639 	    {
   9640 	      /* In the specific case we're doing "exit data" on an array
   9641 		 slice of a reference-to-pointer struct component, we will see
   9642 		 DETACH followed by ATTACH_DETACH here.  We want to treat that
   9643 		 as a single group. In other cases DETACH might represent a
   9644 		 stand-alone "detach" clause, so we don't want to consider
   9645 		 that part of the group.  */
   9646 	      if (nc2
   9647 		  && OMP_CLAUSE_CODE (nc2) == OMP_CLAUSE_MAP
   9648 		  && OMP_CLAUSE_MAP_KIND (nc2) == GOMP_MAP_ATTACH_DETACH)
   9649 		goto consume_two_nodes;
   9650 	      else
   9651 		break;
   9652 	    }
   9653 	  if (nc2
   9654 	      && OMP_CLAUSE_CODE (nc2) == OMP_CLAUSE_MAP
   9655 	      && (OMP_CLAUSE_MAP_KIND (nc)
   9656 		  == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)
   9657 	      && OMP_CLAUSE_MAP_KIND (nc2) == GOMP_MAP_ATTACH)
   9658 	    {
   9659 	    consume_two_nodes:
   9660 	      grp_last_p = &OMP_CLAUSE_CHAIN (nc);
   9661 	      c = nc2;
   9662 	      nc = OMP_CLAUSE_CHAIN (nc2);
   9663 	    }
   9664 	  else
   9665 	    {
   9666 	      grp_last_p = &OMP_CLAUSE_CHAIN (c);
   9667 	      c = nc;
   9668 	      nc = nc2;
   9669 	    }
   9670 	}
   9671       break;
   9672 
   9673     case GOMP_MAP_ATTACH:
   9674     case GOMP_MAP_DETACH:
   9675       /* This is a weird artifact of how directives are parsed: bare attach or
   9676 	 detach clauses get a subsequent (meaningless) FIRSTPRIVATE_POINTER or
   9677 	 FIRSTPRIVATE_REFERENCE node.  FIXME.  */
   9678       if (nc
   9679 	  && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
   9680 	  && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
   9681 	      || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER))
   9682 	grp_last_p = &OMP_CLAUSE_CHAIN (c);
   9683       break;
   9684 
   9685     case GOMP_MAP_TO_PSET:
   9686       if (OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
   9687 	  && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH
   9688 	      || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH))
   9689 	grp_last_p = &OMP_CLAUSE_CHAIN (c);
   9690       break;
   9691 
   9692     case GOMP_MAP_STRUCT:
   9693     case GOMP_MAP_STRUCT_UNORD:
   9694       {
   9695 	unsigned HOST_WIDE_INT num_mappings
   9696 	  = tree_to_uhwi (OMP_CLAUSE_SIZE (c));
   9697 	if (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER
   9698 	    || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
   9699 	    || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH_DETACH)
   9700 	  grp_last_p = &OMP_CLAUSE_CHAIN (*grp_last_p);
   9701 	for (unsigned i = 0; i < num_mappings; i++)
   9702 	  grp_last_p = &OMP_CLAUSE_CHAIN (*grp_last_p);
   9703       }
   9704       break;
   9705     }
   9706 
   9707   return grp_last_p;
   9708 }
   9709 
   9710 /* Walk through LIST_P, and return a list of groups of mappings found (e.g.
   9711    OMP_CLAUSE_MAP with GOMP_MAP_{TO/FROM/TOFROM} followed by one or two
   9712    associated GOMP_MAP_POINTER mappings).  Return a vector of omp_mapping_group
   9713    if we have more than one such group, else return NULL.  */
   9714 
   9715 static void
   9716 omp_gather_mapping_groups_1 (tree *list_p, vec<omp_mapping_group> *groups,
   9717 			     tree gather_sentinel)
   9718 {
   9719   for (tree *cp = list_p;
   9720        *cp && *cp != gather_sentinel;
   9721        cp = &OMP_CLAUSE_CHAIN (*cp))
   9722     {
   9723       if (OMP_CLAUSE_CODE (*cp) != OMP_CLAUSE_MAP)
   9724 	continue;
   9725 
   9726       tree *grp_last_p = omp_group_last (cp);
   9727       omp_mapping_group grp;
   9728 
   9729       grp.grp_start = cp;
   9730       grp.grp_end = *grp_last_p;
   9731       grp.mark = UNVISITED;
   9732       grp.sibling = NULL;
   9733       grp.deleted = false;
   9734       grp.reprocess_struct = false;
   9735       grp.fragile = false;
   9736       grp.next = NULL;
   9737       groups->safe_push (grp);
   9738 
   9739       cp = grp_last_p;
   9740     }
   9741 }
   9742 
   9743 static vec<omp_mapping_group> *
   9744 omp_gather_mapping_groups (tree *list_p)
   9745 {
   9746   vec<omp_mapping_group> *groups = new vec<omp_mapping_group> ();
   9747 
   9748   omp_gather_mapping_groups_1 (list_p, groups, NULL_TREE);
   9749 
   9750   if (groups->length () > 0)
   9751     return groups;
   9752   else
   9753     {
   9754       delete groups;
   9755       return NULL;
   9756     }
   9757 }
   9758 
   9759 /* A pointer mapping group GRP may define a block of memory starting at some
   9760    base address, and maybe also define a firstprivate pointer or firstprivate
   9761    reference that points to that block.  The return value is a node containing
   9762    the former, and the *FIRSTPRIVATE pointer is set if we have the latter.
   9763    If we define several base pointers, i.e. for a GOMP_MAP_STRUCT mapping,
   9764    return the number of consecutive chained nodes in CHAINED.  */
   9765 
   9766 static tree
   9767 omp_group_base (omp_mapping_group *grp, unsigned int *chained,
   9768 		tree *firstprivate)
   9769 {
   9770   tree node = *grp->grp_start;
   9771 
   9772   *firstprivate = NULL_TREE;
   9773   *chained = 1;
   9774 
   9775   switch (OMP_CLAUSE_MAP_KIND (node))
   9776     {
   9777     case GOMP_MAP_TO:
   9778     case GOMP_MAP_FROM:
   9779     case GOMP_MAP_TOFROM:
   9780     case GOMP_MAP_ALWAYS_FROM:
   9781     case GOMP_MAP_ALWAYS_TO:
   9782     case GOMP_MAP_ALWAYS_TOFROM:
   9783     case GOMP_MAP_FORCE_FROM:
   9784     case GOMP_MAP_FORCE_TO:
   9785     case GOMP_MAP_FORCE_TOFROM:
   9786     case GOMP_MAP_FORCE_PRESENT:
   9787     case GOMP_MAP_PRESENT_ALLOC:
   9788     case GOMP_MAP_PRESENT_FROM:
   9789     case GOMP_MAP_PRESENT_TO:
   9790     case GOMP_MAP_PRESENT_TOFROM:
   9791     case GOMP_MAP_ALWAYS_PRESENT_FROM:
   9792     case GOMP_MAP_ALWAYS_PRESENT_TO:
   9793     case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   9794     case GOMP_MAP_ALLOC:
   9795     case GOMP_MAP_RELEASE:
   9796     case GOMP_MAP_DELETE:
   9797     case GOMP_MAP_FORCE_ALLOC:
   9798     case GOMP_MAP_IF_PRESENT:
   9799       if (node == grp->grp_end)
   9800 	return node;
   9801 
   9802       node = OMP_CLAUSE_CHAIN (node);
   9803       if (!node)
   9804 	internal_error ("unexpected mapping node");
   9805       if (omp_map_clause_descriptor_p (node))
   9806 	{
   9807 	  if (node == grp->grp_end)
   9808 	    return *grp->grp_start;
   9809 	  node = OMP_CLAUSE_CHAIN (node);
   9810 	}
   9811       switch (OMP_CLAUSE_MAP_KIND (node))
   9812 	{
   9813 	case GOMP_MAP_POINTER:
   9814 	case GOMP_MAP_FIRSTPRIVATE_POINTER:
   9815 	case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   9816 	case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
   9817 	  *firstprivate = OMP_CLAUSE_DECL (node);
   9818 	  return *grp->grp_start;
   9819 
   9820 	case GOMP_MAP_ALWAYS_POINTER:
   9821 	case GOMP_MAP_ATTACH_DETACH:
   9822 	case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   9823 	case GOMP_MAP_DETACH:
   9824 	  return *grp->grp_start;
   9825 
   9826 	default:
   9827 	  internal_error ("unexpected mapping node");
   9828 	}
   9829       return error_mark_node;
   9830 
   9831     case GOMP_MAP_TO_PSET:
   9832       gcc_assert (node != grp->grp_end);
   9833       node = OMP_CLAUSE_CHAIN (node);
   9834       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH
   9835 	  || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DETACH)
   9836 	return NULL_TREE;
   9837       else
   9838 	internal_error ("unexpected mapping node");
   9839       return error_mark_node;
   9840 
   9841     case GOMP_MAP_ATTACH:
   9842     case GOMP_MAP_DETACH:
   9843       node = OMP_CLAUSE_CHAIN (node);
   9844       if (!node || *grp->grp_start == grp->grp_end)
   9845 	return NULL_TREE;
   9846       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
   9847 	  || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   9848 	{
   9849 	  /* We're mapping the base pointer itself in a bare attach or detach
   9850 	     node.  This is a side effect of how parsing works, and the mapping
   9851 	     will be removed anyway (at least for enter/exit data directives).
   9852 	     We should ignore the mapping here.  FIXME.  */
   9853 	  return NULL_TREE;
   9854 	}
   9855       else
   9856 	internal_error ("unexpected mapping node");
   9857       return error_mark_node;
   9858 
   9859     case GOMP_MAP_STRUCT:
   9860     case GOMP_MAP_STRUCT_UNORD:
   9861       {
   9862 	unsigned HOST_WIDE_INT num_mappings
   9863 	  = tree_to_uhwi (OMP_CLAUSE_SIZE (node));
   9864 	node = OMP_CLAUSE_CHAIN (node);
   9865 	if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
   9866 	    || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   9867 	  {
   9868 	    *firstprivate = OMP_CLAUSE_DECL (node);
   9869 	    node = OMP_CLAUSE_CHAIN (node);
   9870 	  }
   9871 	else if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH_DETACH)
   9872 	  node = OMP_CLAUSE_CHAIN (node);
   9873 	*chained = num_mappings;
   9874 	return node;
   9875       }
   9876 
   9877     case GOMP_MAP_FORCE_DEVICEPTR:
   9878     case GOMP_MAP_DEVICE_RESIDENT:
   9879     case GOMP_MAP_LINK:
   9880     case GOMP_MAP_FIRSTPRIVATE:
   9881     case GOMP_MAP_FIRSTPRIVATE_INT:
   9882     case GOMP_MAP_USE_DEVICE_PTR:
   9883     case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   9884       return NULL_TREE;
   9885 
   9886     case GOMP_MAP_FIRSTPRIVATE_POINTER:
   9887     case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   9888     case GOMP_MAP_POINTER:
   9889     case GOMP_MAP_ALWAYS_POINTER:
   9890     case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
   9891       /* These shouldn't appear by themselves.  */
   9892       if (!seen_error ())
   9893 	internal_error ("unexpected pointer mapping node");
   9894       return error_mark_node;
   9895 
   9896     default:
   9897       gcc_unreachable ();
   9898     }
   9899 
   9900   return error_mark_node;
   9901 }
   9902 
   9903 /* Given a vector of omp_mapping_groups, build a hash table so we can look up
   9904    nodes by tree_operand_hash_no_se.  */
   9905 
   9906 static void
   9907 omp_index_mapping_groups_1 (hash_map<tree_operand_hash_no_se,
   9908 				     omp_mapping_group *> *grpmap,
   9909 			    vec<omp_mapping_group> *groups,
   9910 			    tree reindex_sentinel)
   9911 {
   9912   omp_mapping_group *grp;
   9913   unsigned int i;
   9914   bool reindexing = reindex_sentinel != NULL_TREE, above_hwm = false;
   9915 
   9916   FOR_EACH_VEC_ELT (*groups, i, grp)
   9917     {
   9918       if (reindexing && *grp->grp_start == reindex_sentinel)
   9919 	above_hwm = true;
   9920 
   9921       if (reindexing && !above_hwm)
   9922 	continue;
   9923 
   9924       if (grp->reprocess_struct)
   9925 	continue;
   9926 
   9927       tree fpp;
   9928       unsigned int chained;
   9929       tree node = omp_group_base (grp, &chained, &fpp);
   9930 
   9931       if (node == error_mark_node || (!node && !fpp))
   9932 	continue;
   9933 
   9934       for (unsigned j = 0;
   9935 	   node && j < chained;
   9936 	   node = OMP_CLAUSE_CHAIN (node), j++)
   9937 	{
   9938 	  tree decl = OMP_CLAUSE_DECL (node);
   9939 	  /* Sometimes we see zero-offset MEM_REF instead of INDIRECT_REF,
   9940 	     meaning node-hash lookups don't work.  This is a workaround for
   9941 	     that, but ideally we should just create the INDIRECT_REF at
   9942 	     source instead.  FIXME.  */
   9943 	  if (TREE_CODE (decl) == MEM_REF
   9944 	      && integer_zerop (TREE_OPERAND (decl, 1)))
   9945 	    decl = build_fold_indirect_ref (TREE_OPERAND (decl, 0));
   9946 
   9947 	  omp_mapping_group **prev = grpmap->get (decl);
   9948 
   9949 	  if (prev && *prev == grp)
   9950 	    /* Empty.  */;
   9951 	  else if (prev)
   9952 	    {
   9953 	      /* Mapping the same thing twice is normally diagnosed as an error,
   9954 		 but can happen under some circumstances, e.g. in pr99928-16.c,
   9955 		 the directive:
   9956 
   9957 		 #pragma omp target simd reduction(+:a[:3]) \
   9958 					 map(always, tofrom: a[:6])
   9959 		 ...
   9960 
   9961 		 will result in two "a[0]" mappings (of different sizes).  */
   9962 
   9963 	      grp->sibling = (*prev)->sibling;
   9964 	      (*prev)->sibling = grp;
   9965 	    }
   9966 	  else
   9967 	    grpmap->put (decl, grp);
   9968 	}
   9969 
   9970       if (!fpp)
   9971 	continue;
   9972 
   9973       omp_mapping_group **prev = grpmap->get (fpp);
   9974       if (prev && *prev != grp)
   9975 	{
   9976 	  grp->sibling = (*prev)->sibling;
   9977 	  (*prev)->sibling = grp;
   9978 	}
   9979       else
   9980 	grpmap->put (fpp, grp);
   9981     }
   9982 }
   9983 
   9984 static hash_map<tree_operand_hash_no_se, omp_mapping_group *> *
   9985 omp_index_mapping_groups (vec<omp_mapping_group> *groups)
   9986 {
   9987   hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap
   9988     = new hash_map<tree_operand_hash_no_se, omp_mapping_group *>;
   9989 
   9990   omp_index_mapping_groups_1 (grpmap, groups, NULL_TREE);
   9991 
   9992   return grpmap;
   9993 }
   9994 
   9995 /* Rebuild group map from partially-processed clause list (during
   9996    omp_build_struct_sibling_lists).  We have already processed nodes up until
   9997    a high-water mark (HWM).  This is a bit tricky because the list is being
   9998    reordered as it is scanned, but we know:
   9999 
   10000    1. The list after HWM has not been touched yet, so we can reindex it safely.
   10001 
   10002    2. The list before and including HWM has been altered, but remains
   10003       well-formed throughout the sibling-list building operation.
   10004 
   10005    so, we can do the reindex operation in two parts, on the processed and
   10006    then the unprocessed halves of the list.  */
   10007 
   10008 static hash_map<tree_operand_hash_no_se, omp_mapping_group *> *
   10009 omp_reindex_mapping_groups (tree *list_p,
   10010 			    vec<omp_mapping_group> *groups,
   10011 			    vec<omp_mapping_group> *processed_groups,
   10012 			    tree sentinel)
   10013 {
   10014   hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap
   10015     = new hash_map<tree_operand_hash_no_se, omp_mapping_group *>;
   10016 
   10017   processed_groups->truncate (0);
   10018 
   10019   omp_gather_mapping_groups_1 (list_p, processed_groups, sentinel);
   10020   omp_index_mapping_groups_1 (grpmap, processed_groups, NULL_TREE);
   10021   if (sentinel)
   10022     omp_index_mapping_groups_1 (grpmap, groups, sentinel);
   10023 
   10024   return grpmap;
   10025 }
   10026 
   10027 /* Find the immediately-containing struct for a component ref (etc.)
   10028    expression EXPR.  */
   10029 
   10030 static tree
   10031 omp_containing_struct (tree expr)
   10032 {
   10033   tree expr0 = expr;
   10034 
   10035   STRIP_NOPS (expr);
   10036 
   10037   /* Note: don't strip NOPs unless we're also stripping off array refs or a
   10038      component ref.  */
   10039   if (TREE_CODE (expr) != ARRAY_REF && TREE_CODE (expr) != COMPONENT_REF)
   10040     return expr0;
   10041 
   10042   while (TREE_CODE (expr) == ARRAY_REF)
   10043     expr = TREE_OPERAND (expr, 0);
   10044 
   10045   if (TREE_CODE (expr) == COMPONENT_REF)
   10046     expr = TREE_OPERAND (expr, 0);
   10047 
   10048   return expr;
   10049 }
   10050 
   10051 /* Return TRUE if DECL describes a component that is part of a whole structure
   10052    that is mapped elsewhere in GRPMAP.  *MAPPED_BY_GROUP is set to the group
   10053    that maps that structure, if present.  */
   10054 
   10055 static bool
   10056 omp_mapped_by_containing_struct (hash_map<tree_operand_hash_no_se,
   10057 					  omp_mapping_group *> *grpmap,
   10058 				 tree decl,
   10059 				 omp_mapping_group **mapped_by_group)
   10060 {
   10061   tree wsdecl = NULL_TREE;
   10062 
   10063   *mapped_by_group = NULL;
   10064 
   10065   while (true)
   10066     {
   10067       wsdecl = omp_containing_struct (decl);
   10068       if (wsdecl == decl)
   10069 	break;
   10070       omp_mapping_group **wholestruct = grpmap->get (wsdecl);
   10071       if (!wholestruct
   10072 	  && TREE_CODE (wsdecl) == MEM_REF
   10073 	  && integer_zerop (TREE_OPERAND (wsdecl, 1)))
   10074 	{
   10075 	  tree deref = TREE_OPERAND (wsdecl, 0);
   10076 	  deref = build_fold_indirect_ref (deref);
   10077 	  wholestruct = grpmap->get (deref);
   10078 	}
   10079       if (wholestruct)
   10080 	{
   10081 	  *mapped_by_group = *wholestruct;
   10082 	  return true;
   10083 	}
   10084       decl = wsdecl;
   10085     }
   10086 
   10087   return false;
   10088 }
   10089 
   10090 /* Helper function for omp_tsort_mapping_groups.  Returns TRUE on success, or
   10091    FALSE on error.  */
   10092 
   10093 static bool
   10094 omp_tsort_mapping_groups_1 (omp_mapping_group ***outlist,
   10095 			    vec<omp_mapping_group> *groups,
   10096 			    hash_map<tree_operand_hash_no_se,
   10097 				     omp_mapping_group *> *grpmap,
   10098 			    omp_mapping_group *grp)
   10099 {
   10100   if (grp->mark == PERMANENT)
   10101     return true;
   10102   if (grp->mark == TEMPORARY)
   10103     {
   10104       fprintf (stderr, "when processing group:\n");
   10105       debug_mapping_group (grp);
   10106       internal_error ("base pointer cycle detected");
   10107       return false;
   10108     }
   10109   grp->mark = TEMPORARY;
   10110 
   10111   tree attaches_to = omp_get_attachment (grp);
   10112 
   10113   if (attaches_to)
   10114     {
   10115       omp_mapping_group **basep = grpmap->get (attaches_to);
   10116 
   10117       if (basep && *basep != grp)
   10118 	{
   10119 	  for (omp_mapping_group *w = *basep; w; w = w->sibling)
   10120 	    if (!omp_tsort_mapping_groups_1 (outlist, groups, grpmap, w))
   10121 	      return false;
   10122 	}
   10123     }
   10124 
   10125   tree decl = OMP_CLAUSE_DECL (*grp->grp_start);
   10126 
   10127   while (decl)
   10128     {
   10129       tree base = omp_get_base_pointer (decl);
   10130 
   10131       if (!base)
   10132 	break;
   10133 
   10134       omp_mapping_group **innerp = grpmap->get (base);
   10135       omp_mapping_group *wholestruct;
   10136 
   10137       /* We should treat whole-structure mappings as if all (pointer, in this
   10138 	 case) members are mapped as individual list items.  Check if we have
   10139 	 such a whole-structure mapping, if we don't have an explicit reference
   10140 	 to the pointer member itself.  */
   10141       if (!innerp
   10142 	  && TREE_CODE (base) == COMPONENT_REF
   10143 	  && omp_mapped_by_containing_struct (grpmap, base, &wholestruct))
   10144 	innerp = &wholestruct;
   10145 
   10146       if (innerp && *innerp != grp)
   10147 	{
   10148 	  for (omp_mapping_group *w = *innerp; w; w = w->sibling)
   10149 	    if (!omp_tsort_mapping_groups_1 (outlist, groups, grpmap, w))
   10150 	      return false;
   10151 	  break;
   10152 	}
   10153 
   10154       decl = base;
   10155     }
   10156 
   10157   grp->mark = PERMANENT;
   10158 
   10159   /* Emit grp to output list.  */
   10160 
   10161   **outlist = grp;
   10162   *outlist = &grp->next;
   10163 
   10164   return true;
   10165 }
   10166 
   10167 /* Topologically sort GROUPS, so that OMP 5.0-defined base pointers come
   10168    before mappings that use those pointers.  This is an implementation of the
   10169    depth-first search algorithm, described e.g. at:
   10170 
   10171      https://en.wikipedia.org/wiki/Topological_sorting
   10172 */
   10173 
   10174 static omp_mapping_group *
   10175 omp_tsort_mapping_groups (vec<omp_mapping_group> *groups,
   10176 			  hash_map<tree_operand_hash_no_se, omp_mapping_group *>
   10177 			    *grpmap,
   10178 			  bool enter_exit_data)
   10179 {
   10180   omp_mapping_group *grp, *outlist = NULL, **cursor;
   10181   unsigned int i;
   10182   bool saw_runtime_implicit = false;
   10183 
   10184   cursor = &outlist;
   10185 
   10186   FOR_EACH_VEC_ELT (*groups, i, grp)
   10187     {
   10188       if (grp->mark != PERMANENT)
   10189 	{
   10190 	  if (OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start))
   10191 	    {
   10192 	      saw_runtime_implicit = true;
   10193 	      continue;
   10194 	    }
   10195 	  if (!omp_tsort_mapping_groups_1 (&cursor, groups, grpmap, grp))
   10196 	    return NULL;
   10197 	}
   10198     }
   10199 
   10200   if (!saw_runtime_implicit)
   10201     return outlist;
   10202 
   10203   FOR_EACH_VEC_ELT (*groups, i, grp)
   10204     {
   10205       if (grp->mark != PERMANENT
   10206 	  && OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start))
   10207 	{
   10208 	  /* Clear the flag for enter/exit data because it is currently
   10209 	     meaningless for those operations in libgomp.  */
   10210 	  if (enter_exit_data)
   10211 	    OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start) = 0;
   10212 
   10213 	  if (!omp_tsort_mapping_groups_1 (&cursor, groups, grpmap, grp))
   10214 	    return NULL;
   10215 	}
   10216     }
   10217 
   10218   return outlist;
   10219 }
   10220 
   10221 /* Split INLIST into three parts:
   10222 
   10223      - "present" alloc/to/from groups
   10224      - other to/from groups
   10225      - other alloc/release/delete groups
   10226 
   10227    These sub-lists are then concatenated together to form the final list.
   10228    Each sub-list retains the order of the original list.
   10229    Note that ATTACH nodes are later moved to the end of the list in
   10230    gimplify_adjust_omp_clauses, for target regions.  */
   10231 
   10232 static omp_mapping_group *
   10233 omp_segregate_mapping_groups (omp_mapping_group *inlist)
   10234 {
   10235   omp_mapping_group *ard_groups = NULL, *tf_groups = NULL;
   10236   omp_mapping_group *p_groups = NULL;
   10237   omp_mapping_group **ard_tail = &ard_groups, **tf_tail = &tf_groups;
   10238   omp_mapping_group **p_tail = &p_groups;
   10239 
   10240   for (omp_mapping_group *w = inlist; w;)
   10241     {
   10242       tree c = *w->grp_start;
   10243       omp_mapping_group *next = w->next;
   10244 
   10245       gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP);
   10246 
   10247       switch (OMP_CLAUSE_MAP_KIND (c))
   10248 	{
   10249 	case GOMP_MAP_ALLOC:
   10250 	case GOMP_MAP_RELEASE:
   10251 	case GOMP_MAP_DELETE:
   10252 	  *ard_tail = w;
   10253 	  w->next = NULL;
   10254 	  ard_tail = &w->next;
   10255 	  break;
   10256 
   10257 	/* These map types are all semantically identical, so are moved into a
   10258 	   single group.  They will each be changed into GOMP_MAP_FORCE_PRESENT
   10259 	   in gimplify_adjust_omp_clauses.  */
   10260 	case GOMP_MAP_PRESENT_ALLOC:
   10261 	case GOMP_MAP_PRESENT_FROM:
   10262 	case GOMP_MAP_PRESENT_TO:
   10263 	case GOMP_MAP_PRESENT_TOFROM:
   10264 	  *p_tail = w;
   10265 	  w->next = NULL;
   10266 	  p_tail = &w->next;
   10267 	  break;
   10268 
   10269 	default:
   10270 	  *tf_tail = w;
   10271 	  w->next = NULL;
   10272 	  tf_tail = &w->next;
   10273 	}
   10274 
   10275       w = next;
   10276     }
   10277 
   10278   /* Now splice the lists together...  */
   10279   *tf_tail = ard_groups;
   10280   *p_tail = tf_groups;
   10281 
   10282   return p_groups;
   10283 }
   10284 
   10285 /* Given a list LIST_P containing groups of mappings given by GROUPS, reorder
   10286    those groups based on the output list of omp_tsort_mapping_groups --
   10287    singly-linked, threaded through each element's NEXT pointer starting at
   10288    HEAD.  Each list element appears exactly once in that linked list.
   10289 
   10290    Each element of GROUPS may correspond to one or several mapping nodes.
   10291    Node groups are kept together, and in the reordered list, the positions of
   10292    the original groups are reused for the positions of the reordered list.
   10293    Hence if we have e.g.
   10294 
   10295      {to ptr ptr} firstprivate {tofrom ptr} ...
   10296       ^             ^           ^
   10297       first group  non-"map"    second group
   10298 
   10299    and say the second group contains a base pointer for the first so must be
   10300    moved before it, the resulting list will contain:
   10301 
   10302      {tofrom ptr} firstprivate {to ptr ptr} ...
   10303       ^ prev. second group      ^ prev. first group
   10304 */
   10305 
   10306 static tree *
   10307 omp_reorder_mapping_groups (vec<omp_mapping_group> *groups,
   10308 			    omp_mapping_group *head,
   10309 			    tree *list_p)
   10310 {
   10311   omp_mapping_group *grp;
   10312   unsigned int i;
   10313   unsigned numgroups = groups->length ();
   10314   auto_vec<tree> old_heads (numgroups);
   10315   auto_vec<tree *> old_headps (numgroups);
   10316   auto_vec<tree> new_heads (numgroups);
   10317   auto_vec<tree> old_succs (numgroups);
   10318   bool map_at_start = (list_p == (*groups)[0].grp_start);
   10319 
   10320   tree *new_grp_tail = NULL;
   10321 
   10322   /* Stash the start & end nodes of each mapping group before we start
   10323      modifying the list.  */
   10324   FOR_EACH_VEC_ELT (*groups, i, grp)
   10325     {
   10326       old_headps.quick_push (grp->grp_start);
   10327       old_heads.quick_push (*grp->grp_start);
   10328       old_succs.quick_push (OMP_CLAUSE_CHAIN (grp->grp_end));
   10329     }
   10330 
   10331   /* And similarly, the heads of the groups in the order we want to rearrange
   10332      the list to.  */
   10333   for (omp_mapping_group *w = head; w; w = w->next)
   10334     new_heads.quick_push (*w->grp_start);
   10335 
   10336   FOR_EACH_VEC_ELT (*groups, i, grp)
   10337     {
   10338       gcc_assert (head);
   10339 
   10340       if (new_grp_tail && old_succs[i - 1] == old_heads[i])
   10341 	{
   10342 	  /* a {b c d} {e f g} h i j   (original)
   10343 	     -->
   10344 	     a {k l m} {e f g} h i j   (inserted new group on last iter)
   10345 	     -->
   10346 	     a {k l m} {n o p} h i j   (this time, chain last group to new one)
   10347 		      ^new_grp_tail
   10348 	  */
   10349 	  *new_grp_tail = new_heads[i];
   10350 	}
   10351       else if (new_grp_tail)
   10352 	{
   10353 	  /* a {b c d} e {f g h} i j k   (original)
   10354 	     -->
   10355 	     a {l m n} e {f g h} i j k   (gap after last iter's group)
   10356 	     -->
   10357 	     a {l m n} e {o p q} h i j   (chain last group to old successor)
   10358 		      ^new_grp_tail
   10359 	   */
   10360 	  *new_grp_tail = old_succs[i - 1];
   10361 	  *old_headps[i] = new_heads[i];
   10362 	}
   10363       else
   10364 	{
   10365 	  /* The first inserted group -- point to new group, and leave end
   10366 	     open.
   10367 	     a {b c d} e f
   10368 	     -->
   10369 	     a {g h i...
   10370 	  */
   10371 	  *grp->grp_start = new_heads[i];
   10372 	}
   10373 
   10374       new_grp_tail = &OMP_CLAUSE_CHAIN (head->grp_end);
   10375 
   10376       head = head->next;
   10377     }
   10378 
   10379   if (new_grp_tail)
   10380     *new_grp_tail = old_succs[numgroups - 1];
   10381 
   10382   gcc_assert (!head);
   10383 
   10384   return map_at_start ? (*groups)[0].grp_start : list_p;
   10385 }
   10386 
   10387 /* DECL is supposed to have lastprivate semantics in the outer contexts
   10388    of combined/composite constructs, starting with OCTX.
   10389    Add needed lastprivate, shared or map clause if no data sharing or
   10390    mapping clause are present.  IMPLICIT_P is true if it is an implicit
   10391    clause (IV on simd), in which case the lastprivate will not be
   10392    copied to some constructs.  */
   10393 
   10394 static void
   10395 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx,
   10396 					       tree decl, bool implicit_p)
   10397 {
   10398   struct gimplify_omp_ctx *orig_octx = octx;
   10399   for (; octx; octx = octx->outer_context)
   10400     {
   10401       if ((octx->region_type == ORT_COMBINED_PARALLEL
   10402 	   || (octx->region_type & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS)
   10403 	  && splay_tree_lookup (octx->variables,
   10404 				(splay_tree_key) decl) == NULL)
   10405 	{
   10406 	  omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
   10407 	  continue;
   10408 	}
   10409       if ((octx->region_type & ORT_TASK) != 0
   10410 	  && octx->combined_loop
   10411 	  && splay_tree_lookup (octx->variables,
   10412 				(splay_tree_key) decl) == NULL)
   10413 	{
   10414 	  omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
   10415 	  continue;
   10416 	}
   10417       if (implicit_p
   10418 	  && octx->region_type == ORT_WORKSHARE
   10419 	  && octx->combined_loop
   10420 	  && splay_tree_lookup (octx->variables,
   10421 				(splay_tree_key) decl) == NULL
   10422 	  && octx->outer_context
   10423 	  && octx->outer_context->region_type == ORT_COMBINED_PARALLEL
   10424 	  && splay_tree_lookup (octx->outer_context->variables,
   10425 				(splay_tree_key) decl) == NULL)
   10426 	{
   10427 	  octx = octx->outer_context;
   10428 	  omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
   10429 	  continue;
   10430 	}
   10431       if ((octx->region_type == ORT_WORKSHARE || octx->region_type == ORT_ACC)
   10432 	  && octx->combined_loop
   10433 	  && splay_tree_lookup (octx->variables,
   10434 				(splay_tree_key) decl) == NULL
   10435 	  && !omp_check_private (octx, decl, false))
   10436 	{
   10437 	  omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
   10438 	  continue;
   10439 	}
   10440       if (octx->region_type == ORT_COMBINED_TARGET)
   10441 	{
   10442 	  splay_tree_node n = splay_tree_lookup (octx->variables,
   10443 						 (splay_tree_key) decl);
   10444 	  if (n == NULL)
   10445 	    {
   10446 	      omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
   10447 	      octx = octx->outer_context;
   10448 	    }
   10449 	  else if (!implicit_p
   10450 		   && (n->value & GOVD_FIRSTPRIVATE_IMPLICIT))
   10451 	    {
   10452 	      n->value &= ~(GOVD_FIRSTPRIVATE
   10453 			    | GOVD_FIRSTPRIVATE_IMPLICIT
   10454 			    | GOVD_EXPLICIT);
   10455 	      omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
   10456 	      octx = octx->outer_context;
   10457 	    }
   10458 	}
   10459       break;
   10460     }
   10461   if (octx && (implicit_p || octx != orig_octx))
   10462     omp_notice_variable (octx, decl, true);
   10463 }
   10464 
   10465 /* We might have indexed several groups for DECL, e.g. a "TO" mapping and also
   10466    a "FIRSTPRIVATE" mapping.  Return the one that isn't firstprivate, etc.  */
   10467 
   10468 static omp_mapping_group *
   10469 omp_get_nonfirstprivate_group (hash_map<tree_operand_hash_no_se,
   10470 					omp_mapping_group *> *grpmap,
   10471 			       tree decl, bool allow_deleted = false)
   10472 {
   10473   omp_mapping_group **to_group_p = grpmap->get (decl);
   10474 
   10475   if (!to_group_p)
   10476     return NULL;
   10477 
   10478   omp_mapping_group *to_group = *to_group_p;
   10479 
   10480   for (; to_group; to_group = to_group->sibling)
   10481     {
   10482       tree grp_end = to_group->grp_end;
   10483       switch (OMP_CLAUSE_MAP_KIND (grp_end))
   10484 	{
   10485 	case GOMP_MAP_FIRSTPRIVATE_POINTER:
   10486 	case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   10487 	  break;
   10488 
   10489 	default:
   10490 	  if (allow_deleted || !to_group->deleted)
   10491 	    return to_group;
   10492 	}
   10493     }
   10494 
   10495   return NULL;
   10496 }
   10497 
   10498 /* Return TRUE if the directive (whose clauses are described by the hash table
   10499    of mapping groups, GRPMAP) maps DECL explicitly.  If TO_SPECIFICALLY is
   10500    true, only count TO mappings.  If ALLOW_DELETED is true, ignore the
   10501    "deleted" flag for groups.  If CONTAINED_IN_STRUCT is true, also return
   10502    TRUE if DECL is mapped as a member of a whole-struct mapping.  */
   10503 
   10504 static bool
   10505 omp_directive_maps_explicitly (hash_map<tree_operand_hash_no_se,
   10506 					omp_mapping_group *> *grpmap,
   10507 			       tree decl, omp_mapping_group **base_group,
   10508 			       bool to_specifically, bool allow_deleted,
   10509 			       bool contained_in_struct)
   10510 {
   10511   omp_mapping_group *decl_group
   10512     = omp_get_nonfirstprivate_group (grpmap, decl, allow_deleted);
   10513 
   10514   *base_group = NULL;
   10515 
   10516   if (decl_group)
   10517     {
   10518       tree grp_first = *decl_group->grp_start;
   10519       /* We might be called during omp_build_struct_sibling_lists, when
   10520 	 GOMP_MAP_STRUCT might have been inserted at the start of the group.
   10521 	 Skip over that, and also possibly the node after it.  */
   10522       if (OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_STRUCT
   10523 	  || OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_STRUCT_UNORD)
   10524 	{
   10525 	  grp_first = OMP_CLAUSE_CHAIN (grp_first);
   10526 	  if (OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_FIRSTPRIVATE_POINTER
   10527 	      || (OMP_CLAUSE_MAP_KIND (grp_first)
   10528 		  == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   10529 	      || OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_ATTACH_DETACH)
   10530 	    grp_first = OMP_CLAUSE_CHAIN (grp_first);
   10531 	}
   10532       enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first);
   10533       if (!to_specifically
   10534 	  || GOMP_MAP_COPY_TO_P (first_kind)
   10535 	  || first_kind == GOMP_MAP_ALLOC)
   10536 	{
   10537 	  *base_group = decl_group;
   10538 	  return true;
   10539 	}
   10540     }
   10541 
   10542   if (contained_in_struct
   10543       && omp_mapped_by_containing_struct (grpmap, decl, base_group))
   10544     return true;
   10545 
   10546   return false;
   10547 }
   10548 
   10549 /* If we have mappings INNER and OUTER, where INNER is a component access and
   10550    OUTER is a mapping of the whole containing struct, check that the mappings
   10551    are compatible.  We'll be deleting the inner mapping, so we need to make
   10552    sure the outer mapping does (at least) the same transfers to/from the device
   10553    as the inner mapping.  */
   10554 
   10555 bool
   10556 omp_check_mapping_compatibility (location_t loc,
   10557 				 omp_mapping_group *outer,
   10558 				 omp_mapping_group *inner)
   10559 {
   10560   tree first_outer = *outer->grp_start, first_inner = *inner->grp_start;
   10561 
   10562   gcc_assert (OMP_CLAUSE_CODE (first_outer) == OMP_CLAUSE_MAP);
   10563   gcc_assert (OMP_CLAUSE_CODE (first_inner) == OMP_CLAUSE_MAP);
   10564 
   10565   enum gomp_map_kind outer_kind = OMP_CLAUSE_MAP_KIND (first_outer);
   10566   enum gomp_map_kind inner_kind = OMP_CLAUSE_MAP_KIND (first_inner);
   10567 
   10568   if (outer_kind == inner_kind)
   10569     return true;
   10570 
   10571   switch (outer_kind)
   10572     {
   10573     case GOMP_MAP_ALWAYS_TO:
   10574       if (inner_kind == GOMP_MAP_FORCE_PRESENT
   10575 	  || inner_kind == GOMP_MAP_ALLOC
   10576 	  || inner_kind == GOMP_MAP_TO)
   10577 	return true;
   10578       break;
   10579 
   10580     case GOMP_MAP_ALWAYS_FROM:
   10581       if (inner_kind == GOMP_MAP_FORCE_PRESENT
   10582 	  || inner_kind == GOMP_MAP_RELEASE
   10583 	  || inner_kind == GOMP_MAP_FROM)
   10584 	return true;
   10585       break;
   10586 
   10587     case GOMP_MAP_TO:
   10588       if (inner_kind == GOMP_MAP_FORCE_PRESENT
   10589 	  || inner_kind == GOMP_MAP_ALLOC)
   10590 	return true;
   10591       break;
   10592 
   10593     case GOMP_MAP_FROM:
   10594       if (inner_kind == GOMP_MAP_RELEASE
   10595 	  || inner_kind == GOMP_MAP_FORCE_PRESENT)
   10596 	return true;
   10597       break;
   10598 
   10599     case GOMP_MAP_ALWAYS_TOFROM:
   10600     case GOMP_MAP_TOFROM:
   10601       if (inner_kind == GOMP_MAP_FORCE_PRESENT
   10602 	  || inner_kind == GOMP_MAP_ALLOC
   10603 	  || inner_kind == GOMP_MAP_TO
   10604 	  || inner_kind == GOMP_MAP_FROM
   10605 	  || inner_kind == GOMP_MAP_TOFROM)
   10606 	return true;
   10607       break;
   10608 
   10609     default:
   10610       ;
   10611     }
   10612 
   10613   error_at (loc, "data movement for component %qE is not compatible with "
   10614 	    "movement for struct %qE", OMP_CLAUSE_DECL (first_inner),
   10615 	    OMP_CLAUSE_DECL (first_outer));
   10616 
   10617   return false;
   10618 }
   10619 
   10620 /* This function handles several cases where clauses on a mapping directive
   10621    can interact with each other.
   10622 
   10623    If we have a FIRSTPRIVATE_POINTER node and we're also mapping the pointer
   10624    on the same directive, change the mapping of the first node to
   10625    ATTACH_DETACH.  We should have detected that this will happen already in
   10626    c-omp.cc:c_omp_adjust_map_clauses and marked the appropriate decl
   10627    as addressable.  (If we didn't, bail out.)
   10628 
   10629    If we have a FIRSTPRIVATE_REFERENCE (for a reference to pointer) and we're
   10630    mapping the base pointer also, we may need to change the mapping type to
   10631    ATTACH_DETACH and synthesize an alloc node for the reference itself.
   10632 
   10633    If we have an ATTACH_DETACH node, this is an array section with a pointer
   10634    base.  If we're mapping the base on the same directive too, we can drop its
   10635    mapping.  However, if we have a reference to pointer, make other appropriate
   10636    adjustments to the mapping nodes instead.
   10637 
   10638    If we have an ATTACH_DETACH node with a Fortran pointer-set (array
   10639    descriptor) mapping for a derived-type component, and we're also mapping the
   10640    whole of the derived-type variable on another clause, the pointer-set
   10641    mapping is removed.
   10642 
   10643    If we have a component access but we're also mapping the whole of the
   10644    containing struct, drop the former access.
   10645 
   10646    If the expression is a component access, and we're also mapping a base
   10647    pointer used in that component access in the same expression, change the
   10648    mapping type of the latter to ALLOC (ready for processing by
   10649    omp_build_struct_sibling_lists).  */
   10650 
   10651 void
   10652 omp_resolve_clause_dependencies (enum tree_code code,
   10653 				 vec<omp_mapping_group> *groups,
   10654 				 hash_map<tree_operand_hash_no_se,
   10655 					  omp_mapping_group *> *grpmap)
   10656 {
   10657   int i;
   10658   omp_mapping_group *grp;
   10659   bool repair_chain = false;
   10660 
   10661   FOR_EACH_VEC_ELT (*groups, i, grp)
   10662     {
   10663       tree grp_end = grp->grp_end;
   10664       tree decl = OMP_CLAUSE_DECL (grp_end);
   10665 
   10666       gcc_assert (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP);
   10667 
   10668       switch (OMP_CLAUSE_MAP_KIND (grp_end))
   10669 	{
   10670 	case GOMP_MAP_FIRSTPRIVATE_POINTER:
   10671 	  {
   10672 	    omp_mapping_group *to_group
   10673 	      = omp_get_nonfirstprivate_group (grpmap, decl);
   10674 
   10675 	    if (!to_group || to_group == grp)
   10676 	      continue;
   10677 
   10678 	    tree grp_first = *to_group->grp_start;
   10679 	    enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first);
   10680 
   10681 	    if ((GOMP_MAP_COPY_TO_P (first_kind)
   10682 		 || first_kind == GOMP_MAP_ALLOC)
   10683 		&& (OMP_CLAUSE_MAP_KIND (to_group->grp_end)
   10684 		    != GOMP_MAP_FIRSTPRIVATE_POINTER))
   10685 	      {
   10686 		gcc_assert (TREE_ADDRESSABLE (OMP_CLAUSE_DECL (grp_end)));
   10687 		OMP_CLAUSE_SET_MAP_KIND (grp_end, GOMP_MAP_ATTACH_DETACH);
   10688 	      }
   10689 	  }
   10690 	  break;
   10691 
   10692 	case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   10693 	  {
   10694 	    tree ptr = build_fold_indirect_ref (decl);
   10695 
   10696 	    omp_mapping_group *to_group
   10697 	      = omp_get_nonfirstprivate_group (grpmap, ptr);
   10698 
   10699 	    if (!to_group || to_group == grp)
   10700 	      continue;
   10701 
   10702 	    tree grp_first = *to_group->grp_start;
   10703 	    enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first);
   10704 
   10705 	    if (GOMP_MAP_COPY_TO_P (first_kind)
   10706 		|| first_kind == GOMP_MAP_ALLOC)
   10707 	      {
   10708 		OMP_CLAUSE_SET_MAP_KIND (grp_end, GOMP_MAP_ATTACH_DETACH);
   10709 		OMP_CLAUSE_DECL (grp_end) = ptr;
   10710 		if ((OMP_CLAUSE_CHAIN (*to_group->grp_start)
   10711 		     == to_group->grp_end)
   10712 		    && (OMP_CLAUSE_MAP_KIND (to_group->grp_end)
   10713 			== GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   10714 		  {
   10715 		    gcc_assert (TREE_ADDRESSABLE
   10716 				  (OMP_CLAUSE_DECL (to_group->grp_end)));
   10717 		    OMP_CLAUSE_SET_MAP_KIND (to_group->grp_end,
   10718 					     GOMP_MAP_ATTACH_DETACH);
   10719 
   10720 		    location_t loc = OMP_CLAUSE_LOCATION (to_group->grp_end);
   10721 		    tree alloc
   10722 		      = build_omp_clause (loc, OMP_CLAUSE_MAP);
   10723 		    OMP_CLAUSE_SET_MAP_KIND (alloc, GOMP_MAP_ALLOC);
   10724 		    tree tmp = build_fold_addr_expr (OMP_CLAUSE_DECL
   10725 						      (to_group->grp_end));
   10726 		    tree char_ptr_type = build_pointer_type (char_type_node);
   10727 		    OMP_CLAUSE_DECL (alloc)
   10728 		      = build2 (MEM_REF, char_type_node,
   10729 				tmp,
   10730 				build_int_cst (char_ptr_type, 0));
   10731 		    OMP_CLAUSE_SIZE (alloc) = TYPE_SIZE_UNIT (TREE_TYPE (tmp));
   10732 
   10733 		    OMP_CLAUSE_CHAIN (alloc)
   10734 		      = OMP_CLAUSE_CHAIN (*to_group->grp_start);
   10735 		    OMP_CLAUSE_CHAIN (*to_group->grp_start) = alloc;
   10736 		  }
   10737 	      }
   10738 	  }
   10739 	  break;
   10740 
   10741 	case GOMP_MAP_ATTACH_DETACH:
   10742 	case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   10743 	  {
   10744 	    tree base_ptr, referenced_ptr_node = NULL_TREE;
   10745 
   10746 	    while (TREE_CODE (decl) == ARRAY_REF)
   10747 	      decl = TREE_OPERAND (decl, 0);
   10748 
   10749 	    if (TREE_CODE (decl) == INDIRECT_REF)
   10750 	      decl = TREE_OPERAND (decl, 0);
   10751 
   10752 	    /* Only component accesses.  */
   10753 	    if (DECL_P (decl))
   10754 	      continue;
   10755 
   10756 	    /* We want the pointer itself when checking if the base pointer is
   10757 	       mapped elsewhere in the same directive -- if we have a
   10758 	       reference to the pointer, don't use that.  */
   10759 
   10760 	    if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
   10761 		&& TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
   10762 	      {
   10763 		referenced_ptr_node = OMP_CLAUSE_CHAIN (*grp->grp_start);
   10764 		base_ptr = OMP_CLAUSE_DECL (referenced_ptr_node);
   10765 	      }
   10766 	    else
   10767 	      base_ptr = decl;
   10768 
   10769 	    gomp_map_kind zlas_kind
   10770 	      = (code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
   10771 		? GOMP_MAP_DETACH : GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION;
   10772 
   10773 	    if (TREE_CODE (TREE_TYPE (base_ptr)) == POINTER_TYPE)
   10774 	      {
   10775 		/* If we map the base TO, and we're doing an attachment, we can
   10776 		   skip the TO mapping altogether and create an ALLOC mapping
   10777 		   instead, since the attachment will overwrite the device
   10778 		   pointer in that location immediately anyway.  Otherwise,
   10779 		   change our mapping to
   10780 		   GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION in case the
   10781 		   attachment target has not been copied to the device already
   10782 		   by some earlier directive.  */
   10783 
   10784 		bool base_mapped_to = false;
   10785 
   10786 		omp_mapping_group *base_group;
   10787 
   10788 		if (omp_directive_maps_explicitly (grpmap, base_ptr,
   10789 						   &base_group, false, true,
   10790 						   false))
   10791 		  {
   10792 		    if (referenced_ptr_node)
   10793 		      {
   10794 			base_mapped_to = true;
   10795 			if ((OMP_CLAUSE_MAP_KIND (base_group->grp_end)
   10796 			     == GOMP_MAP_ATTACH_DETACH)
   10797 			    && (OMP_CLAUSE_CHAIN (*base_group->grp_start)
   10798 				== base_group->grp_end))
   10799 			  {
   10800 			    OMP_CLAUSE_CHAIN (*base_group->grp_start)
   10801 			      = OMP_CLAUSE_CHAIN (base_group->grp_end);
   10802 			    base_group->grp_end = *base_group->grp_start;
   10803 			    repair_chain = true;
   10804 			  }
   10805 		      }
   10806 		    else
   10807 		      {
   10808 			base_group->deleted = true;
   10809 			OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end) = 1;
   10810 		      }
   10811 		  }
   10812 
   10813 		/* We're dealing with a reference to a pointer, and we are
   10814 		   attaching both the reference and the pointer.  We know the
   10815 		   reference itself is on the target, because we are going to
   10816 		   create an ALLOC node for it in accumulate_sibling_list.  The
   10817 		   pointer might be on the target already or it might not, but
   10818 		   if it isn't then it's not an error, so use
   10819 		   GOMP_MAP_ATTACH_ZLAS for it.  */
   10820 		if (!base_mapped_to && referenced_ptr_node)
   10821 		  OMP_CLAUSE_SET_MAP_KIND (referenced_ptr_node, zlas_kind);
   10822 
   10823 		omp_mapping_group *struct_group;
   10824 		tree desc;
   10825 		if ((desc = OMP_CLAUSE_CHAIN (*grp->grp_start))
   10826 		    && omp_map_clause_descriptor_p (desc)
   10827 		    && omp_mapped_by_containing_struct (grpmap, decl,
   10828 							&struct_group))
   10829 		  /* If we have a pointer set but we're mapping (or unmapping)
   10830 		     the whole of the containing struct, we can remove the
   10831 		     pointer set mapping.  */
   10832 		  OMP_CLAUSE_CHAIN (*grp->grp_start) = OMP_CLAUSE_CHAIN (desc);
   10833 	      }
   10834 	    else if (TREE_CODE (TREE_TYPE (base_ptr)) == REFERENCE_TYPE
   10835 		     && (TREE_CODE (TREE_TYPE (TREE_TYPE (base_ptr)))
   10836 			 == ARRAY_TYPE)
   10837 		     && OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION
   10838 			  (*grp->grp_start))
   10839 	      OMP_CLAUSE_SET_MAP_KIND (grp->grp_end, zlas_kind);
   10840 	  }
   10841 	  break;
   10842 
   10843 	case GOMP_MAP_ATTACH:
   10844 	  /* Ignore standalone attach here.  */
   10845 	  break;
   10846 
   10847 	default:
   10848 	  {
   10849 	    omp_mapping_group *struct_group;
   10850 	    if (omp_mapped_by_containing_struct (grpmap, decl, &struct_group)
   10851 		&& *grp->grp_start == grp_end)
   10852 	      {
   10853 		omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end),
   10854 						 struct_group, grp);
   10855 		/* Remove the whole of this mapping -- redundant.  */
   10856 		grp->deleted = true;
   10857 	      }
   10858 
   10859 	    tree base = decl;
   10860 	    while ((base = omp_get_base_pointer (base)))
   10861 	      {
   10862 		omp_mapping_group *base_group;
   10863 
   10864 		if (omp_directive_maps_explicitly (grpmap, base, &base_group,
   10865 						   true, true, false))
   10866 		  {
   10867 		    tree grp_first = *base_group->grp_start;
   10868 		    OMP_CLAUSE_SET_MAP_KIND (grp_first, GOMP_MAP_ALLOC);
   10869 		  }
   10870 	      }
   10871 	  }
   10872 	}
   10873     }
   10874 
   10875   if (repair_chain)
   10876     {
   10877       /* Group start pointers may have become detached from the
   10878 	 OMP_CLAUSE_CHAIN of previous groups if elements were removed from the
   10879 	 end of those groups.  Fix that now.  */
   10880       tree *new_next = NULL;
   10881       FOR_EACH_VEC_ELT (*groups, i, grp)
   10882 	{
   10883 	  if (new_next)
   10884 	    grp->grp_start = new_next;
   10885 
   10886 	  new_next = &OMP_CLAUSE_CHAIN (grp->grp_end);
   10887 	}
   10888     }
   10889 }
   10890 
   10891 /* Similar to omp_resolve_clause_dependencies, but for OpenACC.  The only
   10892    clause dependencies we handle for now are struct element mappings and
   10893    whole-struct mappings on the same directive, and duplicate clause
   10894    detection.  */
   10895 
   10896 void
   10897 oacc_resolve_clause_dependencies (vec<omp_mapping_group> *groups,
   10898 				  hash_map<tree_operand_hash_no_se,
   10899 					   omp_mapping_group *> *grpmap)
   10900 {
   10901   int i;
   10902   omp_mapping_group *grp;
   10903   hash_set<tree_operand_hash> *seen_components = NULL;
   10904   hash_set<tree_operand_hash> *shown_error = NULL;
   10905 
   10906   FOR_EACH_VEC_ELT (*groups, i, grp)
   10907     {
   10908       tree grp_end = grp->grp_end;
   10909       tree decl = OMP_CLAUSE_DECL (grp_end);
   10910 
   10911       gcc_assert (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP);
   10912 
   10913       if (DECL_P (grp_end))
   10914 	continue;
   10915 
   10916       tree c = OMP_CLAUSE_DECL (*grp->grp_start);
   10917       while (TREE_CODE (c) == ARRAY_REF)
   10918 	c = TREE_OPERAND (c, 0);
   10919       if (TREE_CODE (c) != COMPONENT_REF)
   10920 	continue;
   10921       if (!seen_components)
   10922 	seen_components = new hash_set<tree_operand_hash> ();
   10923       if (!shown_error)
   10924 	shown_error = new hash_set<tree_operand_hash> ();
   10925       if (seen_components->contains (c)
   10926 	  && !shown_error->contains (c))
   10927 	{
   10928 	  error_at (OMP_CLAUSE_LOCATION (grp_end),
   10929 		    "%qE appears more than once in map clauses",
   10930 		    OMP_CLAUSE_DECL (grp_end));
   10931 	  shown_error->add (c);
   10932 	}
   10933       else
   10934 	seen_components->add (c);
   10935 
   10936       omp_mapping_group *struct_group;
   10937       if (omp_mapped_by_containing_struct (grpmap, decl, &struct_group)
   10938 	  && *grp->grp_start == grp_end)
   10939 	{
   10940 	  omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end),
   10941 					   struct_group, grp);
   10942 	  /* Remove the whole of this mapping -- redundant.  */
   10943 	  grp->deleted = true;
   10944 	}
   10945     }
   10946 
   10947   if (seen_components)
   10948     delete seen_components;
   10949   if (shown_error)
   10950     delete shown_error;
   10951 }
   10952 
   10953 /* Link node NEWNODE so it is pointed to by chain INSERT_AT.  NEWNODE's chain
   10954    is linked to the previous node pointed to by INSERT_AT.  */
   10955 
   10956 static tree *
   10957 omp_siblist_insert_node_after (tree newnode, tree *insert_at)
   10958 {
   10959   OMP_CLAUSE_CHAIN (newnode) = *insert_at;
   10960   *insert_at = newnode;
   10961   return &OMP_CLAUSE_CHAIN (newnode);
   10962 }
   10963 
   10964 /* Move NODE (which is currently pointed to by the chain OLD_POS) so it is
   10965    pointed to by chain MOVE_AFTER instead.  */
   10966 
   10967 static void
   10968 omp_siblist_move_node_after (tree node, tree *old_pos, tree *move_after)
   10969 {
   10970   gcc_assert (node == *old_pos);
   10971   *old_pos = OMP_CLAUSE_CHAIN (node);
   10972   OMP_CLAUSE_CHAIN (node) = *move_after;
   10973   *move_after = node;
   10974 }
   10975 
   10976 /* Move nodes from FIRST_PTR (pointed to by previous node's chain) to
   10977    LAST_NODE to after MOVE_AFTER chain.  Similar to below function, but no
   10978    new nodes are prepended to the list before splicing into the new position.
   10979    Return the position we should continue scanning the list at, or NULL to
   10980    stay where we were.  */
   10981 
   10982 static tree *
   10983 omp_siblist_move_nodes_after (tree *first_ptr, tree last_node,
   10984 			      tree *move_after)
   10985 {
   10986   if (first_ptr == move_after)
   10987     return NULL;
   10988 
   10989   tree tmp = *first_ptr;
   10990   *first_ptr = OMP_CLAUSE_CHAIN (last_node);
   10991   OMP_CLAUSE_CHAIN (last_node) = *move_after;
   10992   *move_after = tmp;
   10993 
   10994   return first_ptr;
   10995 }
   10996 
   10997 /* Concatenate two lists described by [FIRST_NEW, LAST_NEW_TAIL] and
   10998    [FIRST_PTR, LAST_NODE], and insert them in the OMP clause list after chain
   10999    pointer MOVE_AFTER.
   11000 
   11001    The latter list was previously part of the OMP clause list, and the former
   11002    (prepended) part is comprised of new nodes.
   11003 
   11004    We start with a list of nodes starting with a struct mapping node.  We
   11005    rearrange the list so that new nodes starting from FIRST_NEW and whose last
   11006    node's chain is LAST_NEW_TAIL comes directly after MOVE_AFTER, followed by
   11007    the group of mapping nodes we are currently processing (from the chain
   11008    FIRST_PTR to LAST_NODE).  The return value is the pointer to the next chain
   11009    we should continue processing from, or NULL to stay where we were.
   11010 
   11011    The transformation (in the case where MOVE_AFTER and FIRST_PTR are
   11012    different) is worked through below.  Here we are processing LAST_NODE, and
   11013    FIRST_PTR points at the preceding mapping clause:
   11014 
   11015   #. mapping node		chain
   11016   ---------------------------------------------------
   11017   A. struct_node		[->B]
   11018   B. comp_1			[->C]
   11019   C. comp_2			[->D (move_after)]
   11020   D. map_to_3			[->E]
   11021   E. attach_3			[->F (first_ptr)]
   11022   F. map_to_4			[->G (continue_at)]
   11023   G. attach_4 (last_node)	[->H]
   11024   H. ...
   11025 
   11026      *last_new_tail = *first_ptr;
   11027 
   11028   I. new_node (first_new)	[->F (last_new_tail)]
   11029 
   11030      *first_ptr = OMP_CLAUSE_CHAIN (last_node)
   11031 
   11032   #. mapping node		chain
   11033   ----------------------------------------------------
   11034   A. struct_node		[->B]
   11035   B. comp_1			[->C]
   11036   C. comp_2			[->D (move_after)]
   11037   D. map_to_3			[->E]
   11038   E. attach_3			[->H (first_ptr)]
   11039   F. map_to_4			[->G (continue_at)]
   11040   G. attach_4 (last_node)	[->H]
   11041   H. ...
   11042 
   11043   I. new_node (first_new)	[->F  (last_new_tail)]
   11044 
   11045      OMP_CLAUSE_CHAIN (last_node) = *move_after;
   11046 
   11047   #. mapping node		chain
   11048   ---------------------------------------------------
   11049   A. struct_node		[->B]
   11050   B. comp_1			[->C]
   11051   C. comp_2			[->D (move_after)]
   11052   D. map_to_3			[->E]
   11053   E. attach_3			[->H (continue_at)]
   11054   F. map_to_4			[->G]
   11055   G. attach_4 (last_node)	[->D]
   11056   H. ...
   11057 
   11058   I. new_node (first_new)	[->F  (last_new_tail)]
   11059 
   11060      *move_after = first_new;
   11061 
   11062   #. mapping node		chain
   11063   ---------------------------------------------------
   11064   A. struct_node		[->B]
   11065   B. comp_1			[->C]
   11066   C. comp_2			[->I (move_after)]
   11067   D. map_to_3			[->E]
   11068   E. attach_3			[->H (continue_at)]
   11069   F. map_to_4			[->G]
   11070   G. attach_4 (last_node)	[->D]
   11071   H. ...
   11072   I. new_node (first_new)	[->F (last_new_tail)]
   11073 
   11074   or, in order:
   11075 
   11076   #. mapping node		chain
   11077   ---------------------------------------------------
   11078   A. struct_node		[->B]
   11079   B. comp_1			[->C]
   11080   C. comp_2			[->I (move_after)]
   11081   I. new_node (first_new)	[->F (last_new_tail)]
   11082   F. map_to_4			[->G]
   11083   G. attach_4 (last_node)	[->D]
   11084   D. map_to_3			[->E]
   11085   E. attach_3			[->H (continue_at)]
   11086   H. ...
   11087 */
   11088 
   11089 static tree *
   11090 omp_siblist_move_concat_nodes_after (tree first_new, tree *last_new_tail,
   11091 				     tree *first_ptr, tree last_node,
   11092 				     tree *move_after)
   11093 {
   11094   tree *continue_at = NULL;
   11095   *last_new_tail = *first_ptr;
   11096   if (first_ptr == move_after)
   11097     *move_after = first_new;
   11098   else
   11099     {
   11100       *first_ptr = OMP_CLAUSE_CHAIN (last_node);
   11101       continue_at = first_ptr;
   11102       OMP_CLAUSE_CHAIN (last_node) = *move_after;
   11103       *move_after = first_new;
   11104     }
   11105   return continue_at;
   11106 }
   11107 
   11108 static omp_addr_token *
   11109 omp_first_chained_access_token (vec<omp_addr_token *> &addr_tokens)
   11110 {
   11111   using namespace omp_addr_tokenizer;
   11112   int idx = addr_tokens.length () - 1;
   11113   gcc_assert (idx >= 0);
   11114   if (addr_tokens[idx]->type != ACCESS_METHOD)
   11115     return addr_tokens[idx];
   11116   while (idx > 0 && addr_tokens[idx - 1]->type == ACCESS_METHOD)
   11117     idx--;
   11118   return addr_tokens[idx];
   11119 }
   11120 
   11121 /* Mapping struct members causes an additional set of nodes to be created,
   11122    starting with GOMP_MAP_STRUCT followed by a number of mappings equal to the
   11123    number of members being mapped, in order of ascending position (address or
   11124    bitwise).
   11125 
   11126    We scan through the list of mapping clauses, calling this function for each
   11127    struct member mapping we find, and build up the list of mappings after the
   11128    initial GOMP_MAP_STRUCT node.  For pointer members, these will be
   11129    newly-created ALLOC nodes.  For non-pointer members, the existing mapping is
   11130    moved into place in the sorted list.
   11131 
   11132      struct {
   11133        int *a;
   11134        int *b;
   11135        int c;
   11136        int *d;
   11137      };
   11138 
   11139      #pragma (acc|omp directive) copy(struct.a[0:n], struct.b[0:n], struct.c,
   11140 				      struct.d[0:n])
   11141 
   11142      GOMP_MAP_STRUCT (4)
   11143      [GOMP_MAP_FIRSTPRIVATE_REFERENCE -- for refs to structs]
   11144      GOMP_MAP_ALLOC  (struct.a)
   11145      GOMP_MAP_ALLOC  (struct.b)
   11146      GOMP_MAP_TO     (struct.c)
   11147      GOMP_MAP_ALLOC  (struct.d)
   11148      ...
   11149 
   11150    In the case where we are mapping references to pointers, or in Fortran if
   11151    we are mapping an array with a descriptor, additional nodes may be created
   11152    after the struct node list also.
   11153 
   11154    The return code is either a pointer to the next node to process (if the
   11155    list has been rearranged), else NULL to continue with the next node in the
   11156    original list.  */
   11157 
   11158 static tree *
   11159 omp_accumulate_sibling_list (enum omp_region_type region_type,
   11160 			     enum tree_code code,
   11161 			     hash_map<tree_operand_hash, tree>
   11162 			       *&struct_map_to_clause,
   11163 			     hash_map<tree_operand_hash_no_se,
   11164 				      omp_mapping_group *> *group_map,
   11165 			     tree *grp_start_p, tree grp_end,
   11166 			     vec<omp_addr_token *> &addr_tokens, tree **inner,
   11167 			     bool *fragile_p, bool reprocessing_struct,
   11168 			     tree **added_tail)
   11169 {
   11170   using namespace omp_addr_tokenizer;
   11171   poly_offset_int coffset;
   11172   poly_int64 cbitpos;
   11173   tree ocd = OMP_CLAUSE_DECL (grp_end);
   11174   bool openmp = !(region_type & ORT_ACC);
   11175   bool target = (region_type & ORT_TARGET) != 0;
   11176   tree *continue_at = NULL;
   11177 
   11178   while (TREE_CODE (ocd) == ARRAY_REF)
   11179     ocd = TREE_OPERAND (ocd, 0);
   11180 
   11181   if (*fragile_p)
   11182     {
   11183       omp_mapping_group *to_group
   11184 	= omp_get_nonfirstprivate_group (group_map, ocd, true);
   11185 
   11186       if (to_group)
   11187 	return NULL;
   11188     }
   11189 
   11190   omp_addr_token *last_token = omp_first_chained_access_token (addr_tokens);
   11191   if (last_token->type == ACCESS_METHOD)
   11192     {
   11193       switch (last_token->u.access_kind)
   11194 	{
   11195 	case ACCESS_REF:
   11196 	case ACCESS_REF_TO_POINTER:
   11197 	case ACCESS_REF_TO_POINTER_OFFSET:
   11198 	case ACCESS_INDEXED_REF_TO_ARRAY:
   11199 	  /* We may see either a bare reference or a dereferenced
   11200 	     "convert_from_reference"-like one here.  Handle either way.  */
   11201 	  if (TREE_CODE (ocd) == INDIRECT_REF)
   11202 	    ocd = TREE_OPERAND (ocd, 0);
   11203 	  gcc_assert (TREE_CODE (TREE_TYPE (ocd)) == REFERENCE_TYPE);
   11204 	  break;
   11205 
   11206 	default:
   11207 	  ;
   11208 	}
   11209     }
   11210 
   11211   bool variable_offset;
   11212   tree base
   11213     = extract_base_bit_offset (ocd, &cbitpos, &coffset, &variable_offset);
   11214 
   11215   int base_token;
   11216   for (base_token = addr_tokens.length () - 1; base_token >= 0; base_token--)
   11217     {
   11218       if (addr_tokens[base_token]->type == ARRAY_BASE
   11219 	  || addr_tokens[base_token]->type == STRUCTURE_BASE)
   11220 	break;
   11221     }
   11222 
   11223   /* The two expressions in the assertion below aren't quite the same: if we
   11224      have 'struct_base_decl access_indexed_array' for something like
   11225      "myvar[2].x" then base will be "myvar" and addr_tokens[base_token]->expr
   11226      will be "myvar[2]" -- the actual base of the structure.
   11227      The former interpretation leads to a strange situation where we get
   11228        struct(myvar) alloc(myvar[2].ptr1)
   11229      That is, the array of structures is kind of treated as one big structure
   11230      for the purposes of gathering sibling lists, etc.  */
   11231   /* gcc_assert (base == addr_tokens[base_token]->expr);  */
   11232 
   11233   bool attach_detach = ((OMP_CLAUSE_MAP_KIND (grp_end)
   11234 			 == GOMP_MAP_ATTACH_DETACH)
   11235 			|| (OMP_CLAUSE_MAP_KIND (grp_end)
   11236 			    == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION));
   11237   bool has_descriptor = false;
   11238   if (OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end)
   11239     {
   11240       tree grp_mid = OMP_CLAUSE_CHAIN (*grp_start_p);
   11241       if (grp_mid && omp_map_clause_descriptor_p (grp_mid))
   11242 	has_descriptor = true;
   11243     }
   11244 
   11245   if (!struct_map_to_clause || struct_map_to_clause->get (base) == NULL)
   11246     {
   11247       enum gomp_map_kind str_kind = GOMP_MAP_STRUCT;
   11248 
   11249       if (struct_map_to_clause == NULL)
   11250 	struct_map_to_clause = new hash_map<tree_operand_hash, tree>;
   11251 
   11252       if (variable_offset)
   11253 	str_kind = GOMP_MAP_STRUCT_UNORD;
   11254 
   11255       tree l = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
   11256 
   11257       OMP_CLAUSE_SET_MAP_KIND (l, str_kind);
   11258       OMP_CLAUSE_DECL (l) = unshare_expr (base);
   11259       OMP_CLAUSE_SIZE (l) = size_int (1);
   11260 
   11261       struct_map_to_clause->put (base, l);
   11262 
   11263       /* On first iterating through the clause list, we insert the struct node
   11264 	 just before the component access node that triggers the initial
   11265 	 omp_accumulate_sibling_list call for a particular sibling list (and
   11266 	 it then forms the first entry in that list).  When reprocessing
   11267 	 struct bases that are themselves component accesses, we insert the
   11268 	 struct node on an off-side list to avoid inserting the new
   11269 	 GOMP_MAP_STRUCT into the middle of the old one.  */
   11270       tree *insert_node_pos = reprocessing_struct ? *added_tail : grp_start_p;
   11271 
   11272       if (has_descriptor)
   11273 	{
   11274 	  tree desc = OMP_CLAUSE_CHAIN (*grp_start_p);
   11275 	  if (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
   11276 	    OMP_CLAUSE_SET_MAP_KIND (desc, GOMP_MAP_RELEASE);
   11277 	  tree sc = *insert_node_pos;
   11278 	  OMP_CLAUSE_CHAIN (l) = desc;
   11279 	  OMP_CLAUSE_CHAIN (*grp_start_p) = OMP_CLAUSE_CHAIN (desc);
   11280 	  OMP_CLAUSE_CHAIN (desc) = sc;
   11281 	  *insert_node_pos = l;
   11282 	}
   11283       else if (attach_detach)
   11284 	{
   11285 	  tree extra_node;
   11286 	  tree alloc_node
   11287 	    = build_omp_struct_comp_nodes (code, *grp_start_p, grp_end,
   11288 					   &extra_node);
   11289 	  tree *tail;
   11290 	  OMP_CLAUSE_CHAIN (l) = alloc_node;
   11291 
   11292 	  if (extra_node)
   11293 	    {
   11294 	      OMP_CLAUSE_CHAIN (extra_node) = *insert_node_pos;
   11295 	      OMP_CLAUSE_CHAIN (alloc_node) = extra_node;
   11296 	      tail = &OMP_CLAUSE_CHAIN (extra_node);
   11297 	    }
   11298 	  else
   11299 	    {
   11300 	      OMP_CLAUSE_CHAIN (alloc_node) = *insert_node_pos;
   11301 	      tail = &OMP_CLAUSE_CHAIN (alloc_node);
   11302 	    }
   11303 
   11304 	  /* For OpenMP semantics, we don't want to implicitly allocate
   11305 	     space for the pointer here for non-compute regions (e.g. "enter
   11306 	     data").  A FRAGILE_P node is only being created so that
   11307 	     omp-low.cc is able to rewrite the struct properly.
   11308 	     For references (to pointers), we want to actually allocate the
   11309 	     space for the reference itself in the sorted list following the
   11310 	     struct node.
   11311 	     For pointers, we want to allocate space if we had an explicit
   11312 	     mapping of the attachment point, but not otherwise.  */
   11313 	  if (*fragile_p
   11314 	      || (openmp
   11315 		  && !target
   11316 		  && attach_detach
   11317 		  && TREE_CODE (TREE_TYPE (ocd)) == POINTER_TYPE
   11318 		  && !OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end)))
   11319 	    {
   11320 	      if (!lang_GNU_Fortran ())
   11321 	       /* In Fortran, pointers are dereferenced automatically, but may
   11322 		  be unassociated.  So we still want to allocate space for the
   11323 		  pointer (as the base for an attach operation that should be
   11324 		  present in the same directive's clause list also).  */
   11325 		OMP_CLAUSE_SIZE (alloc_node) = size_zero_node;
   11326 	      OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (alloc_node) = 1;
   11327 	    }
   11328 
   11329 	  *insert_node_pos = l;
   11330 
   11331 	  if (reprocessing_struct)
   11332 	    {
   11333 	      /* When reprocessing a struct node group used as the base of a
   11334 		 subcomponent access, if we have a reference-to-pointer base,
   11335 		 we will see:
   11336 		   struct(**ptr) attach(*ptr)
   11337 		 whereas for a non-reprocess-struct group, we see, e.g.:
   11338 		   tofrom(**ptr) attach(*ptr) attach(ptr)
   11339 		 and we create the "alloc" for the second "attach", i.e.
   11340 		 for the reference itself.  When reprocessing a struct group we
   11341 		 thus change the pointer attachment into a reference attachment
   11342 		 by stripping the indirection.  (The attachment of the
   11343 		 referenced pointer must happen elsewhere, either on the same
   11344 		 directive, or otherwise.)  */
   11345 	      tree adecl = OMP_CLAUSE_DECL (alloc_node);
   11346 
   11347 	      if ((TREE_CODE (adecl) == INDIRECT_REF
   11348 		   || (TREE_CODE (adecl) == MEM_REF
   11349 		       && integer_zerop (TREE_OPERAND (adecl, 1))))
   11350 		  && (TREE_CODE (TREE_TYPE (TREE_OPERAND (adecl, 0)))
   11351 		      == REFERENCE_TYPE)
   11352 		  && (TREE_CODE (TREE_TYPE (TREE_TYPE
   11353 			(TREE_OPERAND (adecl, 0)))) == POINTER_TYPE))
   11354 		OMP_CLAUSE_DECL (alloc_node) = TREE_OPERAND (adecl, 0);
   11355 
   11356 	      *added_tail = tail;
   11357 	    }
   11358 	}
   11359       else
   11360 	{
   11361 	  gcc_assert (*grp_start_p == grp_end);
   11362 	  if (reprocessing_struct)
   11363 	    {
   11364 	      /* If we don't have an attach/detach node, this is a
   11365 		 "target data" directive or similar, not an offload region.
   11366 		 Synthesize an "alloc" node using just the initiating
   11367 		 GOMP_MAP_STRUCT decl.  */
   11368 	      gomp_map_kind k = (code == OMP_TARGET_EXIT_DATA
   11369 				 || code == OACC_EXIT_DATA)
   11370 				? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
   11371 	      tree alloc_node
   11372 		= build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
   11373 				    OMP_CLAUSE_MAP);
   11374 	      OMP_CLAUSE_SET_MAP_KIND (alloc_node, k);
   11375 	      OMP_CLAUSE_DECL (alloc_node) = unshare_expr (last_token->expr);
   11376 	      OMP_CLAUSE_SIZE (alloc_node)
   11377 		= TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (alloc_node)));
   11378 
   11379 	      OMP_CLAUSE_CHAIN (alloc_node) = OMP_CLAUSE_CHAIN (l);
   11380 	      OMP_CLAUSE_CHAIN (l) = alloc_node;
   11381 	      *insert_node_pos = l;
   11382 	      *added_tail = &OMP_CLAUSE_CHAIN (alloc_node);
   11383 	    }
   11384 	  else
   11385 	    grp_start_p = omp_siblist_insert_node_after (l, insert_node_pos);
   11386 	}
   11387 
   11388       unsigned last_access = base_token + 1;
   11389 
   11390       while (last_access + 1 < addr_tokens.length ()
   11391 	     && addr_tokens[last_access + 1]->type == ACCESS_METHOD)
   11392 	last_access++;
   11393 
   11394       if ((region_type & ORT_TARGET)
   11395 	  && addr_tokens[base_token + 1]->type == ACCESS_METHOD)
   11396 	{
   11397 	  bool base_ref = false;
   11398 	  access_method_kinds access_kind
   11399 	    = addr_tokens[last_access]->u.access_kind;
   11400 
   11401 	  switch (access_kind)
   11402 	    {
   11403 	    case ACCESS_DIRECT:
   11404 	    case ACCESS_INDEXED_ARRAY:
   11405 	      return NULL;
   11406 
   11407 	    case ACCESS_REF:
   11408 	    case ACCESS_REF_TO_POINTER:
   11409 	    case ACCESS_REF_TO_POINTER_OFFSET:
   11410 	    case ACCESS_INDEXED_REF_TO_ARRAY:
   11411 	      base_ref = true;
   11412 	      break;
   11413 
   11414 	    default:
   11415 	      ;
   11416 	    }
   11417 	  tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
   11418 				      OMP_CLAUSE_MAP);
   11419 	  enum gomp_map_kind mkind;
   11420 	  omp_mapping_group *decl_group;
   11421 	  tree use_base;
   11422 	  switch (access_kind)
   11423 	    {
   11424 	    case ACCESS_POINTER:
   11425 	    case ACCESS_POINTER_OFFSET:
   11426 	      use_base = addr_tokens[last_access]->expr;
   11427 	      break;
   11428 	    case ACCESS_REF_TO_POINTER:
   11429 	    case ACCESS_REF_TO_POINTER_OFFSET:
   11430 	      use_base
   11431 		= build_fold_indirect_ref (addr_tokens[last_access]->expr);
   11432 	      break;
   11433 	    default:
   11434 	      use_base = addr_tokens[base_token]->expr;
   11435 	    }
   11436 	  bool mapped_to_p
   11437 	    = omp_directive_maps_explicitly (group_map, use_base, &decl_group,
   11438 					     true, false, true);
   11439 	  if (addr_tokens[base_token]->type == STRUCTURE_BASE
   11440 	      && DECL_P (addr_tokens[last_access]->expr)
   11441 	      && !mapped_to_p)
   11442 	    mkind = base_ref ? GOMP_MAP_FIRSTPRIVATE_REFERENCE
   11443 			     : GOMP_MAP_FIRSTPRIVATE_POINTER;
   11444 	  else
   11445 	    mkind = GOMP_MAP_ATTACH_DETACH;
   11446 
   11447 	  OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
   11448 	  /* If we have a reference to pointer base, we want to attach the
   11449 	     pointer here, not the reference.  The reference attachment happens
   11450 	     elsewhere.  */
   11451 	  bool ref_to_ptr
   11452 	    = (access_kind == ACCESS_REF_TO_POINTER
   11453 	       || access_kind == ACCESS_REF_TO_POINTER_OFFSET);
   11454 	  tree sdecl = addr_tokens[last_access]->expr;
   11455 	  tree sdecl_ptr = ref_to_ptr ? build_fold_indirect_ref (sdecl)
   11456 				      : sdecl;
   11457 	  /* For the FIRSTPRIVATE_REFERENCE after the struct node, we
   11458 	     want to use the reference itself for the decl, but we
   11459 	     still want to use the pointer to calculate the bias.  */
   11460 	  OMP_CLAUSE_DECL (c2) = (mkind == GOMP_MAP_ATTACH_DETACH)
   11461 				 ? sdecl_ptr : sdecl;
   11462 	  sdecl = sdecl_ptr;
   11463 	  tree baddr = build_fold_addr_expr (base);
   11464 	  baddr = fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end),
   11465 				    ptrdiff_type_node, baddr);
   11466 	  tree decladdr = fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end),
   11467 					    ptrdiff_type_node, sdecl);
   11468 	  OMP_CLAUSE_SIZE (c2)
   11469 	    = fold_build2_loc (OMP_CLAUSE_LOCATION (grp_end), MINUS_EXPR,
   11470 			       ptrdiff_type_node, baddr, decladdr);
   11471 	  /* Insert after struct node.  */
   11472 	  OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
   11473 	  OMP_CLAUSE_CHAIN (l) = c2;
   11474 
   11475 	  if (addr_tokens[base_token]->type == STRUCTURE_BASE
   11476 	      && (addr_tokens[base_token]->u.structure_base_kind
   11477 		  == BASE_COMPONENT_EXPR)
   11478 	      && mkind == GOMP_MAP_ATTACH_DETACH
   11479 	      && addr_tokens[last_access]->u.access_kind != ACCESS_REF)
   11480 	    {
   11481 	      *inner = insert_node_pos;
   11482 	      if (openmp)
   11483 		*fragile_p = true;
   11484 	      return NULL;
   11485 	    }
   11486 	}
   11487 
   11488       if (addr_tokens[base_token]->type == STRUCTURE_BASE
   11489 	  && (addr_tokens[base_token]->u.structure_base_kind
   11490 	      == BASE_COMPONENT_EXPR)
   11491 	  && addr_tokens[last_access]->u.access_kind == ACCESS_REF)
   11492 	*inner = insert_node_pos;
   11493 
   11494       return NULL;
   11495     }
   11496   else if (struct_map_to_clause)
   11497     {
   11498       tree *osc = struct_map_to_clause->get (base);
   11499       tree *sc = NULL, *scp = NULL;
   11500       bool unordered = false;
   11501 
   11502       if (osc && OMP_CLAUSE_MAP_KIND (*osc) == GOMP_MAP_STRUCT_UNORD)
   11503 	unordered = true;
   11504 
   11505       unsigned HOST_WIDE_INT i, elems = tree_to_uhwi (OMP_CLAUSE_SIZE (*osc));
   11506       sc = &OMP_CLAUSE_CHAIN (*osc);
   11507       /* The struct mapping might be immediately followed by a
   11508 	 FIRSTPRIVATE_POINTER,  FIRSTPRIVATE_REFERENCE or an ATTACH_DETACH --
   11509 	 if it's an indirect access or a reference, or if the structure base
   11510 	 is not a decl.  The FIRSTPRIVATE_* nodes are removed in omp-low.cc
   11511 	 after they have been processed there, and ATTACH_DETACH nodes are
   11512 	 recomputed and moved out of the GOMP_MAP_STRUCT construct once
   11513 	 sibling list building is complete.  */
   11514       if (OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_FIRSTPRIVATE_POINTER
   11515 	  || OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
   11516 	  || OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_ATTACH_DETACH)
   11517 	sc = &OMP_CLAUSE_CHAIN (*sc);
   11518       for (i = 0; i < elems; i++, sc = &OMP_CLAUSE_CHAIN (*sc))
   11519 	if (attach_detach && sc == grp_start_p)
   11520 	  break;
   11521 	else if (TREE_CODE (OMP_CLAUSE_DECL (*sc)) != COMPONENT_REF
   11522 		 && TREE_CODE (OMP_CLAUSE_DECL (*sc)) != INDIRECT_REF
   11523 		 && TREE_CODE (OMP_CLAUSE_DECL (*sc)) != ARRAY_REF)
   11524 	  break;
   11525 	else
   11526 	  {
   11527 	    tree sc_decl = OMP_CLAUSE_DECL (*sc);
   11528 	    poly_offset_int offset;
   11529 	    poly_int64 bitpos;
   11530 
   11531 	    if (TREE_CODE (sc_decl) == ARRAY_REF)
   11532 	      {
   11533 		while (TREE_CODE (sc_decl) == ARRAY_REF)
   11534 		  sc_decl = TREE_OPERAND (sc_decl, 0);
   11535 		if (TREE_CODE (sc_decl) != COMPONENT_REF
   11536 		    || TREE_CODE (TREE_TYPE (sc_decl)) != ARRAY_TYPE)
   11537 		  break;
   11538 	      }
   11539 	    else if (INDIRECT_REF_P (sc_decl)
   11540 		     && TREE_CODE (TREE_OPERAND (sc_decl, 0)) == COMPONENT_REF
   11541 		     && (TREE_CODE (TREE_TYPE (TREE_OPERAND (sc_decl, 0)))
   11542 			 == REFERENCE_TYPE))
   11543 	      sc_decl = TREE_OPERAND (sc_decl, 0);
   11544 
   11545 	    bool variable_offset2;
   11546 	    tree base2 = extract_base_bit_offset (sc_decl, &bitpos, &offset,
   11547 						  &variable_offset2);
   11548 	    if (!base2 || !operand_equal_p (base2, base, 0))
   11549 	      break;
   11550 	    if (scp)
   11551 	      continue;
   11552 	    if (variable_offset2)
   11553 	      {
   11554 		OMP_CLAUSE_SET_MAP_KIND (*osc, GOMP_MAP_STRUCT_UNORD);
   11555 		unordered = true;
   11556 		break;
   11557 	      }
   11558 	    else if ((region_type & ORT_ACC) != 0)
   11559 	      {
   11560 		/* For OpenACC, allow (ignore) duplicate struct accesses in
   11561 		   the middle of a mapping clause, e.g. "mystruct->foo" in:
   11562 		   copy(mystruct->foo->bar) copy(mystruct->foo->qux).  */
   11563 		if (reprocessing_struct
   11564 		    && known_eq (coffset, offset)
   11565 		    && known_eq (cbitpos, bitpos))
   11566 		  return NULL;
   11567 	      }
   11568 	    else if (known_eq (coffset, offset)
   11569 		     && known_eq (cbitpos, bitpos))
   11570 	      {
   11571 		/* Having two struct members at the same offset doesn't work,
   11572 		   so make sure we don't.  (We're allowed to ignore this.
   11573 		   Should we report the error?)  */
   11574 		/*error_at (OMP_CLAUSE_LOCATION (grp_end),
   11575 			  "duplicate struct member %qE in map clauses",
   11576 			  OMP_CLAUSE_DECL (grp_end));*/
   11577 		return NULL;
   11578 	      }
   11579 	    if (maybe_lt (coffset, offset)
   11580 		|| (known_eq (coffset, offset)
   11581 		    && maybe_lt (cbitpos, bitpos)))
   11582 	      {
   11583 		if (attach_detach)
   11584 		  scp = sc;
   11585 		else
   11586 		  break;
   11587 	      }
   11588 	  }
   11589 
   11590       /* If this is an unordered struct, just insert the new element at the
   11591 	 end of the list.  */
   11592       if (unordered)
   11593 	{
   11594 	  for (; i < elems; i++)
   11595 	    sc = &OMP_CLAUSE_CHAIN (*sc);
   11596 	  scp = NULL;
   11597 	}
   11598 
   11599       OMP_CLAUSE_SIZE (*osc)
   11600 	= size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc), size_one_node);
   11601 
   11602       if (reprocessing_struct)
   11603 	{
   11604 	  /* If we're reprocessing a struct node, we don't want to do most of
   11605 	     the list manipulation below.  We only need to handle the (pointer
   11606 	     or reference) attach/detach case.  */
   11607 	  tree extra_node, alloc_node;
   11608 	  if (has_descriptor)
   11609 	    gcc_unreachable ();
   11610 	  else if (attach_detach)
   11611 	    alloc_node = build_omp_struct_comp_nodes (code, *grp_start_p,
   11612 						      grp_end, &extra_node);
   11613 	  else
   11614 	    {
   11615 	      /* If we don't have an attach/detach node, this is a
   11616 		 "target data" directive or similar, not an offload region.
   11617 		 Synthesize an "alloc" node using just the initiating
   11618 		 GOMP_MAP_STRUCT decl.  */
   11619 	      gomp_map_kind k = (code == OMP_TARGET_EXIT_DATA
   11620 				 || code == OACC_EXIT_DATA)
   11621 				? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
   11622 	      alloc_node
   11623 		= build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
   11624 				    OMP_CLAUSE_MAP);
   11625 	      OMP_CLAUSE_SET_MAP_KIND (alloc_node, k);
   11626 	      OMP_CLAUSE_DECL (alloc_node) = unshare_expr (last_token->expr);
   11627 	      OMP_CLAUSE_SIZE (alloc_node)
   11628 		= TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (alloc_node)));
   11629 	    }
   11630 
   11631 	  if (scp)
   11632 	    omp_siblist_insert_node_after (alloc_node, scp);
   11633 	  else
   11634 	    {
   11635 	      tree *new_end = omp_siblist_insert_node_after (alloc_node, sc);
   11636 	      if (sc == *added_tail)
   11637 		*added_tail = new_end;
   11638 	    }
   11639 
   11640 	  return NULL;
   11641 	}
   11642 
   11643       if (has_descriptor)
   11644 	{
   11645 	  tree desc = OMP_CLAUSE_CHAIN (*grp_start_p);
   11646 	  if (code == OMP_TARGET_EXIT_DATA
   11647 	      || code == OACC_EXIT_DATA)
   11648 	    OMP_CLAUSE_SET_MAP_KIND (desc, GOMP_MAP_RELEASE);
   11649 	  omp_siblist_move_node_after (desc,
   11650 				       &OMP_CLAUSE_CHAIN (*grp_start_p),
   11651 				       scp ? scp : sc);
   11652 	}
   11653       else if (attach_detach)
   11654 	{
   11655 	  tree cl = NULL_TREE, extra_node;
   11656 	  tree alloc_node = build_omp_struct_comp_nodes (code, *grp_start_p,
   11657 							 grp_end, &extra_node);
   11658 	  tree *tail_chain = NULL;
   11659 
   11660 	  if (*fragile_p
   11661 	      || (openmp
   11662 		  && !target
   11663 		  && attach_detach
   11664 		  && TREE_CODE (TREE_TYPE (ocd)) == POINTER_TYPE
   11665 		  && !OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end)))
   11666 	    {
   11667 	      if (!lang_GNU_Fortran ())
   11668 		OMP_CLAUSE_SIZE (alloc_node) = size_zero_node;
   11669 	      OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (alloc_node) = 1;
   11670 	    }
   11671 
   11672 	  /* Here, we have:
   11673 
   11674 	     grp_end : the last (or only) node in this group.
   11675 	     grp_start_p : pointer to the first node in a pointer mapping group
   11676 			   up to and including GRP_END.
   11677 	     sc : pointer to the chain for the end of the struct component
   11678 		  list.
   11679 	     scp : pointer to the chain for the sorted position at which we
   11680 		   should insert in the middle of the struct component list
   11681 		   (else NULL to insert at end).
   11682 	     alloc_node : the "alloc" node for the structure (pointer-type)
   11683 			  component. We insert at SCP (if present), else SC
   11684 			  (the end of the struct component list).
   11685 	     extra_node : a newly-synthesized node for an additional indirect
   11686 			  pointer mapping or a Fortran pointer set, if needed.
   11687 	     cl : first node to prepend before grp_start_p.
   11688 	     tail_chain : pointer to chain of last prepended node.
   11689 
   11690 	     The general idea is we move the nodes for this struct mapping
   11691 	     together: the alloc node goes into the sorted list directly after
   11692 	     the struct mapping, and any extra nodes (together with the nodes
   11693 	     mapping arrays pointed to by struct components) get moved after
   11694 	     that list.  When SCP is NULL, we insert the nodes at SC, i.e. at
   11695 	     the end of the struct component mapping list.  It's important that
   11696 	     the alloc_node comes first in that case because it's part of the
   11697 	     sorted component mapping list (but subsequent nodes are not!).  */
   11698 
   11699 	  if (scp)
   11700 	    omp_siblist_insert_node_after (alloc_node, scp);
   11701 
   11702 	  /* Make [cl,tail_chain] a list of the alloc node (if we haven't
   11703 	     already inserted it) and the extra_node (if it is present).  The
   11704 	     list can be empty if we added alloc_node above and there is no
   11705 	     extra node.  */
   11706 	  if (scp && extra_node)
   11707 	    {
   11708 	      cl = extra_node;
   11709 	      tail_chain = &OMP_CLAUSE_CHAIN (extra_node);
   11710 	    }
   11711 	  else if (extra_node)
   11712 	    {
   11713 	      OMP_CLAUSE_CHAIN (alloc_node) = extra_node;
   11714 	      cl = alloc_node;
   11715 	      tail_chain = &OMP_CLAUSE_CHAIN (extra_node);
   11716 	    }
   11717 	  else if (!scp)
   11718 	    {
   11719 	      cl = alloc_node;
   11720 	      tail_chain = &OMP_CLAUSE_CHAIN (alloc_node);
   11721 	    }
   11722 
   11723 	  continue_at
   11724 	    = cl ? omp_siblist_move_concat_nodes_after (cl, tail_chain,
   11725 							grp_start_p, grp_end,
   11726 							sc)
   11727 		 : omp_siblist_move_nodes_after (grp_start_p, grp_end, sc);
   11728 	}
   11729       else if (*sc != grp_end)
   11730 	{
   11731 	  gcc_assert (*grp_start_p == grp_end);
   11732 
   11733 	  /* We are moving the current node back to a previous struct node:
   11734 	     the node that used to point to the current node will now point to
   11735 	     the next node.  */
   11736 	  continue_at = grp_start_p;
   11737 	  /* In the non-pointer case, the mapping clause itself is moved into
   11738 	     the correct position in the struct component list, which in this
   11739 	     case is just SC.  */
   11740 	  omp_siblist_move_node_after (*grp_start_p, grp_start_p, sc);
   11741 	}
   11742     }
   11743   return continue_at;
   11744 }
   11745 
   11746 /* Scan through GROUPS, and create sorted structure sibling lists without
   11747    gimplifying.  */
   11748 
   11749 static bool
   11750 omp_build_struct_sibling_lists (enum tree_code code,
   11751 				enum omp_region_type region_type,
   11752 				vec<omp_mapping_group> *groups,
   11753 				hash_map<tree_operand_hash_no_se,
   11754 					 omp_mapping_group *> **grpmap,
   11755 				tree *list_p)
   11756 {
   11757   using namespace omp_addr_tokenizer;
   11758   unsigned i;
   11759   omp_mapping_group *grp;
   11760   hash_map<tree_operand_hash, tree> *struct_map_to_clause = NULL;
   11761   bool success = true;
   11762   tree *new_next = NULL;
   11763   tree *tail = &OMP_CLAUSE_CHAIN ((*groups)[groups->length () - 1].grp_end);
   11764   tree added_nodes = NULL_TREE;
   11765   tree *added_tail = &added_nodes;
   11766   auto_vec<omp_mapping_group> pre_hwm_groups;
   11767 
   11768   FOR_EACH_VEC_ELT (*groups, i, grp)
   11769     {
   11770       tree c = grp->grp_end;
   11771       tree decl = OMP_CLAUSE_DECL (c);
   11772       tree grp_end = grp->grp_end;
   11773       auto_vec<omp_addr_token *> addr_tokens;
   11774       tree sentinel = OMP_CLAUSE_CHAIN (grp_end);
   11775 
   11776       if (new_next && !grp->reprocess_struct)
   11777 	grp->grp_start = new_next;
   11778 
   11779       new_next = NULL;
   11780 
   11781       tree *grp_start_p = grp->grp_start;
   11782 
   11783       if (DECL_P (decl))
   11784 	continue;
   11785 
   11786       /* Skip groups we marked for deletion in
   11787 	 {omp,oacc}_resolve_clause_dependencies.  */
   11788       if (grp->deleted)
   11789 	continue;
   11790 
   11791       if (OMP_CLAUSE_CHAIN (*grp_start_p)
   11792 	  && OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end)
   11793 	{
   11794 	  /* Don't process an array descriptor that isn't inside a derived type
   11795 	     as a struct (the GOMP_MAP_POINTER following will have the form
   11796 	     "var.data", but such mappings are handled specially).  */
   11797 	  tree grpmid = OMP_CLAUSE_CHAIN (*grp_start_p);
   11798 	  if (omp_map_clause_descriptor_p (grpmid)
   11799 	      && DECL_P (OMP_CLAUSE_DECL (grpmid)))
   11800 	    continue;
   11801 	}
   11802 
   11803       tree expr = decl;
   11804 
   11805       while (TREE_CODE (expr) == ARRAY_REF)
   11806 	expr = TREE_OPERAND (expr, 0);
   11807 
   11808       if (!omp_parse_expr (addr_tokens, expr))
   11809 	continue;
   11810 
   11811       omp_addr_token *last_token
   11812 	= omp_first_chained_access_token (addr_tokens);
   11813 
   11814       /* A mapping of a reference to a pointer member that doesn't specify an
   11815 	 array section, etc., like this:
   11816 	   *mystruct.ref_to_ptr
   11817 	 should not be processed by the struct sibling-list handling code --
   11818 	 it just transfers the referenced pointer.
   11819 
   11820 	 In contrast, the quite similar-looking construct:
   11821 	   *mystruct.ptr
   11822 	 which is equivalent to e.g.
   11823 	   mystruct.ptr[0]
   11824 	 *does* trigger sibling-list processing.
   11825 
   11826 	 An exception for the former case is for "fragile" groups where the
   11827 	 reference itself is not handled otherwise; this is subject to special
   11828 	 handling in omp_accumulate_sibling_list also.  */
   11829 
   11830       if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
   11831 	  && last_token->type == ACCESS_METHOD
   11832 	  && last_token->u.access_kind == ACCESS_REF
   11833 	  && !grp->fragile)
   11834 	continue;
   11835 
   11836       tree d = decl;
   11837       if (TREE_CODE (d) == ARRAY_REF)
   11838 	{
   11839 	  while (TREE_CODE (d) == ARRAY_REF)
   11840 	    d = TREE_OPERAND (d, 0);
   11841 	  if (TREE_CODE (d) == COMPONENT_REF
   11842 	      && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
   11843 	    decl = d;
   11844 	}
   11845       if (d == decl
   11846 	  && INDIRECT_REF_P (decl)
   11847 	  && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
   11848 	  && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
   11849 	      == REFERENCE_TYPE)
   11850 	  && (OMP_CLAUSE_MAP_KIND (c)
   11851 	      != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
   11852 	decl = TREE_OPERAND (decl, 0);
   11853 
   11854       STRIP_NOPS (decl);
   11855 
   11856       if (TREE_CODE (decl) != COMPONENT_REF)
   11857 	continue;
   11858 
   11859       /* If we're mapping the whole struct in another node, skip adding this
   11860 	 node to a sibling list.  */
   11861       omp_mapping_group *wholestruct;
   11862       if (omp_mapped_by_containing_struct (*grpmap, OMP_CLAUSE_DECL (c),
   11863 					   &wholestruct))
   11864 	continue;
   11865 
   11866       if (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
   11867 	  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
   11868 	  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
   11869 	  && code != OACC_UPDATE
   11870 	  && code != OMP_TARGET_UPDATE)
   11871 	{
   11872 	  if (error_operand_p (decl))
   11873 	    {
   11874 	      success = false;
   11875 	      goto error_out;
   11876 	    }
   11877 
   11878 	  tree stype = TREE_TYPE (decl);
   11879 	  if (TREE_CODE (stype) == REFERENCE_TYPE)
   11880 	    stype = TREE_TYPE (stype);
   11881 	  if (TYPE_SIZE_UNIT (stype) == NULL
   11882 	      || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
   11883 	    {
   11884 	      error_at (OMP_CLAUSE_LOCATION (c),
   11885 			"mapping field %qE of variable length "
   11886 			"structure", OMP_CLAUSE_DECL (c));
   11887 	      success = false;
   11888 	      goto error_out;
   11889 	    }
   11890 
   11891 	  tree *inner = NULL;
   11892 	  bool fragile_p = grp->fragile;
   11893 
   11894 	  new_next
   11895 	    = omp_accumulate_sibling_list (region_type, code,
   11896 					   struct_map_to_clause, *grpmap,
   11897 					   grp_start_p, grp_end, addr_tokens,
   11898 					   &inner, &fragile_p,
   11899 					   grp->reprocess_struct, &added_tail);
   11900 
   11901 	  if (inner)
   11902 	    {
   11903 	      omp_mapping_group newgrp;
   11904 	      newgrp.grp_start = inner;
   11905 	      if (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (*inner))
   11906 		  == GOMP_MAP_ATTACH_DETACH)
   11907 		newgrp.grp_end = OMP_CLAUSE_CHAIN (*inner);
   11908 	      else
   11909 		newgrp.grp_end = *inner;
   11910 	      newgrp.mark = UNVISITED;
   11911 	      newgrp.sibling = NULL;
   11912 	      newgrp.deleted = false;
   11913 	      newgrp.reprocess_struct = true;
   11914 	      newgrp.fragile = fragile_p;
   11915 	      newgrp.next = NULL;
   11916 	      groups->safe_push (newgrp);
   11917 
   11918 	      /* !!! Growing GROUPS might invalidate the pointers in the group
   11919 		 map.  Rebuild it here.  This is a bit inefficient, but
   11920 		 shouldn't happen very often.  */
   11921 	      delete (*grpmap);
   11922 	      *grpmap
   11923 		= omp_reindex_mapping_groups (list_p, groups, &pre_hwm_groups,
   11924 					      sentinel);
   11925 	    }
   11926 	}
   11927     }
   11928 
   11929   /* Delete groups marked for deletion above.  At this point the order of the
   11930      groups may no longer correspond to the order of the underlying list,
   11931      which complicates this a little.  First clear out OMP_CLAUSE_DECL for
   11932      deleted nodes...  */
   11933 
   11934   FOR_EACH_VEC_ELT (*groups, i, grp)
   11935     if (grp->deleted)
   11936       for (tree d = *grp->grp_start;
   11937 	   d != OMP_CLAUSE_CHAIN (grp->grp_end);
   11938 	   d = OMP_CLAUSE_CHAIN (d))
   11939 	OMP_CLAUSE_DECL (d) = NULL_TREE;
   11940 
   11941   /* ...then sweep through the list removing the now-empty nodes.  */
   11942 
   11943   tail = list_p;
   11944   while (*tail)
   11945     {
   11946       if (OMP_CLAUSE_CODE (*tail) == OMP_CLAUSE_MAP
   11947 	  && OMP_CLAUSE_DECL (*tail) == NULL_TREE)
   11948 	*tail = OMP_CLAUSE_CHAIN (*tail);
   11949       else
   11950 	tail = &OMP_CLAUSE_CHAIN (*tail);
   11951     }
   11952 
   11953   /* Tack on the struct nodes added during nested struct reprocessing.  */
   11954   if (added_nodes)
   11955     {
   11956       *tail = added_nodes;
   11957       tail = added_tail;
   11958     }
   11959 
   11960   /* Now we have finished building the struct sibling lists, reprocess
   11961      newly-added "attach" nodes: we need the address of the first
   11962      mapped element of each struct sibling list for the bias of the attach
   11963      operation -- not necessarily the base address of the whole struct.  */
   11964   if (struct_map_to_clause)
   11965     for (hash_map<tree_operand_hash, tree>::iterator iter
   11966 	   = struct_map_to_clause->begin ();
   11967 	 iter != struct_map_to_clause->end ();
   11968 	 ++iter)
   11969       {
   11970 	tree struct_node = (*iter).second;
   11971 	gcc_assert (OMP_CLAUSE_CODE (struct_node) == OMP_CLAUSE_MAP);
   11972 	tree attach = OMP_CLAUSE_CHAIN (struct_node);
   11973 
   11974 	if (OMP_CLAUSE_CODE (attach) != OMP_CLAUSE_MAP
   11975 	    || OMP_CLAUSE_MAP_KIND (attach) != GOMP_MAP_ATTACH_DETACH)
   11976 	  continue;
   11977 
   11978 	OMP_CLAUSE_SET_MAP_KIND (attach, GOMP_MAP_ATTACH);
   11979 
   11980 	/* Sanity check: the standalone attach node will not work if we have
   11981 	   an "enter data" operation (because for those, variables need to be
   11982 	   mapped separately and attach nodes must be grouped together with the
   11983 	   base they attach to).  We should only have created the
   11984 	   ATTACH_DETACH node after GOMP_MAP_STRUCT for a target region, so
   11985 	   this should never be true.  */
   11986 	gcc_assert ((region_type & ORT_TARGET) != 0);
   11987 
   11988 	/* This is the first sorted node in the struct sibling list.  Use it
   11989 	   to recalculate the correct bias to use.
   11990 	   (&first_node - attach_decl).
   11991 	   For GOMP_MAP_STRUCT_UNORD, we need e.g. the
   11992 	   min(min(min(first,second),third),fourth) element, because the
   11993 	   elements aren't in any particular order.  */
   11994 	tree lowest_addr;
   11995 	if (OMP_CLAUSE_MAP_KIND (struct_node) == GOMP_MAP_STRUCT_UNORD)
   11996 	  {
   11997 	    tree first_node = OMP_CLAUSE_CHAIN (attach);
   11998 	    unsigned HOST_WIDE_INT num_mappings
   11999 	      = tree_to_uhwi (OMP_CLAUSE_SIZE (struct_node));
   12000 	    lowest_addr = OMP_CLAUSE_DECL (first_node);
   12001 	    lowest_addr = build_fold_addr_expr (lowest_addr);
   12002 	    lowest_addr = fold_convert (pointer_sized_int_node, lowest_addr);
   12003 	    tree next_node = OMP_CLAUSE_CHAIN (first_node);
   12004 	    while (num_mappings > 1)
   12005 	      {
   12006 		tree tmp = OMP_CLAUSE_DECL (next_node);
   12007 		tmp = build_fold_addr_expr (tmp);
   12008 		tmp = fold_convert (pointer_sized_int_node, tmp);
   12009 		lowest_addr = fold_build2 (MIN_EXPR, pointer_sized_int_node,
   12010 					   lowest_addr, tmp);
   12011 		next_node = OMP_CLAUSE_CHAIN (next_node);
   12012 		num_mappings--;
   12013 	      }
   12014 	    lowest_addr = fold_convert (ptrdiff_type_node, lowest_addr);
   12015 	  }
   12016 	else
   12017 	  {
   12018 	    tree first_node = OMP_CLAUSE_DECL (OMP_CLAUSE_CHAIN (attach));
   12019 	    first_node = build_fold_addr_expr (first_node);
   12020 	    lowest_addr = fold_convert (ptrdiff_type_node, first_node);
   12021 	  }
   12022 	tree attach_decl = OMP_CLAUSE_DECL (attach);
   12023 	attach_decl = fold_convert (ptrdiff_type_node, attach_decl);
   12024 	OMP_CLAUSE_SIZE (attach)
   12025 	  = fold_build2 (MINUS_EXPR, ptrdiff_type_node, lowest_addr,
   12026 			 attach_decl);
   12027 
   12028 	/* Remove GOMP_MAP_ATTACH node from after struct node.  */
   12029 	OMP_CLAUSE_CHAIN (struct_node) = OMP_CLAUSE_CHAIN (attach);
   12030 	/* ...and re-insert it at the end of our clause list.  */
   12031 	*tail = attach;
   12032 	OMP_CLAUSE_CHAIN (attach) = NULL_TREE;
   12033 	tail = &OMP_CLAUSE_CHAIN (attach);
   12034       }
   12035 
   12036 error_out:
   12037   if (struct_map_to_clause)
   12038     delete struct_map_to_clause;
   12039 
   12040   return success;
   12041 }
   12042 
   12043 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
   12044    and previous omp contexts.  */
   12045 
   12046 static void
   12047 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
   12048 			   enum omp_region_type region_type,
   12049 			   enum tree_code code)
   12050 {
   12051   using namespace omp_addr_tokenizer;
   12052   struct gimplify_omp_ctx *ctx, *outer_ctx;
   12053   tree c;
   12054   tree *orig_list_p = list_p;
   12055   int handled_depend_iterators = -1;
   12056   int nowait = -1;
   12057 
   12058   ctx = new_omp_context (region_type);
   12059   ctx->code = code;
   12060   outer_ctx = ctx->outer_context;
   12061   if (code == OMP_TARGET)
   12062     {
   12063       if (!lang_GNU_Fortran ())
   12064 	ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
   12065       ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
   12066       ctx->defaultmap[GDMK_SCALAR_TARGET] = (lang_GNU_Fortran ()
   12067 					     ? GOVD_MAP : GOVD_FIRSTPRIVATE);
   12068     }
   12069   if (!lang_GNU_Fortran ())
   12070     switch (code)
   12071       {
   12072       case OMP_TARGET:
   12073       case OMP_TARGET_DATA:
   12074       case OMP_TARGET_ENTER_DATA:
   12075       case OMP_TARGET_EXIT_DATA:
   12076       case OACC_DECLARE:
   12077       case OACC_HOST_DATA:
   12078       case OACC_PARALLEL:
   12079       case OACC_KERNELS:
   12080 	ctx->target_firstprivatize_array_bases = true;
   12081       default:
   12082 	break;
   12083       }
   12084 
   12085   vec<omp_mapping_group> *groups = NULL;
   12086   hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap = NULL;
   12087   unsigned grpnum = 0;
   12088   tree *grp_start_p = NULL, grp_end = NULL_TREE;
   12089 
   12090   if (code == OMP_TARGET
   12091       || code == OMP_TARGET_DATA
   12092       || code == OMP_TARGET_ENTER_DATA
   12093       || code == OMP_TARGET_EXIT_DATA
   12094       || code == OACC_DATA
   12095       || code == OACC_KERNELS
   12096       || code == OACC_PARALLEL
   12097       || code == OACC_SERIAL
   12098       || code == OACC_ENTER_DATA
   12099       || code == OACC_EXIT_DATA
   12100       || code == OACC_UPDATE
   12101       || code == OACC_DECLARE)
   12102     {
   12103       groups = omp_gather_mapping_groups (list_p);
   12104 
   12105       if (groups)
   12106 	grpmap = omp_index_mapping_groups (groups);
   12107     }
   12108 
   12109   while ((c = *list_p) != NULL)
   12110     {
   12111       bool remove = false;
   12112       bool notice_outer = true;
   12113       bool map_descriptor;
   12114       const char *check_non_private = NULL;
   12115       unsigned int flags;
   12116       tree decl;
   12117       auto_vec<omp_addr_token *, 10> addr_tokens;
   12118 
   12119       if (grp_end && c == OMP_CLAUSE_CHAIN (grp_end))
   12120 	{
   12121 	  grp_start_p = NULL;
   12122 	  grp_end = NULL_TREE;
   12123 	}
   12124 
   12125       switch (OMP_CLAUSE_CODE (c))
   12126 	{
   12127 	case OMP_CLAUSE_PRIVATE:
   12128 	  flags = GOVD_PRIVATE | GOVD_EXPLICIT;
   12129 	  if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
   12130 	    {
   12131 	      flags |= GOVD_PRIVATE_OUTER_REF;
   12132 	      OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
   12133 	    }
   12134 	  else
   12135 	    notice_outer = false;
   12136 	  goto do_add;
   12137 	case OMP_CLAUSE_SHARED:
   12138 	  flags = GOVD_SHARED | GOVD_EXPLICIT;
   12139 	  goto do_add;
   12140 	case OMP_CLAUSE_FIRSTPRIVATE:
   12141 	  flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
   12142 	  check_non_private = "firstprivate";
   12143 	  if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
   12144 	    {
   12145 	      gcc_assert (code == OMP_TARGET);
   12146 	      flags |= GOVD_FIRSTPRIVATE_IMPLICIT;
   12147 	    }
   12148 	  goto do_add;
   12149 	case OMP_CLAUSE_LASTPRIVATE:
   12150 	  if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   12151 	    switch (code)
   12152 	      {
   12153 	      case OMP_DISTRIBUTE:
   12154 		error_at (OMP_CLAUSE_LOCATION (c),
   12155 			  "conditional %<lastprivate%> clause on "
   12156 			  "%qs construct", "distribute");
   12157 		OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
   12158 		break;
   12159 	      case OMP_TASKLOOP:
   12160 		error_at (OMP_CLAUSE_LOCATION (c),
   12161 			  "conditional %<lastprivate%> clause on "
   12162 			  "%qs construct", "taskloop");
   12163 		OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
   12164 		break;
   12165 	      default:
   12166 		break;
   12167 	      }
   12168 	  flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
   12169 	  if (code != OMP_LOOP)
   12170 	    check_non_private = "lastprivate";
   12171 	  decl = OMP_CLAUSE_DECL (c);
   12172 	  if (error_operand_p (decl))
   12173 	    goto do_add;
   12174 	  if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
   12175 	      && !lang_hooks.decls.omp_scalar_p (decl, true))
   12176 	    {
   12177 	      error_at (OMP_CLAUSE_LOCATION (c),
   12178 			"non-scalar variable %qD in conditional "
   12179 			"%<lastprivate%> clause", decl);
   12180 	      OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
   12181 	    }
   12182 	  if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   12183 	    flags |= GOVD_LASTPRIVATE_CONDITIONAL;
   12184 	  omp_lastprivate_for_combined_outer_constructs (outer_ctx, decl,
   12185 							 false);
   12186 	  goto do_add;
   12187 	case OMP_CLAUSE_REDUCTION:
   12188 	  if (OMP_CLAUSE_REDUCTION_TASK (c))
   12189 	    {
   12190 	      if (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
   12191 		{
   12192 		  if (nowait == -1)
   12193 		    nowait = omp_find_clause (*list_p,
   12194 					      OMP_CLAUSE_NOWAIT) != NULL_TREE;
   12195 		  if (nowait
   12196 		      && (outer_ctx == NULL
   12197 			  || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
   12198 		    {
   12199 		      error_at (OMP_CLAUSE_LOCATION (c),
   12200 				"%<task%> reduction modifier on a construct "
   12201 				"with a %<nowait%> clause");
   12202 		      OMP_CLAUSE_REDUCTION_TASK (c) = 0;
   12203 		    }
   12204 		}
   12205 	      else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
   12206 		{
   12207 		  error_at (OMP_CLAUSE_LOCATION (c),
   12208 			    "invalid %<task%> reduction modifier on construct "
   12209 			    "other than %<parallel%>, %qs, %<sections%> or "
   12210 			    "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
   12211 		  OMP_CLAUSE_REDUCTION_TASK (c) = 0;
   12212 		}
   12213 	    }
   12214 	  if (OMP_CLAUSE_REDUCTION_INSCAN (c))
   12215 	    switch (code)
   12216 	      {
   12217 	      case OMP_SECTIONS:
   12218 		error_at (OMP_CLAUSE_LOCATION (c),
   12219 			  "%<inscan%> %<reduction%> clause on "
   12220 			  "%qs construct", "sections");
   12221 		OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   12222 		break;
   12223 	      case OMP_PARALLEL:
   12224 		error_at (OMP_CLAUSE_LOCATION (c),
   12225 			  "%<inscan%> %<reduction%> clause on "
   12226 			  "%qs construct", "parallel");
   12227 		OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   12228 		break;
   12229 	      case OMP_TEAMS:
   12230 		error_at (OMP_CLAUSE_LOCATION (c),
   12231 			  "%<inscan%> %<reduction%> clause on "
   12232 			  "%qs construct", "teams");
   12233 		OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   12234 		break;
   12235 	      case OMP_TASKLOOP:
   12236 		error_at (OMP_CLAUSE_LOCATION (c),
   12237 			  "%<inscan%> %<reduction%> clause on "
   12238 			  "%qs construct", "taskloop");
   12239 		OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   12240 		break;
   12241 	      case OMP_SCOPE:
   12242 		error_at (OMP_CLAUSE_LOCATION (c),
   12243 			  "%<inscan%> %<reduction%> clause on "
   12244 			  "%qs construct", "scope");
   12245 		OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   12246 		break;
   12247 	      default:
   12248 		break;
   12249 	      }
   12250 	  /* FALLTHRU */
   12251 	case OMP_CLAUSE_IN_REDUCTION:
   12252 	case OMP_CLAUSE_TASK_REDUCTION:
   12253 	  flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
   12254 	  /* OpenACC permits reductions on private variables.  */
   12255 	  if (!(region_type & ORT_ACC)
   12256 	      /* taskgroup is actually not a worksharing region.  */
   12257 	      && code != OMP_TASKGROUP)
   12258 	    check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
   12259 	  decl = OMP_CLAUSE_DECL (c);
   12260 	  if (TREE_CODE (decl) == MEM_REF)
   12261 	    {
   12262 	      tree type = TREE_TYPE (decl);
   12263 	      bool saved_into_ssa = gimplify_ctxp->into_ssa;
   12264 	      gimplify_ctxp->into_ssa = false;
   12265 	      if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
   12266 				 NULL, is_gimple_val, fb_rvalue, false)
   12267 		  == GS_ERROR)
   12268 		{
   12269 		  gimplify_ctxp->into_ssa = saved_into_ssa;
   12270 		  remove = true;
   12271 		  break;
   12272 		}
   12273 	      gimplify_ctxp->into_ssa = saved_into_ssa;
   12274 	      tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
   12275 	      if (DECL_P (v))
   12276 		{
   12277 		  omp_firstprivatize_variable (ctx, v);
   12278 		  omp_notice_variable (ctx, v, true);
   12279 		}
   12280 	      decl = TREE_OPERAND (decl, 0);
   12281 	      if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
   12282 		{
   12283 		  gimplify_ctxp->into_ssa = false;
   12284 		  if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
   12285 				     NULL, is_gimple_val, fb_rvalue, false)
   12286 		      == GS_ERROR)
   12287 		    {
   12288 		      gimplify_ctxp->into_ssa = saved_into_ssa;
   12289 		      remove = true;
   12290 		      break;
   12291 		    }
   12292 		  gimplify_ctxp->into_ssa = saved_into_ssa;
   12293 		  v = TREE_OPERAND (decl, 1);
   12294 		  if (DECL_P (v))
   12295 		    {
   12296 		      omp_firstprivatize_variable (ctx, v);
   12297 		      omp_notice_variable (ctx, v, true);
   12298 		    }
   12299 		  decl = TREE_OPERAND (decl, 0);
   12300 		}
   12301 	      if (TREE_CODE (decl) == ADDR_EXPR
   12302 		  || TREE_CODE (decl) == INDIRECT_REF)
   12303 		decl = TREE_OPERAND (decl, 0);
   12304 	    }
   12305 	  goto do_add_decl;
   12306 	case OMP_CLAUSE_LINEAR:
   12307 	  if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
   12308 			     is_gimple_val, fb_rvalue) == GS_ERROR)
   12309 	    {
   12310 	      remove = true;
   12311 	      break;
   12312 	    }
   12313 	  else
   12314 	    {
   12315 	      if (code == OMP_SIMD
   12316 		  && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
   12317 		{
   12318 		  struct gimplify_omp_ctx *octx = outer_ctx;
   12319 		  if (octx
   12320 		      && octx->region_type == ORT_WORKSHARE
   12321 		      && octx->combined_loop
   12322 		      && !octx->distribute)
   12323 		    {
   12324 		      if (octx->outer_context
   12325 			  && (octx->outer_context->region_type
   12326 			      == ORT_COMBINED_PARALLEL))
   12327 			octx = octx->outer_context->outer_context;
   12328 		      else
   12329 			octx = octx->outer_context;
   12330 		    }
   12331 		  if (octx
   12332 		      && octx->region_type == ORT_WORKSHARE
   12333 		      && octx->combined_loop
   12334 		      && octx->distribute)
   12335 		    {
   12336 		      error_at (OMP_CLAUSE_LOCATION (c),
   12337 				"%<linear%> clause for variable other than "
   12338 				"loop iterator specified on construct "
   12339 				"combined with %<distribute%>");
   12340 		      remove = true;
   12341 		      break;
   12342 		    }
   12343 		}
   12344 	      /* For combined #pragma omp parallel for simd, need to put
   12345 		 lastprivate and perhaps firstprivate too on the
   12346 		 parallel.  Similarly for #pragma omp for simd.  */
   12347 	      struct gimplify_omp_ctx *octx = outer_ctx;
   12348 	      bool taskloop_seen = false;
   12349 	      decl = NULL_TREE;
   12350 	      do
   12351 		{
   12352 		  if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
   12353 		      && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   12354 		    break;
   12355 		  decl = OMP_CLAUSE_DECL (c);
   12356 		  if (error_operand_p (decl))
   12357 		    {
   12358 		      decl = NULL_TREE;
   12359 		      break;
   12360 		    }
   12361 		  flags = GOVD_SEEN;
   12362 		  if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
   12363 		    flags |= GOVD_FIRSTPRIVATE;
   12364 		  if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   12365 		    flags |= GOVD_LASTPRIVATE;
   12366 		  if (octx
   12367 		      && octx->region_type == ORT_WORKSHARE
   12368 		      && octx->combined_loop)
   12369 		    {
   12370 		      if (octx->outer_context
   12371 			  && (octx->outer_context->region_type
   12372 			      == ORT_COMBINED_PARALLEL))
   12373 			octx = octx->outer_context;
   12374 		      else if (omp_check_private (octx, decl, false))
   12375 			break;
   12376 		    }
   12377 		  else if (octx
   12378 			   && (octx->region_type & ORT_TASK) != 0
   12379 			   && octx->combined_loop)
   12380 		    taskloop_seen = true;
   12381 		  else if (octx
   12382 			   && octx->region_type == ORT_COMBINED_PARALLEL
   12383 			   && ((ctx->region_type == ORT_WORKSHARE
   12384 				&& octx == outer_ctx)
   12385 			       || taskloop_seen))
   12386 		    flags = GOVD_SEEN | GOVD_SHARED;
   12387 		  else if (octx
   12388 			   && ((octx->region_type & ORT_COMBINED_TEAMS)
   12389 			       == ORT_COMBINED_TEAMS))
   12390 		    flags = GOVD_SEEN | GOVD_SHARED;
   12391 		  else if (octx
   12392 			   && octx->region_type == ORT_COMBINED_TARGET)
   12393 		    {
   12394 		      if (flags & GOVD_LASTPRIVATE)
   12395 			flags = GOVD_SEEN | GOVD_MAP;
   12396 		    }
   12397 		  else
   12398 		    break;
   12399 		  splay_tree_node on
   12400 		    = splay_tree_lookup (octx->variables,
   12401 					 (splay_tree_key) decl);
   12402 		  if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
   12403 		    {
   12404 		      octx = NULL;
   12405 		      break;
   12406 		    }
   12407 		  omp_add_variable (octx, decl, flags);
   12408 		  if (octx->outer_context == NULL)
   12409 		    break;
   12410 		  octx = octx->outer_context;
   12411 		}
   12412 	      while (1);
   12413 	      if (octx
   12414 		  && decl
   12415 		  && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
   12416 		      || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
   12417 		omp_notice_variable (octx, decl, true);
   12418 	    }
   12419 	  flags = GOVD_LINEAR | GOVD_EXPLICIT;
   12420 	  if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
   12421 	      && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   12422 	    {
   12423 	      notice_outer = false;
   12424 	      flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
   12425 	    }
   12426 	  goto do_add;
   12427 
   12428 	case OMP_CLAUSE_MAP:
   12429 	  if (!grp_start_p)
   12430 	    {
   12431 	      grp_start_p = list_p;
   12432 	      grp_end = (*groups)[grpnum].grp_end;
   12433 	      grpnum++;
   12434 	    }
   12435 	  decl = OMP_CLAUSE_DECL (c);
   12436 
   12437 	  if (error_operand_p (decl))
   12438 	    {
   12439 	      remove = true;
   12440 	      break;
   12441 	    }
   12442 
   12443 	  if (!omp_parse_expr (addr_tokens, decl))
   12444 	    {
   12445 	      remove = true;
   12446 	      break;
   12447 	    }
   12448 
   12449 	  if (remove)
   12450 	    break;
   12451 	  if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
   12452 	    {
   12453 	      struct gimplify_omp_ctx *octx;
   12454 	      for (octx = outer_ctx; octx; octx = octx->outer_context)
   12455 	        {
   12456 		  if (octx->region_type != ORT_ACC_HOST_DATA)
   12457 		    break;
   12458 		  splay_tree_node n2
   12459 		    = splay_tree_lookup (octx->variables,
   12460 					 (splay_tree_key) decl);
   12461 		  if (n2)
   12462 		    error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
   12463 			      "declared in enclosing %<host_data%> region",
   12464 			      DECL_NAME (decl));
   12465 		}
   12466 	    }
   12467 
   12468 	  map_descriptor = false;
   12469 
   12470 	  /* This condition checks if we're mapping an array descriptor that
   12471 	     isn't inside a derived type -- these have special handling, and
   12472 	     are not handled as structs in omp_build_struct_sibling_lists.
   12473 	     See that function for further details.  */
   12474 	  if (*grp_start_p != grp_end
   12475 	      && OMP_CLAUSE_CHAIN (*grp_start_p)
   12476 	      && OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end)
   12477 	    {
   12478 	      tree grp_mid = OMP_CLAUSE_CHAIN (*grp_start_p);
   12479 	      if (omp_map_clause_descriptor_p (grp_mid)
   12480 		  && DECL_P (OMP_CLAUSE_DECL (grp_mid)))
   12481 		map_descriptor = true;
   12482 	    }
   12483 	  else if (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP
   12484 		   && (OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_RELEASE
   12485 		       || OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_DELETE)
   12486 		   && OMP_CLAUSE_RELEASE_DESCRIPTOR (grp_end))
   12487 	    map_descriptor = true;
   12488 
   12489 	  /* Adding the decl for a struct access: we haven't created
   12490 	     GOMP_MAP_STRUCT nodes yet, so this statement needs to predict
   12491 	     whether they will be created in gimplify_adjust_omp_clauses.
   12492 	     NOTE: Technically we should probably look through DECL_VALUE_EXPR
   12493 	     here because something that looks like a DECL_P may actually be a
   12494 	     struct access, e.g. variables in a lambda closure
   12495 	     (__closure->__foo) or class members (this->foo). Currently in both
   12496 	     those cases we map the whole of the containing object (directly in
   12497 	     the C++ FE) though, so struct nodes are not created.  */
   12498 	  if (c == grp_end
   12499 	      && addr_tokens[0]->type == STRUCTURE_BASE
   12500 	      && addr_tokens[0]->u.structure_base_kind == BASE_DECL
   12501 	      && !map_descriptor)
   12502 	    {
   12503 	      gcc_assert (addr_tokens[1]->type == ACCESS_METHOD);
   12504 	      /* If we got to this struct via a chain of pointers, maybe we
   12505 		 want to map it implicitly instead.  */
   12506 	      if (omp_access_chain_p (addr_tokens, 1))
   12507 		break;
   12508 	      omp_mapping_group *wholestruct;
   12509 	      if (!(region_type & ORT_ACC)
   12510 		  && omp_mapped_by_containing_struct (grpmap,
   12511 						      OMP_CLAUSE_DECL (c),
   12512 						      &wholestruct))
   12513 		break;
   12514 	      decl = addr_tokens[1]->expr;
   12515 	      if (splay_tree_lookup (ctx->variables, (splay_tree_key) decl))
   12516 		break;
   12517 	      /* Standalone attach or detach clauses for a struct element
   12518 		 should not inhibit implicit mapping of the whole struct.  */
   12519 	      if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   12520 		  || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
   12521 		break;
   12522 	      flags = GOVD_MAP | GOVD_EXPLICIT;
   12523 
   12524 	      gcc_assert (addr_tokens[1]->u.access_kind != ACCESS_DIRECT
   12525 			  || TREE_ADDRESSABLE (decl));
   12526 	      goto do_add_decl;
   12527 	    }
   12528 
   12529 	  if (!DECL_P (decl))
   12530 	    {
   12531 	      tree d = decl, *pd;
   12532 	      if (TREE_CODE (d) == ARRAY_REF)
   12533 		{
   12534 		  while (TREE_CODE (d) == ARRAY_REF)
   12535 		    d = TREE_OPERAND (d, 0);
   12536 		  if (TREE_CODE (d) == COMPONENT_REF
   12537 		      && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
   12538 		    decl = d;
   12539 		}
   12540 	      pd = &OMP_CLAUSE_DECL (c);
   12541 	      if (d == decl
   12542 		  && TREE_CODE (decl) == INDIRECT_REF
   12543 		  && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
   12544 		  && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
   12545 		      == REFERENCE_TYPE)
   12546 		  && (OMP_CLAUSE_MAP_KIND (c)
   12547 		      != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
   12548 		{
   12549 		  pd = &TREE_OPERAND (decl, 0);
   12550 		  decl = TREE_OPERAND (decl, 0);
   12551 		}
   12552 
   12553 	      if (addr_tokens[0]->type == STRUCTURE_BASE
   12554 		  && addr_tokens[0]->u.structure_base_kind == BASE_DECL
   12555 		  && addr_tokens[1]->type == ACCESS_METHOD
   12556 		  && (addr_tokens[1]->u.access_kind == ACCESS_POINTER
   12557 		      || (addr_tokens[1]->u.access_kind
   12558 			  == ACCESS_POINTER_OFFSET))
   12559 		  && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)))
   12560 		{
   12561 		  tree base = addr_tokens[1]->expr;
   12562 		  splay_tree_node n
   12563 		    = splay_tree_lookup (ctx->variables,
   12564 					 (splay_tree_key) base);
   12565 		  n->value |= GOVD_SEEN;
   12566 		}
   12567 
   12568 	      if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
   12569 		{
   12570 		  /* Don't gimplify *pd fully at this point, as the base
   12571 		     will need to be adjusted during omp lowering.  */
   12572 		  auto_vec<tree, 10> expr_stack;
   12573 		  tree *p = pd;
   12574 		  while (handled_component_p (*p)
   12575 			 || TREE_CODE (*p) == INDIRECT_REF
   12576 			 || TREE_CODE (*p) == ADDR_EXPR
   12577 			 || TREE_CODE (*p) == MEM_REF
   12578 			 || TREE_CODE (*p) == NON_LVALUE_EXPR)
   12579 		    {
   12580 		      expr_stack.safe_push (*p);
   12581 		      p = &TREE_OPERAND (*p, 0);
   12582 		    }
   12583 		  for (int i = expr_stack.length () - 1; i >= 0; i--)
   12584 		    {
   12585 		      tree t = expr_stack[i];
   12586 		      if (TREE_CODE (t) == ARRAY_REF
   12587 			  || TREE_CODE (t) == ARRAY_RANGE_REF)
   12588 			{
   12589 			  if (TREE_OPERAND (t, 2) == NULL_TREE)
   12590 			    {
   12591 			      tree low = unshare_expr (array_ref_low_bound (t));
   12592 			      if (!is_gimple_min_invariant (low))
   12593 				{
   12594 				  TREE_OPERAND (t, 2) = low;
   12595 				  if (gimplify_expr (&TREE_OPERAND (t, 2),
   12596 						     pre_p, NULL,
   12597 						     is_gimple_reg,
   12598 						     fb_rvalue) == GS_ERROR)
   12599 				    remove = true;
   12600 				}
   12601 			    }
   12602 			  else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
   12603 						  NULL, is_gimple_reg,
   12604 						  fb_rvalue) == GS_ERROR)
   12605 			    remove = true;
   12606 			  if (TREE_OPERAND (t, 3) == NULL_TREE)
   12607 			    {
   12608 			      tree elmt_size = array_ref_element_size (t);
   12609 			      if (!is_gimple_min_invariant (elmt_size))
   12610 				{
   12611 				  elmt_size = unshare_expr (elmt_size);
   12612 				  tree elmt_type
   12613 				    = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t,
   12614 									  0)));
   12615 				  tree factor
   12616 				    = size_int (TYPE_ALIGN_UNIT (elmt_type));
   12617 				  elmt_size
   12618 				    = size_binop (EXACT_DIV_EXPR, elmt_size,
   12619 						  factor);
   12620 				  TREE_OPERAND (t, 3) = elmt_size;
   12621 				  if (gimplify_expr (&TREE_OPERAND (t, 3),
   12622 						     pre_p, NULL,
   12623 						     is_gimple_reg,
   12624 						     fb_rvalue) == GS_ERROR)
   12625 				    remove = true;
   12626 				}
   12627 			    }
   12628 			  else if (gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
   12629 						  NULL, is_gimple_reg,
   12630 						  fb_rvalue) == GS_ERROR)
   12631 			    remove = true;
   12632 			}
   12633 		      else if (TREE_CODE (t) == COMPONENT_REF)
   12634 			{
   12635 			  if (TREE_OPERAND (t, 2) == NULL_TREE)
   12636 			    {
   12637 			      tree offset = component_ref_field_offset (t);
   12638 			      if (!is_gimple_min_invariant (offset))
   12639 				{
   12640 				  offset = unshare_expr (offset);
   12641 				  tree field = TREE_OPERAND (t, 1);
   12642 				  tree factor
   12643 				    = size_int (DECL_OFFSET_ALIGN (field)
   12644 						/ BITS_PER_UNIT);
   12645 				  offset = size_binop (EXACT_DIV_EXPR, offset,
   12646 						       factor);
   12647 				  TREE_OPERAND (t, 2) = offset;
   12648 				  if (gimplify_expr (&TREE_OPERAND (t, 2),
   12649 						     pre_p, NULL,
   12650 						     is_gimple_reg,
   12651 						     fb_rvalue) == GS_ERROR)
   12652 				    remove = true;
   12653 				}
   12654 			    }
   12655 			  else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
   12656 						  NULL, is_gimple_reg,
   12657 						  fb_rvalue) == GS_ERROR)
   12658 			    remove = true;
   12659 			}
   12660 		    }
   12661 		  for (; expr_stack.length () > 0; )
   12662 		    {
   12663 		      tree t = expr_stack.pop ();
   12664 
   12665 		      if (TREE_CODE (t) == ARRAY_REF
   12666 			  || TREE_CODE (t) == ARRAY_RANGE_REF)
   12667 			{
   12668 			  if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))
   12669 			      && gimplify_expr (&TREE_OPERAND (t, 1), pre_p,
   12670 						NULL, is_gimple_val,
   12671 						fb_rvalue) == GS_ERROR)
   12672 			    remove = true;
   12673 			}
   12674 		    }
   12675 		}
   12676 	      break;
   12677 	    }
   12678 
   12679 	  if ((code == OMP_TARGET
   12680 	       || code == OMP_TARGET_DATA
   12681 	       || code == OMP_TARGET_ENTER_DATA
   12682 	       || code == OMP_TARGET_EXIT_DATA)
   12683 	      && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   12684 	    {
   12685 	      /* If we have attach/detach but the decl we have is a pointer to
   12686 		 pointer, we're probably mapping the "base level" array
   12687 		 implicitly.  Make sure we don't add the decl as if we mapped
   12688 		 it explicitly.  That is,
   12689 
   12690 		   int **arr;
   12691 		   [...]
   12692 		   #pragma omp target map(arr[a][b:c])
   12693 
   12694 		 should *not* map "arr" explicitly.  That way we get a
   12695 		 zero-length "alloc" mapping for it, and assuming it's been
   12696 		 mapped by some previous directive, etc., things work as they
   12697 		 should.  */
   12698 
   12699 	      tree basetype = TREE_TYPE (addr_tokens[0]->expr);
   12700 
   12701 	      if (TREE_CODE (basetype) == REFERENCE_TYPE)
   12702 		basetype = TREE_TYPE (basetype);
   12703 
   12704 	      if (code == OMP_TARGET
   12705 		  && addr_tokens[0]->type == ARRAY_BASE
   12706 		  && addr_tokens[0]->u.structure_base_kind == BASE_DECL
   12707 		  && TREE_CODE (basetype) == POINTER_TYPE
   12708 		  && TREE_CODE (TREE_TYPE (basetype)) == POINTER_TYPE)
   12709 		break;
   12710 	    }
   12711 
   12712 	  flags = GOVD_MAP | GOVD_EXPLICIT;
   12713 	  if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
   12714 	      || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM
   12715 	      || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_PRESENT_TO
   12716 	      || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_PRESENT_TOFROM)
   12717 	    flags |= GOVD_MAP_ALWAYS_TO;
   12718 
   12719 	  goto do_add;
   12720 
   12721 	case OMP_CLAUSE_AFFINITY:
   12722 	  gimplify_omp_affinity (list_p, pre_p);
   12723 	  remove = true;
   12724 	  break;
   12725 	case OMP_CLAUSE_DOACROSS:
   12726 	  if (OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
   12727 	    {
   12728 	      tree deps = OMP_CLAUSE_DECL (c);
   12729 	      while (deps && TREE_CODE (deps) == TREE_LIST)
   12730 		{
   12731 		  if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
   12732 		      && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
   12733 		    gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
   12734 				   pre_p, NULL, is_gimple_val, fb_rvalue);
   12735 		  deps = TREE_CHAIN (deps);
   12736 		}
   12737 	    }
   12738 	  else
   12739 	    gcc_assert (OMP_CLAUSE_DOACROSS_KIND (c)
   12740 			== OMP_CLAUSE_DOACROSS_SOURCE);
   12741 	  break;
   12742 	case OMP_CLAUSE_DEPEND:
   12743 	  if (handled_depend_iterators == -1)
   12744 	    handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
   12745 	  if (handled_depend_iterators)
   12746 	    {
   12747 	      if (handled_depend_iterators == 2)
   12748 		remove = true;
   12749 	      break;
   12750 	    }
   12751 	  if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
   12752 	    {
   12753 	      gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
   12754 			     NULL, is_gimple_val, fb_rvalue);
   12755 	      OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
   12756 	    }
   12757 	  if (error_operand_p (OMP_CLAUSE_DECL (c)))
   12758 	    {
   12759 	      remove = true;
   12760 	      break;
   12761 	    }
   12762 	  if (OMP_CLAUSE_DECL (c) != null_pointer_node)
   12763 	    {
   12764 	      OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
   12765 	      if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
   12766 				 is_gimple_val, fb_rvalue) == GS_ERROR)
   12767 		{
   12768 		  remove = true;
   12769 		  break;
   12770 		}
   12771 	    }
   12772 	  if (code == OMP_TASK)
   12773 	    ctx->has_depend = true;
   12774 	  break;
   12775 
   12776 	case OMP_CLAUSE_TO:
   12777 	case OMP_CLAUSE_FROM:
   12778 	case OMP_CLAUSE__CACHE_:
   12779 	  decl = OMP_CLAUSE_DECL (c);
   12780 	  if (error_operand_p (decl))
   12781 	    {
   12782 	      remove = true;
   12783 	      break;
   12784 	    }
   12785 	  if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
   12786 	    OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
   12787 				  : TYPE_SIZE_UNIT (TREE_TYPE (decl));
   12788 	  if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
   12789 			     NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
   12790 	    {
   12791 	      remove = true;
   12792 	      break;
   12793 	    }
   12794 	  if (!DECL_P (decl))
   12795 	    {
   12796 	      if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
   12797 				 NULL, is_gimple_lvalue, fb_lvalue)
   12798 		  == GS_ERROR)
   12799 		{
   12800 		  remove = true;
   12801 		  break;
   12802 		}
   12803 	      break;
   12804 	    }
   12805 	  goto do_notice;
   12806 
   12807 	case OMP_CLAUSE_USE_DEVICE_PTR:
   12808 	case OMP_CLAUSE_USE_DEVICE_ADDR:
   12809 	  flags = GOVD_EXPLICIT;
   12810 	  goto do_add;
   12811 
   12812 	case OMP_CLAUSE_HAS_DEVICE_ADDR:
   12813 	  decl = OMP_CLAUSE_DECL (c);
   12814 	  while (TREE_CODE (decl) == INDIRECT_REF
   12815 		 || TREE_CODE (decl) == ARRAY_REF)
   12816 	    decl = TREE_OPERAND (decl, 0);
   12817 	  flags = GOVD_EXPLICIT;
   12818 	  goto do_add_decl;
   12819 
   12820 	case OMP_CLAUSE_IS_DEVICE_PTR:
   12821 	  flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
   12822 	  goto do_add;
   12823 
   12824 	do_add:
   12825 	  decl = OMP_CLAUSE_DECL (c);
   12826 	do_add_decl:
   12827 	  if (error_operand_p (decl))
   12828 	    {
   12829 	      remove = true;
   12830 	      break;
   12831 	    }
   12832 	  if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
   12833 	    {
   12834 	      tree t = omp_member_access_dummy_var (decl);
   12835 	      if (t)
   12836 		{
   12837 		  tree v = DECL_VALUE_EXPR (decl);
   12838 		  DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
   12839 		  if (outer_ctx)
   12840 		    omp_notice_variable (outer_ctx, t, true);
   12841 		}
   12842 	    }
   12843 	  if (code == OACC_DATA
   12844 	      && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   12845 	      && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
   12846 	    flags |= GOVD_MAP_0LEN_ARRAY;
   12847 	  omp_add_variable (ctx, decl, flags);
   12848 	  if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   12849 	       || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
   12850 	       || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
   12851 	      && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
   12852 	    {
   12853 	      struct gimplify_omp_ctx *pctx
   12854 		= code == OMP_TARGET ? outer_ctx : ctx;
   12855 	      if (pctx)
   12856 		omp_add_variable (pctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
   12857 				  GOVD_LOCAL | GOVD_SEEN);
   12858 	      if (pctx
   12859 		  && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
   12860 		  && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
   12861 				find_decl_expr,
   12862 				OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
   12863 				NULL) == NULL_TREE)
   12864 		omp_add_variable (pctx,
   12865 				  OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
   12866 				  GOVD_LOCAL | GOVD_SEEN);
   12867 	      gimplify_omp_ctxp = pctx;
   12868 	      push_gimplify_context ();
   12869 
   12870 	      OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
   12871 	      OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
   12872 
   12873 	      gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
   12874 		  		&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
   12875 	      pop_gimplify_context
   12876 		(gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
   12877 	      push_gimplify_context ();
   12878 	      gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
   12879 		  		&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
   12880 	      pop_gimplify_context
   12881 		(gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
   12882 	      OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
   12883 	      OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
   12884 
   12885 	      gimplify_omp_ctxp = outer_ctx;
   12886 	    }
   12887 	  else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   12888 		   && OMP_CLAUSE_LASTPRIVATE_STMT (c))
   12889 	    {
   12890 	      gimplify_omp_ctxp = ctx;
   12891 	      push_gimplify_context ();
   12892 	      if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
   12893 		{
   12894 		  tree bind = build3 (BIND_EXPR, void_type_node, NULL,
   12895 				      NULL, NULL);
   12896 		  TREE_SIDE_EFFECTS (bind) = 1;
   12897 		  BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
   12898 		  OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
   12899 		}
   12900 	      gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
   12901 				&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
   12902 	      pop_gimplify_context
   12903 		(gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
   12904 	      OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
   12905 
   12906 	      gimplify_omp_ctxp = outer_ctx;
   12907 	    }
   12908 	  else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   12909 		   && OMP_CLAUSE_LINEAR_STMT (c))
   12910 	    {
   12911 	      gimplify_omp_ctxp = ctx;
   12912 	      push_gimplify_context ();
   12913 	      if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
   12914 		{
   12915 		  tree bind = build3 (BIND_EXPR, void_type_node, NULL,
   12916 				      NULL, NULL);
   12917 		  TREE_SIDE_EFFECTS (bind) = 1;
   12918 		  BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
   12919 		  OMP_CLAUSE_LINEAR_STMT (c) = bind;
   12920 		}
   12921 	      gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
   12922 				&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
   12923 	      pop_gimplify_context
   12924 		(gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
   12925 	      OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
   12926 
   12927 	      gimplify_omp_ctxp = outer_ctx;
   12928 	    }
   12929 	  if (notice_outer)
   12930 	    goto do_notice;
   12931 	  break;
   12932 
   12933 	case OMP_CLAUSE_COPYIN:
   12934 	case OMP_CLAUSE_COPYPRIVATE:
   12935 	  decl = OMP_CLAUSE_DECL (c);
   12936 	  if (error_operand_p (decl))
   12937 	    {
   12938 	      remove = true;
   12939 	      break;
   12940 	    }
   12941 	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
   12942 	      && !remove
   12943 	      && !omp_check_private (ctx, decl, true))
   12944 	    {
   12945 	      remove = true;
   12946 	      if (is_global_var (decl))
   12947 		{
   12948 		  if (DECL_THREAD_LOCAL_P (decl))
   12949 		    remove = false;
   12950 		  else if (DECL_HAS_VALUE_EXPR_P (decl))
   12951 		    {
   12952 		      tree value = get_base_address (DECL_VALUE_EXPR (decl));
   12953 
   12954 		      if (value
   12955 			  && DECL_P (value)
   12956 			  && DECL_THREAD_LOCAL_P (value))
   12957 			remove = false;
   12958 		    }
   12959 		}
   12960 	      if (remove)
   12961 		error_at (OMP_CLAUSE_LOCATION (c),
   12962 			  "copyprivate variable %qE is not threadprivate"
   12963 			  " or private in outer context", DECL_NAME (decl));
   12964 	    }
   12965 	do_notice:
   12966 	  if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   12967 	       || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
   12968 	       || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
   12969 	      && outer_ctx
   12970 	      && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
   12971 		   || (region_type == ORT_WORKSHARE
   12972 		       && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   12973 		       && (OMP_CLAUSE_REDUCTION_INSCAN (c)
   12974 			   || code == OMP_LOOP)))
   12975 	      && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
   12976 		  || (code == OMP_LOOP
   12977 		      && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   12978 		      && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
   12979 			  == ORT_COMBINED_TEAMS))))
   12980 	    {
   12981 	      splay_tree_node on
   12982 		= splay_tree_lookup (outer_ctx->variables,
   12983 				     (splay_tree_key)decl);
   12984 	      if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
   12985 		{
   12986 		  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   12987 		      && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
   12988 		      && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
   12989 			  || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
   12990 			      && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
   12991 				  == POINTER_TYPE))))
   12992 		    omp_firstprivatize_variable (outer_ctx, decl);
   12993 		  else
   12994 		    {
   12995 		      omp_add_variable (outer_ctx, decl,
   12996 					GOVD_SEEN | GOVD_SHARED);
   12997 		      if (outer_ctx->outer_context)
   12998 			omp_notice_variable (outer_ctx->outer_context, decl,
   12999 					     true);
   13000 		    }
   13001 		}
   13002 	    }
   13003 	  if (outer_ctx)
   13004 	    omp_notice_variable (outer_ctx, decl, true);
   13005 	  if (check_non_private
   13006 	      && (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
   13007 	      && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
   13008 		  || decl == OMP_CLAUSE_DECL (c)
   13009 		  || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
   13010 		      && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
   13011 			  == ADDR_EXPR
   13012 			  || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
   13013 			      == POINTER_PLUS_EXPR
   13014 			      && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
   13015 						(OMP_CLAUSE_DECL (c), 0), 0))
   13016 				  == ADDR_EXPR)))))
   13017 	      && omp_check_private (ctx, decl, false))
   13018 	    {
   13019 	      error ("%s variable %qE is private in outer context",
   13020 		     check_non_private, DECL_NAME (decl));
   13021 	      remove = true;
   13022 	    }
   13023 	  break;
   13024 
   13025 	case OMP_CLAUSE_DETACH:
   13026 	  flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
   13027 	  goto do_add;
   13028 
   13029 	case OMP_CLAUSE_IF:
   13030 	  if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
   13031 	      && OMP_CLAUSE_IF_MODIFIER (c) != code)
   13032 	    {
   13033 	      const char *p[2];
   13034 	      for (int i = 0; i < 2; i++)
   13035 		switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
   13036 		  {
   13037 		  case VOID_CST: p[i] = "cancel"; break;
   13038 		  case OMP_PARALLEL: p[i] = "parallel"; break;
   13039 		  case OMP_SIMD: p[i] = "simd"; break;
   13040 		  case OMP_TASK: p[i] = "task"; break;
   13041 		  case OMP_TASKLOOP: p[i] = "taskloop"; break;
   13042 		  case OMP_TARGET_DATA: p[i] = "target data"; break;
   13043 		  case OMP_TARGET: p[i] = "target"; break;
   13044 		  case OMP_TARGET_UPDATE: p[i] = "target update"; break;
   13045 		  case OMP_TARGET_ENTER_DATA:
   13046 		    p[i] = "target enter data"; break;
   13047 		  case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
   13048 		  default: gcc_unreachable ();
   13049 		  }
   13050 	      error_at (OMP_CLAUSE_LOCATION (c),
   13051 			"expected %qs %<if%> clause modifier rather than %qs",
   13052 			p[0], p[1]);
   13053 	      remove = true;
   13054 	    }
   13055 	  /* Fall through.  */
   13056 
   13057 	case OMP_CLAUSE_SELF:
   13058 	case OMP_CLAUSE_FINAL:
   13059 	  OMP_CLAUSE_OPERAND (c, 0)
   13060 	    = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
   13061 	  /* Fall through.  */
   13062 
   13063 	case OMP_CLAUSE_NUM_TEAMS:
   13064 	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
   13065 	      && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
   13066 	      && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
   13067 	    {
   13068 	      if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
   13069 		{
   13070 		  remove = true;
   13071 		  break;
   13072 		}
   13073 	      OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
   13074 		= get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c),
   13075 					   pre_p, NULL, true);
   13076 	    }
   13077 	  /* Fall through.  */
   13078 
   13079 	case OMP_CLAUSE_SCHEDULE:
   13080 	case OMP_CLAUSE_NUM_THREADS:
   13081 	case OMP_CLAUSE_THREAD_LIMIT:
   13082 	case OMP_CLAUSE_DIST_SCHEDULE:
   13083 	case OMP_CLAUSE_DEVICE:
   13084 	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE
   13085 	      && OMP_CLAUSE_DEVICE_ANCESTOR (c))
   13086 	    {
   13087 	      if (code != OMP_TARGET)
   13088 		{
   13089 		  error_at (OMP_CLAUSE_LOCATION (c),
   13090 			    "%<device%> clause with %<ancestor%> is only "
   13091 			    "allowed on %<target%> construct");
   13092 		  remove = true;
   13093 		  break;
   13094 		}
   13095 
   13096 	      tree clauses = *orig_list_p;
   13097 	      for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
   13098 		if (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEVICE
   13099 		    && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_FIRSTPRIVATE
   13100 		    && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_PRIVATE
   13101 		    && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEFAULTMAP
   13102 		    && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_MAP
   13103 		   )
   13104 		  {
   13105 		    error_at (OMP_CLAUSE_LOCATION (c),
   13106 			      "with %<ancestor%>, only the %<device%>, "
   13107 			      "%<firstprivate%>, %<private%>, %<defaultmap%>, "
   13108 			      "and %<map%> clauses may appear on the "
   13109 			      "construct");
   13110 		    remove = true;
   13111 		    break;
   13112 		  }
   13113 	    }
   13114 	  /* Fall through.  */
   13115 
   13116 	case OMP_CLAUSE_PRIORITY:
   13117 	case OMP_CLAUSE_GRAINSIZE:
   13118 	case OMP_CLAUSE_NUM_TASKS:
   13119 	case OMP_CLAUSE_FILTER:
   13120 	case OMP_CLAUSE_HINT:
   13121 	case OMP_CLAUSE_ASYNC:
   13122 	case OMP_CLAUSE_WAIT:
   13123 	case OMP_CLAUSE_NUM_GANGS:
   13124 	case OMP_CLAUSE_NUM_WORKERS:
   13125 	case OMP_CLAUSE_VECTOR_LENGTH:
   13126 	case OMP_CLAUSE_WORKER:
   13127 	case OMP_CLAUSE_VECTOR:
   13128 	  if (OMP_CLAUSE_OPERAND (c, 0)
   13129 	      && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0)))
   13130 	    {
   13131 	      if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0)))
   13132 		{
   13133 		  remove = true;
   13134 		  break;
   13135 		}
   13136 	      /* All these clauses care about value, not a particular decl,
   13137 		 so try to force it into a SSA_NAME or fresh temporary.  */
   13138 	      OMP_CLAUSE_OPERAND (c, 0)
   13139 		= get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0),
   13140 					   pre_p, NULL, true);
   13141 	    }
   13142 	  break;
   13143 
   13144 	case OMP_CLAUSE_GANG:
   13145 	  if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
   13146 			     is_gimple_val, fb_rvalue) == GS_ERROR)
   13147 	    remove = true;
   13148 	  if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
   13149 			     is_gimple_val, fb_rvalue) == GS_ERROR)
   13150 	    remove = true;
   13151 	  break;
   13152 
   13153 	case OMP_CLAUSE_NOWAIT:
   13154 	  nowait = 1;
   13155 	  break;
   13156 
   13157 	case OMP_CLAUSE_ORDERED:
   13158 	case OMP_CLAUSE_UNTIED:
   13159 	case OMP_CLAUSE_COLLAPSE:
   13160 	case OMP_CLAUSE_TILE:
   13161 	case OMP_CLAUSE_AUTO:
   13162 	case OMP_CLAUSE_SEQ:
   13163 	case OMP_CLAUSE_INDEPENDENT:
   13164 	case OMP_CLAUSE_MERGEABLE:
   13165 	case OMP_CLAUSE_PROC_BIND:
   13166 	case OMP_CLAUSE_SAFELEN:
   13167 	case OMP_CLAUSE_SIMDLEN:
   13168 	case OMP_CLAUSE_NOGROUP:
   13169 	case OMP_CLAUSE_THREADS:
   13170 	case OMP_CLAUSE_SIMD:
   13171 	case OMP_CLAUSE_BIND:
   13172 	case OMP_CLAUSE_IF_PRESENT:
   13173 	case OMP_CLAUSE_FINALIZE:
   13174 	  break;
   13175 
   13176 	case OMP_CLAUSE_ORDER:
   13177 	  ctx->order_concurrent = true;
   13178 	  break;
   13179 
   13180 	case OMP_CLAUSE_DEFAULTMAP:
   13181 	  enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
   13182 	  switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
   13183 	    {
   13184 	    case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
   13185 	    case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL:
   13186 	      gdmkmin = GDMK_SCALAR;
   13187 	      gdmkmax = GDMK_POINTER;
   13188 	      break;
   13189 	    case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
   13190 	      gdmkmin = GDMK_SCALAR;
   13191 	      gdmkmax = GDMK_SCALAR_TARGET;
   13192 	      break;
   13193 	    case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
   13194 	      gdmkmin = gdmkmax = GDMK_AGGREGATE;
   13195 	      break;
   13196 	    case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
   13197 	      gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
   13198 	      break;
   13199 	    case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
   13200 	      gdmkmin = gdmkmax = GDMK_POINTER;
   13201 	      break;
   13202 	    default:
   13203 	      gcc_unreachable ();
   13204 	    }
   13205 	  for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
   13206 	    switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
   13207 	      {
   13208 	      case OMP_CLAUSE_DEFAULTMAP_ALLOC:
   13209 		ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
   13210 		break;
   13211 	      case OMP_CLAUSE_DEFAULTMAP_TO:
   13212 		ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
   13213 		break;
   13214 	      case OMP_CLAUSE_DEFAULTMAP_FROM:
   13215 		ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
   13216 		break;
   13217 	      case OMP_CLAUSE_DEFAULTMAP_TOFROM:
   13218 		ctx->defaultmap[gdmk] = GOVD_MAP;
   13219 		break;
   13220 	      case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
   13221 		ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
   13222 		break;
   13223 	      case OMP_CLAUSE_DEFAULTMAP_NONE:
   13224 		ctx->defaultmap[gdmk] = 0;
   13225 		break;
   13226 	      case OMP_CLAUSE_DEFAULTMAP_PRESENT:
   13227 		ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
   13228 		break;
   13229 	      case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
   13230 		switch (gdmk)
   13231 		  {
   13232 		  case GDMK_SCALAR:
   13233 		    ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
   13234 		    break;
   13235 		  case GDMK_SCALAR_TARGET:
   13236 		    ctx->defaultmap[gdmk] = (lang_GNU_Fortran ()
   13237 					     ? GOVD_MAP : GOVD_FIRSTPRIVATE);
   13238 		    break;
   13239 		  case GDMK_AGGREGATE:
   13240 		  case GDMK_ALLOCATABLE:
   13241 		    ctx->defaultmap[gdmk] = GOVD_MAP;
   13242 		    break;
   13243 		  case GDMK_POINTER:
   13244 		    ctx->defaultmap[gdmk] = GOVD_MAP;
   13245 		    if (!lang_GNU_Fortran ())
   13246 		      ctx->defaultmap[gdmk] |= GOVD_MAP_0LEN_ARRAY;
   13247 		    break;
   13248 		  default:
   13249 		    gcc_unreachable ();
   13250 		  }
   13251 		break;
   13252 	      default:
   13253 		gcc_unreachable ();
   13254 	      }
   13255 	  break;
   13256 
   13257 	case OMP_CLAUSE_ALIGNED:
   13258 	  decl = OMP_CLAUSE_DECL (c);
   13259 	  if (error_operand_p (decl))
   13260 	    {
   13261 	      remove = true;
   13262 	      break;
   13263 	    }
   13264 	  if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
   13265 			     is_gimple_val, fb_rvalue) == GS_ERROR)
   13266 	    {
   13267 	      remove = true;
   13268 	      break;
   13269 	    }
   13270 	  if (!is_global_var (decl)
   13271 	      && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
   13272 	    omp_add_variable (ctx, decl, GOVD_ALIGNED);
   13273 	  break;
   13274 
   13275 	case OMP_CLAUSE_NONTEMPORAL:
   13276 	  decl = OMP_CLAUSE_DECL (c);
   13277 	  if (error_operand_p (decl))
   13278 	    {
   13279 	      remove = true;
   13280 	      break;
   13281 	    }
   13282 	  omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
   13283 	  break;
   13284 
   13285 	case OMP_CLAUSE_ALLOCATE:
   13286 	  decl = OMP_CLAUSE_DECL (c);
   13287 	  if (error_operand_p (decl))
   13288 	    {
   13289 	      remove = true;
   13290 	      break;
   13291 	    }
   13292 	  if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL,
   13293 			     is_gimple_val, fb_rvalue) == GS_ERROR)
   13294 	    {
   13295 	      remove = true;
   13296 	      break;
   13297 	    }
   13298 	  else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
   13299 		   || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
   13300 		       == INTEGER_CST))
   13301 	    ;
   13302 	  else if (code == OMP_TASKLOOP
   13303 		   || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
   13304 	    OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
   13305 	      = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
   13306 					 pre_p, NULL, false);
   13307 	  break;
   13308 
   13309 	case OMP_CLAUSE_DEFAULT:
   13310 	  ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
   13311 	  break;
   13312 
   13313 	case OMP_CLAUSE_INCLUSIVE:
   13314 	case OMP_CLAUSE_EXCLUSIVE:
   13315 	  decl = OMP_CLAUSE_DECL (c);
   13316 	  {
   13317 	    splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
   13318 						   (splay_tree_key) decl);
   13319 	    if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
   13320 	      {
   13321 		error_at (OMP_CLAUSE_LOCATION (c),
   13322 			  "%qD specified in %qs clause but not in %<inscan%> "
   13323 			  "%<reduction%> clause on the containing construct",
   13324 			  decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
   13325 		remove = true;
   13326 	      }
   13327 	    else
   13328 	      {
   13329 		n->value |= GOVD_REDUCTION_INSCAN;
   13330 		if (outer_ctx->region_type == ORT_SIMD
   13331 		    && outer_ctx->outer_context
   13332 		    && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
   13333 		  {
   13334 		    n = splay_tree_lookup (outer_ctx->outer_context->variables,
   13335 					   (splay_tree_key) decl);
   13336 		    if (n && (n->value & GOVD_REDUCTION) != 0)
   13337 		      n->value |= GOVD_REDUCTION_INSCAN;
   13338 		  }
   13339 	      }
   13340 	  }
   13341 	  break;
   13342 
   13343 	case OMP_CLAUSE_NOHOST:
   13344 	default:
   13345 	  gcc_unreachable ();
   13346 	}
   13347 
   13348       if (code == OACC_DATA
   13349 	  && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13350 	  && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   13351 	      || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   13352 	remove = true;
   13353       if (remove)
   13354 	*list_p = OMP_CLAUSE_CHAIN (c);
   13355       else
   13356 	list_p = &OMP_CLAUSE_CHAIN (c);
   13357     }
   13358 
   13359   if (groups)
   13360     {
   13361       delete grpmap;
   13362       delete groups;
   13363     }
   13364 
   13365   ctx->clauses = *orig_list_p;
   13366   gimplify_omp_ctxp = ctx;
   13367 }
   13368 
   13369 /* Return true if DECL is a candidate for shared to firstprivate
   13370    optimization.  We only consider non-addressable scalars, not
   13371    too big, and not references.  */
   13372 
   13373 static bool
   13374 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
   13375 {
   13376   if (TREE_ADDRESSABLE (decl))
   13377     return false;
   13378   tree type = TREE_TYPE (decl);
   13379   if (!is_gimple_reg_type (type)
   13380       || TREE_CODE (type) == REFERENCE_TYPE
   13381       || TREE_ADDRESSABLE (type))
   13382     return false;
   13383   /* Don't optimize too large decls, as each thread/task will have
   13384      its own.  */
   13385   HOST_WIDE_INT len = int_size_in_bytes (type);
   13386   if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
   13387     return false;
   13388   if (omp_privatize_by_reference (decl))
   13389     return false;
   13390   return true;
   13391 }
   13392 
   13393 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
   13394    For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
   13395    GOVD_WRITTEN in outer contexts.  */
   13396 
   13397 static void
   13398 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
   13399 {
   13400   for (; ctx; ctx = ctx->outer_context)
   13401     {
   13402       splay_tree_node n = splay_tree_lookup (ctx->variables,
   13403 					     (splay_tree_key) decl);
   13404       if (n == NULL)
   13405 	continue;
   13406       else if (n->value & GOVD_SHARED)
   13407 	{
   13408 	  n->value |= GOVD_WRITTEN;
   13409 	  return;
   13410 	}
   13411       else if (n->value & GOVD_DATA_SHARE_CLASS)
   13412 	return;
   13413     }
   13414 }
   13415 
   13416 /* Helper callback for walk_gimple_seq to discover possible stores
   13417    to omp_shared_to_firstprivate_optimizable_decl_p decls and set
   13418    GOVD_WRITTEN if they are GOVD_SHARED in some outer context
   13419    for those.  */
   13420 
   13421 static tree
   13422 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
   13423 {
   13424   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
   13425 
   13426   *walk_subtrees = 0;
   13427   if (!wi->is_lhs)
   13428     return NULL_TREE;
   13429 
   13430   tree op = *tp;
   13431   do
   13432     {
   13433       if (handled_component_p (op))
   13434 	op = TREE_OPERAND (op, 0);
   13435       else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
   13436 	       && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
   13437 	op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
   13438       else
   13439 	break;
   13440     }
   13441   while (1);
   13442   if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
   13443     return NULL_TREE;
   13444 
   13445   omp_mark_stores (gimplify_omp_ctxp, op);
   13446   return NULL_TREE;
   13447 }
   13448 
   13449 /* Helper callback for walk_gimple_seq to discover possible stores
   13450    to omp_shared_to_firstprivate_optimizable_decl_p decls and set
   13451    GOVD_WRITTEN if they are GOVD_SHARED in some outer context
   13452    for those.  */
   13453 
   13454 static tree
   13455 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
   13456 		      bool *handled_ops_p,
   13457 		      struct walk_stmt_info *wi)
   13458 {
   13459   gimple *stmt = gsi_stmt (*gsi_p);
   13460   switch (gimple_code (stmt))
   13461     {
   13462     /* Don't recurse on OpenMP constructs for which
   13463        gimplify_adjust_omp_clauses already handled the bodies,
   13464        except handle gimple_omp_for_pre_body.  */
   13465     case GIMPLE_OMP_FOR:
   13466       *handled_ops_p = true;
   13467       if (gimple_omp_for_pre_body (stmt))
   13468 	walk_gimple_seq (gimple_omp_for_pre_body (stmt),
   13469 			 omp_find_stores_stmt, omp_find_stores_op, wi);
   13470       break;
   13471     case GIMPLE_OMP_PARALLEL:
   13472     case GIMPLE_OMP_TASK:
   13473     case GIMPLE_OMP_SECTIONS:
   13474     case GIMPLE_OMP_SINGLE:
   13475     case GIMPLE_OMP_SCOPE:
   13476     case GIMPLE_OMP_TARGET:
   13477     case GIMPLE_OMP_TEAMS:
   13478     case GIMPLE_OMP_CRITICAL:
   13479       *handled_ops_p = true;
   13480       break;
   13481     default:
   13482       break;
   13483     }
   13484   return NULL_TREE;
   13485 }
   13486 
   13487 struct gimplify_adjust_omp_clauses_data
   13488 {
   13489   tree *list_p;
   13490   gimple_seq *pre_p;
   13491 };
   13492 
   13493 /* For all variables that were not actually used within the context,
   13494    remove PRIVATE, SHARED, and FIRSTPRIVATE clauses.  */
   13495 
   13496 static int
   13497 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
   13498 {
   13499   tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
   13500   gimple_seq *pre_p
   13501     = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
   13502   tree decl = (tree) n->key;
   13503   unsigned flags = n->value;
   13504   enum omp_clause_code code;
   13505   tree clause;
   13506   bool private_debug;
   13507 
   13508   if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
   13509       && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
   13510     flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
   13511   if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
   13512     return 0;
   13513   if ((flags & GOVD_SEEN) == 0)
   13514     return 0;
   13515   if (flags & GOVD_DEBUG_PRIVATE)
   13516     {
   13517       gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
   13518       private_debug = true;
   13519     }
   13520   else if (flags & GOVD_MAP)
   13521     private_debug = false;
   13522   else
   13523     private_debug
   13524       = lang_hooks.decls.omp_private_debug_clause (decl,
   13525 						   !!(flags & GOVD_SHARED));
   13526   if (private_debug)
   13527     code = OMP_CLAUSE_PRIVATE;
   13528   else if (flags & GOVD_MAP)
   13529     {
   13530       code = OMP_CLAUSE_MAP;
   13531       if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
   13532 	  && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
   13533 	{
   13534 	  error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
   13535 	  return 0;
   13536 	}
   13537       if (VAR_P (decl)
   13538 	  && DECL_IN_CONSTANT_POOL (decl)
   13539           && !lookup_attribute ("omp declare target",
   13540 				DECL_ATTRIBUTES (decl)))
   13541 	{
   13542 	  tree id = get_identifier ("omp declare target");
   13543 	  DECL_ATTRIBUTES (decl)
   13544 	    = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
   13545 	  varpool_node *node = varpool_node::get (decl);
   13546 	  if (node)
   13547 	    {
   13548 	      node->offloadable = 1;
   13549 	      if (ENABLE_OFFLOADING)
   13550 		g->have_offload = true;
   13551 	    }
   13552 	}
   13553     }
   13554   else if (flags & GOVD_SHARED)
   13555     {
   13556       if (is_global_var (decl))
   13557 	{
   13558 	  struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
   13559 	  while (ctx != NULL)
   13560 	    {
   13561 	      splay_tree_node on
   13562 		= splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   13563 	      if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
   13564 				      | GOVD_PRIVATE | GOVD_REDUCTION
   13565 				      | GOVD_LINEAR | GOVD_MAP)) != 0)
   13566 		break;
   13567 	      ctx = ctx->outer_context;
   13568 	    }
   13569 	  if (ctx == NULL)
   13570 	    return 0;
   13571 	}
   13572       code = OMP_CLAUSE_SHARED;
   13573       /* Don't optimize shared into firstprivate for read-only vars
   13574 	 on tasks with depend clause, we shouldn't try to copy them
   13575 	 until the dependencies are satisfied.  */
   13576       if (gimplify_omp_ctxp->has_depend)
   13577 	flags |= GOVD_WRITTEN;
   13578     }
   13579   else if (flags & GOVD_PRIVATE)
   13580     code = OMP_CLAUSE_PRIVATE;
   13581   else if (flags & GOVD_FIRSTPRIVATE)
   13582     {
   13583       code = OMP_CLAUSE_FIRSTPRIVATE;
   13584       if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
   13585 	  && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
   13586 	  && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
   13587 	{
   13588 	  error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
   13589 		 "%<target%> construct", decl);
   13590 	  return 0;
   13591 	}
   13592     }
   13593   else if (flags & GOVD_LASTPRIVATE)
   13594     code = OMP_CLAUSE_LASTPRIVATE;
   13595   else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
   13596     return 0;
   13597   else if (flags & GOVD_CONDTEMP)
   13598     {
   13599       code = OMP_CLAUSE__CONDTEMP_;
   13600       gimple_add_tmp_var (decl);
   13601     }
   13602   else
   13603     gcc_unreachable ();
   13604 
   13605   if (((flags & GOVD_LASTPRIVATE)
   13606        || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
   13607       && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   13608     omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
   13609 
   13610   tree chain = *list_p;
   13611   clause = build_omp_clause (input_location, code);
   13612   OMP_CLAUSE_DECL (clause) = decl;
   13613   OMP_CLAUSE_CHAIN (clause) = chain;
   13614   if (private_debug)
   13615     OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
   13616   else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
   13617     OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
   13618   else if (code == OMP_CLAUSE_SHARED
   13619 	   && (flags & GOVD_WRITTEN) == 0
   13620 	   && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   13621     OMP_CLAUSE_SHARED_READONLY (clause) = 1;
   13622   else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
   13623     OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
   13624   else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
   13625     {
   13626       tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
   13627       OMP_CLAUSE_DECL (nc) = decl;
   13628       if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
   13629 	  && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
   13630 	OMP_CLAUSE_DECL (clause)
   13631 	  = build_fold_indirect_ref_loc (input_location, decl);
   13632       OMP_CLAUSE_DECL (clause)
   13633 	= build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
   13634 		  build_int_cst (build_pointer_type (char_type_node), 0));
   13635       OMP_CLAUSE_SIZE (clause) = size_zero_node;
   13636       OMP_CLAUSE_SIZE (nc) = size_zero_node;
   13637       OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
   13638       OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
   13639       tree dtype = TREE_TYPE (decl);
   13640       if (TREE_CODE (dtype) == REFERENCE_TYPE)
   13641 	dtype = TREE_TYPE (dtype);
   13642       /* FIRSTPRIVATE_POINTER doesn't work well if we have a
   13643 	 multiply-indirected pointer.  If we have a reference to a pointer to
   13644 	 a pointer, it's possible that this should really be
   13645 	 GOMP_MAP_FIRSTPRIVATE_REFERENCE -- but that also doesn't work at the
   13646 	 moment, so stick with this.  (See PR113279 and testcases
   13647 	 baseptrs-{4,6}.C:ref2ptrptr_offset_decl_member_slice).  */
   13648       if (TREE_CODE (dtype) == POINTER_TYPE
   13649 	  && TREE_CODE (TREE_TYPE (dtype)) == POINTER_TYPE)
   13650 	OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
   13651       else
   13652 	OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
   13653       OMP_CLAUSE_CHAIN (nc) = chain;
   13654       OMP_CLAUSE_CHAIN (clause) = nc;
   13655       struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   13656       gimplify_omp_ctxp = ctx->outer_context;
   13657       gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
   13658 		     pre_p, NULL, is_gimple_val, fb_rvalue);
   13659       gimplify_omp_ctxp = ctx;
   13660     }
   13661   else if (code == OMP_CLAUSE_MAP)
   13662     {
   13663       int kind;
   13664       /* Not all combinations of these GOVD_MAP flags are actually valid.  */
   13665       switch (flags & (GOVD_MAP_TO_ONLY
   13666 		       | GOVD_MAP_FORCE
   13667 		       | GOVD_MAP_FORCE_PRESENT
   13668 		       | GOVD_MAP_ALLOC_ONLY
   13669 		       | GOVD_MAP_FROM_ONLY))
   13670 	{
   13671 	case 0:
   13672 	  kind = GOMP_MAP_TOFROM;
   13673 	  break;
   13674 	case GOVD_MAP_FORCE:
   13675 	  kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
   13676 	  break;
   13677 	case GOVD_MAP_TO_ONLY:
   13678 	  kind = GOMP_MAP_TO;
   13679 	  break;
   13680 	case GOVD_MAP_FROM_ONLY:
   13681 	  kind = GOMP_MAP_FROM;
   13682 	  break;
   13683 	case GOVD_MAP_ALLOC_ONLY:
   13684 	  kind = GOMP_MAP_ALLOC;
   13685 	  break;
   13686 	case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
   13687 	  kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
   13688 	  break;
   13689 	case GOVD_MAP_FORCE_PRESENT:
   13690 	  kind = GOMP_MAP_FORCE_PRESENT;
   13691 	  break;
   13692 	case GOVD_MAP_FORCE_PRESENT | GOVD_MAP_ALLOC_ONLY:
   13693 	  kind = GOMP_MAP_FORCE_PRESENT;
   13694 	  break;
   13695 	default:
   13696 	  gcc_unreachable ();
   13697 	}
   13698       OMP_CLAUSE_SET_MAP_KIND (clause, kind);
   13699       /* Setting of the implicit flag for the runtime is currently disabled for
   13700 	 OpenACC.  */
   13701       if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
   13702 	OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
   13703       if (DECL_SIZE (decl)
   13704 	  && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
   13705 	{
   13706 	  tree decl2 = DECL_VALUE_EXPR (decl);
   13707 	  gcc_assert (INDIRECT_REF_P (decl2));
   13708 	  decl2 = TREE_OPERAND (decl2, 0);
   13709 	  gcc_assert (DECL_P (decl2));
   13710 	  tree mem = build_simple_mem_ref (decl2);
   13711 	  OMP_CLAUSE_DECL (clause) = mem;
   13712 	  OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
   13713 	  if (gimplify_omp_ctxp->outer_context)
   13714 	    {
   13715 	      struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
   13716 	      omp_notice_variable (ctx, decl2, true);
   13717 	      omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
   13718 	    }
   13719 	  tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
   13720 				      OMP_CLAUSE_MAP);
   13721 	  OMP_CLAUSE_DECL (nc) = decl;
   13722 	  OMP_CLAUSE_SIZE (nc) = size_zero_node;
   13723 	  if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
   13724 	    OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
   13725 	  else
   13726 	    OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
   13727 	  OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
   13728 	  OMP_CLAUSE_CHAIN (clause) = nc;
   13729 	}
   13730       else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
   13731 	       && omp_privatize_by_reference (decl))
   13732 	{
   13733 	  OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
   13734 	  OMP_CLAUSE_SIZE (clause)
   13735 	    = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
   13736 	  struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   13737 	  gimplify_omp_ctxp = ctx->outer_context;
   13738 	  gimplify_expr (&OMP_CLAUSE_SIZE (clause),
   13739 			 pre_p, NULL, is_gimple_val, fb_rvalue);
   13740 	  gimplify_omp_ctxp = ctx;
   13741 	  tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
   13742 				      OMP_CLAUSE_MAP);
   13743 	  OMP_CLAUSE_DECL (nc) = decl;
   13744 	  OMP_CLAUSE_SIZE (nc) = size_zero_node;
   13745 	  OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
   13746 	  OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
   13747 	  OMP_CLAUSE_CHAIN (clause) = nc;
   13748 	}
   13749       else
   13750 	OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
   13751     }
   13752   if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
   13753     {
   13754       tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
   13755       OMP_CLAUSE_DECL (nc) = decl;
   13756       OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
   13757       OMP_CLAUSE_CHAIN (nc) = chain;
   13758       OMP_CLAUSE_CHAIN (clause) = nc;
   13759       struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   13760       gimplify_omp_ctxp = ctx->outer_context;
   13761       lang_hooks.decls.omp_finish_clause (nc, pre_p,
   13762 					  (ctx->region_type & ORT_ACC) != 0);
   13763       gimplify_omp_ctxp = ctx;
   13764     }
   13765   *list_p = clause;
   13766   struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   13767   gimplify_omp_ctxp = ctx->outer_context;
   13768   /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
   13769      in simd.  Those are only added for the local vars inside of simd body
   13770      and they don't need to be e.g. default constructible.  */
   13771   if (code != OMP_CLAUSE_PRIVATE || ctx->region_type != ORT_SIMD)
   13772     lang_hooks.decls.omp_finish_clause (clause, pre_p,
   13773 					(ctx->region_type & ORT_ACC) != 0);
   13774   if (gimplify_omp_ctxp)
   13775     for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
   13776       if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
   13777 	  && DECL_P (OMP_CLAUSE_SIZE (clause)))
   13778 	omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
   13779 			     true);
   13780   gimplify_omp_ctxp = ctx;
   13781   return 0;
   13782 }
   13783 
   13784 static void
   13785 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
   13786 			     enum tree_code code)
   13787 {
   13788   struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   13789   tree *orig_list_p = list_p;
   13790   tree c, decl;
   13791   bool has_inscan_reductions = false;
   13792 
   13793   if (body)
   13794     {
   13795       struct gimplify_omp_ctx *octx;
   13796       for (octx = ctx; octx; octx = octx->outer_context)
   13797 	if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
   13798 	  break;
   13799       if (octx)
   13800 	{
   13801 	  struct walk_stmt_info wi;
   13802 	  memset (&wi, 0, sizeof (wi));
   13803 	  walk_gimple_seq (body, omp_find_stores_stmt,
   13804 			   omp_find_stores_op, &wi);
   13805 	}
   13806     }
   13807 
   13808   if (ctx->add_safelen1)
   13809     {
   13810       /* If there are VLAs in the body of simd loop, prevent
   13811 	 vectorization.  */
   13812       gcc_assert (ctx->region_type == ORT_SIMD);
   13813       c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
   13814       OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
   13815       OMP_CLAUSE_CHAIN (c) = *list_p;
   13816       *list_p = c;
   13817       list_p = &OMP_CLAUSE_CHAIN (c);
   13818     }
   13819 
   13820   if (ctx->region_type == ORT_WORKSHARE
   13821       && ctx->outer_context
   13822       && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
   13823     {
   13824       for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
   13825 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   13826 	    && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   13827 	  {
   13828 	    decl = OMP_CLAUSE_DECL (c);
   13829 	    splay_tree_node n
   13830 	      = splay_tree_lookup (ctx->outer_context->variables,
   13831 				   (splay_tree_key) decl);
   13832 	    gcc_checking_assert (!splay_tree_lookup (ctx->variables,
   13833 						     (splay_tree_key) decl));
   13834 	    omp_add_variable (ctx, decl, n->value);
   13835 	    tree c2 = copy_node (c);
   13836 	    OMP_CLAUSE_CHAIN (c2) = *list_p;
   13837 	    *list_p = c2;
   13838 	    if ((n->value & GOVD_FIRSTPRIVATE) == 0)
   13839 	      continue;
   13840 	    c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   13841 				   OMP_CLAUSE_FIRSTPRIVATE);
   13842 	    OMP_CLAUSE_DECL (c2) = decl;
   13843 	    OMP_CLAUSE_CHAIN (c2) = *list_p;
   13844 	    *list_p = c2;
   13845 	  }
   13846     }
   13847 
   13848   if (code == OMP_TARGET
   13849       || code == OMP_TARGET_DATA
   13850       || code == OMP_TARGET_ENTER_DATA
   13851       || code == OMP_TARGET_EXIT_DATA)
   13852     {
   13853       vec<omp_mapping_group> *groups;
   13854       groups = omp_gather_mapping_groups (list_p);
   13855       hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap = NULL;
   13856 
   13857       if (groups)
   13858 	{
   13859 	  grpmap = omp_index_mapping_groups (groups);
   13860 
   13861 	  omp_resolve_clause_dependencies (code, groups, grpmap);
   13862 	  omp_build_struct_sibling_lists (code, ctx->region_type, groups,
   13863 					  &grpmap, list_p);
   13864 
   13865 	  omp_mapping_group *outlist = NULL;
   13866 
   13867 	  delete grpmap;
   13868 	  delete groups;
   13869 
   13870 	  /* Rebuild now we have struct sibling lists.  */
   13871 	  groups = omp_gather_mapping_groups (list_p);
   13872 	  grpmap = omp_index_mapping_groups (groups);
   13873 
   13874 	  bool enter_exit = (code == OMP_TARGET_ENTER_DATA
   13875 			     || code == OMP_TARGET_EXIT_DATA);
   13876 
   13877 	  outlist = omp_tsort_mapping_groups (groups, grpmap, enter_exit);
   13878 	  outlist = omp_segregate_mapping_groups (outlist);
   13879 	  list_p = omp_reorder_mapping_groups (groups, outlist, list_p);
   13880 
   13881 	  delete grpmap;
   13882 	  delete groups;
   13883 	}
   13884     }
   13885   else if (ctx->region_type & ORT_ACC)
   13886     {
   13887       vec<omp_mapping_group> *groups;
   13888       groups = omp_gather_mapping_groups (list_p);
   13889       if (groups)
   13890 	{
   13891 	  hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap;
   13892 	  grpmap = omp_index_mapping_groups (groups);
   13893 
   13894 	  oacc_resolve_clause_dependencies (groups, grpmap);
   13895 	  omp_build_struct_sibling_lists (code, ctx->region_type, groups,
   13896 					  &grpmap, list_p);
   13897 
   13898 	  delete groups;
   13899 	  delete grpmap;
   13900 	}
   13901     }
   13902 
   13903   tree attach_list = NULL_TREE;
   13904   tree *attach_tail = &attach_list;
   13905 
   13906   tree *grp_start_p = NULL, grp_end = NULL_TREE;
   13907 
   13908   while ((c = *list_p) != NULL)
   13909     {
   13910       splay_tree_node n;
   13911       bool remove = false;
   13912       bool move_attach = false;
   13913 
   13914       if (grp_end && c == OMP_CLAUSE_CHAIN (grp_end))
   13915 	grp_end = NULL_TREE;
   13916 
   13917       switch (OMP_CLAUSE_CODE (c))
   13918 	{
   13919 	case OMP_CLAUSE_FIRSTPRIVATE:
   13920 	  if ((ctx->region_type & ORT_TARGET)
   13921 	      && (ctx->region_type & ORT_ACC) == 0
   13922 	      && TYPE_ATOMIC (strip_array_types
   13923 					(TREE_TYPE (OMP_CLAUSE_DECL (c)))))
   13924 	    {
   13925 	      error_at (OMP_CLAUSE_LOCATION (c),
   13926 			"%<_Atomic%> %qD in %<firstprivate%> clause on "
   13927 			"%<target%> construct", OMP_CLAUSE_DECL (c));
   13928 	      remove = true;
   13929 	      break;
   13930 	    }
   13931 	  if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
   13932 	    {
   13933 	      decl = OMP_CLAUSE_DECL (c);
   13934 	      n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   13935 	      if ((n->value & GOVD_MAP) != 0)
   13936 		{
   13937 		  remove = true;
   13938 		  break;
   13939 		}
   13940 	      OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) = 0;
   13941 	      OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) = 0;
   13942 	    }
   13943 	  /* FALLTHRU */
   13944 	case OMP_CLAUSE_PRIVATE:
   13945 	case OMP_CLAUSE_SHARED:
   13946 	case OMP_CLAUSE_LINEAR:
   13947 	  decl = OMP_CLAUSE_DECL (c);
   13948 	  n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   13949 	  remove = !(n->value & GOVD_SEEN);
   13950 	  if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
   13951 	      && code == OMP_PARALLEL
   13952 	      && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
   13953 	    remove = true;
   13954 	  if (! remove)
   13955 	    {
   13956 	      bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
   13957 	      if ((n->value & GOVD_DEBUG_PRIVATE)
   13958 		  || lang_hooks.decls.omp_private_debug_clause (decl, shared))
   13959 		{
   13960 		  gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
   13961 			      || ((n->value & GOVD_DATA_SHARE_CLASS)
   13962 				  == GOVD_SHARED));
   13963 		  OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
   13964 		  OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
   13965 		}
   13966               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
   13967 		  && ctx->has_depend
   13968 		  && DECL_P (decl))
   13969 		n->value |= GOVD_WRITTEN;
   13970 	      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
   13971 		  && (n->value & GOVD_WRITTEN) == 0
   13972 		  && DECL_P (decl)
   13973 		  && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   13974 		OMP_CLAUSE_SHARED_READONLY (c) = 1;
   13975 	      else if (DECL_P (decl)
   13976 		       && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
   13977 			    && (n->value & GOVD_WRITTEN) != 0)
   13978 			   || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   13979 			       && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
   13980 		       && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   13981 		omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
   13982 	    }
   13983 	  else
   13984 	    n->value &= ~GOVD_EXPLICIT;
   13985 	  break;
   13986 
   13987 	case OMP_CLAUSE_LASTPRIVATE:
   13988 	  /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
   13989 	     accurately reflect the presence of a FIRSTPRIVATE clause.  */
   13990 	  decl = OMP_CLAUSE_DECL (c);
   13991 	  n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   13992 	  OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
   13993 	    = (n->value & GOVD_FIRSTPRIVATE) != 0;
   13994 	  if (code == OMP_DISTRIBUTE
   13995 	      && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
   13996 	    {
   13997 	      remove = true;
   13998 	      error_at (OMP_CLAUSE_LOCATION (c),
   13999 			"same variable used in %<firstprivate%> and "
   14000 			"%<lastprivate%> clauses on %<distribute%> "
   14001 			"construct");
   14002 	    }
   14003 	  if (!remove
   14004 	      && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   14005 	      && DECL_P (decl)
   14006 	      && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   14007 	    omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
   14008 	  if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
   14009 	    remove = true;
   14010 	  break;
   14011 
   14012 	case OMP_CLAUSE_ALIGNED:
   14013 	  decl = OMP_CLAUSE_DECL (c);
   14014 	  if (!is_global_var (decl))
   14015 	    {
   14016 	      n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   14017 	      remove = n == NULL || !(n->value & GOVD_SEEN);
   14018 	      if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
   14019 		{
   14020 		  struct gimplify_omp_ctx *octx;
   14021 		  if (n != NULL
   14022 		      && (n->value & (GOVD_DATA_SHARE_CLASS
   14023 				      & ~GOVD_FIRSTPRIVATE)))
   14024 		    remove = true;
   14025 		  else
   14026 		    for (octx = ctx->outer_context; octx;
   14027 			 octx = octx->outer_context)
   14028 		      {
   14029 			n = splay_tree_lookup (octx->variables,
   14030 					       (splay_tree_key) decl);
   14031 			if (n == NULL)
   14032 			  continue;
   14033 			if (n->value & GOVD_LOCAL)
   14034 			  break;
   14035 			/* We have to avoid assigning a shared variable
   14036 			   to itself when trying to add
   14037 			   __builtin_assume_aligned.  */
   14038 			if (n->value & GOVD_SHARED)
   14039 			  {
   14040 			    remove = true;
   14041 			    break;
   14042 			  }
   14043 		      }
   14044 		}
   14045 	    }
   14046 	  else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
   14047 	    {
   14048 	      n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   14049 	      if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
   14050 		remove = true;
   14051 	    }
   14052 	  break;
   14053 
   14054 	case OMP_CLAUSE_HAS_DEVICE_ADDR:
   14055 	  decl = OMP_CLAUSE_DECL (c);
   14056 	  while (INDIRECT_REF_P (decl)
   14057 		 || TREE_CODE (decl) == ARRAY_REF)
   14058 	    decl = TREE_OPERAND (decl, 0);
   14059 	  n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   14060 	  remove = n == NULL || !(n->value & GOVD_SEEN);
   14061 	  break;
   14062 
   14063 	case OMP_CLAUSE_IS_DEVICE_PTR:
   14064 	case OMP_CLAUSE_NONTEMPORAL:
   14065 	  decl = OMP_CLAUSE_DECL (c);
   14066 	  n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   14067 	  remove = n == NULL || !(n->value & GOVD_SEEN);
   14068 	  break;
   14069 
   14070 	case OMP_CLAUSE_MAP:
   14071 	  decl = OMP_CLAUSE_DECL (c);
   14072 	  if (!grp_end)
   14073 	    {
   14074 	      grp_start_p = list_p;
   14075 	      grp_end = *omp_group_last (grp_start_p);
   14076 	    }
   14077 	  switch (OMP_CLAUSE_MAP_KIND (c))
   14078 	    {
   14079 	    case GOMP_MAP_PRESENT_ALLOC:
   14080 	    case GOMP_MAP_PRESENT_TO:
   14081 	    case GOMP_MAP_PRESENT_FROM:
   14082 	    case GOMP_MAP_PRESENT_TOFROM:
   14083 	      OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_PRESENT);
   14084 	      break;
   14085 	    default:
   14086 	      break;
   14087 	    }
   14088 	  switch (code)
   14089 	    {
   14090 	    case OACC_DATA:
   14091 	      if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
   14092 		break;
   14093 	      /* Fallthrough.  */
   14094 	    case OACC_HOST_DATA:
   14095 	    case OACC_ENTER_DATA:
   14096 	    case OACC_EXIT_DATA:
   14097 	    case OMP_TARGET_DATA:
   14098 	    case OMP_TARGET_ENTER_DATA:
   14099 	    case OMP_TARGET_EXIT_DATA:
   14100 	      if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   14101 		  || (OMP_CLAUSE_MAP_KIND (c)
   14102 		      == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   14103 		/* For target {,enter ,exit }data only the array slice is
   14104 		   mapped, but not the pointer to it.  */
   14105 		remove = true;
   14106 	      if (code == OMP_TARGET_EXIT_DATA
   14107 		  && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
   14108 		      || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER))
   14109 		remove = true;
   14110 	      break;
   14111 	    case OMP_TARGET:
   14112 	      break;
   14113 	    default:
   14114 	      break;
   14115 	    }
   14116 	  if (remove)
   14117 	    break;
   14118 	  if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
   14119 	    {
   14120 	      /* Sanity check: attach/detach map kinds use the size as a bias,
   14121 		 and it's never right to use the decl size for such
   14122 		 mappings.  */
   14123 	      gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
   14124 			  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
   14125 			  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DETACH
   14126 			  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
   14127 			  && (OMP_CLAUSE_MAP_KIND (c)
   14128 			      != GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION));
   14129 	      OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
   14130 				    : TYPE_SIZE_UNIT (TREE_TYPE (decl));
   14131 	    }
   14132 	  gimplify_omp_ctxp = ctx->outer_context;
   14133 	  if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p, NULL,
   14134 				  is_gimple_val, fb_rvalue) == GS_ERROR)
   14135 	    {
   14136 	      gimplify_omp_ctxp = ctx;
   14137 	      remove = true;
   14138 	      break;
   14139 	    }
   14140 	  else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   14141 		    || (OMP_CLAUSE_MAP_KIND (c)
   14142 			== GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   14143 		    || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   14144 		   && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
   14145 	    {
   14146 	      OMP_CLAUSE_SIZE (c)
   14147 		= get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
   14148 					   false);
   14149 	      if ((ctx->region_type & ORT_TARGET) != 0)
   14150 		omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
   14151 				  GOVD_FIRSTPRIVATE | GOVD_SEEN);
   14152 	    }
   14153 	  gimplify_omp_ctxp = ctx;
   14154 	  /* Data clauses associated with reductions must be
   14155 	     compatible with present_or_copy.  Warn and adjust the clause
   14156 	     if that is not the case.  */
   14157 	  if (ctx->region_type == ORT_ACC_PARALLEL
   14158 	      || ctx->region_type == ORT_ACC_SERIAL)
   14159 	    {
   14160 	      tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
   14161 	      n = NULL;
   14162 
   14163 	      if (DECL_P (t))
   14164 		n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
   14165 
   14166 	      if (n && (n->value & GOVD_REDUCTION))
   14167 		{
   14168 		  enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
   14169 
   14170 		  OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
   14171 		  if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
   14172 		      && kind != GOMP_MAP_FORCE_PRESENT
   14173 		      && kind != GOMP_MAP_POINTER)
   14174 		    {
   14175 		      warning_at (OMP_CLAUSE_LOCATION (c), 0,
   14176 				  "incompatible data clause with reduction "
   14177 				  "on %qE; promoting to %<present_or_copy%>",
   14178 				  DECL_NAME (t));
   14179 		      OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
   14180 		    }
   14181 		}
   14182 	    }
   14183 	  if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
   14184 	       || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT_UNORD)
   14185 	      && (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA))
   14186 	    {
   14187 	      remove = true;
   14188 	      break;
   14189 	    }
   14190 	  /* If we have a DECL_VALUE_EXPR (e.g. this is a class member and/or
   14191 	     a variable captured in a lambda closure), look through that now
   14192 	     before the DECL_P check below.  (A code other than COMPONENT_REF,
   14193 	     i.e. INDIRECT_REF, will be a VLA/variable-length array
   14194 	     section.  A global var may be a variable in a common block.  We
   14195 	     don't want to do this here for either of those.)  */
   14196 	  if ((ctx->region_type & ORT_ACC) == 0
   14197 	      && DECL_P (decl)
   14198 	      && !is_global_var (decl)
   14199 	      && DECL_HAS_VALUE_EXPR_P (decl)
   14200 	      && TREE_CODE (DECL_VALUE_EXPR (decl)) == COMPONENT_REF)
   14201 	    decl = OMP_CLAUSE_DECL (c) = DECL_VALUE_EXPR (decl);
   14202 	  if (TREE_CODE (decl) == TARGET_EXPR)
   14203 	    {
   14204 	      if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
   14205 				 is_gimple_lvalue, fb_lvalue) == GS_ERROR)
   14206 		remove = true;
   14207 	    }
   14208 	  else if (!DECL_P (decl))
   14209 	    {
   14210 	      if ((ctx->region_type & ORT_TARGET) != 0
   14211 		  && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
   14212 		{
   14213 		  if (INDIRECT_REF_P (decl)
   14214 		      && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
   14215 		      && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
   14216 			  == REFERENCE_TYPE))
   14217 		    decl = TREE_OPERAND (decl, 0);
   14218 		  if (TREE_CODE (decl) == COMPONENT_REF)
   14219 		    {
   14220 		      while (TREE_CODE (decl) == COMPONENT_REF)
   14221 			decl = TREE_OPERAND (decl, 0);
   14222 		      if (DECL_P (decl))
   14223 			{
   14224 			  n = splay_tree_lookup (ctx->variables,
   14225 						 (splay_tree_key) decl);
   14226 			  if (!(n->value & GOVD_SEEN))
   14227 			    remove = true;
   14228 			}
   14229 		    }
   14230 		}
   14231 
   14232 	      tree d = decl, *pd;
   14233 	      if (TREE_CODE (d) == ARRAY_REF)
   14234 		{
   14235 		  while (TREE_CODE (d) == ARRAY_REF)
   14236 		    d = TREE_OPERAND (d, 0);
   14237 		  if (TREE_CODE (d) == COMPONENT_REF
   14238 		      && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
   14239 		    decl = d;
   14240 		}
   14241 	      pd = &OMP_CLAUSE_DECL (c);
   14242 	      if (d == decl
   14243 		  && TREE_CODE (decl) == INDIRECT_REF
   14244 		  && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
   14245 		  && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
   14246 		      == REFERENCE_TYPE)
   14247 		  && (OMP_CLAUSE_MAP_KIND (c)
   14248 		      != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
   14249 		{
   14250 		  pd = &TREE_OPERAND (decl, 0);
   14251 		  decl = TREE_OPERAND (decl, 0);
   14252 		}
   14253 
   14254 	      if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   14255 		switch (code)
   14256 		  {
   14257 		  case OACC_ENTER_DATA:
   14258 		  case OACC_EXIT_DATA:
   14259 		    if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
   14260 			== ARRAY_TYPE)
   14261 		      remove = true;
   14262 		    else if (code == OACC_ENTER_DATA)
   14263 		      goto change_to_attach;
   14264 		    /* Fallthrough.  */
   14265 		  case OMP_TARGET_EXIT_DATA:
   14266 		    OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DETACH);
   14267 		    break;
   14268 		  case OACC_UPDATE:
   14269 		    /* An "attach/detach" operation on an update directive
   14270 		       should behave as a GOMP_MAP_ALWAYS_POINTER.  Note that
   14271 		       both GOMP_MAP_ATTACH_DETACH and GOMP_MAP_ALWAYS_POINTER
   14272 		       kinds depend on the previous mapping (for non-TARGET
   14273 		       regions).  */
   14274 		    OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
   14275 		    break;
   14276 		  default:
   14277 		  change_to_attach:
   14278 		    OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ATTACH);
   14279 		    if ((ctx->region_type & ORT_TARGET) != 0)
   14280 		      move_attach = true;
   14281 		  }
   14282 	      else if ((ctx->region_type & ORT_TARGET) != 0
   14283 		       && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   14284 			   || (OMP_CLAUSE_MAP_KIND (c)
   14285 			       == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)))
   14286 		move_attach = true;
   14287 
   14288 	      /* If we have e.g. map(struct: *var), don't gimplify the
   14289 		 argument since omp-low.cc wants to see the decl itself.  */
   14290 	      if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
   14291 		break;
   14292 
   14293 	      /* We've already partly gimplified this in
   14294 		 gimplify_scan_omp_clauses.  Don't do any more.  */
   14295 	      if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
   14296 		break;
   14297 
   14298 	      gimplify_omp_ctxp = ctx->outer_context;
   14299 	      if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
   14300 				 fb_lvalue) == GS_ERROR)
   14301 		remove = true;
   14302 	      gimplify_omp_ctxp = ctx;
   14303 	      break;
   14304 	    }
   14305 
   14306 	 if ((code == OMP_TARGET
   14307 	      || code == OMP_TARGET_DATA
   14308 	      || code == OMP_TARGET_ENTER_DATA
   14309 	      || code == OMP_TARGET_EXIT_DATA)
   14310 	     && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   14311 	   {
   14312 	     bool firstprivatize = false;
   14313 
   14314 	     for (struct gimplify_omp_ctx *octx = ctx->outer_context; octx;
   14315 		  octx = octx->outer_context)
   14316 	       {
   14317 		 splay_tree_node n
   14318 		   = splay_tree_lookup (octx->variables,
   14319 					(splay_tree_key) OMP_CLAUSE_DECL (c));
   14320 		 /* If this is contained in an outer OpenMP region as a
   14321 		    firstprivate value, remove the attach/detach.  */
   14322 		 if (n && (n->value & GOVD_FIRSTPRIVATE))
   14323 		   {
   14324 		     firstprivatize = true;
   14325 		     break;
   14326 		   }
   14327 	       }
   14328 
   14329 	     enum gomp_map_kind map_kind;
   14330 	     if (firstprivatize)
   14331 	       map_kind = GOMP_MAP_FIRSTPRIVATE_POINTER;
   14332 	     else if (code == OMP_TARGET_EXIT_DATA)
   14333 	       map_kind = GOMP_MAP_DETACH;
   14334 	     else
   14335 	       map_kind = GOMP_MAP_ATTACH;
   14336 	     OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
   14337 	   }
   14338 	 else if ((ctx->region_type & ORT_ACC) != 0
   14339 		  && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   14340 	   {
   14341 	     enum gomp_map_kind map_kind = (code == OACC_EXIT_DATA
   14342 					    ? GOMP_MAP_DETACH
   14343 					    : GOMP_MAP_ATTACH);
   14344 	     OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
   14345 	   }
   14346 
   14347 	  n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   14348 	  if ((ctx->region_type & ORT_TARGET) != 0
   14349 	      && !(n->value & GOVD_SEEN)
   14350 	      && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
   14351 	      && (!is_global_var (decl)
   14352 		  || !lookup_attribute ("omp declare target link",
   14353 					DECL_ATTRIBUTES (decl))))
   14354 	    {
   14355 	      remove = true;
   14356 	      /* For struct element mapping, if struct is never referenced
   14357 		 in target block and none of the mapping has always modifier,
   14358 		 remove all the struct element mappings, which immediately
   14359 		 follow the GOMP_MAP_STRUCT map clause.  */
   14360 	      if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
   14361 		  || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT_UNORD)
   14362 		{
   14363 		  HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
   14364 		  while (cnt--)
   14365 		    OMP_CLAUSE_CHAIN (c)
   14366 		      = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
   14367 		}
   14368 	    }
   14369 	  else if (DECL_SIZE (decl)
   14370 		   && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
   14371 		   && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
   14372 		   && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
   14373 		   && (OMP_CLAUSE_MAP_KIND (c)
   14374 		       != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   14375 	    {
   14376 	      /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
   14377 		 for these, TREE_CODE (DECL_SIZE (decl)) will always be
   14378 		 INTEGER_CST.  */
   14379 	      gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
   14380 
   14381 	      tree decl2 = DECL_VALUE_EXPR (decl);
   14382 	      gcc_assert (INDIRECT_REF_P (decl2));
   14383 	      decl2 = TREE_OPERAND (decl2, 0);
   14384 	      gcc_assert (DECL_P (decl2));
   14385 	      tree mem = build_simple_mem_ref (decl2);
   14386 	      OMP_CLAUSE_DECL (c) = mem;
   14387 	      OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
   14388 	      if (ctx->outer_context)
   14389 		{
   14390 		  omp_notice_variable (ctx->outer_context, decl2, true);
   14391 		  omp_notice_variable (ctx->outer_context,
   14392 				       OMP_CLAUSE_SIZE (c), true);
   14393 		}
   14394 	      if (((ctx->region_type & ORT_TARGET) != 0
   14395 		   || !ctx->target_firstprivatize_array_bases)
   14396 		  && ((n->value & GOVD_SEEN) == 0
   14397 		      || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
   14398 		{
   14399 		  tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   14400 					      OMP_CLAUSE_MAP);
   14401 		  OMP_CLAUSE_DECL (nc) = decl;
   14402 		  OMP_CLAUSE_SIZE (nc) = size_zero_node;
   14403 		  if (ctx->target_firstprivatize_array_bases)
   14404 		    OMP_CLAUSE_SET_MAP_KIND (nc,
   14405 					     GOMP_MAP_FIRSTPRIVATE_POINTER);
   14406 		  else
   14407 		    OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
   14408 		  OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
   14409 		  OMP_CLAUSE_CHAIN (c) = nc;
   14410 		  c = nc;
   14411 		}
   14412 	    }
   14413 	  else
   14414 	    {
   14415 	      if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
   14416 		OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
   14417 	      gcc_assert ((n->value & GOVD_SEEN) == 0
   14418 			  || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
   14419 			      == 0));
   14420 	    }
   14421 
   14422 	  /* If we have a target region, we can push all the attaches to the
   14423 	     end of the list (we may have standalone "attach" operations
   14424 	     synthesized for GOMP_MAP_STRUCT nodes that must be processed after
   14425 	     the attachment point AND the pointed-to block have been mapped).
   14426 	     If we have something else, e.g. "enter data", we need to keep
   14427 	     "attach" nodes together with the previous node they attach to so
   14428 	     that separate "exit data" operations work properly (see
   14429 	     libgomp/target.c).  */
   14430 	  if ((ctx->region_type & ORT_TARGET) != 0
   14431 	      && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   14432 		  || (OMP_CLAUSE_MAP_KIND (c)
   14433 		      == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)))
   14434 	    move_attach = true;
   14435 
   14436 	  break;
   14437 
   14438 	case OMP_CLAUSE_TO:
   14439 	case OMP_CLAUSE_FROM:
   14440 	case OMP_CLAUSE__CACHE_:
   14441 	  decl = OMP_CLAUSE_DECL (c);
   14442 	  if (!DECL_P (decl))
   14443 	    break;
   14444 	  if (DECL_SIZE (decl)
   14445 	      && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
   14446 	    {
   14447 	      tree decl2 = DECL_VALUE_EXPR (decl);
   14448 	      gcc_assert (INDIRECT_REF_P (decl2));
   14449 	      decl2 = TREE_OPERAND (decl2, 0);
   14450 	      gcc_assert (DECL_P (decl2));
   14451 	      tree mem = build_simple_mem_ref (decl2);
   14452 	      OMP_CLAUSE_DECL (c) = mem;
   14453 	      OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
   14454 	      if (ctx->outer_context)
   14455 		{
   14456 		  omp_notice_variable (ctx->outer_context, decl2, true);
   14457 		  omp_notice_variable (ctx->outer_context,
   14458 				       OMP_CLAUSE_SIZE (c), true);
   14459 		}
   14460 	    }
   14461 	  else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
   14462 	    OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
   14463 	  break;
   14464 
   14465 	case OMP_CLAUSE_REDUCTION:
   14466 	  if (OMP_CLAUSE_REDUCTION_INSCAN (c))
   14467 	    {
   14468 	      decl = OMP_CLAUSE_DECL (c);
   14469 	      n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   14470 	      if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
   14471 		{
   14472 		  remove = true;
   14473 		  error_at (OMP_CLAUSE_LOCATION (c),
   14474 			    "%qD specified in %<inscan%> %<reduction%> clause "
   14475 			    "but not in %<scan%> directive clause", decl);
   14476 		  break;
   14477 		}
   14478 	      has_inscan_reductions = true;
   14479 	    }
   14480 	  /* FALLTHRU */
   14481 	case OMP_CLAUSE_IN_REDUCTION:
   14482 	case OMP_CLAUSE_TASK_REDUCTION:
   14483 	  decl = OMP_CLAUSE_DECL (c);
   14484 	  /* OpenACC reductions need a present_or_copy data clause.
   14485 	     Add one if necessary.  Emit error when the reduction is private.  */
   14486 	  if (ctx->region_type == ORT_ACC_PARALLEL
   14487 	      || ctx->region_type == ORT_ACC_SERIAL)
   14488 	    {
   14489 	      n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   14490 	      if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
   14491 		{
   14492 		  remove = true;
   14493 		  error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
   14494 			    "reduction on %qE", DECL_NAME (decl));
   14495 		}
   14496 	      else if ((n->value & GOVD_MAP) == 0)
   14497 		{
   14498 		  tree next = OMP_CLAUSE_CHAIN (c);
   14499 		  tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
   14500 		  OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
   14501 		  OMP_CLAUSE_DECL (nc) = decl;
   14502 		  OMP_CLAUSE_CHAIN (c) = nc;
   14503 		  lang_hooks.decls.omp_finish_clause (nc, pre_p,
   14504 						      (ctx->region_type
   14505 						       & ORT_ACC) != 0);
   14506 		  while (1)
   14507 		    {
   14508 		      OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
   14509 		      if (OMP_CLAUSE_CHAIN (nc) == NULL)
   14510 			break;
   14511 		      nc = OMP_CLAUSE_CHAIN (nc);
   14512 		    }
   14513 		  OMP_CLAUSE_CHAIN (nc) = next;
   14514 		  n->value |= GOVD_MAP;
   14515 		}
   14516 	    }
   14517 	  if (DECL_P (decl)
   14518 	      && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   14519 	    omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
   14520 	  break;
   14521 
   14522 	case OMP_CLAUSE_ALLOCATE:
   14523 	  decl = OMP_CLAUSE_DECL (c);
   14524 	  n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   14525 	  if (n != NULL && !(n->value & GOVD_SEEN))
   14526 	    {
   14527 	      if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR))
   14528 		  != 0
   14529 		  && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0)
   14530 		remove = true;
   14531 	    }
   14532 	  if (!remove
   14533 	      && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
   14534 	      && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST
   14535 	      && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0
   14536 		  || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK
   14537 		  || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS))
   14538 	    {
   14539 	      tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
   14540 	      n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator);
   14541 	      if (n == NULL)
   14542 		{
   14543 		  enum omp_clause_default_kind default_kind
   14544 		    = ctx->default_kind;
   14545 		  ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
   14546 		  omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
   14547 				       true);
   14548 		  ctx->default_kind = default_kind;
   14549 		}
   14550 	      else
   14551 		omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
   14552 				     true);
   14553 	    }
   14554 	  break;
   14555 
   14556 	case OMP_CLAUSE_COPYIN:
   14557 	case OMP_CLAUSE_COPYPRIVATE:
   14558 	case OMP_CLAUSE_IF:
   14559 	case OMP_CLAUSE_SELF:
   14560 	case OMP_CLAUSE_NUM_THREADS:
   14561 	case OMP_CLAUSE_NUM_TEAMS:
   14562 	case OMP_CLAUSE_THREAD_LIMIT:
   14563 	case OMP_CLAUSE_DIST_SCHEDULE:
   14564 	case OMP_CLAUSE_DEVICE:
   14565 	case OMP_CLAUSE_SCHEDULE:
   14566 	case OMP_CLAUSE_NOWAIT:
   14567 	case OMP_CLAUSE_ORDERED:
   14568 	case OMP_CLAUSE_DEFAULT:
   14569 	case OMP_CLAUSE_UNTIED:
   14570 	case OMP_CLAUSE_COLLAPSE:
   14571 	case OMP_CLAUSE_FINAL:
   14572 	case OMP_CLAUSE_MERGEABLE:
   14573 	case OMP_CLAUSE_PROC_BIND:
   14574 	case OMP_CLAUSE_SAFELEN:
   14575 	case OMP_CLAUSE_SIMDLEN:
   14576 	case OMP_CLAUSE_DEPEND:
   14577 	case OMP_CLAUSE_DOACROSS:
   14578 	case OMP_CLAUSE_PRIORITY:
   14579 	case OMP_CLAUSE_GRAINSIZE:
   14580 	case OMP_CLAUSE_NUM_TASKS:
   14581 	case OMP_CLAUSE_NOGROUP:
   14582 	case OMP_CLAUSE_THREADS:
   14583 	case OMP_CLAUSE_SIMD:
   14584 	case OMP_CLAUSE_FILTER:
   14585 	case OMP_CLAUSE_HINT:
   14586 	case OMP_CLAUSE_DEFAULTMAP:
   14587 	case OMP_CLAUSE_ORDER:
   14588 	case OMP_CLAUSE_BIND:
   14589 	case OMP_CLAUSE_DETACH:
   14590 	case OMP_CLAUSE_USE_DEVICE_PTR:
   14591 	case OMP_CLAUSE_USE_DEVICE_ADDR:
   14592 	case OMP_CLAUSE_ASYNC:
   14593 	case OMP_CLAUSE_WAIT:
   14594 	case OMP_CLAUSE_INDEPENDENT:
   14595 	case OMP_CLAUSE_NUM_GANGS:
   14596 	case OMP_CLAUSE_NUM_WORKERS:
   14597 	case OMP_CLAUSE_VECTOR_LENGTH:
   14598 	case OMP_CLAUSE_GANG:
   14599 	case OMP_CLAUSE_WORKER:
   14600 	case OMP_CLAUSE_VECTOR:
   14601 	case OMP_CLAUSE_AUTO:
   14602 	case OMP_CLAUSE_SEQ:
   14603 	case OMP_CLAUSE_TILE:
   14604 	case OMP_CLAUSE_IF_PRESENT:
   14605 	case OMP_CLAUSE_FINALIZE:
   14606 	case OMP_CLAUSE_INCLUSIVE:
   14607 	case OMP_CLAUSE_EXCLUSIVE:
   14608 	  break;
   14609 
   14610 	case OMP_CLAUSE_NOHOST:
   14611 	default:
   14612 	  gcc_unreachable ();
   14613 	}
   14614 
   14615       if (remove)
   14616 	*list_p = OMP_CLAUSE_CHAIN (c);
   14617       else if (move_attach)
   14618 	{
   14619 	  /* Remove attach node from here, separate out into its own list.  */
   14620 	  *attach_tail = c;
   14621 	  *list_p = OMP_CLAUSE_CHAIN (c);
   14622 	  OMP_CLAUSE_CHAIN (c) = NULL_TREE;
   14623 	  attach_tail = &OMP_CLAUSE_CHAIN (c);
   14624 	}
   14625       else
   14626 	list_p = &OMP_CLAUSE_CHAIN (c);
   14627     }
   14628 
   14629   /* Splice attach nodes at the end of the list.  */
   14630   if (attach_list)
   14631     {
   14632       *list_p = attach_list;
   14633       list_p = attach_tail;
   14634     }
   14635 
   14636   /* Add in any implicit data sharing.  */
   14637   struct gimplify_adjust_omp_clauses_data data;
   14638   if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
   14639     {
   14640       /* OpenMP.  Implicit clauses are added at the start of the clause list,
   14641 	 but after any non-map clauses.  */
   14642       tree *implicit_add_list_p = orig_list_p;
   14643       while (*implicit_add_list_p
   14644 	     && OMP_CLAUSE_CODE (*implicit_add_list_p) != OMP_CLAUSE_MAP)
   14645 	implicit_add_list_p = &OMP_CLAUSE_CHAIN (*implicit_add_list_p);
   14646       data.list_p = implicit_add_list_p;
   14647     }
   14648   else
   14649     /* OpenACC.  */
   14650     data.list_p = list_p;
   14651   data.pre_p = pre_p;
   14652   splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
   14653 
   14654   if (has_inscan_reductions)
   14655     for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
   14656       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   14657 	  && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
   14658 	{
   14659 	  error_at (OMP_CLAUSE_LOCATION (c),
   14660 		    "%<inscan%> %<reduction%> clause used together with "
   14661 		    "%<linear%> clause for a variable other than loop "
   14662 		    "iterator");
   14663 	  break;
   14664 	}
   14665 
   14666   gimplify_omp_ctxp = ctx->outer_context;
   14667   delete_omp_context (ctx);
   14668 }
   14669 
   14670 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
   14671    -1 if unknown yet (simd is involved, won't be known until vectorization)
   14672    and 1 if they do.  If SCORES is non-NULL, it should point to an array
   14673    of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
   14674    of the CONSTRUCTS (position -1 if it will never match) followed by
   14675    number of constructs in the OpenMP context construct trait.  If the
   14676    score depends on whether it will be in a declare simd clone or not,
   14677    the function returns 2 and there will be two sets of the scores, the first
   14678    one for the case that it is not in a declare simd clone, the other
   14679    that it is in a declare simd clone.  */
   14680 
   14681 int
   14682 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
   14683 				int *scores)
   14684 {
   14685   int matched = 0, cnt = 0;
   14686   bool simd_seen = false;
   14687   bool target_seen = false;
   14688   int declare_simd_cnt = -1;
   14689   auto_vec<enum tree_code, 16> codes;
   14690   for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
   14691     {
   14692       if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
   14693 	  || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
   14694 	      == ORT_TARGET && ctx->code == OMP_TARGET)
   14695 	  || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
   14696 	  || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
   14697 	  || (ctx->region_type == ORT_SIMD
   14698 	      && ctx->code == OMP_SIMD
   14699 	      && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
   14700 	{
   14701 	  ++cnt;
   14702 	  if (scores)
   14703 	    codes.safe_push (ctx->code);
   14704 	  else if (matched < nconstructs && ctx->code == constructs[matched])
   14705 	    {
   14706 	      if (ctx->code == OMP_SIMD)
   14707 		{
   14708 		  if (matched)
   14709 		    return 0;
   14710 		  simd_seen = true;
   14711 		}
   14712 	      ++matched;
   14713 	    }
   14714 	  if (ctx->code == OMP_TARGET)
   14715 	    {
   14716 	      if (scores == NULL)
   14717 		return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
   14718 	      target_seen = true;
   14719 	      break;
   14720 	    }
   14721 	}
   14722       else if (ctx->region_type == ORT_WORKSHARE
   14723 	       && ctx->code == OMP_LOOP
   14724 	       && ctx->outer_context
   14725 	       && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
   14726 	       && ctx->outer_context->outer_context
   14727 	       && ctx->outer_context->outer_context->code == OMP_LOOP
   14728 	       && ctx->outer_context->outer_context->distribute)
   14729 	ctx = ctx->outer_context->outer_context;
   14730       ctx = ctx->outer_context;
   14731     }
   14732   if (!target_seen
   14733       && lookup_attribute ("omp declare simd",
   14734 			   DECL_ATTRIBUTES (current_function_decl)))
   14735     {
   14736       /* Declare simd is a maybe case, it is supposed to be added only to the
   14737 	 omp-simd-clone.cc added clones and not to the base function.  */
   14738       declare_simd_cnt = cnt++;
   14739       if (scores)
   14740 	codes.safe_push (OMP_SIMD);
   14741       else if (cnt == 0
   14742 	       && constructs[0] == OMP_SIMD)
   14743 	{
   14744 	  gcc_assert (matched == 0);
   14745 	  simd_seen = true;
   14746 	  if (++matched == nconstructs)
   14747 	    return -1;
   14748 	}
   14749     }
   14750   if (tree attr = lookup_attribute ("omp declare variant variant",
   14751 				    DECL_ATTRIBUTES (current_function_decl)))
   14752     {
   14753       tree selectors = TREE_VALUE (attr);
   14754       int variant_nconstructs = list_length (selectors);
   14755       enum tree_code *variant_constructs = NULL;
   14756       if (!target_seen && variant_nconstructs)
   14757 	{
   14758 	  variant_constructs
   14759 	    = (enum tree_code *) alloca (variant_nconstructs
   14760 					 * sizeof (enum tree_code));
   14761 	  omp_construct_traits_to_codes (selectors, variant_nconstructs,
   14762 					 variant_constructs);
   14763 	}
   14764       for (int i = 0; i < variant_nconstructs; i++)
   14765 	{
   14766 	  ++cnt;
   14767 	  if (scores)
   14768 	    codes.safe_push (variant_constructs[i]);
   14769 	  else if (matched < nconstructs
   14770 		   && variant_constructs[i] == constructs[matched])
   14771 	    {
   14772 	      if (variant_constructs[i] == OMP_SIMD)
   14773 		{
   14774 		  if (matched)
   14775 		    return 0;
   14776 		  simd_seen = true;
   14777 		}
   14778 	      ++matched;
   14779 	    }
   14780 	}
   14781     }
   14782   if (!target_seen
   14783       && lookup_attribute ("omp declare target block",
   14784 			   DECL_ATTRIBUTES (current_function_decl)))
   14785     {
   14786       if (scores)
   14787 	codes.safe_push (OMP_TARGET);
   14788       else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
   14789 	++matched;
   14790     }
   14791   if (scores)
   14792     {
   14793       for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
   14794 	{
   14795 	  int j = codes.length () - 1;
   14796 	  for (int i = nconstructs - 1; i >= 0; i--)
   14797 	    {
   14798 	      while (j >= 0
   14799 		     && (pass != 0 || declare_simd_cnt != j)
   14800 		     && constructs[i] != codes[j])
   14801 		--j;
   14802 	      if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
   14803 		*scores++ = j - 1;
   14804 	      else
   14805 		*scores++ = j;
   14806 	    }
   14807 	  *scores++ = ((pass == 0 && declare_simd_cnt != -1)
   14808 		       ? codes.length () - 1 : codes.length ());
   14809 	}
   14810       return declare_simd_cnt == -1 ? 1 : 2;
   14811     }
   14812   if (matched == nconstructs)
   14813     return simd_seen ? -1 : 1;
   14814   return 0;
   14815 }
   14816 
   14817 /* Gimplify OACC_CACHE.  */
   14818 
   14819 static void
   14820 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
   14821 {
   14822   tree expr = *expr_p;
   14823 
   14824   gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
   14825 			     OACC_CACHE);
   14826   gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
   14827 			       OACC_CACHE);
   14828 
   14829   /* TODO: Do something sensible with this information.  */
   14830 
   14831   *expr_p = NULL_TREE;
   14832 }
   14833 
   14834 /* Helper function of gimplify_oacc_declare.  The helper's purpose is to,
   14835    if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
   14836    kind.  The entry kind will replace the one in CLAUSE, while the exit
   14837    kind will be used in a new omp_clause and returned to the caller.  */
   14838 
   14839 static tree
   14840 gimplify_oacc_declare_1 (tree clause)
   14841 {
   14842   HOST_WIDE_INT kind, new_op;
   14843   bool ret = false;
   14844   tree c = NULL;
   14845 
   14846   kind = OMP_CLAUSE_MAP_KIND (clause);
   14847 
   14848   switch (kind)
   14849     {
   14850       case GOMP_MAP_ALLOC:
   14851 	new_op = GOMP_MAP_RELEASE;
   14852 	ret = true;
   14853 	break;
   14854 
   14855       case GOMP_MAP_FROM:
   14856 	OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
   14857 	new_op = GOMP_MAP_FROM;
   14858 	ret = true;
   14859 	break;
   14860 
   14861       case GOMP_MAP_TOFROM:
   14862 	OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
   14863 	new_op = GOMP_MAP_FROM;
   14864 	ret = true;
   14865 	break;
   14866 
   14867       case GOMP_MAP_DEVICE_RESIDENT:
   14868       case GOMP_MAP_FORCE_DEVICEPTR:
   14869       case GOMP_MAP_FORCE_PRESENT:
   14870       case GOMP_MAP_LINK:
   14871       case GOMP_MAP_POINTER:
   14872       case GOMP_MAP_TO:
   14873 	break;
   14874 
   14875       default:
   14876 	gcc_unreachable ();
   14877 	break;
   14878     }
   14879 
   14880   if (ret)
   14881     {
   14882       c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
   14883       OMP_CLAUSE_SET_MAP_KIND (c, new_op);
   14884       OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
   14885     }
   14886 
   14887   return c;
   14888 }
   14889 
   14890 /* Gimplify OACC_DECLARE.  */
   14891 
   14892 static void
   14893 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
   14894 {
   14895   tree expr = *expr_p;
   14896   gomp_target *stmt;
   14897   tree clauses, t, decl;
   14898 
   14899   clauses = OACC_DECLARE_CLAUSES (expr);
   14900 
   14901   gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
   14902   gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
   14903 
   14904   for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
   14905     {
   14906       decl = OMP_CLAUSE_DECL (t);
   14907 
   14908       if (TREE_CODE (decl) == MEM_REF)
   14909 	decl = TREE_OPERAND (decl, 0);
   14910 
   14911       if (VAR_P (decl) && !is_oacc_declared (decl))
   14912 	{
   14913 	  tree attr = get_identifier ("oacc declare target");
   14914 	  DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
   14915 					      DECL_ATTRIBUTES (decl));
   14916 	}
   14917 
   14918       if (VAR_P (decl)
   14919 	  && !is_global_var (decl)
   14920 	  && DECL_CONTEXT (decl) == current_function_decl)
   14921 	{
   14922 	  tree c = gimplify_oacc_declare_1 (t);
   14923 	  if (c)
   14924 	    {
   14925 	      if (oacc_declare_returns == NULL)
   14926 		oacc_declare_returns = new hash_map<tree, tree>;
   14927 
   14928 	      oacc_declare_returns->put (decl, c);
   14929 	    }
   14930 	}
   14931 
   14932       if (gimplify_omp_ctxp)
   14933 	omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
   14934     }
   14935 
   14936   stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
   14937 				  clauses);
   14938 
   14939   gimplify_seq_add_stmt (pre_p, stmt);
   14940 
   14941   *expr_p = NULL_TREE;
   14942 }
   14943 
   14944 /* Gimplify the contents of an OMP_PARALLEL statement.  This involves
   14945    gimplification of the body, as well as scanning the body for used
   14946    variables.  We need to do this scan now, because variable-sized
   14947    decls will be decomposed during gimplification.  */
   14948 
   14949 static void
   14950 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
   14951 {
   14952   tree expr = *expr_p;
   14953   gimple *g;
   14954   gimple_seq body = NULL;
   14955 
   14956   gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
   14957 			     OMP_PARALLEL_COMBINED (expr)
   14958 			     ? ORT_COMBINED_PARALLEL
   14959 			     : ORT_PARALLEL, OMP_PARALLEL);
   14960 
   14961   push_gimplify_context ();
   14962 
   14963   g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
   14964   if (gimple_code (g) == GIMPLE_BIND)
   14965     pop_gimplify_context (g);
   14966   else
   14967     pop_gimplify_context (NULL);
   14968 
   14969   gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
   14970 			       OMP_PARALLEL);
   14971 
   14972   g = gimple_build_omp_parallel (body,
   14973 				 OMP_PARALLEL_CLAUSES (expr),
   14974 				 NULL_TREE, NULL_TREE);
   14975   if (OMP_PARALLEL_COMBINED (expr))
   14976     gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
   14977   gimplify_seq_add_stmt (pre_p, g);
   14978   *expr_p = NULL_TREE;
   14979 }
   14980 
   14981 /* Gimplify the contents of an OMP_TASK statement.  This involves
   14982    gimplification of the body, as well as scanning the body for used
   14983    variables.  We need to do this scan now, because variable-sized
   14984    decls will be decomposed during gimplification.  */
   14985 
   14986 static void
   14987 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
   14988 {
   14989   tree expr = *expr_p;
   14990   gimple *g;
   14991   gimple_seq body = NULL;
   14992   bool nowait = false;
   14993   bool has_depend = false;
   14994 
   14995   if (OMP_TASK_BODY (expr) == NULL_TREE)
   14996     {
   14997       for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   14998 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
   14999 	  {
   15000 	    has_depend = true;
   15001 	    if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
   15002 	      {
   15003 		error_at (OMP_CLAUSE_LOCATION (c),
   15004 			  "%<mutexinoutset%> kind in %<depend%> clause on a "
   15005 			  "%<taskwait%> construct");
   15006 		break;
   15007 	      }
   15008 	  }
   15009 	else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOWAIT)
   15010 	  nowait = true;
   15011       if (nowait && !has_depend)
   15012 	{
   15013 	  error_at (EXPR_LOCATION (expr),
   15014 		    "%<taskwait%> construct with %<nowait%> clause but no "
   15015 		    "%<depend%> clauses");
   15016 	  *expr_p = NULL_TREE;
   15017 	  return;
   15018 	}
   15019     }
   15020 
   15021   gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
   15022 			     omp_find_clause (OMP_TASK_CLAUSES (expr),
   15023 					      OMP_CLAUSE_UNTIED)
   15024 			     ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
   15025 
   15026   if (OMP_TASK_BODY (expr))
   15027     {
   15028       push_gimplify_context ();
   15029 
   15030       g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
   15031       if (gimple_code (g) == GIMPLE_BIND)
   15032 	pop_gimplify_context (g);
   15033       else
   15034 	pop_gimplify_context (NULL);
   15035     }
   15036 
   15037   gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
   15038 			       OMP_TASK);
   15039 
   15040   g = gimple_build_omp_task (body,
   15041 			     OMP_TASK_CLAUSES (expr),
   15042 			     NULL_TREE, NULL_TREE,
   15043 			     NULL_TREE, NULL_TREE, NULL_TREE);
   15044   if (OMP_TASK_BODY (expr) == NULL_TREE)
   15045     gimple_omp_task_set_taskwait_p (g, true);
   15046   gimplify_seq_add_stmt (pre_p, g);
   15047   *expr_p = NULL_TREE;
   15048 }
   15049 
   15050 /* Helper function for gimplify_omp_for.  If *TP is not a gimple constant,
   15051    force it into a temporary initialized in PRE_P and add firstprivate clause
   15052    to ORIG_FOR_STMT.  */
   15053 
   15054 static void
   15055 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
   15056 			    tree orig_for_stmt)
   15057 {
   15058   if (*tp == NULL || is_gimple_constant (*tp))
   15059     return;
   15060 
   15061   *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
   15062   /* Reference to pointer conversion is considered useless,
   15063      but is significant for firstprivate clause.  Force it
   15064      here.  */
   15065   if (type
   15066       && TREE_CODE (type) == POINTER_TYPE
   15067       && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
   15068     {
   15069       tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
   15070       tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
   15071       gimplify_and_add (m, pre_p);
   15072       *tp = v;
   15073     }
   15074 
   15075   tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
   15076   OMP_CLAUSE_DECL (c) = *tp;
   15077   OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
   15078   OMP_FOR_CLAUSES (orig_for_stmt) = c;
   15079 }
   15080 
   15081 /* Helper function of gimplify_omp_for, find OMP_ORDERED with
   15082    null OMP_ORDERED_BODY inside of OMP_FOR's body.  */
   15083 
   15084 static tree
   15085 find_standalone_omp_ordered (tree *tp, int *walk_subtrees, void *)
   15086 {
   15087   switch (TREE_CODE (*tp))
   15088     {
   15089     case OMP_ORDERED:
   15090       if (OMP_ORDERED_BODY (*tp) == NULL_TREE)
   15091 	return *tp;
   15092       break;
   15093     case OMP_SIMD:
   15094     case OMP_PARALLEL:
   15095     case OMP_TARGET:
   15096       *walk_subtrees = 0;
   15097       break;
   15098     default:
   15099       break;
   15100     }
   15101   return NULL_TREE;
   15102 }
   15103 
   15104 /* Gimplify the gross structure of an OMP_FOR statement.  */
   15105 
   15106 static enum gimplify_status
   15107 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
   15108 {
   15109   tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
   15110   enum gimplify_status ret = GS_ALL_DONE;
   15111   enum gimplify_status tret;
   15112   gomp_for *gfor;
   15113   gimple_seq for_body, for_pre_body;
   15114   int i;
   15115   bitmap has_decl_expr = NULL;
   15116   enum omp_region_type ort = ORT_WORKSHARE;
   15117   bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
   15118 
   15119   orig_for_stmt = for_stmt = *expr_p;
   15120 
   15121   bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
   15122 		 != NULL_TREE);
   15123   if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
   15124     {
   15125       tree *data[4] = { NULL, NULL, NULL, NULL };
   15126       gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
   15127       inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
   15128 				  find_combined_omp_for, data, NULL);
   15129       if (inner_for_stmt == NULL_TREE)
   15130 	{
   15131 	  gcc_assert (seen_error ());
   15132 	  *expr_p = NULL_TREE;
   15133 	  return GS_ERROR;
   15134 	}
   15135       if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
   15136 	{
   15137 	  append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
   15138 					  &OMP_FOR_PRE_BODY (for_stmt));
   15139 	  OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
   15140 	}
   15141       if (OMP_FOR_PRE_BODY (inner_for_stmt))
   15142 	{
   15143 	  append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
   15144 					  &OMP_FOR_PRE_BODY (for_stmt));
   15145 	  OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
   15146 	}
   15147 
   15148       if (data[0])
   15149 	{
   15150 	  /* We have some statements or variable declarations in between
   15151 	     the composite construct directives.  Move them around the
   15152 	     inner_for_stmt.  */
   15153 	  data[0] = expr_p;
   15154 	  for (i = 0; i < 3; i++)
   15155 	    if (data[i])
   15156 	      {
   15157 		tree t = *data[i];
   15158 		if (i < 2 && data[i + 1] == &OMP_BODY (t))
   15159 		  data[i + 1] = data[i];
   15160 		*data[i] = OMP_BODY (t);
   15161 		tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
   15162 				    NULL_TREE, make_node (BLOCK));
   15163 		OMP_BODY (t) = body;
   15164 		append_to_statement_list_force (inner_for_stmt,
   15165 						&BIND_EXPR_BODY (body));
   15166 		*data[3] = t;
   15167 		data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
   15168 		gcc_assert (*data[3] == inner_for_stmt);
   15169 	      }
   15170 	  return GS_OK;
   15171 	}
   15172 
   15173       for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
   15174 	if (!loop_p
   15175 	    && OMP_FOR_ORIG_DECLS (inner_for_stmt)
   15176 	    && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
   15177 					i)) == TREE_LIST
   15178 	    && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
   15179 					   i)))
   15180 	  {
   15181 	    tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
   15182 	    /* Class iterators aren't allowed on OMP_SIMD, so the only
   15183 	       case we need to solve is distribute parallel for.  They are
   15184 	       allowed on the loop construct, but that is already handled
   15185 	       in gimplify_omp_loop.  */
   15186 	    gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
   15187 			&& TREE_CODE (for_stmt) == OMP_DISTRIBUTE
   15188 			&& data[1]);
   15189 	    tree orig_decl = TREE_PURPOSE (orig);
   15190 	    tree last = TREE_VALUE (orig);
   15191 	    tree *pc;
   15192 	    for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
   15193 		 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
   15194 	      if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
   15195 		   || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
   15196 		  && OMP_CLAUSE_DECL (*pc) == orig_decl)
   15197 		break;
   15198 	    if (*pc == NULL_TREE)
   15199 	      {
   15200 		tree *spc;
   15201 		for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
   15202 		     *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
   15203 		  if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
   15204 		      && OMP_CLAUSE_DECL (*spc) == orig_decl)
   15205 		    break;
   15206 		if (*spc)
   15207 		  {
   15208 		    tree c = *spc;
   15209 		    *spc = OMP_CLAUSE_CHAIN (c);
   15210 		    OMP_CLAUSE_CHAIN (c) = NULL_TREE;
   15211 		    *pc = c;
   15212 		  }
   15213 	      }
   15214 	    if (*pc == NULL_TREE)
   15215 	      ;
   15216 	    else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
   15217 	      {
   15218 		/* private clause will appear only on inner_for_stmt.
   15219 		   Change it into firstprivate, and add private clause
   15220 		   on for_stmt.  */
   15221 		tree c = copy_node (*pc);
   15222 		OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
   15223 		OMP_FOR_CLAUSES (for_stmt) = c;
   15224 		OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
   15225 		lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
   15226 	      }
   15227 	    else
   15228 	      {
   15229 		/* lastprivate clause will appear on both inner_for_stmt
   15230 		   and for_stmt.  Add firstprivate clause to
   15231 		   inner_for_stmt.  */
   15232 		tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
   15233 					   OMP_CLAUSE_FIRSTPRIVATE);
   15234 		OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
   15235 		OMP_CLAUSE_CHAIN (c) = *pc;
   15236 		*pc = c;
   15237 		lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
   15238 	      }
   15239 	    tree c = build_omp_clause (UNKNOWN_LOCATION,
   15240 				       OMP_CLAUSE_FIRSTPRIVATE);
   15241 	    OMP_CLAUSE_DECL (c) = last;
   15242 	    OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
   15243 	    OMP_PARALLEL_CLAUSES (*data[1]) = c;
   15244 	    c = build_omp_clause (UNKNOWN_LOCATION,
   15245 				  *pc ? OMP_CLAUSE_SHARED
   15246 				      : OMP_CLAUSE_FIRSTPRIVATE);
   15247 	    OMP_CLAUSE_DECL (c) = orig_decl;
   15248 	    OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
   15249 	    OMP_PARALLEL_CLAUSES (*data[1]) = c;
   15250 	  }
   15251       /* Similarly, take care of C++ range for temporaries, those should
   15252 	 be firstprivate on OMP_PARALLEL if any.  */
   15253       if (data[1])
   15254 	for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
   15255 	  if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
   15256 	      && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
   15257 					  i)) == TREE_LIST
   15258 	      && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
   15259 					   i)))
   15260 	    {
   15261 	      tree orig
   15262 		= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
   15263 	      tree v = TREE_CHAIN (orig);
   15264 	      tree c = build_omp_clause (UNKNOWN_LOCATION,
   15265 					 OMP_CLAUSE_FIRSTPRIVATE);
   15266 	      /* First add firstprivate clause for the __for_end artificial
   15267 		 decl.  */
   15268 	      OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
   15269 	      if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
   15270 		  == REFERENCE_TYPE)
   15271 		OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
   15272 	      OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
   15273 	      OMP_PARALLEL_CLAUSES (*data[1]) = c;
   15274 	      if (TREE_VEC_ELT (v, 0))
   15275 		{
   15276 		  /* And now the same for __for_range artificial decl if it
   15277 		     exists.  */
   15278 		  c = build_omp_clause (UNKNOWN_LOCATION,
   15279 					OMP_CLAUSE_FIRSTPRIVATE);
   15280 		  OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
   15281 		  if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
   15282 		      == REFERENCE_TYPE)
   15283 		    OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
   15284 		  OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
   15285 		  OMP_PARALLEL_CLAUSES (*data[1]) = c;
   15286 		}
   15287 	    }
   15288     }
   15289 
   15290   switch (TREE_CODE (for_stmt))
   15291     {
   15292     case OMP_FOR:
   15293       if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
   15294 	{
   15295 	  if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   15296 			       OMP_CLAUSE_SCHEDULE))
   15297 	    error_at (EXPR_LOCATION (for_stmt),
   15298 		      "%qs clause may not appear on non-rectangular %qs",
   15299 		      "schedule", lang_GNU_Fortran () ? "do" : "for");
   15300 	  if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
   15301 	    error_at (EXPR_LOCATION (for_stmt),
   15302 		      "%qs clause may not appear on non-rectangular %qs",
   15303 		      "ordered", lang_GNU_Fortran () ? "do" : "for");
   15304 	}
   15305       break;
   15306     case OMP_DISTRIBUTE:
   15307       if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
   15308 	  && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   15309 			      OMP_CLAUSE_DIST_SCHEDULE))
   15310 	error_at (EXPR_LOCATION (for_stmt),
   15311 		  "%qs clause may not appear on non-rectangular %qs",
   15312 		  "dist_schedule", "distribute");
   15313       break;
   15314     case OACC_LOOP:
   15315       ort = ORT_ACC;
   15316       break;
   15317     case OMP_TASKLOOP:
   15318       if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
   15319 	{
   15320 	  if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   15321 			       OMP_CLAUSE_GRAINSIZE))
   15322 	    error_at (EXPR_LOCATION (for_stmt),
   15323 		      "%qs clause may not appear on non-rectangular %qs",
   15324 		      "grainsize", "taskloop");
   15325 	  if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   15326 			       OMP_CLAUSE_NUM_TASKS))
   15327 	    error_at (EXPR_LOCATION (for_stmt),
   15328 		      "%qs clause may not appear on non-rectangular %qs",
   15329 		      "num_tasks", "taskloop");
   15330 	}
   15331       if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
   15332 	ort = ORT_UNTIED_TASKLOOP;
   15333       else
   15334 	ort = ORT_TASKLOOP;
   15335       break;
   15336     case OMP_SIMD:
   15337       ort = ORT_SIMD;
   15338       break;
   15339     default:
   15340       gcc_unreachable ();
   15341     }
   15342 
   15343   /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
   15344      clause for the IV.  */
   15345   if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
   15346     {
   15347       t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
   15348       gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   15349       decl = TREE_OPERAND (t, 0);
   15350       for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
   15351 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   15352 	    && OMP_CLAUSE_DECL (c) == decl)
   15353 	  {
   15354 	    OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
   15355 	    break;
   15356 	  }
   15357     }
   15358 
   15359   if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
   15360     gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
   15361 			       loop_p && TREE_CODE (for_stmt) != OMP_SIMD
   15362 			       ? OMP_LOOP : TREE_CODE (for_stmt));
   15363 
   15364   if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
   15365     gimplify_omp_ctxp->distribute = true;
   15366 
   15367   /* Handle OMP_FOR_INIT.  */
   15368   for_pre_body = NULL;
   15369   if ((ort == ORT_SIMD
   15370        || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
   15371       && OMP_FOR_PRE_BODY (for_stmt))
   15372     {
   15373       has_decl_expr = BITMAP_ALLOC (NULL);
   15374       if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
   15375 	  && VAR_P (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt))))
   15376 	{
   15377 	  t = OMP_FOR_PRE_BODY (for_stmt);
   15378 	  bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
   15379 	}
   15380       else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
   15381 	{
   15382 	  tree_stmt_iterator si;
   15383 	  for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
   15384 	       tsi_next (&si))
   15385 	    {
   15386 	      t = tsi_stmt (si);
   15387 	      if (TREE_CODE (t) == DECL_EXPR
   15388 		  && VAR_P (DECL_EXPR_DECL (t)))
   15389 		bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
   15390 	    }
   15391 	}
   15392     }
   15393   if (OMP_FOR_PRE_BODY (for_stmt))
   15394     {
   15395       if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
   15396 	gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
   15397       else
   15398 	{
   15399 	  struct gimplify_omp_ctx ctx;
   15400 	  memset (&ctx, 0, sizeof (ctx));
   15401 	  ctx.region_type = ORT_NONE;
   15402 	  gimplify_omp_ctxp = &ctx;
   15403 	  gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
   15404 	  gimplify_omp_ctxp = NULL;
   15405 	}
   15406     }
   15407   OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
   15408 
   15409   if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
   15410     for_stmt = inner_for_stmt;
   15411 
   15412   /* For taskloop, need to gimplify the start, end and step before the
   15413      taskloop, outside of the taskloop omp context.  */
   15414   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
   15415     {
   15416       for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   15417 	{
   15418 	  t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   15419 	  gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
   15420 				   ? pre_p : &for_pre_body);
   15421 	      tree type = TREE_TYPE (TREE_OPERAND (t, 0));
   15422 	  if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   15423 	    {
   15424 	      tree v = TREE_OPERAND (t, 1);
   15425 	      gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
   15426 					  for_pre_p, orig_for_stmt);
   15427 	      gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
   15428 					  for_pre_p, orig_for_stmt);
   15429 	    }
   15430 	  else
   15431 	    gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
   15432 					orig_for_stmt);
   15433 
   15434 	  /* Handle OMP_FOR_COND.  */
   15435 	  t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
   15436 	  if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   15437 	    {
   15438 	      tree v = TREE_OPERAND (t, 1);
   15439 	      gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
   15440 					  for_pre_p, orig_for_stmt);
   15441 	      gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
   15442 					  for_pre_p, orig_for_stmt);
   15443 	    }
   15444 	  else
   15445 	    gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
   15446 					orig_for_stmt);
   15447 
   15448 	  /* Handle OMP_FOR_INCR.  */
   15449 	  t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   15450 	  if (TREE_CODE (t) == MODIFY_EXPR)
   15451 	    {
   15452 	      decl = TREE_OPERAND (t, 0);
   15453 	      t = TREE_OPERAND (t, 1);
   15454 	      tree *tp = &TREE_OPERAND (t, 1);
   15455 	      if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
   15456 		tp = &TREE_OPERAND (t, 0);
   15457 
   15458 	      gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
   15459 					  orig_for_stmt);
   15460 	    }
   15461 	}
   15462 
   15463       gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
   15464 				 OMP_TASKLOOP);
   15465     }
   15466 
   15467   if (orig_for_stmt != for_stmt)
   15468     gimplify_omp_ctxp->combined_loop = true;
   15469 
   15470   for_body = NULL;
   15471   gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
   15472 	      == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
   15473   gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
   15474 	      == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
   15475 
   15476   tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
   15477   bool is_doacross = false;
   15478   if (c && walk_tree_without_duplicates (&OMP_FOR_BODY (for_stmt),
   15479 					 find_standalone_omp_ordered, NULL))
   15480     {
   15481       OMP_CLAUSE_ORDERED_DOACROSS (c) = 1;
   15482       is_doacross = true;
   15483       int len = TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt));
   15484       gimplify_omp_ctxp->loop_iter_var.create (len * 2);
   15485       for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
   15486 	if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
   15487 	  {
   15488 	    error_at (OMP_CLAUSE_LOCATION (*pc),
   15489 		      "%<linear%> clause may not be specified together "
   15490 		      "with %<ordered%> clause if stand-alone %<ordered%> "
   15491 		      "construct is nested in it");
   15492 	    *pc = OMP_CLAUSE_CHAIN (*pc);
   15493 	  }
   15494 	else
   15495 	  pc = &OMP_CLAUSE_CHAIN (*pc);
   15496     }
   15497   int collapse = 1, tile = 0;
   15498   c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
   15499   if (c)
   15500     collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
   15501   c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
   15502   if (c)
   15503     tile = list_length (OMP_CLAUSE_TILE_LIST (c));
   15504   c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
   15505   hash_set<tree> *allocate_uids = NULL;
   15506   if (c)
   15507     {
   15508       allocate_uids = new hash_set<tree>;
   15509       for (; c; c = OMP_CLAUSE_CHAIN (c))
   15510 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
   15511 	  allocate_uids->add (OMP_CLAUSE_DECL (c));
   15512     }
   15513   for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   15514     {
   15515       t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   15516       gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   15517       decl = TREE_OPERAND (t, 0);
   15518       gcc_assert (DECL_P (decl));
   15519       gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
   15520 		  || POINTER_TYPE_P (TREE_TYPE (decl)));
   15521       if (is_doacross)
   15522 	{
   15523 	  if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
   15524 	    {
   15525 	      tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   15526 	      if (TREE_CODE (orig_decl) == TREE_LIST)
   15527 		{
   15528 		  orig_decl = TREE_PURPOSE (orig_decl);
   15529 		  if (!orig_decl)
   15530 		    orig_decl = decl;
   15531 		}
   15532 	      gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
   15533 	    }
   15534 	  else
   15535 	    gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
   15536 	  gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
   15537 	}
   15538 
   15539       if (for_stmt == orig_for_stmt)
   15540 	{
   15541 	  tree orig_decl = decl;
   15542 	  if (OMP_FOR_ORIG_DECLS (for_stmt))
   15543 	    {
   15544 	      tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   15545 	      if (TREE_CODE (orig_decl) == TREE_LIST)
   15546 		{
   15547 		  orig_decl = TREE_PURPOSE (orig_decl);
   15548 		  if (!orig_decl)
   15549 		    orig_decl = decl;
   15550 		}
   15551 	    }
   15552 	  if (is_global_var (orig_decl) && DECL_THREAD_LOCAL_P (orig_decl))
   15553 	    error_at (EXPR_LOCATION (for_stmt),
   15554 		      "threadprivate iteration variable %qD", orig_decl);
   15555 	}
   15556 
   15557       /* Make sure the iteration variable is private.  */
   15558       tree c = NULL_TREE;
   15559       tree c2 = NULL_TREE;
   15560       if (orig_for_stmt != for_stmt)
   15561 	{
   15562 	  /* Preserve this information until we gimplify the inner simd.  */
   15563 	  if (has_decl_expr
   15564 	      && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
   15565 	    TREE_PRIVATE (t) = 1;
   15566 	}
   15567       else if (ort == ORT_SIMD)
   15568 	{
   15569 	  splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
   15570 						 (splay_tree_key) decl);
   15571 	  omp_is_private (gimplify_omp_ctxp, decl,
   15572 			  1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
   15573 			       != 1));
   15574 	  if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
   15575 	    {
   15576 	      omp_notice_variable (gimplify_omp_ctxp, decl, true);
   15577 	      if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
   15578 		for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   15579 						OMP_CLAUSE_LASTPRIVATE);
   15580 		     c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
   15581 					       OMP_CLAUSE_LASTPRIVATE))
   15582 		  if (OMP_CLAUSE_DECL (c3) == decl)
   15583 		    {
   15584 		      warning_at (OMP_CLAUSE_LOCATION (c3), OPT_Wopenmp,
   15585 				  "conditional %<lastprivate%> on loop "
   15586 				  "iterator %qD ignored", decl);
   15587 		      OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
   15588 		      n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
   15589 		    }
   15590 	    }
   15591 	  else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
   15592 	    {
   15593 	      c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
   15594 	      OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
   15595 	      unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
   15596 	      if ((has_decl_expr
   15597 		   && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
   15598 		  || TREE_PRIVATE (t))
   15599 		{
   15600 		  OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
   15601 		  flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
   15602 		}
   15603 	      struct gimplify_omp_ctx *outer
   15604 		= gimplify_omp_ctxp->outer_context;
   15605 	      if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   15606 		{
   15607 		  if (outer->region_type == ORT_WORKSHARE
   15608 		      && outer->combined_loop)
   15609 		    {
   15610 		      n = splay_tree_lookup (outer->variables,
   15611 					     (splay_tree_key)decl);
   15612 		      if (n != NULL && (n->value & GOVD_LOCAL) != 0)
   15613 			{
   15614 			  OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
   15615 			  flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
   15616 			}
   15617 		      else
   15618 			{
   15619 			  struct gimplify_omp_ctx *octx = outer->outer_context;
   15620 			  if (octx
   15621 			      && octx->region_type == ORT_COMBINED_PARALLEL
   15622 			      && octx->outer_context
   15623 			      && (octx->outer_context->region_type
   15624 				  == ORT_WORKSHARE)
   15625 			      && octx->outer_context->combined_loop)
   15626 			    {
   15627 			      octx = octx->outer_context;
   15628 			      n = splay_tree_lookup (octx->variables,
   15629 						     (splay_tree_key)decl);
   15630 			      if (n != NULL && (n->value & GOVD_LOCAL) != 0)
   15631 				{
   15632 				  OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
   15633 				  flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
   15634 				}
   15635 			    }
   15636 			}
   15637 		    }
   15638 		}
   15639 
   15640 	      OMP_CLAUSE_DECL (c) = decl;
   15641 	      OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
   15642 	      OMP_FOR_CLAUSES (for_stmt) = c;
   15643 	      omp_add_variable (gimplify_omp_ctxp, decl, flags);
   15644 	      if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   15645 		omp_lastprivate_for_combined_outer_constructs (outer, decl,
   15646 							       true);
   15647 	    }
   15648 	  else
   15649 	    {
   15650 	      bool lastprivate
   15651 		= (!has_decl_expr
   15652 		   || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
   15653 	      if (TREE_PRIVATE (t))
   15654 		lastprivate = false;
   15655 	      if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
   15656 		{
   15657 		  tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   15658 		  if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
   15659 		    lastprivate = false;
   15660 		}
   15661 
   15662 	      struct gimplify_omp_ctx *outer
   15663 		= gimplify_omp_ctxp->outer_context;
   15664 	      if (outer && lastprivate)
   15665 		omp_lastprivate_for_combined_outer_constructs (outer, decl,
   15666 							       true);
   15667 
   15668 	      c = build_omp_clause (input_location,
   15669 				    lastprivate ? OMP_CLAUSE_LASTPRIVATE
   15670 						: OMP_CLAUSE_PRIVATE);
   15671 	      OMP_CLAUSE_DECL (c) = decl;
   15672 	      OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
   15673 	      OMP_FOR_CLAUSES (for_stmt) = c;
   15674 	      omp_add_variable (gimplify_omp_ctxp, decl,
   15675 				(lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
   15676 				| GOVD_EXPLICIT | GOVD_SEEN);
   15677 	      c = NULL_TREE;
   15678 	    }
   15679 	}
   15680       else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
   15681 	{
   15682 	  omp_notice_variable (gimplify_omp_ctxp, decl, true);
   15683 	  splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
   15684 						 (splay_tree_key) decl);
   15685 	  if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
   15686 	    for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   15687 					    OMP_CLAUSE_LASTPRIVATE);
   15688 		 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
   15689 					   OMP_CLAUSE_LASTPRIVATE))
   15690 	      if (OMP_CLAUSE_DECL (c3) == decl)
   15691 		{
   15692 		  warning_at (OMP_CLAUSE_LOCATION (c3), OPT_Wopenmp,
   15693 			      "conditional %<lastprivate%> on loop "
   15694 			      "iterator %qD ignored", decl);
   15695 		  OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
   15696 		  n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
   15697 		}
   15698 	}
   15699       else
   15700 	omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
   15701 
   15702       /* If DECL is not a gimple register, create a temporary variable to act
   15703 	 as an iteration counter.  This is valid, since DECL cannot be
   15704 	 modified in the body of the loop.  Similarly for any iteration vars
   15705 	 in simd with collapse > 1 where the iterator vars must be
   15706 	 lastprivate.  And similarly for vars mentioned in allocate clauses.  */
   15707       if (orig_for_stmt != for_stmt)
   15708 	var = decl;
   15709       else if (!is_gimple_reg (decl)
   15710 	       || (ort == ORT_SIMD
   15711 		   && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
   15712 	       || (allocate_uids && allocate_uids->contains (decl)))
   15713 	{
   15714 	  struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   15715 	  /* Make sure omp_add_variable is not called on it prematurely.
   15716 	     We call it ourselves a few lines later.  */
   15717 	  gimplify_omp_ctxp = NULL;
   15718 	  var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
   15719 	  gimplify_omp_ctxp = ctx;
   15720 	  TREE_OPERAND (t, 0) = var;
   15721 
   15722 	  gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
   15723 
   15724 	  if (ort == ORT_SIMD
   15725 	      && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
   15726 	    {
   15727 	      c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
   15728 	      OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
   15729 	      OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
   15730 	      OMP_CLAUSE_DECL (c2) = var;
   15731 	      OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
   15732 	      OMP_FOR_CLAUSES (for_stmt) = c2;
   15733 	      omp_add_variable (gimplify_omp_ctxp, var,
   15734 				GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
   15735 	      if (c == NULL_TREE)
   15736 		{
   15737 		  c = c2;
   15738 		  c2 = NULL_TREE;
   15739 		}
   15740 	    }
   15741 	  else
   15742 	    omp_add_variable (gimplify_omp_ctxp, var,
   15743 			      GOVD_PRIVATE | GOVD_SEEN);
   15744 	}
   15745       else
   15746 	var = decl;
   15747 
   15748       gimplify_omp_ctxp->in_for_exprs = true;
   15749       if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   15750 	{
   15751 	  tree lb = TREE_OPERAND (t, 1);
   15752 	  tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
   15753 				is_gimple_val, fb_rvalue, false);
   15754 	  ret = MIN (ret, tret);
   15755 	  tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
   15756 				is_gimple_val, fb_rvalue, false);
   15757 	}
   15758       else
   15759 	tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
   15760 			      is_gimple_val, fb_rvalue, false);
   15761       gimplify_omp_ctxp->in_for_exprs = false;
   15762       ret = MIN (ret, tret);
   15763       if (ret == GS_ERROR)
   15764 	return ret;
   15765 
   15766       /* Handle OMP_FOR_COND.  */
   15767       t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
   15768       gcc_assert (COMPARISON_CLASS_P (t));
   15769       gcc_assert (TREE_OPERAND (t, 0) == decl);
   15770 
   15771       gimplify_omp_ctxp->in_for_exprs = true;
   15772       if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   15773 	{
   15774 	  tree ub = TREE_OPERAND (t, 1);
   15775 	  tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
   15776 				is_gimple_val, fb_rvalue, false);
   15777 	  ret = MIN (ret, tret);
   15778 	  tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
   15779 				is_gimple_val, fb_rvalue, false);
   15780 	}
   15781       else
   15782 	tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
   15783 			      is_gimple_val, fb_rvalue, false);
   15784       gimplify_omp_ctxp->in_for_exprs = false;
   15785       ret = MIN (ret, tret);
   15786 
   15787       /* Handle OMP_FOR_INCR.  */
   15788       t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   15789       switch (TREE_CODE (t))
   15790 	{
   15791 	case PREINCREMENT_EXPR:
   15792 	case POSTINCREMENT_EXPR:
   15793 	  {
   15794 	    tree decl = TREE_OPERAND (t, 0);
   15795 	    /* c_omp_for_incr_canonicalize_ptr() should have been
   15796 	       called to massage things appropriately.  */
   15797 	    gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
   15798 
   15799 	    if (orig_for_stmt != for_stmt)
   15800 	      break;
   15801 	    t = build_int_cst (TREE_TYPE (decl), 1);
   15802 	    if (c)
   15803 	      OMP_CLAUSE_LINEAR_STEP (c) = t;
   15804 	    t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
   15805 	    t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
   15806 	    TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
   15807 	    break;
   15808 	  }
   15809 
   15810 	case PREDECREMENT_EXPR:
   15811 	case POSTDECREMENT_EXPR:
   15812 	  /* c_omp_for_incr_canonicalize_ptr() should have been
   15813 	     called to massage things appropriately.  */
   15814 	  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
   15815 	  if (orig_for_stmt != for_stmt)
   15816 	    break;
   15817 	  t = build_int_cst (TREE_TYPE (decl), -1);
   15818 	  if (c)
   15819 	    OMP_CLAUSE_LINEAR_STEP (c) = t;
   15820 	  t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
   15821 	  t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
   15822 	  TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
   15823 	  break;
   15824 
   15825 	case MODIFY_EXPR:
   15826 	  gcc_assert (TREE_OPERAND (t, 0) == decl);
   15827 	  TREE_OPERAND (t, 0) = var;
   15828 
   15829 	  t = TREE_OPERAND (t, 1);
   15830 	  switch (TREE_CODE (t))
   15831 	    {
   15832 	    case PLUS_EXPR:
   15833 	      if (TREE_OPERAND (t, 1) == decl)
   15834 		{
   15835 		  TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
   15836 		  TREE_OPERAND (t, 0) = var;
   15837 		  break;
   15838 		}
   15839 
   15840 	      /* Fallthru.  */
   15841 	    case MINUS_EXPR:
   15842 	    case POINTER_PLUS_EXPR:
   15843 	      gcc_assert (TREE_OPERAND (t, 0) == decl);
   15844 	      TREE_OPERAND (t, 0) = var;
   15845 	      break;
   15846 	    default:
   15847 	      gcc_unreachable ();
   15848 	    }
   15849 
   15850 	  gimplify_omp_ctxp->in_for_exprs = true;
   15851 	  tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
   15852 				is_gimple_val, fb_rvalue, false);
   15853 	  ret = MIN (ret, tret);
   15854 	  if (c)
   15855 	    {
   15856 	      tree step = TREE_OPERAND (t, 1);
   15857 	      tree stept = TREE_TYPE (decl);
   15858 	      if (POINTER_TYPE_P (stept))
   15859 		stept = sizetype;
   15860 	      step = fold_convert (stept, step);
   15861 	      if (TREE_CODE (t) == MINUS_EXPR)
   15862 		step = fold_build1 (NEGATE_EXPR, stept, step);
   15863 	      OMP_CLAUSE_LINEAR_STEP (c) = step;
   15864 	      if (step != TREE_OPERAND (t, 1))
   15865 		{
   15866 		  tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
   15867 					&for_pre_body, NULL,
   15868 					is_gimple_val, fb_rvalue, false);
   15869 		  ret = MIN (ret, tret);
   15870 		}
   15871 	    }
   15872 	  gimplify_omp_ctxp->in_for_exprs = false;
   15873 	  break;
   15874 
   15875 	default:
   15876 	  gcc_unreachable ();
   15877 	}
   15878 
   15879       if (c2)
   15880 	{
   15881 	  gcc_assert (c);
   15882 	  OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
   15883 	}
   15884 
   15885       if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
   15886 	{
   15887 	  for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
   15888 	    if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   15889 		  && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
   15890 		 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   15891 		     && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
   15892 		     && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
   15893 		&& OMP_CLAUSE_DECL (c) == decl)
   15894 	      {
   15895 		if (is_doacross && (collapse == 1 || i >= collapse))
   15896 		  t = var;
   15897 		else
   15898 		  {
   15899 		    t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   15900 		    gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   15901 		    gcc_assert (TREE_OPERAND (t, 0) == var);
   15902 		    t = TREE_OPERAND (t, 1);
   15903 		    gcc_assert (TREE_CODE (t) == PLUS_EXPR
   15904 				|| TREE_CODE (t) == MINUS_EXPR
   15905 				|| TREE_CODE (t) == POINTER_PLUS_EXPR);
   15906 		    gcc_assert (TREE_OPERAND (t, 0) == var);
   15907 		    t = build2 (TREE_CODE (t), TREE_TYPE (decl),
   15908 				is_doacross ? var : decl,
   15909 				TREE_OPERAND (t, 1));
   15910 		  }
   15911 		gimple_seq *seq;
   15912 		if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
   15913 		  seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
   15914 		else
   15915 		  seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
   15916 		push_gimplify_context ();
   15917 		gimplify_assign (decl, t, seq);
   15918 		gimple *bind = NULL;
   15919 		if (gimplify_ctxp->temps)
   15920 		  {
   15921 		    bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
   15922 		    *seq = NULL;
   15923 		    gimplify_seq_add_stmt (seq, bind);
   15924 		  }
   15925 		pop_gimplify_context (bind);
   15926 	      }
   15927 	}
   15928       if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
   15929 	for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
   15930 	  {
   15931 	    t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
   15932 	    gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   15933 	    if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
   15934 		&& TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
   15935 	      TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
   15936 	    t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
   15937 	    gcc_assert (COMPARISON_CLASS_P (t));
   15938 	    if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
   15939 		&& TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
   15940 	      TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
   15941 	  }
   15942     }
   15943 
   15944   BITMAP_FREE (has_decl_expr);
   15945   delete allocate_uids;
   15946 
   15947   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
   15948       || (loop_p && orig_for_stmt == for_stmt))
   15949     {
   15950       push_gimplify_context ();
   15951       if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
   15952 	{
   15953 	  OMP_FOR_BODY (orig_for_stmt)
   15954 	    = build3 (BIND_EXPR, void_type_node, NULL,
   15955 		      OMP_FOR_BODY (orig_for_stmt), NULL);
   15956 	  TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
   15957 	}
   15958     }
   15959 
   15960   gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
   15961 					 &for_body);
   15962 
   15963   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
   15964       || (loop_p && orig_for_stmt == for_stmt))
   15965     {
   15966       if (gimple_code (g) == GIMPLE_BIND)
   15967 	pop_gimplify_context (g);
   15968       else
   15969 	pop_gimplify_context (NULL);
   15970     }
   15971 
   15972   if (orig_for_stmt != for_stmt)
   15973     for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   15974       {
   15975 	t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   15976 	decl = TREE_OPERAND (t, 0);
   15977 	struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   15978 	if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
   15979 	  gimplify_omp_ctxp = ctx->outer_context;
   15980 	var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
   15981 	gimplify_omp_ctxp = ctx;
   15982 	omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
   15983 	TREE_OPERAND (t, 0) = var;
   15984 	t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   15985 	TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
   15986 	TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
   15987 	if (OMP_FOR_NON_RECTANGULAR (for_stmt))
   15988 	  for (int j = i + 1;
   15989 	       j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
   15990 	    {
   15991 	      t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
   15992 	      gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   15993 	      if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
   15994 		  && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
   15995 		{
   15996 		  TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
   15997 		  TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
   15998 		}
   15999 	      t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
   16000 	      gcc_assert (COMPARISON_CLASS_P (t));
   16001 	      if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
   16002 		  && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
   16003 		{
   16004 		  TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
   16005 		  TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
   16006 		}
   16007 	  }
   16008       }
   16009 
   16010   gimplify_adjust_omp_clauses (pre_p, for_body,
   16011 			       &OMP_FOR_CLAUSES (orig_for_stmt),
   16012 			       TREE_CODE (orig_for_stmt));
   16013 
   16014   int kind;
   16015   switch (TREE_CODE (orig_for_stmt))
   16016     {
   16017     case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
   16018     case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
   16019     case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
   16020     case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
   16021     case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
   16022     default:
   16023       gcc_unreachable ();
   16024     }
   16025   if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
   16026     {
   16027       gimplify_seq_add_seq (pre_p, for_pre_body);
   16028       for_pre_body = NULL;
   16029     }
   16030   gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
   16031 			       TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
   16032 			       for_pre_body);
   16033   if (orig_for_stmt != for_stmt)
   16034     gimple_omp_for_set_combined_p (gfor, true);
   16035   if (gimplify_omp_ctxp
   16036       && (gimplify_omp_ctxp->combined_loop
   16037 	  || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
   16038 	      && gimplify_omp_ctxp->outer_context
   16039 	      && gimplify_omp_ctxp->outer_context->combined_loop)))
   16040     {
   16041       gimple_omp_for_set_combined_into_p (gfor, true);
   16042       if (gimplify_omp_ctxp->combined_loop)
   16043 	gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
   16044       else
   16045 	gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
   16046     }
   16047 
   16048   for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   16049     {
   16050       t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   16051       gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
   16052       gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
   16053       t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
   16054       gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
   16055       gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
   16056       t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   16057       gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
   16058     }
   16059 
   16060   /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
   16061      constructs with GIMPLE_OMP_TASK sandwiched in between them.
   16062      The outer taskloop stands for computing the number of iterations,
   16063      counts for collapsed loops and holding taskloop specific clauses.
   16064      The task construct stands for the effect of data sharing on the
   16065      explicit task it creates and the inner taskloop stands for expansion
   16066      of the static loop inside of the explicit task construct.  */
   16067   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
   16068     {
   16069       tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
   16070       tree task_clauses = NULL_TREE;
   16071       tree c = *gfor_clauses_ptr;
   16072       tree *gtask_clauses_ptr = &task_clauses;
   16073       tree outer_for_clauses = NULL_TREE;
   16074       tree *gforo_clauses_ptr = &outer_for_clauses;
   16075       bitmap lastprivate_uids = NULL;
   16076       if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
   16077 	{
   16078 	  c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
   16079 	  if (c)
   16080 	    {
   16081 	      lastprivate_uids = BITMAP_ALLOC (NULL);
   16082 	      for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
   16083 					     OMP_CLAUSE_LASTPRIVATE))
   16084 		bitmap_set_bit (lastprivate_uids,
   16085 				DECL_UID (OMP_CLAUSE_DECL (c)));
   16086 	    }
   16087 	  c = *gfor_clauses_ptr;
   16088 	}
   16089       for (; c; c = OMP_CLAUSE_CHAIN (c))
   16090 	switch (OMP_CLAUSE_CODE (c))
   16091 	  {
   16092 	  /* These clauses are allowed on task, move them there.  */
   16093 	  case OMP_CLAUSE_SHARED:
   16094 	  case OMP_CLAUSE_FIRSTPRIVATE:
   16095 	  case OMP_CLAUSE_DEFAULT:
   16096 	  case OMP_CLAUSE_IF:
   16097 	  case OMP_CLAUSE_UNTIED:
   16098 	  case OMP_CLAUSE_FINAL:
   16099 	  case OMP_CLAUSE_MERGEABLE:
   16100 	  case OMP_CLAUSE_PRIORITY:
   16101 	  case OMP_CLAUSE_REDUCTION:
   16102 	  case OMP_CLAUSE_IN_REDUCTION:
   16103 	    *gtask_clauses_ptr = c;
   16104 	    gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   16105 	    break;
   16106 	  case OMP_CLAUSE_PRIVATE:
   16107 	    if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
   16108 	      {
   16109 		/* We want private on outer for and firstprivate
   16110 		   on task.  */
   16111 		*gtask_clauses_ptr
   16112 		  = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   16113 				      OMP_CLAUSE_FIRSTPRIVATE);
   16114 		OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
   16115 		lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
   16116 						    openacc);
   16117 		gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   16118 		*gforo_clauses_ptr = c;
   16119 		gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   16120 	      }
   16121 	    else
   16122 	      {
   16123 		*gtask_clauses_ptr = c;
   16124 		gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   16125 	      }
   16126 	    break;
   16127 	  /* These clauses go into outer taskloop clauses.  */
   16128 	  case OMP_CLAUSE_GRAINSIZE:
   16129 	  case OMP_CLAUSE_NUM_TASKS:
   16130 	  case OMP_CLAUSE_NOGROUP:
   16131 	    *gforo_clauses_ptr = c;
   16132 	    gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   16133 	    break;
   16134 	  /* Collapse clause we duplicate on both taskloops.  */
   16135 	  case OMP_CLAUSE_COLLAPSE:
   16136 	    *gfor_clauses_ptr = c;
   16137 	    gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   16138 	    *gforo_clauses_ptr = copy_node (c);
   16139 	    gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
   16140 	    break;
   16141 	  /* For lastprivate, keep the clause on inner taskloop, and add
   16142 	     a shared clause on task.  If the same decl is also firstprivate,
   16143 	     add also firstprivate clause on the inner taskloop.  */
   16144 	  case OMP_CLAUSE_LASTPRIVATE:
   16145 	    if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
   16146 	      {
   16147 		/* For taskloop C++ lastprivate IVs, we want:
   16148 		   1) private on outer taskloop
   16149 		   2) firstprivate and shared on task
   16150 		   3) lastprivate on inner taskloop  */
   16151 		*gtask_clauses_ptr
   16152 		  = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   16153 				      OMP_CLAUSE_FIRSTPRIVATE);
   16154 		OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
   16155 		lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
   16156 						    openacc);
   16157 		gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   16158 		OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
   16159 		*gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   16160 						       OMP_CLAUSE_PRIVATE);
   16161 		OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
   16162 		OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
   16163 		TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
   16164 		gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
   16165 	      }
   16166 	    *gfor_clauses_ptr = c;
   16167 	    gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   16168 	    *gtask_clauses_ptr
   16169 	      = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
   16170 	    OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
   16171 	    if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
   16172 	      OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
   16173 	    gtask_clauses_ptr
   16174 	      = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   16175 	    break;
   16176 	  /* Allocate clause we duplicate on task and inner taskloop
   16177 	     if the decl is lastprivate, otherwise just put on task.  */
   16178 	  case OMP_CLAUSE_ALLOCATE:
   16179 	    if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
   16180 		&& DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
   16181 	      {
   16182 		/* Additionally, put firstprivate clause on task
   16183 		   for the allocator if it is not constant.  */
   16184 		*gtask_clauses_ptr
   16185 		  = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   16186 				      OMP_CLAUSE_FIRSTPRIVATE);
   16187 		OMP_CLAUSE_DECL (*gtask_clauses_ptr)
   16188 		  = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
   16189 		gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   16190 	      }
   16191 	    if (lastprivate_uids
   16192 		&& bitmap_bit_p (lastprivate_uids,
   16193 				 DECL_UID (OMP_CLAUSE_DECL (c))))
   16194 	      {
   16195 		*gfor_clauses_ptr = c;
   16196 		gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   16197 		*gtask_clauses_ptr = copy_node (c);
   16198 		gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   16199 	      }
   16200 	    else
   16201 	      {
   16202 		*gtask_clauses_ptr = c;
   16203 		gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   16204 	      }
   16205 	    break;
   16206 	  default:
   16207 	    gcc_unreachable ();
   16208 	  }
   16209       *gfor_clauses_ptr = NULL_TREE;
   16210       *gtask_clauses_ptr = NULL_TREE;
   16211       *gforo_clauses_ptr = NULL_TREE;
   16212       BITMAP_FREE (lastprivate_uids);
   16213       gimple_set_location (gfor, input_location);
   16214       g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
   16215       g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
   16216 				 NULL_TREE, NULL_TREE, NULL_TREE);
   16217       gimple_set_location (g, input_location);
   16218       gimple_omp_task_set_taskloop_p (g, true);
   16219       g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
   16220       gomp_for *gforo
   16221 	= gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
   16222 				gimple_omp_for_collapse (gfor),
   16223 				gimple_omp_for_pre_body (gfor));
   16224       gimple_omp_for_set_pre_body (gfor, NULL);
   16225       gimple_omp_for_set_combined_p (gforo, true);
   16226       gimple_omp_for_set_combined_into_p (gfor, true);
   16227       for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
   16228 	{
   16229 	  tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
   16230 	  tree v = create_tmp_var (type);
   16231 	  gimple_omp_for_set_index (gforo, i, v);
   16232 	  t = unshare_expr (gimple_omp_for_initial (gfor, i));
   16233 	  gimple_omp_for_set_initial (gforo, i, t);
   16234 	  gimple_omp_for_set_cond (gforo, i,
   16235 				   gimple_omp_for_cond (gfor, i));
   16236 	  t = unshare_expr (gimple_omp_for_final (gfor, i));
   16237 	  gimple_omp_for_set_final (gforo, i, t);
   16238 	  t = unshare_expr (gimple_omp_for_incr (gfor, i));
   16239 	  gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
   16240 	  TREE_OPERAND (t, 0) = v;
   16241 	  gimple_omp_for_set_incr (gforo, i, t);
   16242 	  t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
   16243 	  OMP_CLAUSE_DECL (t) = v;
   16244 	  OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
   16245 	  gimple_omp_for_set_clauses (gforo, t);
   16246 	  if (OMP_FOR_NON_RECTANGULAR (for_stmt))
   16247 	    {
   16248 	      tree *p1 = NULL, *p2 = NULL;
   16249 	      t = gimple_omp_for_initial (gforo, i);
   16250 	      if (TREE_CODE (t) == TREE_VEC)
   16251 		p1 = &TREE_VEC_ELT (t, 0);
   16252 	      t = gimple_omp_for_final (gforo, i);
   16253 	      if (TREE_CODE (t) == TREE_VEC)
   16254 		{
   16255 		  if (p1)
   16256 		    p2 = &TREE_VEC_ELT (t, 0);
   16257 		  else
   16258 		    p1 = &TREE_VEC_ELT (t, 0);
   16259 		}
   16260 	      if (p1)
   16261 		{
   16262 		  int j;
   16263 		  for (j = 0; j < i; j++)
   16264 		    if (*p1 == gimple_omp_for_index (gfor, j))
   16265 		      {
   16266 			*p1 = gimple_omp_for_index (gforo, j);
   16267 			if (p2)
   16268 			  *p2 = *p1;
   16269 			break;
   16270 		      }
   16271 		  gcc_assert (j < i);
   16272 		}
   16273 	    }
   16274 	}
   16275       gimplify_seq_add_stmt (pre_p, gforo);
   16276     }
   16277   else
   16278     gimplify_seq_add_stmt (pre_p, gfor);
   16279 
   16280   if (TREE_CODE (orig_for_stmt) == OMP_FOR)
   16281     {
   16282       struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   16283       unsigned lastprivate_conditional = 0;
   16284       while (ctx
   16285 	     && (ctx->region_type == ORT_TARGET_DATA
   16286 		 || ctx->region_type == ORT_TASKGROUP))
   16287 	ctx = ctx->outer_context;
   16288       if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
   16289 	for (tree c = gimple_omp_for_clauses (gfor);
   16290 	     c; c = OMP_CLAUSE_CHAIN (c))
   16291 	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   16292 	      && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   16293 	    ++lastprivate_conditional;
   16294       if (lastprivate_conditional)
   16295 	{
   16296 	  struct omp_for_data fd;
   16297 	  omp_extract_for_data (gfor, &fd, NULL);
   16298 	  tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
   16299 					      lastprivate_conditional);
   16300 	  tree var = create_tmp_var_raw (type);
   16301 	  tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
   16302 	  OMP_CLAUSE_DECL (c) = var;
   16303 	  OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
   16304 	  gimple_omp_for_set_clauses (gfor, c);
   16305 	  omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
   16306 	}
   16307     }
   16308   else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
   16309     {
   16310       unsigned lastprivate_conditional = 0;
   16311       for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
   16312 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   16313 	    && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   16314 	  ++lastprivate_conditional;
   16315       if (lastprivate_conditional)
   16316 	{
   16317 	  struct omp_for_data fd;
   16318 	  omp_extract_for_data (gfor, &fd, NULL);
   16319 	  tree type = unsigned_type_for (fd.iter_type);
   16320 	  while (lastprivate_conditional--)
   16321 	    {
   16322 	      tree c = build_omp_clause (UNKNOWN_LOCATION,
   16323 					 OMP_CLAUSE__CONDTEMP_);
   16324 	      OMP_CLAUSE_DECL (c) = create_tmp_var (type);
   16325 	      OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
   16326 	      gimple_omp_for_set_clauses (gfor, c);
   16327 	    }
   16328 	}
   16329     }
   16330 
   16331   if (ret != GS_ALL_DONE)
   16332     return GS_ERROR;
   16333   *expr_p = NULL_TREE;
   16334   return GS_ALL_DONE;
   16335 }
   16336 
   16337 /* Helper for gimplify_omp_loop, called through walk_tree.  */
   16338 
   16339 static tree
   16340 note_no_context_vars (tree *tp, int *, void *data)
   16341 {
   16342   if (VAR_P (*tp)
   16343       && DECL_CONTEXT (*tp) == NULL_TREE
   16344       && !is_global_var (*tp))
   16345     {
   16346       vec<tree> *d = (vec<tree> *) data;
   16347       d->safe_push (*tp);
   16348       DECL_CONTEXT (*tp) = current_function_decl;
   16349     }
   16350   return NULL_TREE;
   16351 }
   16352 
   16353 /* Gimplify the gross structure of an OMP_LOOP statement.  */
   16354 
   16355 static enum gimplify_status
   16356 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
   16357 {
   16358   tree for_stmt = *expr_p;
   16359   tree clauses = OMP_FOR_CLAUSES (for_stmt);
   16360   struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
   16361   enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
   16362   int i;
   16363 
   16364   /* If order is not present, the behavior is as if order(concurrent)
   16365      appeared.  */
   16366   tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
   16367   if (order == NULL_TREE)
   16368     {
   16369       order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
   16370       OMP_CLAUSE_CHAIN (order) = clauses;
   16371       OMP_FOR_CLAUSES (for_stmt) = clauses = order;
   16372     }
   16373 
   16374   tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
   16375   if (bind == NULL_TREE)
   16376     {
   16377       if (!flag_openmp) /* flag_openmp_simd */
   16378 	;
   16379       else if (octx && (octx->region_type & ORT_TEAMS) != 0)
   16380 	kind = OMP_CLAUSE_BIND_TEAMS;
   16381       else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
   16382 	kind = OMP_CLAUSE_BIND_PARALLEL;
   16383       else
   16384 	{
   16385 	  for (; octx; octx = octx->outer_context)
   16386 	    {
   16387 	      if ((octx->region_type & ORT_ACC) != 0
   16388 		  || octx->region_type == ORT_NONE
   16389 		  || octx->region_type == ORT_IMPLICIT_TARGET)
   16390 		continue;
   16391 	      break;
   16392 	    }
   16393 	  if (octx == NULL && !in_omp_construct)
   16394 	    error_at (EXPR_LOCATION (for_stmt),
   16395 		      "%<bind%> clause not specified on a %<loop%> "
   16396 		      "construct not nested inside another OpenMP construct");
   16397 	}
   16398       bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
   16399       OMP_CLAUSE_CHAIN (bind) = clauses;
   16400       OMP_CLAUSE_BIND_KIND (bind) = kind;
   16401       OMP_FOR_CLAUSES (for_stmt) = bind;
   16402     }
   16403   else
   16404     switch (OMP_CLAUSE_BIND_KIND (bind))
   16405       {
   16406       case OMP_CLAUSE_BIND_THREAD:
   16407 	break;
   16408       case OMP_CLAUSE_BIND_PARALLEL:
   16409 	if (!flag_openmp) /* flag_openmp_simd */
   16410 	  {
   16411 	    OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
   16412 	    break;
   16413 	  }
   16414 	for (; octx; octx = octx->outer_context)
   16415 	  if (octx->region_type == ORT_SIMD
   16416 	      && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
   16417 	    {
   16418 	      error_at (EXPR_LOCATION (for_stmt),
   16419 			"%<bind(parallel)%> on a %<loop%> construct nested "
   16420 			"inside %<simd%> construct");
   16421 	      OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
   16422 	      break;
   16423 	    }
   16424 	kind = OMP_CLAUSE_BIND_PARALLEL;
   16425 	break;
   16426       case OMP_CLAUSE_BIND_TEAMS:
   16427 	if (!flag_openmp) /* flag_openmp_simd */
   16428 	  {
   16429 	    OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
   16430 	    break;
   16431 	  }
   16432 	if ((octx
   16433 	     && octx->region_type != ORT_IMPLICIT_TARGET
   16434 	     && octx->region_type != ORT_NONE
   16435 	     && (octx->region_type & ORT_TEAMS) == 0)
   16436 	    || in_omp_construct)
   16437 	  {
   16438 	    error_at (EXPR_LOCATION (for_stmt),
   16439 		      "%<bind(teams)%> on a %<loop%> region not strictly "
   16440 		      "nested inside of a %<teams%> region");
   16441 	    OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
   16442 	    break;
   16443 	  }
   16444 	kind = OMP_CLAUSE_BIND_TEAMS;
   16445 	break;
   16446       default:
   16447 	gcc_unreachable ();
   16448       }
   16449 
   16450   for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
   16451     switch (OMP_CLAUSE_CODE (*pc))
   16452       {
   16453       case OMP_CLAUSE_REDUCTION:
   16454 	if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
   16455 	  {
   16456 	    error_at (OMP_CLAUSE_LOCATION (*pc),
   16457 		      "%<inscan%> %<reduction%> clause on "
   16458 		      "%qs construct", "loop");
   16459 	    OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
   16460 	  }
   16461 	if (OMP_CLAUSE_REDUCTION_TASK (*pc))
   16462 	  {
   16463 	    error_at (OMP_CLAUSE_LOCATION (*pc),
   16464 		      "invalid %<task%> reduction modifier on construct "
   16465 		      "other than %<parallel%>, %qs or %<sections%>",
   16466 		      lang_GNU_Fortran () ? "do" : "for");
   16467 	    OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
   16468 	  }
   16469 	pc = &OMP_CLAUSE_CHAIN (*pc);
   16470 	break;
   16471       case OMP_CLAUSE_LASTPRIVATE:
   16472 	for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   16473 	  {
   16474 	    tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   16475 	    gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   16476 	    if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
   16477 	      break;
   16478 	    if (OMP_FOR_ORIG_DECLS (for_stmt)
   16479 		&& TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
   16480 					    i)) == TREE_LIST
   16481 		&& TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
   16482 					       i)))
   16483 	      {
   16484 		tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   16485 		if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
   16486 		  break;
   16487 	      }
   16488 	  }
   16489 	if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
   16490 	  {
   16491 	    error_at (OMP_CLAUSE_LOCATION (*pc),
   16492 		      "%<lastprivate%> clause on a %<loop%> construct refers "
   16493 		      "to a variable %qD which is not the loop iterator",
   16494 		      OMP_CLAUSE_DECL (*pc));
   16495 	    *pc = OMP_CLAUSE_CHAIN (*pc);
   16496 	    break;
   16497 	  }
   16498 	pc = &OMP_CLAUSE_CHAIN (*pc);
   16499 	break;
   16500       default:
   16501 	pc = &OMP_CLAUSE_CHAIN (*pc);
   16502 	break;
   16503     }
   16504 
   16505   TREE_SET_CODE (for_stmt, OMP_SIMD);
   16506 
   16507   int last;
   16508   switch (kind)
   16509     {
   16510     case OMP_CLAUSE_BIND_THREAD: last = 0; break;
   16511     case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
   16512     case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
   16513     }
   16514   for (int pass = 1; pass <= last; pass++)
   16515     {
   16516       if (pass == 2)
   16517 	{
   16518 	  tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
   16519 			      make_node (BLOCK));
   16520 	  append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
   16521 	  *expr_p = make_node (OMP_PARALLEL);
   16522 	  TREE_TYPE (*expr_p) = void_type_node;
   16523 	  OMP_PARALLEL_BODY (*expr_p) = bind;
   16524 	  OMP_PARALLEL_COMBINED (*expr_p) = 1;
   16525 	  SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
   16526 	  tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
   16527 	  for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   16528 	    if (OMP_FOR_ORIG_DECLS (for_stmt)
   16529 		&& (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
   16530 		    == TREE_LIST))
   16531 	      {
   16532 		tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   16533 		if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
   16534 		  {
   16535 		    *pc = build_omp_clause (UNKNOWN_LOCATION,
   16536 					    OMP_CLAUSE_FIRSTPRIVATE);
   16537 		    OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
   16538 		    pc = &OMP_CLAUSE_CHAIN (*pc);
   16539 		  }
   16540 	      }
   16541 	}
   16542       tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
   16543       tree *pc = &OMP_FOR_CLAUSES (t);
   16544       TREE_TYPE (t) = void_type_node;
   16545       OMP_FOR_BODY (t) = *expr_p;
   16546       SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
   16547       for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
   16548 	switch (OMP_CLAUSE_CODE (c))
   16549 	  {
   16550 	  case OMP_CLAUSE_BIND:
   16551 	  case OMP_CLAUSE_ORDER:
   16552 	  case OMP_CLAUSE_COLLAPSE:
   16553 	    *pc = copy_node (c);
   16554 	    pc = &OMP_CLAUSE_CHAIN (*pc);
   16555 	    break;
   16556 	  case OMP_CLAUSE_PRIVATE:
   16557 	  case OMP_CLAUSE_FIRSTPRIVATE:
   16558 	    /* Only needed on innermost.  */
   16559 	    break;
   16560 	  case OMP_CLAUSE_LASTPRIVATE:
   16561 	    if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
   16562 	      {
   16563 		*pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   16564 					OMP_CLAUSE_FIRSTPRIVATE);
   16565 		OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
   16566 		lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
   16567 		pc = &OMP_CLAUSE_CHAIN (*pc);
   16568 	      }
   16569 	    *pc = copy_node (c);
   16570 	    OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
   16571 	    TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
   16572 	    if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
   16573 	      {
   16574 		if (pass != last)
   16575 		  OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
   16576 		else
   16577 		  lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
   16578 		OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
   16579 	      }
   16580 	    pc = &OMP_CLAUSE_CHAIN (*pc);
   16581 	    break;
   16582 	  case OMP_CLAUSE_REDUCTION:
   16583 	    *pc = copy_node (c);
   16584 	    OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
   16585 	    TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
   16586 	    if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
   16587 	      {
   16588 		auto_vec<tree> no_context_vars;
   16589 		int walk_subtrees = 0;
   16590 		note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
   16591 				      &walk_subtrees, &no_context_vars);
   16592 		if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c))
   16593 		  note_no_context_vars (&p, &walk_subtrees, &no_context_vars);
   16594 		walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c),
   16595 					      note_no_context_vars,
   16596 					      &no_context_vars);
   16597 		walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c),
   16598 					      note_no_context_vars,
   16599 					      &no_context_vars);
   16600 
   16601 		OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
   16602 		  = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
   16603 		if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
   16604 		  OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
   16605 		    = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
   16606 
   16607 		hash_map<tree, tree> decl_map;
   16608 		decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c));
   16609 		decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
   16610 			      OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc));
   16611 		if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
   16612 		  decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
   16613 				OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc));
   16614 
   16615 		copy_body_data id;
   16616 		memset (&id, 0, sizeof (id));
   16617 		id.src_fn = current_function_decl;
   16618 		id.dst_fn = current_function_decl;
   16619 		id.src_cfun = cfun;
   16620 		id.decl_map = &decl_map;
   16621 		id.copy_decl = copy_decl_no_change;
   16622 		id.transform_call_graph_edges = CB_CGE_DUPLICATE;
   16623 		id.transform_new_cfg = true;
   16624 		id.transform_return_to_modify = false;
   16625 		id.eh_lp_nr = 0;
   16626 		walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r,
   16627 			   &id, NULL);
   16628 		walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r,
   16629 			   &id, NULL);
   16630 
   16631 		for (tree d : no_context_vars)
   16632 		  {
   16633 		    DECL_CONTEXT (d) = NULL_TREE;
   16634 		    DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE;
   16635 		  }
   16636 	      }
   16637 	    else
   16638 	      {
   16639 		OMP_CLAUSE_REDUCTION_INIT (*pc)
   16640 		  = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
   16641 		OMP_CLAUSE_REDUCTION_MERGE (*pc)
   16642 		  = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
   16643 	      }
   16644 	    pc = &OMP_CLAUSE_CHAIN (*pc);
   16645 	    break;
   16646 	  default:
   16647 	    gcc_unreachable ();
   16648 	  }
   16649       *pc = NULL_TREE;
   16650       *expr_p = t;
   16651     }
   16652   return gimplify_expr (expr_p, pre_p, NULL, is_gimple_stmt, fb_none);
   16653 }
   16654 
   16655 
   16656 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
   16657    of OMP_TARGET's body.  */
   16658 
   16659 static tree
   16660 find_omp_teams (tree *tp, int *walk_subtrees, void *)
   16661 {
   16662   *walk_subtrees = 0;
   16663   switch (TREE_CODE (*tp))
   16664     {
   16665     case OMP_TEAMS:
   16666       return *tp;
   16667     case BIND_EXPR:
   16668     case STATEMENT_LIST:
   16669       *walk_subtrees = 1;
   16670       break;
   16671     default:
   16672       break;
   16673     }
   16674   return NULL_TREE;
   16675 }
   16676 
   16677 /* Helper function of optimize_target_teams, determine if the expression
   16678    can be computed safely before the target construct on the host.  */
   16679 
   16680 static tree
   16681 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
   16682 {
   16683   splay_tree_node n;
   16684 
   16685   if (TYPE_P (*tp))
   16686     {
   16687       *walk_subtrees = 0;
   16688       return NULL_TREE;
   16689     }
   16690   switch (TREE_CODE (*tp))
   16691     {
   16692     case VAR_DECL:
   16693     case PARM_DECL:
   16694     case RESULT_DECL:
   16695       *walk_subtrees = 0;
   16696       if (error_operand_p (*tp)
   16697 	  || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
   16698 	  || DECL_HAS_VALUE_EXPR_P (*tp)
   16699 	  || DECL_THREAD_LOCAL_P (*tp)
   16700 	  || TREE_SIDE_EFFECTS (*tp)
   16701 	  || TREE_THIS_VOLATILE (*tp))
   16702 	return *tp;
   16703       if (is_global_var (*tp)
   16704 	  && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
   16705 	      || lookup_attribute ("omp declare target link",
   16706 				   DECL_ATTRIBUTES (*tp))))
   16707 	return *tp;
   16708       if (VAR_P (*tp)
   16709 	  && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
   16710 	  && !is_global_var (*tp)
   16711 	  && decl_function_context (*tp) == current_function_decl)
   16712 	return *tp;
   16713       n = splay_tree_lookup (gimplify_omp_ctxp->variables,
   16714 			     (splay_tree_key) *tp);
   16715       if (n == NULL)
   16716 	{
   16717 	  if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
   16718 	    return NULL_TREE;
   16719 	  return *tp;
   16720 	}
   16721       else if (n->value & GOVD_LOCAL)
   16722 	return *tp;
   16723       else if (n->value & GOVD_FIRSTPRIVATE)
   16724 	return NULL_TREE;
   16725       else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
   16726 	       == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
   16727 	return NULL_TREE;
   16728       return *tp;
   16729     case INTEGER_CST:
   16730       if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
   16731 	return *tp;
   16732       return NULL_TREE;
   16733     case TARGET_EXPR:
   16734       if (TARGET_EXPR_INITIAL (*tp)
   16735 	  || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
   16736 	return *tp;
   16737       return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
   16738 				      walk_subtrees, NULL);
   16739     /* Allow some reasonable subset of integral arithmetics.  */
   16740     case PLUS_EXPR:
   16741     case MINUS_EXPR:
   16742     case MULT_EXPR:
   16743     case TRUNC_DIV_EXPR:
   16744     case CEIL_DIV_EXPR:
   16745     case FLOOR_DIV_EXPR:
   16746     case ROUND_DIV_EXPR:
   16747     case TRUNC_MOD_EXPR:
   16748     case CEIL_MOD_EXPR:
   16749     case FLOOR_MOD_EXPR:
   16750     case ROUND_MOD_EXPR:
   16751     case RDIV_EXPR:
   16752     case EXACT_DIV_EXPR:
   16753     case MIN_EXPR:
   16754     case MAX_EXPR:
   16755     case LSHIFT_EXPR:
   16756     case RSHIFT_EXPR:
   16757     case BIT_IOR_EXPR:
   16758     case BIT_XOR_EXPR:
   16759     case BIT_AND_EXPR:
   16760     case NEGATE_EXPR:
   16761     case ABS_EXPR:
   16762     case BIT_NOT_EXPR:
   16763     case NON_LVALUE_EXPR:
   16764     CASE_CONVERT:
   16765       if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
   16766 	return *tp;
   16767       return NULL_TREE;
   16768     /* And disallow anything else, except for comparisons.  */
   16769     default:
   16770       if (COMPARISON_CLASS_P (*tp))
   16771 	return NULL_TREE;
   16772       return *tp;
   16773     }
   16774 }
   16775 
   16776 /* Try to determine if the num_teams and/or thread_limit expressions
   16777    can have their values determined already before entering the
   16778    target construct.
   16779    INTEGER_CSTs trivially are,
   16780    integral decls that are firstprivate (explicitly or implicitly)
   16781    or explicitly map(always, to:) or map(always, tofrom:) on the target
   16782    region too, and expressions involving simple arithmetics on those
   16783    too, function calls are not ok, dereferencing something neither etc.
   16784    Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
   16785    EXPR based on what we find:
   16786    0 stands for clause not specified at all, use implementation default
   16787    -1 stands for value that can't be determined easily before entering
   16788       the target construct.
   16789    -2 means that no explicit teams construct was specified
   16790    If teams construct is not present at all, use 1 for num_teams
   16791    and 0 for thread_limit (only one team is involved, and the thread
   16792    limit is implementation defined.  */
   16793 
   16794 static void
   16795 optimize_target_teams (tree target, gimple_seq *pre_p)
   16796 {
   16797   tree body = OMP_BODY (target);
   16798   tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
   16799   tree num_teams_lower = NULL_TREE;
   16800   tree num_teams_upper = integer_zero_node;
   16801   tree thread_limit = integer_zero_node;
   16802   location_t num_teams_loc = EXPR_LOCATION (target);
   16803   location_t thread_limit_loc = EXPR_LOCATION (target);
   16804   tree c, *p, expr;
   16805   struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
   16806 
   16807   if (teams == NULL_TREE)
   16808     num_teams_upper = build_int_cst (integer_type_node, -2);
   16809   else
   16810     for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
   16811       {
   16812 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
   16813 	  {
   16814 	    p = &num_teams_upper;
   16815 	    num_teams_loc = OMP_CLAUSE_LOCATION (c);
   16816 	    if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))
   16817 	      {
   16818 		expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
   16819 		if (TREE_CODE (expr) == INTEGER_CST)
   16820 		  num_teams_lower = expr;
   16821 		else if (walk_tree (&expr, computable_teams_clause,
   16822 				    NULL, NULL))
   16823 		  num_teams_lower = integer_minus_one_node;
   16824 		else
   16825 		  {
   16826 		    num_teams_lower = expr;
   16827 		    gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
   16828 		    if (gimplify_expr (&num_teams_lower, pre_p, NULL,
   16829 				       is_gimple_val, fb_rvalue, false)
   16830 			== GS_ERROR)
   16831 		      {
   16832 			gimplify_omp_ctxp = target_ctx;
   16833 			num_teams_lower = integer_minus_one_node;
   16834 		      }
   16835 		    else
   16836 		      {
   16837 			gimplify_omp_ctxp = target_ctx;
   16838 			if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
   16839 			  OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
   16840 			    = num_teams_lower;
   16841 		      }
   16842 		  }
   16843 	      }
   16844 	  }
   16845 	else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
   16846 	  {
   16847 	    p = &thread_limit;
   16848 	    thread_limit_loc = OMP_CLAUSE_LOCATION (c);
   16849 	  }
   16850 	else
   16851 	  continue;
   16852 	expr = OMP_CLAUSE_OPERAND (c, 0);
   16853 	if (TREE_CODE (expr) == INTEGER_CST)
   16854 	  {
   16855 	    *p = expr;
   16856 	    continue;
   16857 	  }
   16858 	if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
   16859 	  {
   16860 	    *p = integer_minus_one_node;
   16861 	    continue;
   16862 	  }
   16863 	*p = expr;
   16864 	gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
   16865 	if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
   16866 	    == GS_ERROR)
   16867 	  {
   16868 	    gimplify_omp_ctxp = target_ctx;
   16869 	    *p = integer_minus_one_node;
   16870 	    continue;
   16871 	  }
   16872 	gimplify_omp_ctxp = target_ctx;
   16873 	if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
   16874 	  OMP_CLAUSE_OPERAND (c, 0) = *p;
   16875       }
   16876   if (!omp_find_clause (OMP_TARGET_CLAUSES (target), OMP_CLAUSE_THREAD_LIMIT))
   16877     {
   16878       c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
   16879       OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
   16880       OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
   16881       OMP_TARGET_CLAUSES (target) = c;
   16882     }
   16883   c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
   16884   OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper;
   16885   OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower;
   16886   OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
   16887   OMP_TARGET_CLAUSES (target) = c;
   16888 }
   16889 
   16890 /* Gimplify the gross structure of several OMP constructs.  */
   16891 
   16892 static void
   16893 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
   16894 {
   16895   tree expr = *expr_p;
   16896   gimple *stmt;
   16897   gimple_seq body = NULL;
   16898   enum omp_region_type ort;
   16899 
   16900   switch (TREE_CODE (expr))
   16901     {
   16902     case OMP_SECTIONS:
   16903     case OMP_SINGLE:
   16904       ort = ORT_WORKSHARE;
   16905       break;
   16906     case OMP_SCOPE:
   16907       ort = ORT_TASKGROUP;
   16908       break;
   16909     case OMP_TARGET:
   16910       ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
   16911       break;
   16912     case OACC_KERNELS:
   16913       ort = ORT_ACC_KERNELS;
   16914       break;
   16915     case OACC_PARALLEL:
   16916       ort = ORT_ACC_PARALLEL;
   16917       break;
   16918     case OACC_SERIAL:
   16919       ort = ORT_ACC_SERIAL;
   16920       break;
   16921     case OACC_DATA:
   16922       ort = ORT_ACC_DATA;
   16923       break;
   16924     case OMP_TARGET_DATA:
   16925       ort = ORT_TARGET_DATA;
   16926       break;
   16927     case OMP_TEAMS:
   16928       ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
   16929       if (gimplify_omp_ctxp == NULL
   16930 	  || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
   16931 	ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
   16932       break;
   16933     case OACC_HOST_DATA:
   16934       ort = ORT_ACC_HOST_DATA;
   16935       break;
   16936     default:
   16937       gcc_unreachable ();
   16938     }
   16939 
   16940   bool save_in_omp_construct = in_omp_construct;
   16941   if ((ort & ORT_ACC) == 0)
   16942     in_omp_construct = false;
   16943   gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
   16944 			     TREE_CODE (expr));
   16945   if (TREE_CODE (expr) == OMP_TARGET)
   16946     optimize_target_teams (expr, pre_p);
   16947   if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
   16948       || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
   16949     {
   16950       push_gimplify_context ();
   16951       gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
   16952       if (gimple_code (g) == GIMPLE_BIND)
   16953 	pop_gimplify_context (g);
   16954       else
   16955 	pop_gimplify_context (NULL);
   16956       if ((ort & ORT_TARGET_DATA) != 0)
   16957 	{
   16958 	  enum built_in_function end_ix;
   16959 	  switch (TREE_CODE (expr))
   16960 	    {
   16961 	    case OACC_DATA:
   16962 	    case OACC_HOST_DATA:
   16963 	      end_ix = BUILT_IN_GOACC_DATA_END;
   16964 	      break;
   16965 	    case OMP_TARGET_DATA:
   16966 	      end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
   16967 	      break;
   16968 	    default:
   16969 	      gcc_unreachable ();
   16970 	    }
   16971 	  tree fn = builtin_decl_explicit (end_ix);
   16972 	  g = gimple_build_call (fn, 0);
   16973 	  gimple_seq cleanup = NULL;
   16974 	  gimple_seq_add_stmt (&cleanup, g);
   16975 	  g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
   16976 	  body = NULL;
   16977 	  gimple_seq_add_stmt (&body, g);
   16978 	}
   16979     }
   16980   else
   16981     gimplify_and_add (OMP_BODY (expr), &body);
   16982   gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
   16983 			       TREE_CODE (expr));
   16984   in_omp_construct = save_in_omp_construct;
   16985 
   16986   switch (TREE_CODE (expr))
   16987     {
   16988     case OACC_DATA:
   16989       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
   16990 				      OMP_CLAUSES (expr));
   16991       break;
   16992     case OACC_HOST_DATA:
   16993       if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
   16994 	{
   16995 	  for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   16996 	    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
   16997 	      OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
   16998 	}
   16999 
   17000       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
   17001 				      OMP_CLAUSES (expr));
   17002       break;
   17003     case OACC_KERNELS:
   17004       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
   17005 				      OMP_CLAUSES (expr));
   17006       break;
   17007     case OACC_PARALLEL:
   17008       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
   17009 				      OMP_CLAUSES (expr));
   17010       break;
   17011     case OACC_SERIAL:
   17012       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
   17013 				      OMP_CLAUSES (expr));
   17014       break;
   17015     case OMP_SECTIONS:
   17016       stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
   17017       break;
   17018     case OMP_SINGLE:
   17019       stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
   17020       break;
   17021     case OMP_SCOPE:
   17022       stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr));
   17023       break;
   17024     case OMP_TARGET:
   17025       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
   17026 				      OMP_CLAUSES (expr));
   17027       break;
   17028     case OMP_TARGET_DATA:
   17029       /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
   17030 	 to be evaluated before the use_device_{ptr,addr} clauses if they
   17031 	 refer to the same variables.  */
   17032       {
   17033 	tree use_device_clauses;
   17034 	tree *pc, *uc = &use_device_clauses;
   17035 	for (pc = &OMP_CLAUSES (expr); *pc; )
   17036 	  if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
   17037 	      || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
   17038 	    {
   17039 	      *uc = *pc;
   17040 	      *pc = OMP_CLAUSE_CHAIN (*pc);
   17041 	      uc = &OMP_CLAUSE_CHAIN (*uc);
   17042 	    }
   17043 	  else
   17044 	    pc = &OMP_CLAUSE_CHAIN (*pc);
   17045 	*uc = NULL_TREE;
   17046 	*pc = use_device_clauses;
   17047 	stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
   17048 					OMP_CLAUSES (expr));
   17049       }
   17050       break;
   17051     case OMP_TEAMS:
   17052       stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
   17053       if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
   17054 	gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
   17055       break;
   17056     default:
   17057       gcc_unreachable ();
   17058     }
   17059 
   17060   gimplify_seq_add_stmt (pre_p, stmt);
   17061   *expr_p = NULL_TREE;
   17062 }
   17063 
   17064 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
   17065    target update constructs.  */
   17066 
   17067 static void
   17068 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
   17069 {
   17070   tree expr = *expr_p;
   17071   int kind;
   17072   gomp_target *stmt;
   17073   enum omp_region_type ort = ORT_WORKSHARE;
   17074 
   17075   switch (TREE_CODE (expr))
   17076     {
   17077     case OACC_ENTER_DATA:
   17078       kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA;
   17079       ort = ORT_ACC;
   17080       break;
   17081     case OACC_EXIT_DATA:
   17082       kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA;
   17083       ort = ORT_ACC;
   17084       break;
   17085     case OACC_UPDATE:
   17086       kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
   17087       ort = ORT_ACC;
   17088       break;
   17089     case OMP_TARGET_UPDATE:
   17090       kind = GF_OMP_TARGET_KIND_UPDATE;
   17091       break;
   17092     case OMP_TARGET_ENTER_DATA:
   17093       kind = GF_OMP_TARGET_KIND_ENTER_DATA;
   17094       break;
   17095     case OMP_TARGET_EXIT_DATA:
   17096       kind = GF_OMP_TARGET_KIND_EXIT_DATA;
   17097       break;
   17098     default:
   17099       gcc_unreachable ();
   17100     }
   17101   gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
   17102 			     ort, TREE_CODE (expr));
   17103   gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
   17104 			       TREE_CODE (expr));
   17105   if (TREE_CODE (expr) == OACC_UPDATE
   17106       && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
   17107 			  OMP_CLAUSE_IF_PRESENT))
   17108     {
   17109       /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
   17110 	 clause.  */
   17111       for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   17112 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
   17113 	  switch (OMP_CLAUSE_MAP_KIND (c))
   17114 	    {
   17115 	    case GOMP_MAP_FORCE_TO:
   17116 	      OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
   17117 	      break;
   17118 	    case GOMP_MAP_FORCE_FROM:
   17119 	      OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
   17120 	      break;
   17121 	    default:
   17122 	      break;
   17123 	    }
   17124     }
   17125   else if (TREE_CODE (expr) == OACC_EXIT_DATA
   17126 	   && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
   17127 			       OMP_CLAUSE_FINALIZE))
   17128     {
   17129       /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
   17130 	 semantics.  */
   17131       bool have_clause = false;
   17132       for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   17133 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
   17134 	  switch (OMP_CLAUSE_MAP_KIND (c))
   17135 	    {
   17136 	    case GOMP_MAP_FROM:
   17137 	      OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
   17138 	      have_clause = true;
   17139 	      break;
   17140 	    case GOMP_MAP_RELEASE:
   17141 	      OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
   17142 	      have_clause = true;
   17143 	      break;
   17144 	    case GOMP_MAP_TO_PSET:
   17145 	      /* Fortran arrays with descriptors must map that descriptor when
   17146 		 doing standalone "attach" operations (in OpenACC).  In that
   17147 		 case GOMP_MAP_TO_PSET appears by itself with no preceding
   17148 		 clause (see trans-openmp.cc:gfc_trans_omp_clauses).  */
   17149 	      break;
   17150 	    case GOMP_MAP_POINTER:
   17151 	      /* TODO PR92929: we may see these here, but they'll always follow
   17152 		 one of the clauses above, and will be handled by libgomp as
   17153 		 one group, so no handling required here.  */
   17154 	      gcc_assert (have_clause);
   17155 	      break;
   17156 	    case GOMP_MAP_DETACH:
   17157 	      OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
   17158 	      have_clause = false;
   17159 	      break;
   17160 	    case GOMP_MAP_STRUCT:
   17161 	    case GOMP_MAP_STRUCT_UNORD:
   17162 	      have_clause = false;
   17163 	      break;
   17164 	    default:
   17165 	      gcc_unreachable ();
   17166 	    }
   17167     }
   17168   stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
   17169 
   17170   gimplify_seq_add_stmt (pre_p, stmt);
   17171   *expr_p = NULL_TREE;
   17172 }
   17173 
   17174 /* A subroutine of gimplify_omp_atomic.  The front end is supposed to have
   17175    stabilized the lhs of the atomic operation as *ADDR.  Return true if
   17176    EXPR is this stabilized form.  */
   17177 
   17178 static bool
   17179 goa_lhs_expr_p (tree expr, tree addr)
   17180 {
   17181   /* Also include casts to other type variants.  The C front end is fond
   17182      of adding these for e.g. volatile variables.  This is like
   17183      STRIP_TYPE_NOPS but includes the main variant lookup.  */
   17184   STRIP_USELESS_TYPE_CONVERSION (expr);
   17185 
   17186   if (INDIRECT_REF_P (expr))
   17187     {
   17188       expr = TREE_OPERAND (expr, 0);
   17189       while (expr != addr
   17190 	     && (CONVERT_EXPR_P (expr)
   17191 		 || TREE_CODE (expr) == NON_LVALUE_EXPR)
   17192 	     && TREE_CODE (expr) == TREE_CODE (addr)
   17193 	     && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
   17194 	{
   17195 	  expr = TREE_OPERAND (expr, 0);
   17196 	  addr = TREE_OPERAND (addr, 0);
   17197 	}
   17198       if (expr == addr)
   17199 	return true;
   17200       return (TREE_CODE (addr) == ADDR_EXPR
   17201 	      && TREE_CODE (expr) == ADDR_EXPR
   17202 	      && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
   17203     }
   17204   if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
   17205     return true;
   17206   return false;
   17207 }
   17208 
   17209 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR.  If an
   17210    expression does not involve the lhs, evaluate it into a temporary.
   17211    Return 1 if the lhs appeared as a subexpression, 0 if it did not,
   17212    or -1 if an error was encountered.  */
   17213 
   17214 static int
   17215 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
   17216 		    tree lhs_var, tree &target_expr, bool rhs, int depth)
   17217 {
   17218   tree expr = *expr_p;
   17219   int saw_lhs = 0;
   17220 
   17221   if (goa_lhs_expr_p (expr, lhs_addr))
   17222     {
   17223       if (pre_p)
   17224 	*expr_p = lhs_var;
   17225       return 1;
   17226     }
   17227   if (is_gimple_val (expr))
   17228     return 0;
   17229 
   17230   /* Maximum depth of lhs in expression is for the
   17231      __builtin_clear_padding (...), __builtin_clear_padding (...),
   17232      __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs;  */
   17233   if (++depth > 7)
   17234     goto finish;
   17235 
   17236   switch (TREE_CODE_CLASS (TREE_CODE (expr)))
   17237     {
   17238     case tcc_binary:
   17239     case tcc_comparison:
   17240       saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
   17241 				     lhs_var, target_expr, true, depth);
   17242       /* FALLTHRU */
   17243     case tcc_unary:
   17244       saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
   17245 				     lhs_var, target_expr, true, depth);
   17246       break;
   17247     case tcc_expression:
   17248       switch (TREE_CODE (expr))
   17249 	{
   17250 	case TRUTH_ANDIF_EXPR:
   17251 	case TRUTH_ORIF_EXPR:
   17252 	case TRUTH_AND_EXPR:
   17253 	case TRUTH_OR_EXPR:
   17254 	case TRUTH_XOR_EXPR:
   17255 	case BIT_INSERT_EXPR:
   17256 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
   17257 					 lhs_addr, lhs_var, target_expr, true,
   17258 					 depth);
   17259 	  /* FALLTHRU */
   17260 	case TRUTH_NOT_EXPR:
   17261 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   17262 					 lhs_addr, lhs_var, target_expr, true,
   17263 					 depth);
   17264 	  break;
   17265 	case MODIFY_EXPR:
   17266 	  if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
   17267 					    target_expr, true, depth))
   17268 	    break;
   17269 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
   17270 					 lhs_addr, lhs_var, target_expr, true,
   17271 					 depth);
   17272 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   17273 					 lhs_addr, lhs_var, target_expr, false,
   17274 					 depth);
   17275 	  break;
   17276 	  /* FALLTHRU */
   17277 	case ADDR_EXPR:
   17278 	  if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
   17279 					    target_expr, true, depth))
   17280 	    break;
   17281 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   17282 					 lhs_addr, lhs_var, target_expr, false,
   17283 					 depth);
   17284 	  break;
   17285 	case COMPOUND_EXPR:
   17286 	  /* Break out any preevaluations from cp_build_modify_expr.  */
   17287 	  for (; TREE_CODE (expr) == COMPOUND_EXPR;
   17288 	       expr = TREE_OPERAND (expr, 1))
   17289 	    {
   17290 	      /* Special-case __builtin_clear_padding call before
   17291 		 __builtin_memcmp.  */
   17292 	      if (TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR)
   17293 		{
   17294 		  tree fndecl = get_callee_fndecl (TREE_OPERAND (expr, 0));
   17295 		  if (fndecl
   17296 		      && fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
   17297 		      && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
   17298 		      && (!pre_p
   17299 			  || goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL,
   17300 						 lhs_addr, lhs_var,
   17301 						 target_expr, true, depth)))
   17302 		    {
   17303 		      if (pre_p)
   17304 			*expr_p = expr;
   17305 		      saw_lhs = goa_stabilize_expr (&TREE_OPERAND (expr, 0),
   17306 						    pre_p, lhs_addr, lhs_var,
   17307 						    target_expr, true, depth);
   17308 		      saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1),
   17309 						     pre_p, lhs_addr, lhs_var,
   17310 						     target_expr, rhs, depth);
   17311 		      return saw_lhs;
   17312 		    }
   17313 		}
   17314 
   17315 	      if (pre_p)
   17316 		gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
   17317 	    }
   17318 	  if (!pre_p)
   17319 	    return goa_stabilize_expr (&expr, pre_p, lhs_addr, lhs_var,
   17320 				       target_expr, rhs, depth);
   17321 	  *expr_p = expr;
   17322 	  return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var,
   17323 				     target_expr, rhs, depth);
   17324 	case COND_EXPR:
   17325 	  if (!goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, lhs_addr,
   17326 				   lhs_var, target_expr, true, depth))
   17327 	    break;
   17328 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   17329 					 lhs_addr, lhs_var, target_expr, true,
   17330 					 depth);
   17331 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
   17332 					 lhs_addr, lhs_var, target_expr, true,
   17333 					 depth);
   17334 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 2), pre_p,
   17335 					 lhs_addr, lhs_var, target_expr, true,
   17336 					 depth);
   17337 	  break;
   17338 	case TARGET_EXPR:
   17339 	  if (TARGET_EXPR_INITIAL (expr))
   17340 	    {
   17341 	      if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr,
   17342 						lhs_var, target_expr, true,
   17343 						depth))
   17344 		break;
   17345 	      if (expr == target_expr)
   17346 		saw_lhs = 1;
   17347 	      else
   17348 		{
   17349 		  saw_lhs = goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr),
   17350 						pre_p, lhs_addr, lhs_var,
   17351 						target_expr, true, depth);
   17352 		  if (saw_lhs && target_expr == NULL_TREE && pre_p)
   17353 		    target_expr = expr;
   17354 		}
   17355 	    }
   17356 	  break;
   17357 	default:
   17358 	  break;
   17359 	}
   17360       break;
   17361     case tcc_reference:
   17362       if (TREE_CODE (expr) == BIT_FIELD_REF
   17363 	  || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
   17364 	saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   17365 				       lhs_addr, lhs_var, target_expr, true,
   17366 				       depth);
   17367       break;
   17368     case tcc_vl_exp:
   17369       if (TREE_CODE (expr) == CALL_EXPR)
   17370 	{
   17371 	  if (tree fndecl = get_callee_fndecl (expr))
   17372 	    if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING,
   17373 					   BUILT_IN_MEMCMP))
   17374 	      {
   17375 		int nargs = call_expr_nargs (expr);
   17376 		for (int i = 0; i < nargs; i++)
   17377 		  saw_lhs |= goa_stabilize_expr (&CALL_EXPR_ARG (expr, i),
   17378 						 pre_p, lhs_addr, lhs_var,
   17379 						 target_expr, true, depth);
   17380 	      }
   17381 	}
   17382       break;
   17383     default:
   17384       break;
   17385     }
   17386 
   17387  finish:
   17388   if (saw_lhs == 0 && pre_p)
   17389     {
   17390       enum gimplify_status gs;
   17391       if (TREE_CODE (expr) == CALL_EXPR && VOID_TYPE_P (TREE_TYPE (expr)))
   17392 	{
   17393 	  gimplify_stmt (&expr, pre_p);
   17394 	  return saw_lhs;
   17395 	}
   17396       else if (rhs)
   17397 	gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
   17398       else
   17399 	gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_lvalue, fb_lvalue);
   17400       if (gs != GS_ALL_DONE)
   17401 	saw_lhs = -1;
   17402     }
   17403 
   17404   return saw_lhs;
   17405 }
   17406 
   17407 /* Gimplify an OMP_ATOMIC statement.  */
   17408 
   17409 static enum gimplify_status
   17410 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
   17411 {
   17412   tree addr = TREE_OPERAND (*expr_p, 0);
   17413   tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
   17414 	     ? NULL : TREE_OPERAND (*expr_p, 1);
   17415   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
   17416   tree tmp_load;
   17417   gomp_atomic_load *loadstmt;
   17418   gomp_atomic_store *storestmt;
   17419   tree target_expr = NULL_TREE;
   17420 
   17421   tmp_load = create_tmp_reg (type);
   17422   if (rhs
   17423       && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load, target_expr,
   17424 			     true, 0) < 0)
   17425     return GS_ERROR;
   17426 
   17427   if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
   17428       != GS_ALL_DONE)
   17429     return GS_ERROR;
   17430 
   17431   loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
   17432 					   OMP_ATOMIC_MEMORY_ORDER (*expr_p));
   17433   gimplify_seq_add_stmt (pre_p, loadstmt);
   17434   if (rhs)
   17435     {
   17436       /* BIT_INSERT_EXPR is not valid for non-integral bitfield
   17437 	 representatives.  Use BIT_FIELD_REF on the lhs instead.  */
   17438       tree rhsarg = rhs;
   17439       if (TREE_CODE (rhs) == COND_EXPR)
   17440 	rhsarg = TREE_OPERAND (rhs, 1);
   17441       if (TREE_CODE (rhsarg) == BIT_INSERT_EXPR
   17442 	  && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
   17443 	{
   17444 	  tree bitpos = TREE_OPERAND (rhsarg, 2);
   17445 	  tree op1 = TREE_OPERAND (rhsarg, 1);
   17446 	  tree bitsize;
   17447 	  tree tmp_store = tmp_load;
   17448 	  if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
   17449 	    tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
   17450 	  if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
   17451 	    bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
   17452 	  else
   17453 	    bitsize = TYPE_SIZE (TREE_TYPE (op1));
   17454 	  gcc_assert (TREE_OPERAND (rhsarg, 0) == tmp_load);
   17455 	  tree t = build2_loc (EXPR_LOCATION (rhsarg),
   17456 			       MODIFY_EXPR, void_type_node,
   17457 			       build3_loc (EXPR_LOCATION (rhsarg),
   17458 					   BIT_FIELD_REF, TREE_TYPE (op1),
   17459 					   tmp_store, bitsize, bitpos), op1);
   17460 	  if (TREE_CODE (rhs) == COND_EXPR)
   17461 	    t = build3_loc (EXPR_LOCATION (rhs), COND_EXPR, void_type_node,
   17462 			    TREE_OPERAND (rhs, 0), t, void_node);
   17463 	  gimplify_and_add (t, pre_p);
   17464 	  rhs = tmp_store;
   17465 	}
   17466       bool save_allow_rhs_cond_expr = gimplify_ctxp->allow_rhs_cond_expr;
   17467       if (TREE_CODE (rhs) == COND_EXPR)
   17468 	gimplify_ctxp->allow_rhs_cond_expr = true;
   17469       enum gimplify_status gs = gimplify_expr (&rhs, pre_p, NULL,
   17470 					       is_gimple_val, fb_rvalue);
   17471       gimplify_ctxp->allow_rhs_cond_expr = save_allow_rhs_cond_expr;
   17472       if (gs != GS_ALL_DONE)
   17473 	return GS_ERROR;
   17474     }
   17475 
   17476   if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
   17477     rhs = tmp_load;
   17478   storestmt
   17479     = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
   17480   if (TREE_CODE (*expr_p) != OMP_ATOMIC_READ && OMP_ATOMIC_WEAK (*expr_p))
   17481     {
   17482       gimple_omp_atomic_set_weak (loadstmt);
   17483       gimple_omp_atomic_set_weak (storestmt);
   17484     }
   17485   gimplify_seq_add_stmt (pre_p, storestmt);
   17486   switch (TREE_CODE (*expr_p))
   17487     {
   17488     case OMP_ATOMIC_READ:
   17489     case OMP_ATOMIC_CAPTURE_OLD:
   17490       *expr_p = tmp_load;
   17491       gimple_omp_atomic_set_need_value (loadstmt);
   17492       break;
   17493     case OMP_ATOMIC_CAPTURE_NEW:
   17494       *expr_p = rhs;
   17495       gimple_omp_atomic_set_need_value (storestmt);
   17496       break;
   17497     default:
   17498       *expr_p = NULL;
   17499       break;
   17500     }
   17501 
   17502   return GS_ALL_DONE;
   17503 }
   17504 
   17505 /* Gimplify a TRANSACTION_EXPR.  This involves gimplification of the
   17506    body, and adding some EH bits.  */
   17507 
   17508 static enum gimplify_status
   17509 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
   17510 {
   17511   tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
   17512   gimple *body_stmt;
   17513   gtransaction *trans_stmt;
   17514   gimple_seq body = NULL;
   17515   int subcode = 0;
   17516 
   17517   /* Wrap the transaction body in a BIND_EXPR so we have a context
   17518      where to put decls for OMP.  */
   17519   if (TREE_CODE (tbody) != BIND_EXPR)
   17520     {
   17521       tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
   17522       TREE_SIDE_EFFECTS (bind) = 1;
   17523       SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
   17524       TRANSACTION_EXPR_BODY (expr) = bind;
   17525     }
   17526 
   17527   push_gimplify_context ();
   17528   temp = voidify_wrapper_expr (*expr_p, NULL);
   17529 
   17530   body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
   17531   pop_gimplify_context (body_stmt);
   17532 
   17533   trans_stmt = gimple_build_transaction (body);
   17534   if (TRANSACTION_EXPR_OUTER (expr))
   17535     subcode = GTMA_IS_OUTER;
   17536   else if (TRANSACTION_EXPR_RELAXED (expr))
   17537     subcode = GTMA_IS_RELAXED;
   17538   gimple_transaction_set_subcode (trans_stmt, subcode);
   17539 
   17540   gimplify_seq_add_stmt (pre_p, trans_stmt);
   17541 
   17542   if (temp)
   17543     {
   17544       *expr_p = temp;
   17545       return GS_OK;
   17546     }
   17547 
   17548   *expr_p = NULL_TREE;
   17549   return GS_ALL_DONE;
   17550 }
   17551 
   17552 /* Gimplify an OMP_ORDERED construct.  EXPR is the tree version.  BODY
   17553    is the OMP_BODY of the original EXPR (which has already been
   17554    gimplified so it's not present in the EXPR).
   17555 
   17556    Return the gimplified GIMPLE_OMP_ORDERED tuple.  */
   17557 
   17558 static gimple *
   17559 gimplify_omp_ordered (tree expr, gimple_seq body)
   17560 {
   17561   tree c, decls;
   17562   int failures = 0;
   17563   unsigned int i;
   17564   tree source_c = NULL_TREE;
   17565   tree sink_c = NULL_TREE;
   17566 
   17567   if (gimplify_omp_ctxp)
   17568     {
   17569       for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   17570 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
   17571 	    && gimplify_omp_ctxp->loop_iter_var.is_empty ())
   17572 	  {
   17573 	    error_at (OMP_CLAUSE_LOCATION (c),
   17574 		      "%<ordered%> construct with %qs clause must be "
   17575 		      "closely nested inside a loop with %<ordered%> clause",
   17576 		      OMP_CLAUSE_DOACROSS_DEPEND (c) ? "depend" : "doacross");
   17577 	    failures++;
   17578 	  }
   17579 	else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
   17580 		 && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
   17581 	  {
   17582 	    bool fail = false;
   17583 	    sink_c = c;
   17584 	    if (OMP_CLAUSE_DECL (c) == NULL_TREE)
   17585 	      continue;  /* omp_cur_iteration - 1 */
   17586 	    for (decls = OMP_CLAUSE_DECL (c), i = 0;
   17587 		 decls && TREE_CODE (decls) == TREE_LIST;
   17588 		 decls = TREE_CHAIN (decls), ++i)
   17589 	      if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
   17590 		continue;
   17591 	      else if (TREE_VALUE (decls)
   17592 		       != gimplify_omp_ctxp->loop_iter_var[2 * i])
   17593 		{
   17594 		  error_at (OMP_CLAUSE_LOCATION (c),
   17595 			    "variable %qE is not an iteration "
   17596 			    "of outermost loop %d, expected %qE",
   17597 			    TREE_VALUE (decls), i + 1,
   17598 			    gimplify_omp_ctxp->loop_iter_var[2 * i]);
   17599 		  fail = true;
   17600 		  failures++;
   17601 		}
   17602 	      else
   17603 		TREE_VALUE (decls)
   17604 		  = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
   17605 	    if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
   17606 	      {
   17607 		error_at (OMP_CLAUSE_LOCATION (c),
   17608 			  "number of variables in %qs clause with "
   17609 			  "%<sink%> modifier does not match number of "
   17610 			  "iteration variables",
   17611 			  OMP_CLAUSE_DOACROSS_DEPEND (c)
   17612 			  ? "depend" : "doacross");
   17613 		failures++;
   17614 	      }
   17615 	  }
   17616 	else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
   17617 		 && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SOURCE)
   17618 	  {
   17619 	    if (source_c)
   17620 	      {
   17621 		error_at (OMP_CLAUSE_LOCATION (c),
   17622 			  "more than one %qs clause with %<source%> "
   17623 			  "modifier on an %<ordered%> construct",
   17624 			  OMP_CLAUSE_DOACROSS_DEPEND (source_c)
   17625 			  ? "depend" : "doacross");
   17626 		failures++;
   17627 	      }
   17628 	    else
   17629 	      source_c = c;
   17630 	  }
   17631     }
   17632   if (source_c && sink_c)
   17633     {
   17634       error_at (OMP_CLAUSE_LOCATION (source_c),
   17635 		"%qs clause with %<source%> modifier specified "
   17636 		"together with %qs clauses with %<sink%> modifier "
   17637 		"on the same construct",
   17638 		OMP_CLAUSE_DOACROSS_DEPEND (source_c) ? "depend" : "doacross",
   17639 		OMP_CLAUSE_DOACROSS_DEPEND (sink_c) ? "depend" : "doacross");
   17640       failures++;
   17641     }
   17642 
   17643   if (failures)
   17644     return gimple_build_nop ();
   17645   return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
   17646 }
   17647 
   17648 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE.  If the
   17649    expression produces a value to be used as an operand inside a GIMPLE
   17650    statement, the value will be stored back in *EXPR_P.  This value will
   17651    be a tree of class tcc_declaration, tcc_constant, tcc_reference or
   17652    an SSA_NAME.  The corresponding sequence of GIMPLE statements is
   17653    emitted in PRE_P and POST_P.
   17654 
   17655    Additionally, this process may overwrite parts of the input
   17656    expression during gimplification.  Ideally, it should be
   17657    possible to do non-destructive gimplification.
   17658 
   17659    EXPR_P points to the GENERIC expression to convert to GIMPLE.  If
   17660       the expression needs to evaluate to a value to be used as
   17661       an operand in a GIMPLE statement, this value will be stored in
   17662       *EXPR_P on exit.  This happens when the caller specifies one
   17663       of fb_lvalue or fb_rvalue fallback flags.
   17664 
   17665    PRE_P will contain the sequence of GIMPLE statements corresponding
   17666        to the evaluation of EXPR and all the side-effects that must
   17667        be executed before the main expression.  On exit, the last
   17668        statement of PRE_P is the core statement being gimplified.  For
   17669        instance, when gimplifying 'if (++a)' the last statement in
   17670        PRE_P will be 'if (t.1)' where t.1 is the result of
   17671        pre-incrementing 'a'.
   17672 
   17673    POST_P will contain the sequence of GIMPLE statements corresponding
   17674        to the evaluation of all the side-effects that must be executed
   17675        after the main expression.  If this is NULL, the post
   17676        side-effects are stored at the end of PRE_P.
   17677 
   17678        The reason why the output is split in two is to handle post
   17679        side-effects explicitly.  In some cases, an expression may have
   17680        inner and outer post side-effects which need to be emitted in
   17681        an order different from the one given by the recursive
   17682        traversal.  For instance, for the expression (*p--)++ the post
   17683        side-effects of '--' must actually occur *after* the post
   17684        side-effects of '++'.  However, gimplification will first visit
   17685        the inner expression, so if a separate POST sequence was not
   17686        used, the resulting sequence would be:
   17687 
   17688        	    1	t.1 = *p
   17689        	    2	p = p - 1
   17690        	    3	t.2 = t.1 + 1
   17691        	    4	*p = t.2
   17692 
   17693        However, the post-decrement operation in line #2 must not be
   17694        evaluated until after the store to *p at line #4, so the
   17695        correct sequence should be:
   17696 
   17697        	    1	t.1 = *p
   17698        	    2	t.2 = t.1 + 1
   17699        	    3	*p = t.2
   17700        	    4	p = p - 1
   17701 
   17702        So, by specifying a separate post queue, it is possible
   17703        to emit the post side-effects in the correct order.
   17704        If POST_P is NULL, an internal queue will be used.  Before
   17705        returning to the caller, the sequence POST_P is appended to
   17706        the main output sequence PRE_P.
   17707 
   17708    GIMPLE_TEST_F points to a function that takes a tree T and
   17709        returns nonzero if T is in the GIMPLE form requested by the
   17710        caller.  The GIMPLE predicates are in gimple.cc.
   17711 
   17712    FALLBACK tells the function what sort of a temporary we want if
   17713        gimplification cannot produce an expression that complies with
   17714        GIMPLE_TEST_F.
   17715 
   17716        fb_none means that no temporary should be generated
   17717        fb_rvalue means that an rvalue is OK to generate
   17718        fb_lvalue means that an lvalue is OK to generate
   17719        fb_either means that either is OK, but an lvalue is preferable.
   17720        fb_mayfail means that gimplification may fail (in which case
   17721        GS_ERROR will be returned)
   17722 
   17723    The return value is either GS_ERROR or GS_ALL_DONE, since this
   17724    function iterates until EXPR is completely gimplified or an error
   17725    occurs.  */
   17726 
   17727 enum gimplify_status
   17728 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   17729 	       bool (*gimple_test_f) (tree), fallback_t fallback)
   17730 {
   17731   tree tmp;
   17732   gimple_seq internal_pre = NULL;
   17733   gimple_seq internal_post = NULL;
   17734   tree save_expr;
   17735   bool is_statement;
   17736   location_t saved_location;
   17737   enum gimplify_status ret;
   17738   gimple_stmt_iterator pre_last_gsi, post_last_gsi;
   17739   tree label;
   17740 
   17741   save_expr = *expr_p;
   17742   if (save_expr == NULL_TREE)
   17743     return GS_ALL_DONE;
   17744 
   17745   /* If we are gimplifying a top-level statement, PRE_P must be valid.  */
   17746   is_statement = gimple_test_f == is_gimple_stmt;
   17747   if (is_statement)
   17748     gcc_assert (pre_p);
   17749 
   17750   /* Consistency checks.  */
   17751   if (gimple_test_f == is_gimple_reg)
   17752     gcc_assert (fallback & (fb_rvalue | fb_lvalue));
   17753   else if (gimple_test_f == is_gimple_val
   17754            || gimple_test_f == is_gimple_call_addr
   17755 	   || gimple_test_f == is_gimple_condexpr_for_cond
   17756            || gimple_test_f == is_gimple_mem_rhs
   17757            || gimple_test_f == is_gimple_mem_rhs_or_call
   17758            || gimple_test_f == is_gimple_reg_rhs
   17759            || gimple_test_f == is_gimple_reg_rhs_or_call
   17760            || gimple_test_f == is_gimple_asm_val
   17761 	   || gimple_test_f == is_gimple_mem_ref_addr)
   17762     gcc_assert (fallback & fb_rvalue);
   17763   else if (gimple_test_f == is_gimple_min_lval
   17764 	   || gimple_test_f == is_gimple_lvalue)
   17765     gcc_assert (fallback & fb_lvalue);
   17766   else if (gimple_test_f == is_gimple_addressable)
   17767     gcc_assert (fallback & fb_either);
   17768   else if (gimple_test_f == is_gimple_stmt)
   17769     gcc_assert (fallback == fb_none);
   17770   else
   17771     {
   17772       /* We should have recognized the GIMPLE_TEST_F predicate to
   17773 	 know what kind of fallback to use in case a temporary is
   17774 	 needed to hold the value or address of *EXPR_P.  */
   17775       gcc_unreachable ();
   17776     }
   17777 
   17778   /* We used to check the predicate here and return immediately if it
   17779      succeeds.  This is wrong; the design is for gimplification to be
   17780      idempotent, and for the predicates to only test for valid forms, not
   17781      whether they are fully simplified.  */
   17782   if (pre_p == NULL)
   17783     pre_p = &internal_pre;
   17784 
   17785   if (post_p == NULL)
   17786     post_p = &internal_post;
   17787 
   17788   /* Remember the last statements added to PRE_P and POST_P.  Every
   17789      new statement added by the gimplification helpers needs to be
   17790      annotated with location information.  To centralize the
   17791      responsibility, we remember the last statement that had been
   17792      added to both queues before gimplifying *EXPR_P.  If
   17793      gimplification produces new statements in PRE_P and POST_P, those
   17794      statements will be annotated with the same location information
   17795      as *EXPR_P.  */
   17796   pre_last_gsi = gsi_last (*pre_p);
   17797   post_last_gsi = gsi_last (*post_p);
   17798 
   17799   saved_location = input_location;
   17800   if (save_expr != error_mark_node
   17801       && EXPR_HAS_LOCATION (*expr_p))
   17802     input_location = EXPR_LOCATION (*expr_p);
   17803 
   17804   /* Loop over the specific gimplifiers until the toplevel node
   17805      remains the same.  */
   17806   do
   17807     {
   17808       /* Strip away as many useless type conversions as possible
   17809 	 at the toplevel.  */
   17810       STRIP_USELESS_TYPE_CONVERSION (*expr_p);
   17811 
   17812       /* Remember the expr.  */
   17813       save_expr = *expr_p;
   17814 
   17815       /* Die, die, die, my darling.  */
   17816       if (error_operand_p (save_expr))
   17817 	{
   17818 	  ret = GS_ERROR;
   17819 	  break;
   17820 	}
   17821 
   17822       /* Do any language-specific gimplification.  */
   17823       ret = ((enum gimplify_status)
   17824 	     lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
   17825       if (ret == GS_OK)
   17826 	{
   17827 	  if (*expr_p == NULL_TREE)
   17828 	    break;
   17829 	  if (*expr_p != save_expr)
   17830 	    continue;
   17831 	}
   17832       else if (ret != GS_UNHANDLED)
   17833 	break;
   17834 
   17835       /* Make sure that all the cases set 'ret' appropriately.  */
   17836       ret = GS_UNHANDLED;
   17837       switch (TREE_CODE (*expr_p))
   17838 	{
   17839 	  /* First deal with the special cases.  */
   17840 
   17841 	case POSTINCREMENT_EXPR:
   17842 	case POSTDECREMENT_EXPR:
   17843 	case PREINCREMENT_EXPR:
   17844 	case PREDECREMENT_EXPR:
   17845 	  ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
   17846 					fallback != fb_none,
   17847 					TREE_TYPE (*expr_p));
   17848 	  break;
   17849 
   17850 	case VIEW_CONVERT_EXPR:
   17851 	  if ((fallback & fb_rvalue)
   17852 	      && is_gimple_reg_type (TREE_TYPE (*expr_p))
   17853 	      && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
   17854 	    {
   17855 	      ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   17856 				   post_p, is_gimple_val, fb_rvalue);
   17857 	      recalculate_side_effects (*expr_p);
   17858 	      break;
   17859 	    }
   17860 	  /* Fallthru.  */
   17861 
   17862 	case ARRAY_REF:
   17863 	case ARRAY_RANGE_REF:
   17864 	case REALPART_EXPR:
   17865 	case IMAGPART_EXPR:
   17866 	case COMPONENT_REF:
   17867 	  ret = gimplify_compound_lval (expr_p, pre_p, post_p,
   17868 					fallback ? fallback : fb_rvalue);
   17869 	  break;
   17870 
   17871 	case COND_EXPR:
   17872 	  ret = gimplify_cond_expr (expr_p, pre_p, fallback);
   17873 
   17874 	  /* C99 code may assign to an array in a structure value of a
   17875 	     conditional expression, and this has undefined behavior
   17876 	     only on execution, so create a temporary if an lvalue is
   17877 	     required.  */
   17878 	  if (fallback == fb_lvalue)
   17879 	    {
   17880 	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
   17881 	      mark_addressable (*expr_p);
   17882 	      ret = GS_OK;
   17883 	    }
   17884 	  break;
   17885 
   17886 	case CALL_EXPR:
   17887 	  ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
   17888 
   17889 	  /* C99 code may assign to an array in a structure returned
   17890 	     from a function, and this has undefined behavior only on
   17891 	     execution, so create a temporary if an lvalue is
   17892 	     required.  */
   17893 	  if (fallback == fb_lvalue)
   17894 	    {
   17895 	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
   17896 	      mark_addressable (*expr_p);
   17897 	      ret = GS_OK;
   17898 	    }
   17899 	  break;
   17900 
   17901 	case TREE_LIST:
   17902 	  gcc_unreachable ();
   17903 
   17904 	case OMP_ARRAY_SECTION:
   17905 	  gcc_unreachable ();
   17906 
   17907 	case COMPOUND_EXPR:
   17908 	  ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
   17909 	  break;
   17910 
   17911 	case COMPOUND_LITERAL_EXPR:
   17912 	  ret = gimplify_compound_literal_expr (expr_p, pre_p,
   17913 						gimple_test_f, fallback);
   17914 	  break;
   17915 
   17916 	case MODIFY_EXPR:
   17917 	case INIT_EXPR:
   17918 	  ret = gimplify_modify_expr (expr_p, pre_p, post_p,
   17919 				      fallback != fb_none);
   17920 	  break;
   17921 
   17922 	case TRUTH_ANDIF_EXPR:
   17923 	case TRUTH_ORIF_EXPR:
   17924 	  {
   17925 	    /* Preserve the original type of the expression and the
   17926 	       source location of the outer expression.  */
   17927 	    tree org_type = TREE_TYPE (*expr_p);
   17928 	    *expr_p = gimple_boolify (*expr_p);
   17929 	    *expr_p = build3_loc (input_location, COND_EXPR,
   17930 				  org_type, *expr_p,
   17931 				  fold_convert_loc
   17932 				    (input_location,
   17933 				     org_type, boolean_true_node),
   17934 				  fold_convert_loc
   17935 				    (input_location,
   17936 				     org_type, boolean_false_node));
   17937 	    ret = GS_OK;
   17938 	    break;
   17939 	  }
   17940 
   17941 	case TRUTH_NOT_EXPR:
   17942 	  {
   17943 	    tree type = TREE_TYPE (*expr_p);
   17944 	    /* The parsers are careful to generate TRUTH_NOT_EXPR
   17945 	       only with operands that are always zero or one.
   17946 	       We do not fold here but handle the only interesting case
   17947 	       manually, as fold may re-introduce the TRUTH_NOT_EXPR.  */
   17948 	    *expr_p = gimple_boolify (*expr_p);
   17949 	    if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
   17950 	      *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
   17951 				    TREE_TYPE (*expr_p),
   17952 				    TREE_OPERAND (*expr_p, 0));
   17953 	    else
   17954 	      *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
   17955 				    TREE_TYPE (*expr_p),
   17956 				    TREE_OPERAND (*expr_p, 0),
   17957 				    build_int_cst (TREE_TYPE (*expr_p), 1));
   17958 	    if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
   17959 	      *expr_p = fold_convert_loc (input_location, type, *expr_p);
   17960 	    ret = GS_OK;
   17961 	    break;
   17962 	  }
   17963 
   17964 	case ADDR_EXPR:
   17965 	  ret = gimplify_addr_expr (expr_p, pre_p, post_p);
   17966 	  break;
   17967 
   17968 	case ANNOTATE_EXPR:
   17969 	  {
   17970 	    tree cond = TREE_OPERAND (*expr_p, 0);
   17971 	    tree kind = TREE_OPERAND (*expr_p, 1);
   17972 	    tree data = TREE_OPERAND (*expr_p, 2);
   17973 	    tree type = TREE_TYPE (cond);
   17974 	    if (!INTEGRAL_TYPE_P (type))
   17975 	      {
   17976 		*expr_p = cond;
   17977 		ret = GS_OK;
   17978 		break;
   17979 	      }
   17980 	    tree tmp = create_tmp_var (type);
   17981 	    gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
   17982 	    gcall *call
   17983 	      = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
   17984 	    gimple_call_set_lhs (call, tmp);
   17985 	    gimplify_seq_add_stmt (pre_p, call);
   17986 	    *expr_p = tmp;
   17987 	    ret = GS_ALL_DONE;
   17988 	    break;
   17989 	  }
   17990 
   17991 	case VA_ARG_EXPR:
   17992 	  ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
   17993 	  break;
   17994 
   17995 	CASE_CONVERT:
   17996 	  if (IS_EMPTY_STMT (*expr_p))
   17997 	    {
   17998 	      ret = GS_ALL_DONE;
   17999 	      break;
   18000 	    }
   18001 
   18002 	  if (VOID_TYPE_P (TREE_TYPE (*expr_p))
   18003 	      || fallback == fb_none)
   18004 	    {
   18005 	      /* Just strip a conversion to void (or in void context) and
   18006 		 try again.  */
   18007 	      *expr_p = TREE_OPERAND (*expr_p, 0);
   18008 	      ret = GS_OK;
   18009 	      break;
   18010 	    }
   18011 
   18012 	  ret = gimplify_conversion (expr_p);
   18013 	  if (ret == GS_ERROR)
   18014 	    break;
   18015 	  if (*expr_p != save_expr)
   18016 	    break;
   18017 	  /* FALLTHRU */
   18018 
   18019 	case FIX_TRUNC_EXPR:
   18020 	  /* unary_expr: ... | '(' cast ')' val | ...  */
   18021 	  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   18022 			       is_gimple_val, fb_rvalue);
   18023 	  recalculate_side_effects (*expr_p);
   18024 	  break;
   18025 
   18026 	case INDIRECT_REF:
   18027 	  {
   18028 	    bool volatilep = TREE_THIS_VOLATILE (*expr_p);
   18029 	    bool notrap = TREE_THIS_NOTRAP (*expr_p);
   18030 	    tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
   18031 
   18032 	    *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
   18033 	    if (*expr_p != save_expr)
   18034 	      {
   18035 		ret = GS_OK;
   18036 		break;
   18037 	      }
   18038 
   18039 	    ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   18040 				 is_gimple_reg, fb_rvalue);
   18041 	    if (ret == GS_ERROR)
   18042 	      break;
   18043 
   18044 	    recalculate_side_effects (*expr_p);
   18045 	    *expr_p = fold_build2_loc (input_location, MEM_REF,
   18046 				       TREE_TYPE (*expr_p),
   18047 				       TREE_OPERAND (*expr_p, 0),
   18048 				       build_int_cst (saved_ptr_type, 0));
   18049 	    TREE_THIS_VOLATILE (*expr_p) = volatilep;
   18050 	    TREE_THIS_NOTRAP (*expr_p) = notrap;
   18051 	    ret = GS_OK;
   18052 	    break;
   18053 	  }
   18054 
   18055 	/* We arrive here through the various re-gimplifcation paths.  */
   18056 	case MEM_REF:
   18057 	  /* First try re-folding the whole thing.  */
   18058 	  tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
   18059 			     TREE_OPERAND (*expr_p, 0),
   18060 			     TREE_OPERAND (*expr_p, 1));
   18061 	  if (tmp)
   18062 	    {
   18063 	      REF_REVERSE_STORAGE_ORDER (tmp)
   18064 	        = REF_REVERSE_STORAGE_ORDER (*expr_p);
   18065 	      *expr_p = tmp;
   18066 	      recalculate_side_effects (*expr_p);
   18067 	      ret = GS_OK;
   18068 	      break;
   18069 	    }
   18070 	  /* Avoid re-gimplifying the address operand if it is already
   18071 	     in suitable form.  Re-gimplifying would mark the address
   18072 	     operand addressable.  Always gimplify when not in SSA form
   18073 	     as we still may have to gimplify decls with value-exprs.  */
   18074 	  if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
   18075 	      || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
   18076 	    {
   18077 	      ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   18078 				   is_gimple_mem_ref_addr, fb_rvalue);
   18079 	      if (ret == GS_ERROR)
   18080 		break;
   18081 	    }
   18082 	  recalculate_side_effects (*expr_p);
   18083 	  ret = GS_ALL_DONE;
   18084 	  break;
   18085 
   18086 	/* Constants need not be gimplified.  */
   18087 	case INTEGER_CST:
   18088 	case REAL_CST:
   18089 	case FIXED_CST:
   18090 	case STRING_CST:
   18091 	case COMPLEX_CST:
   18092 	case VECTOR_CST:
   18093 	  /* Drop the overflow flag on constants, we do not want
   18094 	     that in the GIMPLE IL.  */
   18095 	  if (TREE_OVERFLOW_P (*expr_p))
   18096 	    *expr_p = drop_tree_overflow (*expr_p);
   18097 	  ret = GS_ALL_DONE;
   18098 	  break;
   18099 
   18100 	case CONST_DECL:
   18101 	  /* If we require an lvalue, such as for ADDR_EXPR, retain the
   18102 	     CONST_DECL node.  Otherwise the decl is replaceable by its
   18103 	     value.  */
   18104 	  /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either.  */
   18105 	  if (fallback & fb_lvalue)
   18106 	    ret = GS_ALL_DONE;
   18107 	  else
   18108 	    {
   18109 	      *expr_p = DECL_INITIAL (*expr_p);
   18110 	      ret = GS_OK;
   18111 	    }
   18112 	  break;
   18113 
   18114 	case DECL_EXPR:
   18115 	  ret = gimplify_decl_expr (expr_p, pre_p);
   18116 	  break;
   18117 
   18118 	case BIND_EXPR:
   18119 	  ret = gimplify_bind_expr (expr_p, pre_p);
   18120 	  break;
   18121 
   18122 	case LOOP_EXPR:
   18123 	  ret = gimplify_loop_expr (expr_p, pre_p);
   18124 	  break;
   18125 
   18126 	case SWITCH_EXPR:
   18127 	  ret = gimplify_switch_expr (expr_p, pre_p);
   18128 	  break;
   18129 
   18130 	case EXIT_EXPR:
   18131 	  ret = gimplify_exit_expr (expr_p);
   18132 	  break;
   18133 
   18134 	case GOTO_EXPR:
   18135 	  /* If the target is not LABEL, then it is a computed jump
   18136 	     and the target needs to be gimplified.  */
   18137 	  if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
   18138 	    {
   18139 	      ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
   18140 				   NULL, is_gimple_val, fb_rvalue);
   18141 	      if (ret == GS_ERROR)
   18142 		break;
   18143 	    }
   18144 	  gimplify_seq_add_stmt (pre_p,
   18145 			  gimple_build_goto (GOTO_DESTINATION (*expr_p)));
   18146 	  ret = GS_ALL_DONE;
   18147 	  break;
   18148 
   18149 	case PREDICT_EXPR:
   18150 	  gimplify_seq_add_stmt (pre_p,
   18151 			gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
   18152 					      PREDICT_EXPR_OUTCOME (*expr_p)));
   18153 	  ret = GS_ALL_DONE;
   18154 	  break;
   18155 
   18156 	case LABEL_EXPR:
   18157 	  ret = gimplify_label_expr (expr_p, pre_p);
   18158 	  label = LABEL_EXPR_LABEL (*expr_p);
   18159 	  gcc_assert (decl_function_context (label) == current_function_decl);
   18160 
   18161 	  /* If the label is used in a goto statement, or address of the label
   18162 	     is taken, we need to unpoison all variables that were seen so far.
   18163 	     Doing so would prevent us from reporting a false positives.  */
   18164 	  if (asan_poisoned_variables
   18165 	      && asan_used_labels != NULL
   18166 	      && asan_used_labels->contains (label)
   18167 	      && !gimplify_omp_ctxp)
   18168 	    asan_poison_variables (asan_poisoned_variables, false, pre_p);
   18169 	  break;
   18170 
   18171 	case CASE_LABEL_EXPR:
   18172 	  ret = gimplify_case_label_expr (expr_p, pre_p);
   18173 
   18174 	  if (gimplify_ctxp->live_switch_vars)
   18175 	    asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
   18176 				   pre_p);
   18177 	  break;
   18178 
   18179 	case RETURN_EXPR:
   18180 	  ret = gimplify_return_expr (*expr_p, pre_p);
   18181 	  break;
   18182 
   18183 	case CONSTRUCTOR:
   18184 	  /* Don't reduce this in place; let gimplify_init_constructor work its
   18185 	     magic.  Buf if we're just elaborating this for side effects, just
   18186 	     gimplify any element that has side-effects.  */
   18187 	  if (fallback == fb_none)
   18188 	    {
   18189 	      unsigned HOST_WIDE_INT ix;
   18190 	      tree val;
   18191 	      tree temp = NULL_TREE;
   18192 	      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
   18193 		if (TREE_SIDE_EFFECTS (val))
   18194 		  append_to_statement_list (val, &temp);
   18195 
   18196 	      *expr_p = temp;
   18197 	      ret = temp ? GS_OK : GS_ALL_DONE;
   18198 	    }
   18199 	  /* C99 code may assign to an array in a constructed
   18200 	     structure or union, and this has undefined behavior only
   18201 	     on execution, so create a temporary if an lvalue is
   18202 	     required.  */
   18203 	  else if (fallback == fb_lvalue)
   18204 	    {
   18205 	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
   18206 	      mark_addressable (*expr_p);
   18207 	      ret = GS_OK;
   18208 	    }
   18209 	  else
   18210 	    ret = GS_ALL_DONE;
   18211 	  break;
   18212 
   18213 	  /* The following are special cases that are not handled by the
   18214 	     original GIMPLE grammar.  */
   18215 
   18216 	  /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
   18217 	     eliminated.  */
   18218 	case SAVE_EXPR:
   18219 	  ret = gimplify_save_expr (expr_p, pre_p, post_p);
   18220 	  break;
   18221 
   18222 	case BIT_FIELD_REF:
   18223 	  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   18224 			       post_p, is_gimple_lvalue, fb_either);
   18225 	  recalculate_side_effects (*expr_p);
   18226 	  break;
   18227 
   18228 	case TARGET_MEM_REF:
   18229 	  {
   18230 	    enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
   18231 
   18232 	    if (TMR_BASE (*expr_p))
   18233 	      r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
   18234 				  post_p, is_gimple_mem_ref_addr, fb_either);
   18235 	    if (TMR_INDEX (*expr_p))
   18236 	      r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
   18237 				  post_p, is_gimple_val, fb_rvalue);
   18238 	    if (TMR_INDEX2 (*expr_p))
   18239 	      r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
   18240 				  post_p, is_gimple_val, fb_rvalue);
   18241 	    /* TMR_STEP and TMR_OFFSET are always integer constants.  */
   18242 	    ret = MIN (r0, r1);
   18243 	  }
   18244 	  break;
   18245 
   18246 	case NON_LVALUE_EXPR:
   18247 	  /* This should have been stripped above.  */
   18248 	  gcc_unreachable ();
   18249 
   18250 	case ASM_EXPR:
   18251 	  ret = gimplify_asm_expr (expr_p, pre_p, post_p);
   18252 	  break;
   18253 
   18254 	case TRY_FINALLY_EXPR:
   18255 	case TRY_CATCH_EXPR:
   18256 	  {
   18257 	    gimple_seq eval, cleanup;
   18258 	    gtry *try_;
   18259 
   18260 	    /* Calls to destructors are generated automatically in FINALLY/CATCH
   18261 	       block. They should have location as UNKNOWN_LOCATION. However,
   18262 	       gimplify_call_expr will reset these call stmts to input_location
   18263 	       if it finds stmt's location is unknown. To prevent resetting for
   18264 	       destructors, we set the input_location to unknown.
   18265 	       Note that this only affects the destructor calls in FINALLY/CATCH
   18266 	       block, and will automatically reset to its original value by the
   18267 	       end of gimplify_expr.  */
   18268 	    input_location = UNKNOWN_LOCATION;
   18269 	    eval = cleanup = NULL;
   18270 	    gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
   18271 	    bool save_in_handler_expr = gimplify_ctxp->in_handler_expr;
   18272 	    if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
   18273 		&& TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
   18274 	      {
   18275 		gimple_seq n = NULL, e = NULL;
   18276 		gimplify_ctxp->in_handler_expr = true;
   18277 		gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
   18278 						0), &n);
   18279 		gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
   18280 						1), &e);
   18281 		if (!gimple_seq_empty_p (n) || !gimple_seq_empty_p (e))
   18282 		  {
   18283 		    geh_else *stmt = gimple_build_eh_else (n, e);
   18284 		    gimple_seq_add_stmt (&cleanup, stmt);
   18285 		  }
   18286 	      }
   18287 	    else
   18288 	      {
   18289 		gimplify_ctxp->in_handler_expr = true;
   18290 		gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
   18291 	      }
   18292 	    gimplify_ctxp->in_handler_expr = save_in_handler_expr;
   18293 	    /* Don't create bogus GIMPLE_TRY with empty cleanup.  */
   18294 	    if (gimple_seq_empty_p (cleanup))
   18295 	      {
   18296 		gimple_seq_add_seq (pre_p, eval);
   18297 		ret = GS_ALL_DONE;
   18298 		break;
   18299 	      }
   18300 	    try_ = gimple_build_try (eval, cleanup,
   18301 				     TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
   18302 				     ? GIMPLE_TRY_FINALLY
   18303 				     : GIMPLE_TRY_CATCH);
   18304 	    if (EXPR_HAS_LOCATION (save_expr))
   18305 	      gimple_set_location (try_, EXPR_LOCATION (save_expr));
   18306 	    else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
   18307 	      gimple_set_location (try_, saved_location);
   18308 	    if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
   18309 	      gimple_try_set_catch_is_cleanup (try_,
   18310 					       TRY_CATCH_IS_CLEANUP (*expr_p));
   18311 	    gimplify_seq_add_stmt (pre_p, try_);
   18312 	    ret = GS_ALL_DONE;
   18313 	    break;
   18314 	  }
   18315 
   18316 	case CLEANUP_POINT_EXPR:
   18317 	  ret = gimplify_cleanup_point_expr (expr_p, pre_p);
   18318 	  break;
   18319 
   18320 	case TARGET_EXPR:
   18321 	  ret = gimplify_target_expr (expr_p, pre_p, post_p);
   18322 	  break;
   18323 
   18324 	case CATCH_EXPR:
   18325 	  {
   18326 	    gimple *c;
   18327 	    gimple_seq handler = NULL;
   18328 	    gimplify_and_add (CATCH_BODY (*expr_p), &handler);
   18329 	    c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
   18330 	    gimplify_seq_add_stmt (pre_p, c);
   18331 	    ret = GS_ALL_DONE;
   18332 	    break;
   18333 	  }
   18334 
   18335 	case EH_FILTER_EXPR:
   18336 	  {
   18337 	    gimple *ehf;
   18338 	    gimple_seq failure = NULL;
   18339 
   18340 	    gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
   18341 	    ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
   18342 	    copy_warning (ehf, *expr_p);
   18343 	    gimplify_seq_add_stmt (pre_p, ehf);
   18344 	    ret = GS_ALL_DONE;
   18345 	    break;
   18346 	  }
   18347 
   18348 	case OBJ_TYPE_REF:
   18349 	  {
   18350 	    enum gimplify_status r0, r1;
   18351 	    r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
   18352 				post_p, is_gimple_val, fb_rvalue);
   18353 	    r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
   18354 				post_p, is_gimple_val, fb_rvalue);
   18355 	    TREE_SIDE_EFFECTS (*expr_p) = 0;
   18356 	    ret = MIN (r0, r1);
   18357 	  }
   18358 	  break;
   18359 
   18360 	case LABEL_DECL:
   18361 	  /* We get here when taking the address of a label.  We mark
   18362 	     the label as "forced"; meaning it can never be removed and
   18363 	     it is a potential target for any computed goto.  */
   18364 	  FORCED_LABEL (*expr_p) = 1;
   18365 	  ret = GS_ALL_DONE;
   18366 	  break;
   18367 
   18368 	case STATEMENT_LIST:
   18369 	  ret = gimplify_statement_list (expr_p, pre_p);
   18370 	  break;
   18371 
   18372 	case WITH_SIZE_EXPR:
   18373 	  {
   18374 	    gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   18375 			   post_p == &internal_post ? NULL : post_p,
   18376 			   gimple_test_f, fallback);
   18377 	    gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
   18378 			   is_gimple_val, fb_rvalue);
   18379 	    ret = GS_ALL_DONE;
   18380 	  }
   18381 	  break;
   18382 
   18383 	case VAR_DECL:
   18384 	case PARM_DECL:
   18385 	  ret = gimplify_var_or_parm_decl (expr_p);
   18386 	  break;
   18387 
   18388 	case RESULT_DECL:
   18389 	  /* When within an OMP context, notice uses of variables.  */
   18390 	  if (gimplify_omp_ctxp)
   18391 	    omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
   18392 	  /* Handlers can refer to the function result; if that has been
   18393 	     moved, we need to track it.  */
   18394 	  if (gimplify_ctxp->in_handler_expr && gimplify_ctxp->return_temp)
   18395 	    *expr_p = gimplify_ctxp->return_temp;
   18396 	  ret = GS_ALL_DONE;
   18397 	  break;
   18398 
   18399 	case DEBUG_EXPR_DECL:
   18400 	  gcc_unreachable ();
   18401 
   18402 	case DEBUG_BEGIN_STMT:
   18403 	  gimplify_seq_add_stmt (pre_p,
   18404 				 gimple_build_debug_begin_stmt
   18405 				 (TREE_BLOCK (*expr_p),
   18406 				  EXPR_LOCATION (*expr_p)));
   18407 	  ret = GS_ALL_DONE;
   18408 	  *expr_p = NULL;
   18409 	  break;
   18410 
   18411 	case SSA_NAME:
   18412 	  /* Allow callbacks into the gimplifier during optimization.  */
   18413 	  ret = GS_ALL_DONE;
   18414 	  break;
   18415 
   18416 	case OMP_PARALLEL:
   18417 	  gimplify_omp_parallel (expr_p, pre_p);
   18418 	  ret = GS_ALL_DONE;
   18419 	  break;
   18420 
   18421 	case OMP_TASK:
   18422 	  gimplify_omp_task (expr_p, pre_p);
   18423 	  ret = GS_ALL_DONE;
   18424 	  break;
   18425 
   18426 	case OMP_SIMD:
   18427 	  {
   18428 	    /* Temporarily disable into_ssa, as scan_omp_simd
   18429 	       which calls copy_gimple_seq_and_replace_locals can't deal
   18430 	       with SSA_NAMEs defined outside of the body properly.  */
   18431 	    bool saved_into_ssa = gimplify_ctxp->into_ssa;
   18432 	    gimplify_ctxp->into_ssa = false;
   18433 	    ret = gimplify_omp_for (expr_p, pre_p);
   18434 	    gimplify_ctxp->into_ssa = saved_into_ssa;
   18435 	    break;
   18436 	  }
   18437 
   18438 	case OMP_FOR:
   18439 	case OMP_DISTRIBUTE:
   18440 	case OMP_TASKLOOP:
   18441 	case OACC_LOOP:
   18442 	  ret = gimplify_omp_for (expr_p, pre_p);
   18443 	  break;
   18444 
   18445 	case OMP_LOOP:
   18446 	  ret = gimplify_omp_loop (expr_p, pre_p);
   18447 	  break;
   18448 
   18449 	case OACC_CACHE:
   18450 	  gimplify_oacc_cache (expr_p, pre_p);
   18451 	  ret = GS_ALL_DONE;
   18452 	  break;
   18453 
   18454 	case OACC_DECLARE:
   18455 	  gimplify_oacc_declare (expr_p, pre_p);
   18456 	  ret = GS_ALL_DONE;
   18457 	  break;
   18458 
   18459 	case OACC_HOST_DATA:
   18460 	case OACC_DATA:
   18461 	case OACC_KERNELS:
   18462 	case OACC_PARALLEL:
   18463 	case OACC_SERIAL:
   18464 	case OMP_SCOPE:
   18465 	case OMP_SECTIONS:
   18466 	case OMP_SINGLE:
   18467 	case OMP_TARGET:
   18468 	case OMP_TARGET_DATA:
   18469 	case OMP_TEAMS:
   18470 	  gimplify_omp_workshare (expr_p, pre_p);
   18471 	  ret = GS_ALL_DONE;
   18472 	  break;
   18473 
   18474 	case OACC_ENTER_DATA:
   18475 	case OACC_EXIT_DATA:
   18476 	case OACC_UPDATE:
   18477 	case OMP_TARGET_UPDATE:
   18478 	case OMP_TARGET_ENTER_DATA:
   18479 	case OMP_TARGET_EXIT_DATA:
   18480 	  gimplify_omp_target_update (expr_p, pre_p);
   18481 	  ret = GS_ALL_DONE;
   18482 	  break;
   18483 
   18484 	case OMP_SECTION:
   18485 	case OMP_STRUCTURED_BLOCK:
   18486 	case OMP_MASTER:
   18487 	case OMP_MASKED:
   18488 	case OMP_ORDERED:
   18489 	case OMP_CRITICAL:
   18490 	case OMP_SCAN:
   18491 	  {
   18492 	    gimple_seq body = NULL;
   18493 	    gimple *g;
   18494 	    bool saved_in_omp_construct = in_omp_construct;
   18495 
   18496 	    in_omp_construct = true;
   18497 	    gimplify_and_add (OMP_BODY (*expr_p), &body);
   18498 	    in_omp_construct = saved_in_omp_construct;
   18499 	    switch (TREE_CODE (*expr_p))
   18500 	      {
   18501 	      case OMP_SECTION:
   18502 	        g = gimple_build_omp_section (body);
   18503 	        break;
   18504 	      case OMP_STRUCTURED_BLOCK:
   18505 		g = gimple_build_omp_structured_block (body);
   18506 		break;
   18507 	      case OMP_MASTER:
   18508 		g = gimple_build_omp_master (body);
   18509 		break;
   18510 	      case OMP_ORDERED:
   18511 		g = gimplify_omp_ordered (*expr_p, body);
   18512 		if (OMP_BODY (*expr_p) == NULL_TREE
   18513 		    && gimple_code (g) == GIMPLE_OMP_ORDERED)
   18514 		  gimple_omp_ordered_standalone (g);
   18515 		break;
   18516 	      case OMP_MASKED:
   18517 		gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p),
   18518 					   pre_p, ORT_WORKSHARE, OMP_MASKED);
   18519 		gimplify_adjust_omp_clauses (pre_p, body,
   18520 					     &OMP_MASKED_CLAUSES (*expr_p),
   18521 					     OMP_MASKED);
   18522 		g = gimple_build_omp_masked (body,
   18523 					     OMP_MASKED_CLAUSES (*expr_p));
   18524 		break;
   18525 	      case OMP_CRITICAL:
   18526 		gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
   18527 					   pre_p, ORT_WORKSHARE, OMP_CRITICAL);
   18528 		gimplify_adjust_omp_clauses (pre_p, body,
   18529 					     &OMP_CRITICAL_CLAUSES (*expr_p),
   18530 					     OMP_CRITICAL);
   18531 		g = gimple_build_omp_critical (body,
   18532 		    			       OMP_CRITICAL_NAME (*expr_p),
   18533 		    			       OMP_CRITICAL_CLAUSES (*expr_p));
   18534 		break;
   18535 	      case OMP_SCAN:
   18536 		gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
   18537 					   pre_p, ORT_WORKSHARE, OMP_SCAN);
   18538 		gimplify_adjust_omp_clauses (pre_p, body,
   18539 					     &OMP_SCAN_CLAUSES (*expr_p),
   18540 					     OMP_SCAN);
   18541 		g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
   18542 		break;
   18543 	      default:
   18544 		gcc_unreachable ();
   18545 	      }
   18546 	    gimplify_seq_add_stmt (pre_p, g);
   18547 	    ret = GS_ALL_DONE;
   18548 	    break;
   18549 	  }
   18550 
   18551 	case OMP_TASKGROUP:
   18552 	  {
   18553 	    gimple_seq body = NULL;
   18554 
   18555 	    tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
   18556 	    bool saved_in_omp_construct = in_omp_construct;
   18557 	    gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
   18558 				       OMP_TASKGROUP);
   18559 	    gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
   18560 
   18561 	    in_omp_construct = true;
   18562 	    gimplify_and_add (OMP_BODY (*expr_p), &body);
   18563 	    in_omp_construct = saved_in_omp_construct;
   18564 	    gimple_seq cleanup = NULL;
   18565 	    tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
   18566 	    gimple *g = gimple_build_call (fn, 0);
   18567 	    gimple_seq_add_stmt (&cleanup, g);
   18568 	    g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
   18569 	    body = NULL;
   18570 	    gimple_seq_add_stmt (&body, g);
   18571 	    g = gimple_build_omp_taskgroup (body, *pclauses);
   18572 	    gimplify_seq_add_stmt (pre_p, g);
   18573 	    ret = GS_ALL_DONE;
   18574 	    break;
   18575 	  }
   18576 
   18577 	case OMP_ATOMIC:
   18578 	case OMP_ATOMIC_READ:
   18579 	case OMP_ATOMIC_CAPTURE_OLD:
   18580 	case OMP_ATOMIC_CAPTURE_NEW:
   18581 	  ret = gimplify_omp_atomic (expr_p, pre_p);
   18582 	  break;
   18583 
   18584 	case TRANSACTION_EXPR:
   18585 	  ret = gimplify_transaction (expr_p, pre_p);
   18586 	  break;
   18587 
   18588 	case TRUTH_AND_EXPR:
   18589 	case TRUTH_OR_EXPR:
   18590 	case TRUTH_XOR_EXPR:
   18591 	  {
   18592 	    tree orig_type = TREE_TYPE (*expr_p);
   18593 	    tree new_type, xop0, xop1;
   18594 	    *expr_p = gimple_boolify (*expr_p);
   18595 	    new_type = TREE_TYPE (*expr_p);
   18596 	    if (!useless_type_conversion_p (orig_type, new_type))
   18597 	      {
   18598 		*expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
   18599 		ret = GS_OK;
   18600 		break;
   18601 	      }
   18602 
   18603 	  /* Boolified binary truth expressions are semantically equivalent
   18604 	     to bitwise binary expressions.  Canonicalize them to the
   18605 	     bitwise variant.  */
   18606 	    switch (TREE_CODE (*expr_p))
   18607 	      {
   18608 	      case TRUTH_AND_EXPR:
   18609 		TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
   18610 		break;
   18611 	      case TRUTH_OR_EXPR:
   18612 		TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
   18613 		break;
   18614 	      case TRUTH_XOR_EXPR:
   18615 		TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
   18616 		break;
   18617 	      default:
   18618 		break;
   18619 	      }
   18620 	    /* Now make sure that operands have compatible type to
   18621 	       expression's new_type.  */
   18622 	    xop0 = TREE_OPERAND (*expr_p, 0);
   18623 	    xop1 = TREE_OPERAND (*expr_p, 1);
   18624 	    if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
   18625 	      TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
   18626 							    new_type,
   18627 	      						    xop0);
   18628 	    if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
   18629 	      TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
   18630 							    new_type,
   18631 	      						    xop1);
   18632 	    /* Continue classified as tcc_binary.  */
   18633 	    goto expr_2;
   18634 	  }
   18635 
   18636 	case VEC_COND_EXPR:
   18637 	  goto expr_3;
   18638 
   18639 	case VEC_PERM_EXPR:
   18640 	  /* Classified as tcc_expression.  */
   18641 	  goto expr_3;
   18642 
   18643 	case BIT_INSERT_EXPR:
   18644 	  /* Argument 3 is a constant.  */
   18645 	  goto expr_2;
   18646 
   18647 	case POINTER_PLUS_EXPR:
   18648 	  {
   18649 	    enum gimplify_status r0, r1;
   18650 	    r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   18651 				post_p, is_gimple_val, fb_rvalue);
   18652 	    r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
   18653 				post_p, is_gimple_val, fb_rvalue);
   18654 	    recalculate_side_effects (*expr_p);
   18655 	    ret = MIN (r0, r1);
   18656 	    break;
   18657 	  }
   18658 
   18659 	default:
   18660 	  switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
   18661 	    {
   18662 	    case tcc_comparison:
   18663 	      /* Handle comparison of objects of non scalar mode aggregates
   18664 	     	 with a call to memcmp.  It would be nice to only have to do
   18665 	     	 this for variable-sized objects, but then we'd have to allow
   18666 	     	 the same nest of reference nodes we allow for MODIFY_EXPR and
   18667 	     	 that's too complex.
   18668 
   18669 		 Compare scalar mode aggregates as scalar mode values.  Using
   18670 		 memcmp for them would be very inefficient at best, and is
   18671 		 plain wrong if bitfields are involved.  */
   18672 	      if (error_operand_p (TREE_OPERAND (*expr_p, 1)))
   18673 		ret = GS_ERROR;
   18674 	      else
   18675 		{
   18676 		  tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
   18677 
   18678 		  /* Vector comparisons need no boolification.  */
   18679 		  if (TREE_CODE (type) == VECTOR_TYPE)
   18680 		    goto expr_2;
   18681 		  else if (!AGGREGATE_TYPE_P (type))
   18682 		    {
   18683 		      tree org_type = TREE_TYPE (*expr_p);
   18684 		      *expr_p = gimple_boolify (*expr_p);
   18685 		      if (!useless_type_conversion_p (org_type,
   18686 						      TREE_TYPE (*expr_p)))
   18687 			{
   18688 			  *expr_p = fold_convert_loc (input_location,
   18689 						      org_type, *expr_p);
   18690 			  ret = GS_OK;
   18691 			}
   18692 		      else
   18693 			goto expr_2;
   18694 		    }
   18695 		  else if (TYPE_MODE (type) != BLKmode)
   18696 		    ret = gimplify_scalar_mode_aggregate_compare (expr_p);
   18697 		  else
   18698 		    ret = gimplify_variable_sized_compare (expr_p);
   18699 		}
   18700 	      break;
   18701 
   18702 	    /* If *EXPR_P does not need to be special-cased, handle it
   18703 	       according to its class.  */
   18704 	    case tcc_unary:
   18705 	      ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   18706 				   post_p, is_gimple_val, fb_rvalue);
   18707 	      break;
   18708 
   18709 	    case tcc_binary:
   18710 	    expr_2:
   18711 	      {
   18712 		enum gimplify_status r0, r1;
   18713 
   18714 		r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   18715 		                    post_p, is_gimple_val, fb_rvalue);
   18716 		r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
   18717 				    post_p, is_gimple_val, fb_rvalue);
   18718 
   18719 		ret = MIN (r0, r1);
   18720 		break;
   18721 	      }
   18722 
   18723 	    expr_3:
   18724 	      {
   18725 		enum gimplify_status r0, r1, r2;
   18726 
   18727 		r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   18728 		                    post_p, is_gimple_val, fb_rvalue);
   18729 		r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
   18730 				    post_p, is_gimple_val, fb_rvalue);
   18731 		r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
   18732 				    post_p, is_gimple_val, fb_rvalue);
   18733 
   18734 		ret = MIN (MIN (r0, r1), r2);
   18735 		break;
   18736 	      }
   18737 
   18738 	    case tcc_declaration:
   18739 	    case tcc_constant:
   18740 	      ret = GS_ALL_DONE;
   18741 	      goto dont_recalculate;
   18742 
   18743 	    default:
   18744 	      gcc_unreachable ();
   18745 	    }
   18746 
   18747 	  recalculate_side_effects (*expr_p);
   18748 
   18749 	dont_recalculate:
   18750 	  break;
   18751 	}
   18752 
   18753       gcc_assert (*expr_p || ret != GS_OK);
   18754     }
   18755   while (ret == GS_OK);
   18756 
   18757   /* If we encountered an error_mark somewhere nested inside, either
   18758      stub out the statement or propagate the error back out.  */
   18759   if (ret == GS_ERROR)
   18760     {
   18761       if (is_statement)
   18762 	*expr_p = NULL;
   18763       goto out;
   18764     }
   18765 
   18766   /* This was only valid as a return value from the langhook, which
   18767      we handled.  Make sure it doesn't escape from any other context.  */
   18768   gcc_assert (ret != GS_UNHANDLED);
   18769 
   18770   if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
   18771     {
   18772       /* We aren't looking for a value, and we don't have a valid
   18773 	 statement.  If it doesn't have side-effects, throw it away.
   18774 	 We can also get here with code such as "*&&L;", where L is
   18775 	 a LABEL_DECL that is marked as FORCED_LABEL.  */
   18776       if (TREE_CODE (*expr_p) == LABEL_DECL
   18777 	  || !TREE_SIDE_EFFECTS (*expr_p))
   18778 	*expr_p = NULL;
   18779       else if (!TREE_THIS_VOLATILE (*expr_p))
   18780 	{
   18781 	  /* This is probably a _REF that contains something nested that
   18782 	     has side effects.  Recurse through the operands to find it.  */
   18783 	  enum tree_code code = TREE_CODE (*expr_p);
   18784 
   18785 	  switch (code)
   18786 	    {
   18787 	    case COMPONENT_REF:
   18788 	    case REALPART_EXPR:
   18789 	    case IMAGPART_EXPR:
   18790 	    case VIEW_CONVERT_EXPR:
   18791 	      gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   18792 			     gimple_test_f, fallback);
   18793 	      break;
   18794 
   18795 	    case ARRAY_REF:
   18796 	    case ARRAY_RANGE_REF:
   18797 	      gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   18798 			     gimple_test_f, fallback);
   18799 	      gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
   18800 			     gimple_test_f, fallback);
   18801 	      break;
   18802 
   18803 	    default:
   18804 	       /* Anything else with side-effects must be converted to
   18805 		  a valid statement before we get here.  */
   18806 	      gcc_unreachable ();
   18807 	    }
   18808 
   18809 	  *expr_p = NULL;
   18810 	}
   18811       else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
   18812 	       && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode
   18813 	       && !is_empty_type (TREE_TYPE (*expr_p)))
   18814 	{
   18815 	  /* Historically, the compiler has treated a bare reference
   18816 	     to a non-BLKmode volatile lvalue as forcing a load.  */
   18817 	  tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
   18818 
   18819 	  /* Normally, we do not want to create a temporary for a
   18820 	     TREE_ADDRESSABLE type because such a type should not be
   18821 	     copied by bitwise-assignment.  However, we make an
   18822 	     exception here, as all we are doing here is ensuring that
   18823 	     we read the bytes that make up the type.  We use
   18824 	     create_tmp_var_raw because create_tmp_var will abort when
   18825 	     given a TREE_ADDRESSABLE type.  */
   18826 	  tree tmp = create_tmp_var_raw (type, "vol");
   18827 	  gimple_add_tmp_var (tmp);
   18828 	  gimplify_assign (tmp, *expr_p, pre_p);
   18829 	  *expr_p = NULL;
   18830 	}
   18831       else
   18832 	/* We can't do anything useful with a volatile reference to
   18833 	   an incomplete type, so just throw it away.  Likewise for
   18834 	   a BLKmode type, since any implicit inner load should
   18835 	   already have been turned into an explicit one by the
   18836 	   gimplification process.  */
   18837 	*expr_p = NULL;
   18838     }
   18839 
   18840   /* If we are gimplifying at the statement level, we're done.  Tack
   18841      everything together and return.  */
   18842   if (fallback == fb_none || is_statement)
   18843     {
   18844       /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
   18845          it out for GC to reclaim it.  */
   18846       *expr_p = NULL_TREE;
   18847 
   18848       if (!gimple_seq_empty_p (internal_pre)
   18849 	  || !gimple_seq_empty_p (internal_post))
   18850 	{
   18851 	  gimplify_seq_add_seq (&internal_pre, internal_post);
   18852 	  gimplify_seq_add_seq (pre_p, internal_pre);
   18853 	}
   18854 
   18855       /* The result of gimplifying *EXPR_P is going to be the last few
   18856 	 statements in *PRE_P and *POST_P.  Add location information
   18857 	 to all the statements that were added by the gimplification
   18858 	 helpers.  */
   18859       if (!gimple_seq_empty_p (*pre_p))
   18860 	annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
   18861 
   18862       if (!gimple_seq_empty_p (*post_p))
   18863 	annotate_all_with_location_after (*post_p, post_last_gsi,
   18864 					  input_location);
   18865 
   18866       goto out;
   18867     }
   18868 
   18869 #ifdef ENABLE_GIMPLE_CHECKING
   18870   if (*expr_p)
   18871     {
   18872       enum tree_code code = TREE_CODE (*expr_p);
   18873       /* These expressions should already be in gimple IR form.  */
   18874       gcc_assert (code != MODIFY_EXPR
   18875 		  && code != ASM_EXPR
   18876 		  && code != BIND_EXPR
   18877 		  && code != CATCH_EXPR
   18878 		  && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
   18879 		  && code != EH_FILTER_EXPR
   18880 		  && code != GOTO_EXPR
   18881 		  && code != LABEL_EXPR
   18882 		  && code != LOOP_EXPR
   18883 		  && code != SWITCH_EXPR
   18884 		  && code != TRY_FINALLY_EXPR
   18885 		  && code != EH_ELSE_EXPR
   18886 		  && code != OACC_PARALLEL
   18887 		  && code != OACC_KERNELS
   18888 		  && code != OACC_SERIAL
   18889 		  && code != OACC_DATA
   18890 		  && code != OACC_HOST_DATA
   18891 		  && code != OACC_DECLARE
   18892 		  && code != OACC_UPDATE
   18893 		  && code != OACC_ENTER_DATA
   18894 		  && code != OACC_EXIT_DATA
   18895 		  && code != OACC_CACHE
   18896 		  && code != OMP_CRITICAL
   18897 		  && code != OMP_FOR
   18898 		  && code != OACC_LOOP
   18899 		  && code != OMP_MASTER
   18900 		  && code != OMP_MASKED
   18901 		  && code != OMP_TASKGROUP
   18902 		  && code != OMP_ORDERED
   18903 		  && code != OMP_PARALLEL
   18904 		  && code != OMP_SCAN
   18905 		  && code != OMP_SECTIONS
   18906 		  && code != OMP_SECTION
   18907 		  && code != OMP_STRUCTURED_BLOCK
   18908 		  && code != OMP_SINGLE
   18909 		  && code != OMP_SCOPE);
   18910     }
   18911 #endif
   18912 
   18913   /* Otherwise we're gimplifying a subexpression, so the resulting
   18914      value is interesting.  If it's a valid operand that matches
   18915      GIMPLE_TEST_F, we're done. Unless we are handling some
   18916      post-effects internally; if that's the case, we need to copy into
   18917      a temporary before adding the post-effects to POST_P.  */
   18918   if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
   18919     goto out;
   18920 
   18921   /* Otherwise, we need to create a new temporary for the gimplified
   18922      expression.  */
   18923 
   18924   /* We can't return an lvalue if we have an internal postqueue.  The
   18925      object the lvalue refers to would (probably) be modified by the
   18926      postqueue; we need to copy the value out first, which means an
   18927      rvalue.  */
   18928   if ((fallback & fb_lvalue)
   18929       && gimple_seq_empty_p (internal_post)
   18930       && is_gimple_addressable (*expr_p))
   18931     {
   18932       /* An lvalue will do.  Take the address of the expression, store it
   18933 	 in a temporary, and replace the expression with an INDIRECT_REF of
   18934 	 that temporary.  */
   18935       tree ref_alias_type = reference_alias_ptr_type (*expr_p);
   18936       unsigned int ref_align = get_object_alignment (*expr_p);
   18937       tree ref_type = TREE_TYPE (*expr_p);
   18938       tmp = build_fold_addr_expr_loc (input_location, *expr_p);
   18939       gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
   18940       if (TYPE_ALIGN (ref_type) != ref_align)
   18941 	ref_type = build_aligned_type (ref_type, ref_align);
   18942       *expr_p = build2 (MEM_REF, ref_type,
   18943 			tmp, build_zero_cst (ref_alias_type));
   18944     }
   18945   else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
   18946     {
   18947       /* An rvalue will do.  Assign the gimplified expression into a
   18948 	 new temporary TMP and replace the original expression with
   18949 	 TMP.  First, make sure that the expression has a type so that
   18950 	 it can be assigned into a temporary.  */
   18951       gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
   18952       *expr_p = get_formal_tmp_var (*expr_p, pre_p);
   18953     }
   18954   else
   18955     {
   18956 #ifdef ENABLE_GIMPLE_CHECKING
   18957       if (!(fallback & fb_mayfail))
   18958 	{
   18959 	  fprintf (stderr, "gimplification failed:\n");
   18960 	  print_generic_expr (stderr, *expr_p);
   18961 	  debug_tree (*expr_p);
   18962 	  internal_error ("gimplification failed");
   18963 	}
   18964 #endif
   18965       gcc_assert (fallback & fb_mayfail);
   18966 
   18967       /* If this is an asm statement, and the user asked for the
   18968 	 impossible, don't die.  Fail and let gimplify_asm_expr
   18969 	 issue an error.  */
   18970       ret = GS_ERROR;
   18971       goto out;
   18972     }
   18973 
   18974   /* Make sure the temporary matches our predicate.  */
   18975   gcc_assert ((*gimple_test_f) (*expr_p));
   18976 
   18977   if (!gimple_seq_empty_p (internal_post))
   18978     {
   18979       annotate_all_with_location (internal_post, input_location);
   18980       gimplify_seq_add_seq (pre_p, internal_post);
   18981     }
   18982 
   18983  out:
   18984   input_location = saved_location;
   18985   return ret;
   18986 }
   18987 
   18988 /* Like gimplify_expr but make sure the gimplified result is not itself
   18989    a SSA name (but a decl if it were).  Temporaries required by
   18990    evaluating *EXPR_P may be still SSA names.  */
   18991 
   18992 static enum gimplify_status
   18993 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   18994 	       bool (*gimple_test_f) (tree), fallback_t fallback,
   18995 	       bool allow_ssa)
   18996 {
   18997   enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
   18998 					    gimple_test_f, fallback);
   18999   if (! allow_ssa
   19000       && TREE_CODE (*expr_p) == SSA_NAME)
   19001     *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
   19002   return ret;
   19003 }
   19004 
   19005 /* Look through TYPE for variable-sized objects and gimplify each such
   19006    size that we find.  Add to LIST_P any statements generated.  */
   19007 
   19008 void
   19009 gimplify_type_sizes (tree type, gimple_seq *list_p)
   19010 {
   19011   if (type == NULL || type == error_mark_node)
   19012     return;
   19013 
   19014   const bool ignored_p
   19015     = TYPE_NAME (type)
   19016       && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
   19017       && DECL_IGNORED_P (TYPE_NAME (type));
   19018   tree t;
   19019 
   19020   /* We first do the main variant, then copy into any other variants.  */
   19021   type = TYPE_MAIN_VARIANT (type);
   19022 
   19023   /* Avoid infinite recursion.  */
   19024   if (TYPE_SIZES_GIMPLIFIED (type))
   19025     return;
   19026 
   19027   TYPE_SIZES_GIMPLIFIED (type) = 1;
   19028 
   19029   switch (TREE_CODE (type))
   19030     {
   19031     case INTEGER_TYPE:
   19032     case ENUMERAL_TYPE:
   19033     case BOOLEAN_TYPE:
   19034     case REAL_TYPE:
   19035     case FIXED_POINT_TYPE:
   19036       gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
   19037       gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
   19038 
   19039       for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
   19040 	{
   19041 	  TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
   19042 	  TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
   19043 	}
   19044       break;
   19045 
   19046     case ARRAY_TYPE:
   19047       /* These types may not have declarations, so handle them here.  */
   19048       gimplify_type_sizes (TREE_TYPE (type), list_p);
   19049       gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
   19050       /* Ensure VLA bounds aren't removed, for -O0 they should be variables
   19051 	 with assigned stack slots, for -O1+ -g they should be tracked
   19052 	 by VTA.  */
   19053       if (!ignored_p
   19054 	  && TYPE_DOMAIN (type)
   19055 	  && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
   19056 	{
   19057 	  t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
   19058 	  if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
   19059 	    DECL_IGNORED_P (t) = 0;
   19060 	  t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
   19061 	  if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
   19062 	    DECL_IGNORED_P (t) = 0;
   19063 	}
   19064       break;
   19065 
   19066     case RECORD_TYPE:
   19067     case UNION_TYPE:
   19068     case QUAL_UNION_TYPE:
   19069       for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
   19070 	if (TREE_CODE (field) == FIELD_DECL)
   19071 	  {
   19072 	    gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
   19073 	    /* Likewise, ensure variable offsets aren't removed.  */
   19074 	    if (!ignored_p
   19075 		&& (t = DECL_FIELD_OFFSET (field))
   19076 		&& VAR_P (t)
   19077 		&& DECL_ARTIFICIAL (t))
   19078 	      DECL_IGNORED_P (t) = 0;
   19079 	    gimplify_one_sizepos (&DECL_SIZE (field), list_p);
   19080 	    gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
   19081 	    gimplify_type_sizes (TREE_TYPE (field), list_p);
   19082 	  }
   19083       break;
   19084 
   19085     case POINTER_TYPE:
   19086     case REFERENCE_TYPE:
   19087 	/* We used to recurse on the pointed-to type here, which turned out to
   19088 	   be incorrect because its definition might refer to variables not
   19089 	   yet initialized at this point if a forward declaration is involved.
   19090 
   19091 	   It was actually useful for anonymous pointed-to types to ensure
   19092 	   that the sizes evaluation dominates every possible later use of the
   19093 	   values.  Restricting to such types here would be safe since there
   19094 	   is no possible forward declaration around, but would introduce an
   19095 	   undesirable middle-end semantic to anonymity.  We then defer to
   19096 	   front-ends the responsibility of ensuring that the sizes are
   19097 	   evaluated both early and late enough, e.g. by attaching artificial
   19098 	   type declarations to the tree.  */
   19099       break;
   19100 
   19101     default:
   19102       break;
   19103     }
   19104 
   19105   gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
   19106   gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
   19107 
   19108   for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
   19109     {
   19110       TYPE_SIZE (t) = TYPE_SIZE (type);
   19111       TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
   19112       TYPE_SIZES_GIMPLIFIED (t) = 1;
   19113     }
   19114 }
   19115 
   19116 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
   19117    a size or position, has had all of its SAVE_EXPRs evaluated.
   19118    We add any required statements to *STMT_P.  */
   19119 
   19120 void
   19121 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
   19122 {
   19123   tree expr = *expr_p;
   19124 
   19125   /* We don't do anything if the value isn't there, is constant, or contains
   19126      A PLACEHOLDER_EXPR.  We also don't want to do anything if it's already
   19127      a VAR_DECL.  If it's a VAR_DECL from another function, the gimplifier
   19128      will want to replace it with a new variable, but that will cause problems
   19129      if this type is from outside the function.  It's OK to have that here.  */
   19130   if (expr == NULL_TREE
   19131       || is_gimple_constant (expr)
   19132       || VAR_P (expr)
   19133       || CONTAINS_PLACEHOLDER_P (expr))
   19134     return;
   19135 
   19136   *expr_p = unshare_expr (expr);
   19137 
   19138   /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
   19139      if the def vanishes.  */
   19140   gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
   19141 
   19142   /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
   19143      FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
   19144      as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs.  */
   19145   if (is_gimple_constant (*expr_p))
   19146     *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
   19147 }
   19148 
   19149 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
   19150    containing the sequence of corresponding GIMPLE statements.  If DO_PARMS
   19151    is true, also gimplify the parameters.  */
   19152 
   19153 gbind *
   19154 gimplify_body (tree fndecl, bool do_parms)
   19155 {
   19156   location_t saved_location = input_location;
   19157   gimple_seq parm_stmts, parm_cleanup = NULL, seq;
   19158   gimple *outer_stmt;
   19159   gbind *outer_bind;
   19160 
   19161   timevar_push (TV_TREE_GIMPLIFY);
   19162 
   19163   init_tree_ssa (cfun);
   19164 
   19165   /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
   19166      gimplification.  */
   19167   default_rtl_profile ();
   19168 
   19169   gcc_assert (gimplify_ctxp == NULL);
   19170   push_gimplify_context (true);
   19171 
   19172   if (flag_openacc || flag_openmp)
   19173     {
   19174       gcc_assert (gimplify_omp_ctxp == NULL);
   19175       if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
   19176 	gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
   19177     }
   19178 
   19179   /* Unshare most shared trees in the body and in that of any nested functions.
   19180      It would seem we don't have to do this for nested functions because
   19181      they are supposed to be output and then the outer function gimplified
   19182      first, but the g++ front end doesn't always do it that way.  */
   19183   unshare_body (fndecl);
   19184   unvisit_body (fndecl);
   19185 
   19186   /* Make sure input_location isn't set to something weird.  */
   19187   input_location = DECL_SOURCE_LOCATION (fndecl);
   19188 
   19189   /* Resolve callee-copies.  This has to be done before processing
   19190      the body so that DECL_VALUE_EXPR gets processed correctly.  */
   19191   parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
   19192 
   19193   /* Gimplify the function's body.  */
   19194   seq = NULL;
   19195   gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
   19196   outer_stmt = gimple_seq_first_nondebug_stmt (seq);
   19197   if (!outer_stmt)
   19198     {
   19199       outer_stmt = gimple_build_nop ();
   19200       gimplify_seq_add_stmt (&seq, outer_stmt);
   19201     }
   19202 
   19203   /* The body must contain exactly one statement, a GIMPLE_BIND.  If this is
   19204      not the case, wrap everything in a GIMPLE_BIND to make it so.  */
   19205   if (gimple_code (outer_stmt) == GIMPLE_BIND
   19206       && (gimple_seq_first_nondebug_stmt (seq)
   19207 	  == gimple_seq_last_nondebug_stmt (seq)))
   19208     {
   19209       outer_bind = as_a <gbind *> (outer_stmt);
   19210       if (gimple_seq_first_stmt (seq) != outer_stmt
   19211 	  || gimple_seq_last_stmt (seq) != outer_stmt)
   19212 	{
   19213 	  /* If there are debug stmts before or after outer_stmt, move them
   19214 	     inside of outer_bind body.  */
   19215 	  gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
   19216 	  gimple_seq second_seq = NULL;
   19217 	  if (gimple_seq_first_stmt (seq) != outer_stmt
   19218 	      && gimple_seq_last_stmt (seq) != outer_stmt)
   19219 	    {
   19220 	      second_seq = gsi_split_seq_after (gsi);
   19221 	      gsi_remove (&gsi, false);
   19222 	    }
   19223 	  else if (gimple_seq_first_stmt (seq) != outer_stmt)
   19224 	    gsi_remove (&gsi, false);
   19225 	  else
   19226 	    {
   19227 	      gsi_remove (&gsi, false);
   19228 	      second_seq = seq;
   19229 	      seq = NULL;
   19230 	    }
   19231 	  gimple_seq_add_seq_without_update (&seq,
   19232 					     gimple_bind_body (outer_bind));
   19233 	  gimple_seq_add_seq_without_update (&seq, second_seq);
   19234 	  gimple_bind_set_body (outer_bind, seq);
   19235 	}
   19236     }
   19237   else
   19238     outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
   19239 
   19240   DECL_SAVED_TREE (fndecl) = NULL_TREE;
   19241 
   19242   /* If we had callee-copies statements, insert them at the beginning
   19243      of the function and clear DECL_VALUE_EXPR_P on the parameters.  */
   19244   if (!gimple_seq_empty_p (parm_stmts))
   19245     {
   19246       tree parm;
   19247 
   19248       gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
   19249       if (parm_cleanup)
   19250 	{
   19251 	  gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
   19252 				      GIMPLE_TRY_FINALLY);
   19253 	  parm_stmts = NULL;
   19254 	  gimple_seq_add_stmt (&parm_stmts, g);
   19255 	}
   19256       gimple_bind_set_body (outer_bind, parm_stmts);
   19257 
   19258       for (parm = DECL_ARGUMENTS (current_function_decl);
   19259 	   parm; parm = DECL_CHAIN (parm))
   19260 	if (DECL_HAS_VALUE_EXPR_P (parm))
   19261 	  {
   19262 	    DECL_HAS_VALUE_EXPR_P (parm) = 0;
   19263 	    DECL_IGNORED_P (parm) = 0;
   19264 	  }
   19265     }
   19266 
   19267   if ((flag_openacc || flag_openmp || flag_openmp_simd)
   19268       && gimplify_omp_ctxp)
   19269     {
   19270       delete_omp_context (gimplify_omp_ctxp);
   19271       gimplify_omp_ctxp = NULL;
   19272     }
   19273 
   19274   pop_gimplify_context (outer_bind);
   19275   gcc_assert (gimplify_ctxp == NULL);
   19276 
   19277   if (flag_checking && !seen_error ())
   19278     verify_gimple_in_seq (gimple_bind_body (outer_bind));
   19279 
   19280   timevar_pop (TV_TREE_GIMPLIFY);
   19281   input_location = saved_location;
   19282 
   19283   return outer_bind;
   19284 }
   19285 
   19286 typedef char *char_p; /* For DEF_VEC_P.  */
   19287 
   19288 /* Return whether we should exclude FNDECL from instrumentation.  */
   19289 
   19290 static bool
   19291 flag_instrument_functions_exclude_p (tree fndecl)
   19292 {
   19293   vec<char_p> *v;
   19294 
   19295   v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
   19296   if (v && v->length () > 0)
   19297     {
   19298       const char *name;
   19299       int i;
   19300       char *s;
   19301 
   19302       name = lang_hooks.decl_printable_name (fndecl, 1);
   19303       FOR_EACH_VEC_ELT (*v, i, s)
   19304 	if (strstr (name, s) != NULL)
   19305 	  return true;
   19306     }
   19307 
   19308   v = (vec<char_p> *) flag_instrument_functions_exclude_files;
   19309   if (v && v->length () > 0)
   19310     {
   19311       const char *name;
   19312       int i;
   19313       char *s;
   19314 
   19315       name = DECL_SOURCE_FILE (fndecl);
   19316       FOR_EACH_VEC_ELT (*v, i, s)
   19317 	if (strstr (name, s) != NULL)
   19318 	  return true;
   19319     }
   19320 
   19321   return false;
   19322 }
   19323 
   19324 /* Build a call to the instrumentation function FNCODE and add it to SEQ.
   19325    If COND_VAR is not NULL, it is a boolean variable guarding the call to
   19326    the instrumentation function.  IF STMT is not NULL, it is a statement
   19327    to be executed just before the call to the instrumentation function.  */
   19328 
   19329 static void
   19330 build_instrumentation_call (gimple_seq *seq, enum built_in_function fncode,
   19331 			    tree cond_var, gimple *stmt)
   19332 {
   19333   /* The instrumentation hooks aren't going to call the instrumented
   19334      function and the address they receive is expected to be matchable
   19335      against symbol addresses.  Make sure we don't create a trampoline,
   19336      in case the current function is nested.  */
   19337   tree this_fn_addr = build_fold_addr_expr (current_function_decl);
   19338   TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
   19339 
   19340   tree label_true, label_false;
   19341   if (cond_var)
   19342     {
   19343       label_true = create_artificial_label (UNKNOWN_LOCATION);
   19344       label_false = create_artificial_label (UNKNOWN_LOCATION);
   19345       gcond *cond = gimple_build_cond (EQ_EXPR, cond_var, boolean_false_node,
   19346 				      label_true, label_false);
   19347       gimplify_seq_add_stmt (seq, cond);
   19348       gimplify_seq_add_stmt (seq, gimple_build_label (label_true));
   19349       gimplify_seq_add_stmt (seq, gimple_build_predict (PRED_COLD_LABEL,
   19350 							NOT_TAKEN));
   19351     }
   19352 
   19353   if (stmt)
   19354     gimplify_seq_add_stmt (seq, stmt);
   19355 
   19356   tree x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
   19357   gcall *call = gimple_build_call (x, 1, integer_zero_node);
   19358   tree tmp_var = create_tmp_var (ptr_type_node, "return_addr");
   19359   gimple_call_set_lhs (call, tmp_var);
   19360   gimplify_seq_add_stmt (seq, call);
   19361   x = builtin_decl_implicit (fncode);
   19362   call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
   19363   gimplify_seq_add_stmt (seq, call);
   19364 
   19365   if (cond_var)
   19366     gimplify_seq_add_stmt (seq, gimple_build_label (label_false));
   19367 }
   19368 
   19369 /* Entry point to the gimplification pass.  FNDECL is the FUNCTION_DECL
   19370    node for the function we want to gimplify.
   19371 
   19372    Return the sequence of GIMPLE statements corresponding to the body
   19373    of FNDECL.  */
   19374 
   19375 void
   19376 gimplify_function_tree (tree fndecl)
   19377 {
   19378   gimple_seq seq;
   19379   gbind *bind;
   19380 
   19381   gcc_assert (!gimple_body (fndecl));
   19382 
   19383   if (DECL_STRUCT_FUNCTION (fndecl))
   19384     push_cfun (DECL_STRUCT_FUNCTION (fndecl));
   19385   else
   19386     push_struct_function (fndecl);
   19387 
   19388   reset_cond_uid ();
   19389 
   19390   /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
   19391      if necessary.  */
   19392   cfun->curr_properties |= PROP_gimple_lva;
   19393 
   19394   if (asan_sanitize_use_after_scope ())
   19395     asan_poisoned_variables = new hash_set<tree> ();
   19396   bind = gimplify_body (fndecl, true);
   19397   if (asan_poisoned_variables)
   19398     {
   19399       delete asan_poisoned_variables;
   19400       asan_poisoned_variables = NULL;
   19401     }
   19402 
   19403   /* The tree body of the function is no longer needed, replace it
   19404      with the new GIMPLE body.  */
   19405   seq = NULL;
   19406   gimple_seq_add_stmt (&seq, bind);
   19407   gimple_set_body (fndecl, seq);
   19408 
   19409   /* If we're instrumenting function entry/exit, then prepend the call to
   19410      the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
   19411      catch the exit hook.  */
   19412   /* ??? Add some way to ignore exceptions for this TFE.  */
   19413   if (flag_instrument_function_entry_exit
   19414       && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
   19415       /* Do not instrument extern inline functions.  */
   19416       && !(DECL_DECLARED_INLINE_P (fndecl)
   19417 	   && DECL_EXTERNAL (fndecl)
   19418 	   && DECL_DISREGARD_INLINE_LIMITS (fndecl))
   19419       && !flag_instrument_functions_exclude_p (fndecl))
   19420     {
   19421       gimple_seq body = NULL, cleanup = NULL;
   19422       gassign *assign;
   19423       tree cond_var;
   19424 
   19425       /* If -finstrument-functions-once is specified, generate:
   19426 
   19427 	   static volatile bool C.0 = false;
   19428 	   bool tmp_called;
   19429 
   19430 	   tmp_called = C.0;
   19431 	   if (!tmp_called)
   19432 	     {
   19433 	       C.0 = true;
   19434 	       [call profiling enter function]
   19435 	     }
   19436 
   19437 	 without specific protection for data races.  */
   19438       if (flag_instrument_function_entry_exit > 1)
   19439 	{
   19440 	  tree first_var
   19441 	    = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
   19442 			  VAR_DECL,
   19443 			  create_tmp_var_name ("C"),
   19444 			  boolean_type_node);
   19445 	  DECL_ARTIFICIAL (first_var) = 1;
   19446 	  DECL_IGNORED_P (first_var) = 1;
   19447 	  TREE_STATIC (first_var) = 1;
   19448 	  TREE_THIS_VOLATILE (first_var) = 1;
   19449 	  TREE_USED (first_var) = 1;
   19450 	  DECL_INITIAL (first_var) = boolean_false_node;
   19451 	  varpool_node::add (first_var);
   19452 
   19453 	  cond_var = create_tmp_var (boolean_type_node, "tmp_called");
   19454 	  assign = gimple_build_assign (cond_var, first_var);
   19455 	  gimplify_seq_add_stmt (&body, assign);
   19456 
   19457 	  assign = gimple_build_assign (first_var, boolean_true_node);
   19458 	}
   19459 
   19460       else
   19461 	{
   19462 	  cond_var = NULL_TREE;
   19463 	  assign = NULL;
   19464 	}
   19465 
   19466       build_instrumentation_call (&body, BUILT_IN_PROFILE_FUNC_ENTER,
   19467 				  cond_var, assign);
   19468 
   19469       /* If -finstrument-functions-once is specified, generate:
   19470 
   19471 	   if (!tmp_called)
   19472 	     [call profiling exit function]
   19473 
   19474 	 without specific protection for data races.  */
   19475       build_instrumentation_call (&cleanup, BUILT_IN_PROFILE_FUNC_EXIT,
   19476 				  cond_var, NULL);
   19477 
   19478       gimple *tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
   19479       gimplify_seq_add_stmt (&body, tf);
   19480       gbind *new_bind = gimple_build_bind (NULL, body, NULL);
   19481 
   19482       /* Replace the current function body with the body
   19483          wrapped in the try/finally TF.  */
   19484       seq = NULL;
   19485       gimple_seq_add_stmt (&seq, new_bind);
   19486       gimple_set_body (fndecl, seq);
   19487       bind = new_bind;
   19488     }
   19489 
   19490   if (sanitize_flags_p (SANITIZE_THREAD)
   19491       && param_tsan_instrument_func_entry_exit)
   19492     {
   19493       gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
   19494       gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
   19495       gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
   19496       /* Replace the current function body with the body
   19497 	 wrapped in the try/finally TF.  */
   19498       seq = NULL;
   19499       gimple_seq_add_stmt (&seq, new_bind);
   19500       gimple_set_body (fndecl, seq);
   19501     }
   19502 
   19503   DECL_SAVED_TREE (fndecl) = NULL_TREE;
   19504   cfun->curr_properties |= PROP_gimple_any;
   19505 
   19506   pop_cfun ();
   19507 
   19508   dump_function (TDI_gimple, fndecl);
   19509 }
   19510 
   19511 /* Return a dummy expression of type TYPE in order to keep going after an
   19512    error.  */
   19513 
   19514 static tree
   19515 dummy_object (tree type)
   19516 {
   19517   tree t = build_int_cst (build_pointer_type (type), 0);
   19518   return build2 (MEM_REF, type, t, t);
   19519 }
   19520 
   19521 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
   19522    builtin function, but a very special sort of operator.  */
   19523 
   19524 enum gimplify_status
   19525 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
   19526 		      gimple_seq *post_p ATTRIBUTE_UNUSED)
   19527 {
   19528   tree promoted_type, have_va_type;
   19529   tree valist = TREE_OPERAND (*expr_p, 0);
   19530   tree type = TREE_TYPE (*expr_p);
   19531   tree t, tag, aptag;
   19532   location_t loc = EXPR_LOCATION (*expr_p);
   19533 
   19534   /* Verify that valist is of the proper type.  */
   19535   have_va_type = TREE_TYPE (valist);
   19536   if (have_va_type == error_mark_node)
   19537     return GS_ERROR;
   19538   have_va_type = targetm.canonical_va_list_type (have_va_type);
   19539   if (have_va_type == NULL_TREE
   19540       && POINTER_TYPE_P (TREE_TYPE (valist)))
   19541     /* Handle 'Case 1: Not an array type' from c-common.cc/build_va_arg.  */
   19542     have_va_type
   19543       = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
   19544   gcc_assert (have_va_type != NULL_TREE);
   19545 
   19546   /* Generate a diagnostic for requesting data of a type that cannot
   19547      be passed through `...' due to type promotion at the call site.  */
   19548   if ((promoted_type = lang_hooks.types.type_promotes_to (type))
   19549 	   != type)
   19550     {
   19551       static bool gave_help;
   19552       bool warned;
   19553       /* Use the expansion point to handle cases such as passing bool (defined
   19554 	 in a system header) through `...'.  */
   19555       location_t xloc
   19556 	= expansion_point_location_if_in_system_header (loc);
   19557 
   19558       /* Unfortunately, this is merely undefined, rather than a constraint
   19559 	 violation, so we cannot make this an error.  If this call is never
   19560 	 executed, the program is still strictly conforming.  */
   19561       auto_diagnostic_group d;
   19562       warned = warning_at (xloc, 0,
   19563 			   "%qT is promoted to %qT when passed through %<...%>",
   19564 			   type, promoted_type);
   19565       if (!gave_help && warned)
   19566 	{
   19567 	  gave_help = true;
   19568 	  inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
   19569 		  promoted_type, type);
   19570 	}
   19571 
   19572       /* We can, however, treat "undefined" any way we please.
   19573 	 Call abort to encourage the user to fix the program.  */
   19574       if (warned)
   19575 	inform (xloc, "if this code is reached, the program will abort");
   19576       /* Before the abort, allow the evaluation of the va_list
   19577 	 expression to exit or longjmp.  */
   19578       gimplify_and_add (valist, pre_p);
   19579       t = build_call_expr_loc (loc,
   19580 			       builtin_decl_implicit (BUILT_IN_TRAP), 0);
   19581       gimplify_and_add (t, pre_p);
   19582 
   19583       /* This is dead code, but go ahead and finish so that the
   19584 	 mode of the result comes out right.  */
   19585       *expr_p = dummy_object (type);
   19586       return GS_ALL_DONE;
   19587     }
   19588 
   19589   tag = build_int_cst (build_pointer_type (type), 0);
   19590   aptag = build_int_cst (TREE_TYPE (valist), 0);
   19591 
   19592   *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
   19593 					  valist, tag, aptag);
   19594 
   19595   /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
   19596      needs to be expanded.  */
   19597   cfun->curr_properties &= ~PROP_gimple_lva;
   19598 
   19599   return GS_OK;
   19600 }
   19601 
   19602 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
   19603 
   19604    DST/SRC are the destination and source respectively.  You can pass
   19605    ungimplified trees in DST or SRC, in which case they will be
   19606    converted to a gimple operand if necessary.
   19607 
   19608    This function returns the newly created GIMPLE_ASSIGN tuple.  */
   19609 
   19610 gimple *
   19611 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
   19612 {
   19613   tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
   19614   gimplify_and_add (t, seq_p);
   19615   ggc_free (t);
   19616   return gimple_seq_last_stmt (*seq_p);
   19617 }
   19618 
   19619 inline hashval_t
   19620 gimplify_hasher::hash (const elt_t *p)
   19621 {
   19622   tree t = p->val;
   19623   return iterative_hash_expr (t, 0);
   19624 }
   19625 
   19626 inline bool
   19627 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
   19628 {
   19629   tree t1 = p1->val;
   19630   tree t2 = p2->val;
   19631   enum tree_code code = TREE_CODE (t1);
   19632 
   19633   if (TREE_CODE (t2) != code
   19634       || TREE_TYPE (t1) != TREE_TYPE (t2))
   19635     return false;
   19636 
   19637   if (!operand_equal_p (t1, t2, 0))
   19638     return false;
   19639 
   19640   /* Only allow them to compare equal if they also hash equal; otherwise
   19641      results are nondeterminate, and we fail bootstrap comparison.  */
   19642   gcc_checking_assert (hash (p1) == hash (p2));
   19643 
   19644   return true;
   19645 }
   19646