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 
   3881       for (i = 0; i < nargs; i++)
   3882 	{
   3883 	  gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
   3884 			EXPR_LOCATION (*expr_p));
   3885 	  vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
   3886 	}
   3887 
   3888       gcall *call = gimple_build_call_internal_vec (ifn, vargs);
   3889       gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
   3890       gimplify_seq_add_stmt (pre_p, call);
   3891       return GS_ALL_DONE;
   3892     }
   3893 
   3894   /* This may be a call to a builtin function.
   3895 
   3896      Builtin function calls may be transformed into different
   3897      (and more efficient) builtin function calls under certain
   3898      circumstances.  Unfortunately, gimplification can muck things
   3899      up enough that the builtin expanders are not aware that certain
   3900      transformations are still valid.
   3901 
   3902      So we attempt transformation/gimplification of the call before
   3903      we gimplify the CALL_EXPR.  At this time we do not manage to
   3904      transform all calls in the same manner as the expanders do, but
   3905      we do transform most of them.  */
   3906   fndecl = get_callee_fndecl (*expr_p);
   3907   if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
   3908     switch (DECL_FUNCTION_CODE (fndecl))
   3909       {
   3910       CASE_BUILT_IN_ALLOCA:
   3911 	/* If the call has been built for a variable-sized object, then we
   3912 	   want to restore the stack level when the enclosing BIND_EXPR is
   3913 	   exited to reclaim the allocated space; otherwise, we precisely
   3914 	   need to do the opposite and preserve the latest stack level.  */
   3915 	if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
   3916 	  gimplify_ctxp->save_stack = true;
   3917 	else
   3918 	  gimplify_ctxp->keep_stack = true;
   3919 	break;
   3920 
   3921       case BUILT_IN_VA_START:
   3922         {
   3923 	  builtin_va_start_p = true;
   3924 	  if (call_expr_nargs (*expr_p) < 2)
   3925 	    {
   3926 	      error ("too few arguments to function %<va_start%>");
   3927 	      *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
   3928 	      return GS_OK;
   3929 	    }
   3930 
   3931 	  if (fold_builtin_next_arg (*expr_p, true))
   3932 	    {
   3933 	      *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
   3934 	      return GS_OK;
   3935 	    }
   3936 	  break;
   3937 	}
   3938 
   3939       case BUILT_IN_EH_RETURN:
   3940 	cfun->calls_eh_return = true;
   3941 	break;
   3942 
   3943       case BUILT_IN_CLEAR_PADDING:
   3944 	if (call_expr_nargs (*expr_p) == 1)
   3945 	  {
   3946 	    /* Remember the original type of the argument in an internal
   3947 	       dummy second argument, as in GIMPLE pointer conversions are
   3948 	       useless.  Also mark this call as not for automatic
   3949 	       initialization in the internal dummy third argument.  */
   3950 	    p = CALL_EXPR_ARG (*expr_p, 0);
   3951 	    *expr_p
   3952 	      = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p,
   3953 				     build_zero_cst (TREE_TYPE (p)));
   3954 	    return GS_OK;
   3955 	  }
   3956 	break;
   3957 
   3958       default:
   3959         ;
   3960       }
   3961   if (fndecl && fndecl_built_in_p (fndecl))
   3962     {
   3963       tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
   3964       if (new_tree && new_tree != *expr_p)
   3965 	{
   3966 	  /* There was a transformation of this call which computes the
   3967 	     same value, but in a more efficient way.  Return and try
   3968 	     again.  */
   3969 	  *expr_p = new_tree;
   3970 	  return GS_OK;
   3971 	}
   3972     }
   3973 
   3974   /* Remember the original function pointer type.  */
   3975   fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
   3976 
   3977   if (flag_openmp
   3978       && fndecl
   3979       && cfun
   3980       && (cfun->curr_properties & PROP_gimple_any) == 0)
   3981     {
   3982       tree variant = omp_resolve_declare_variant (fndecl);
   3983       if (variant != fndecl)
   3984 	CALL_EXPR_FN (*expr_p) = build1 (ADDR_EXPR, fnptrtype, variant);
   3985     }
   3986 
   3987   /* There is a sequence point before the call, so any side effects in
   3988      the calling expression must occur before the actual call.  Force
   3989      gimplify_expr to use an internal post queue.  */
   3990   ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
   3991 		       is_gimple_call_addr, fb_rvalue);
   3992 
   3993   if (ret == GS_ERROR)
   3994     return GS_ERROR;
   3995 
   3996   nargs = call_expr_nargs (*expr_p);
   3997 
   3998   /* Get argument types for verification.  */
   3999   fndecl = get_callee_fndecl (*expr_p);
   4000   parms = NULL_TREE;
   4001   if (fndecl)
   4002     parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
   4003   else
   4004     parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
   4005 
   4006   if (fndecl && DECL_ARGUMENTS (fndecl))
   4007     p = DECL_ARGUMENTS (fndecl);
   4008   else if (parms)
   4009     p = parms;
   4010   else
   4011     p = NULL_TREE;
   4012   for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
   4013     ;
   4014 
   4015   /* If the last argument is __builtin_va_arg_pack () and it is not
   4016      passed as a named argument, decrease the number of CALL_EXPR
   4017      arguments and set instead the CALL_EXPR_VA_ARG_PACK flag.  */
   4018   if (!p
   4019       && i < nargs
   4020       && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
   4021     {
   4022       tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
   4023       tree last_arg_fndecl = get_callee_fndecl (last_arg);
   4024 
   4025       if (last_arg_fndecl
   4026 	  && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
   4027 	{
   4028 	  tree call = *expr_p;
   4029 
   4030 	  --nargs;
   4031 	  *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
   4032 					  CALL_EXPR_FN (call),
   4033 					  nargs, CALL_EXPR_ARGP (call));
   4034 
   4035 	  /* Copy all CALL_EXPR flags, location and block, except
   4036 	     CALL_EXPR_VA_ARG_PACK flag.  */
   4037 	  CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
   4038 	  CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
   4039 	  CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
   4040 	    = CALL_EXPR_RETURN_SLOT_OPT (call);
   4041 	  CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
   4042 	  SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
   4043 
   4044 	  /* Set CALL_EXPR_VA_ARG_PACK.  */
   4045 	  CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
   4046 	}
   4047     }
   4048 
   4049   /* If the call returns twice then after building the CFG the call
   4050      argument computations will no longer dominate the call because
   4051      we add an abnormal incoming edge to the call.  So do not use SSA
   4052      vars there.  */
   4053   bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
   4054 
   4055   /* Gimplify the function arguments.  */
   4056   if (nargs > 0)
   4057     {
   4058       for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
   4059            PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
   4060            PUSH_ARGS_REVERSED ? i-- : i++)
   4061         {
   4062           enum gimplify_status t;
   4063 
   4064           /* Avoid gimplifying the second argument to va_start, which needs to
   4065              be the plain PARM_DECL.  */
   4066           if ((i != 1) || !builtin_va_start_p)
   4067             {
   4068               t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
   4069 				EXPR_LOCATION (*expr_p), ! returns_twice);
   4070 
   4071               if (t == GS_ERROR)
   4072                 ret = GS_ERROR;
   4073             }
   4074         }
   4075     }
   4076 
   4077   /* Gimplify the static chain.  */
   4078   if (CALL_EXPR_STATIC_CHAIN (*expr_p))
   4079     {
   4080       if (fndecl && !DECL_STATIC_CHAIN (fndecl))
   4081 	CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
   4082       else
   4083 	{
   4084 	  enum gimplify_status t;
   4085 	  t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
   4086 			    EXPR_LOCATION (*expr_p), ! returns_twice);
   4087 	  if (t == GS_ERROR)
   4088 	    ret = GS_ERROR;
   4089 	}
   4090     }
   4091 
   4092   /* Verify the function result.  */
   4093   if (want_value && fndecl
   4094       && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
   4095     {
   4096       error_at (loc, "using result of function returning %<void%>");
   4097       ret = GS_ERROR;
   4098     }
   4099 
   4100   /* Try this again in case gimplification exposed something.  */
   4101   if (ret != GS_ERROR)
   4102     {
   4103       tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
   4104 
   4105       if (new_tree && new_tree != *expr_p)
   4106 	{
   4107 	  /* There was a transformation of this call which computes the
   4108 	     same value, but in a more efficient way.  Return and try
   4109 	     again.  */
   4110 	  *expr_p = new_tree;
   4111 	  return GS_OK;
   4112 	}
   4113     }
   4114   else
   4115     {
   4116       *expr_p = error_mark_node;
   4117       return GS_ERROR;
   4118     }
   4119 
   4120   /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
   4121      decl.  This allows us to eliminate redundant or useless
   4122      calls to "const" functions.  */
   4123   if (TREE_CODE (*expr_p) == CALL_EXPR)
   4124     {
   4125       int flags = call_expr_flags (*expr_p);
   4126       if (flags & (ECF_CONST | ECF_PURE)
   4127 	  /* An infinite loop is considered a side effect.  */
   4128 	  && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
   4129 	TREE_SIDE_EFFECTS (*expr_p) = 0;
   4130     }
   4131 
   4132   /* If the value is not needed by the caller, emit a new GIMPLE_CALL
   4133      and clear *EXPR_P.  Otherwise, leave *EXPR_P in its gimplified
   4134      form and delegate the creation of a GIMPLE_CALL to
   4135      gimplify_modify_expr.  This is always possible because when
   4136      WANT_VALUE is true, the caller wants the result of this call into
   4137      a temporary, which means that we will emit an INIT_EXPR in
   4138      internal_get_tmp_var which will then be handled by
   4139      gimplify_modify_expr.  */
   4140   if (!want_value)
   4141     {
   4142       /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
   4143 	 have to do is replicate it as a GIMPLE_CALL tuple.  */
   4144       gimple_stmt_iterator gsi;
   4145       call = gimple_build_call_from_tree (*expr_p, fnptrtype);
   4146       notice_special_calls (call);
   4147       gimplify_seq_add_stmt (pre_p, call);
   4148       gsi = gsi_last (*pre_p);
   4149       maybe_fold_stmt (&gsi);
   4150       *expr_p = NULL_TREE;
   4151     }
   4152   else
   4153     /* Remember the original function type.  */
   4154     CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
   4155 				     CALL_EXPR_FN (*expr_p));
   4156 
   4157   return ret;
   4158 }
   4159 
   4160 /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
   4161    rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
   4162 
   4163    TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
   4164    condition is true or false, respectively.  If null, we should generate
   4165    our own to skip over the evaluation of this specific expression.
   4166 
   4167    LOCUS is the source location of the COND_EXPR.
   4168 
   4169    The condition_uid is a discriminator tag for condition coverage used to map
   4170    conditions to its corresponding full Boolean function.
   4171 
   4172    This function is the tree equivalent of do_jump.
   4173 
   4174    shortcut_cond_r should only be called by shortcut_cond_expr.  */
   4175 
   4176 static tree
   4177 shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
   4178 		 location_t locus, unsigned condition_uid)
   4179 {
   4180   tree local_label = NULL_TREE;
   4181   tree t, expr = NULL;
   4182 
   4183   /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
   4184      retain the shortcut semantics.  Just insert the gotos here;
   4185      shortcut_cond_expr will append the real blocks later.  */
   4186   if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
   4187     {
   4188       location_t new_locus;
   4189 
   4190       /* Turn if (a && b) into
   4191 
   4192 	 if (a); else goto no;
   4193 	 if (b) goto yes; else goto no;
   4194 	 (no:) */
   4195 
   4196       if (false_label_p == NULL)
   4197 	false_label_p = &local_label;
   4198 
   4199       /* Keep the original source location on the first 'if'.  */
   4200       t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus,
   4201 			   condition_uid);
   4202       append_to_statement_list (t, &expr);
   4203 
   4204       /* Set the source location of the && on the second 'if'.  */
   4205       new_locus = rexpr_location (pred, locus);
   4206       t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
   4207 			   new_locus, condition_uid);
   4208       append_to_statement_list (t, &expr);
   4209     }
   4210   else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
   4211     {
   4212       location_t new_locus;
   4213 
   4214       /* Turn if (a || b) into
   4215 
   4216 	 if (a) goto yes;
   4217 	 if (b) goto yes; else goto no;
   4218 	 (yes:) */
   4219 
   4220       if (true_label_p == NULL)
   4221 	true_label_p = &local_label;
   4222 
   4223       /* Keep the original source location on the first 'if'.  */
   4224       t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus,
   4225 			   condition_uid);
   4226       append_to_statement_list (t, &expr);
   4227 
   4228       /* Set the source location of the || on the second 'if'.  */
   4229       new_locus = rexpr_location (pred, locus);
   4230       t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
   4231 			   new_locus, condition_uid);
   4232       append_to_statement_list (t, &expr);
   4233     }
   4234   else if (TREE_CODE (pred) == COND_EXPR
   4235 	   && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
   4236 	   && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
   4237     {
   4238       location_t new_locus;
   4239 
   4240       /* As long as we're messing with gotos, turn if (a ? b : c) into
   4241 	 if (a)
   4242 	   if (b) goto yes; else goto no;
   4243 	 else
   4244 	   if (c) goto yes; else goto no;
   4245 
   4246 	 Don't do this if one of the arms has void type, which can happen
   4247 	 in C++ when the arm is throw.  */
   4248 
   4249       /* Keep the original source location on the first 'if'.  Set the source
   4250 	 location of the ? on the second 'if'.  */
   4251       new_locus = rexpr_location (pred, locus);
   4252       expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
   4253 		     shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
   4254 				      false_label_p, locus, condition_uid),
   4255 		     shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
   4256 				      false_label_p, new_locus,
   4257 				      condition_uid));
   4258       SET_EXPR_UID (expr, condition_uid);
   4259     }
   4260   else
   4261     {
   4262       expr = build3 (COND_EXPR, void_type_node, pred,
   4263 		     build_and_jump (true_label_p),
   4264 		     build_and_jump (false_label_p));
   4265       SET_EXPR_LOCATION (expr, locus);
   4266       SET_EXPR_UID (expr, condition_uid);
   4267     }
   4268 
   4269   if (local_label)
   4270     {
   4271       t = build1 (LABEL_EXPR, void_type_node, local_label);
   4272       append_to_statement_list (t, &expr);
   4273     }
   4274 
   4275   return expr;
   4276 }
   4277 
   4278 /* If EXPR is a GOTO_EXPR, return it.  If it is a STATEMENT_LIST, skip
   4279    any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
   4280    statement, if it is the last one.  Otherwise, return NULL.  */
   4281 
   4282 static tree
   4283 find_goto (tree expr)
   4284 {
   4285   if (!expr)
   4286     return NULL_TREE;
   4287 
   4288   if (TREE_CODE (expr) == GOTO_EXPR)
   4289     return expr;
   4290 
   4291   if (TREE_CODE (expr) != STATEMENT_LIST)
   4292     return NULL_TREE;
   4293 
   4294   tree_stmt_iterator i = tsi_start (expr);
   4295 
   4296   while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
   4297     tsi_next (&i);
   4298 
   4299   if (!tsi_one_before_end_p (i))
   4300     return NULL_TREE;
   4301 
   4302   return find_goto (tsi_stmt (i));
   4303 }
   4304 
   4305 /* Same as find_goto, except that it returns NULL if the destination
   4306    is not a LABEL_DECL.  */
   4307 
   4308 static inline tree
   4309 find_goto_label (tree expr)
   4310 {
   4311   tree dest = find_goto (expr);
   4312   if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
   4313     return dest;
   4314   return NULL_TREE;
   4315 }
   4316 
   4317 
   4318 /* Given a multi-term condition (ANDIF, ORIF), walk the predicate PRED and tag
   4319    every basic condition with CONDITION_UID.  Two basic conditions share the
   4320    CONDITION_UID discriminator when they belong to the same predicate, which is
   4321    used by the condition coverage.  Doing this as an explicit step makes for a
   4322    simpler implementation than weaving it into the splitting code as the
   4323    splitting code eventually calls the entry point gimplfiy_expr which makes
   4324    bookkeeping complicated.  */
   4325 static void
   4326 tag_shortcut_cond (tree pred, unsigned condition_uid)
   4327 {
   4328   if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR
   4329       || TREE_CODE (pred) == TRUTH_ORIF_EXPR)
   4330     {
   4331       tree fst = TREE_OPERAND (pred, 0);
   4332       tree lst = TREE_OPERAND (pred, 1);
   4333 
   4334       if (TREE_CODE (fst) == TRUTH_ANDIF_EXPR
   4335 	  || TREE_CODE (fst) == TRUTH_ORIF_EXPR)
   4336 	tag_shortcut_cond (fst, condition_uid);
   4337       else if (TREE_CODE (fst) == COND_EXPR)
   4338 	SET_EXPR_UID (fst, condition_uid);
   4339 
   4340       if (TREE_CODE (lst) == TRUTH_ANDIF_EXPR
   4341 	  || TREE_CODE (lst) == TRUTH_ORIF_EXPR)
   4342 	tag_shortcut_cond (lst, condition_uid);
   4343       else if (TREE_CODE (lst) == COND_EXPR)
   4344 	SET_EXPR_UID (lst, condition_uid);
   4345     }
   4346 }
   4347 
   4348 /* Given a conditional expression EXPR with short-circuit boolean
   4349    predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
   4350    predicate apart into the equivalent sequence of conditionals.  CONDITION_UID
   4351    is a the tag/discriminator for this EXPR - all basic conditions in the
   4352    expression will be given the same CONDITION_UID.  */
   4353 static tree
   4354 shortcut_cond_expr (tree expr, unsigned condition_uid)
   4355 {
   4356   tree pred = TREE_OPERAND (expr, 0);
   4357   tree then_ = TREE_OPERAND (expr, 1);
   4358   tree else_ = TREE_OPERAND (expr, 2);
   4359   tree true_label, false_label, end_label, t;
   4360   tree *true_label_p;
   4361   tree *false_label_p;
   4362   bool emit_end, emit_false, jump_over_else;
   4363   bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
   4364   bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
   4365 
   4366   tag_shortcut_cond (pred, condition_uid);
   4367 
   4368   /* First do simple transformations.  */
   4369   if (!else_se)
   4370     {
   4371       /* If there is no 'else', turn
   4372 	   if (a && b) then c
   4373 	 into
   4374 	   if (a) if (b) then c.  */
   4375       while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
   4376 	{
   4377 	  /* Keep the original source location on the first 'if'.  */
   4378 	  location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
   4379 	  TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
   4380 	  /* Set the source location of the && on the second 'if'.  */
   4381 	  if (rexpr_has_location (pred))
   4382 	    SET_EXPR_LOCATION (expr, rexpr_location (pred));
   4383 	  then_ = shortcut_cond_expr (expr, condition_uid);
   4384 	  then_se = then_ && TREE_SIDE_EFFECTS (then_);
   4385 	  pred = TREE_OPERAND (pred, 0);
   4386 	  expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
   4387 	  SET_EXPR_LOCATION (expr, locus);
   4388 	}
   4389     }
   4390 
   4391   if (!then_se)
   4392     {
   4393       /* If there is no 'then', turn
   4394 	   if (a || b); else d
   4395 	 into
   4396 	   if (a); else if (b); else d.  */
   4397       while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
   4398 	{
   4399 	  /* Keep the original source location on the first 'if'.  */
   4400 	  location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
   4401 	  TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
   4402 	  /* Set the source location of the || on the second 'if'.  */
   4403 	  if (rexpr_has_location (pred))
   4404 	    SET_EXPR_LOCATION (expr, rexpr_location (pred));
   4405 	  else_ = shortcut_cond_expr (expr, condition_uid);
   4406 	  else_se = else_ && TREE_SIDE_EFFECTS (else_);
   4407 	  pred = TREE_OPERAND (pred, 0);
   4408 	  expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
   4409 	  SET_EXPR_LOCATION (expr, locus);
   4410 	}
   4411     }
   4412 
   4413   /* The expr tree should also have the expression id set.  */
   4414   SET_EXPR_UID (expr, condition_uid);
   4415 
   4416   /* If we're done, great.  */
   4417   if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
   4418       && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
   4419     return expr;
   4420 
   4421   /* Otherwise we need to mess with gotos.  Change
   4422        if (a) c; else d;
   4423      to
   4424        if (a); else goto no;
   4425        c; goto end;
   4426        no: d; end:
   4427      and recursively gimplify the condition.  */
   4428 
   4429   true_label = false_label = end_label = NULL_TREE;
   4430 
   4431   /* If our arms just jump somewhere, hijack those labels so we don't
   4432      generate jumps to jumps.  */
   4433 
   4434   if (tree then_goto = find_goto_label (then_))
   4435     {
   4436       true_label = GOTO_DESTINATION (then_goto);
   4437       then_ = NULL;
   4438       then_se = false;
   4439     }
   4440 
   4441   if (tree else_goto = find_goto_label (else_))
   4442     {
   4443       false_label = GOTO_DESTINATION (else_goto);
   4444       else_ = NULL;
   4445       else_se = false;
   4446     }
   4447 
   4448   /* If we aren't hijacking a label for the 'then' branch, it falls through.  */
   4449   if (true_label)
   4450     true_label_p = &true_label;
   4451   else
   4452     true_label_p = NULL;
   4453 
   4454   /* The 'else' branch also needs a label if it contains interesting code.  */
   4455   if (false_label || else_se)
   4456     false_label_p = &false_label;
   4457   else
   4458     false_label_p = NULL;
   4459 
   4460   /* If there was nothing else in our arms, just forward the label(s).  */
   4461   if (!then_se && !else_se)
   4462     return shortcut_cond_r (pred, true_label_p, false_label_p,
   4463 			    EXPR_LOC_OR_LOC (expr, input_location), condition_uid);
   4464 
   4465   /* If our last subexpression already has a terminal label, reuse it.  */
   4466   if (else_se)
   4467     t = expr_last (else_);
   4468   else if (then_se)
   4469     t = expr_last (then_);
   4470   else
   4471     t = NULL;
   4472   if (t && TREE_CODE (t) == LABEL_EXPR)
   4473     end_label = LABEL_EXPR_LABEL (t);
   4474 
   4475   /* If we don't care about jumping to the 'else' branch, jump to the end
   4476      if the condition is false.  */
   4477   if (!false_label_p)
   4478     false_label_p = &end_label;
   4479 
   4480   /* We only want to emit these labels if we aren't hijacking them.  */
   4481   emit_end = (end_label == NULL_TREE);
   4482   emit_false = (false_label == NULL_TREE);
   4483 
   4484   /* We only emit the jump over the else clause if we have to--if the
   4485      then clause may fall through.  Otherwise we can wind up with a
   4486      useless jump and a useless label at the end of gimplified code,
   4487      which will cause us to think that this conditional as a whole
   4488      falls through even if it doesn't.  If we then inline a function
   4489      which ends with such a condition, that can cause us to issue an
   4490      inappropriate warning about control reaching the end of a
   4491      non-void function.  */
   4492   jump_over_else = block_may_fallthru (then_);
   4493 
   4494   pred = shortcut_cond_r (pred, true_label_p, false_label_p,
   4495 			  EXPR_LOC_OR_LOC (expr, input_location),
   4496 			  condition_uid);
   4497 
   4498   expr = NULL;
   4499   append_to_statement_list (pred, &expr);
   4500 
   4501   append_to_statement_list (then_, &expr);
   4502   if (else_se)
   4503     {
   4504       if (jump_over_else)
   4505 	{
   4506 	  tree last = expr_last (expr);
   4507 	  t = build_and_jump (&end_label);
   4508 	  if (rexpr_has_location (last))
   4509 	    SET_EXPR_LOCATION (t, rexpr_location (last));
   4510 	  append_to_statement_list (t, &expr);
   4511 	}
   4512       if (emit_false)
   4513 	{
   4514 	  t = build1 (LABEL_EXPR, void_type_node, false_label);
   4515 	  append_to_statement_list (t, &expr);
   4516 	}
   4517       append_to_statement_list (else_, &expr);
   4518     }
   4519   if (emit_end && end_label)
   4520     {
   4521       t = build1 (LABEL_EXPR, void_type_node, end_label);
   4522       append_to_statement_list (t, &expr);
   4523     }
   4524 
   4525   return expr;
   4526 }
   4527 
   4528 /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE.  */
   4529 
   4530 tree
   4531 gimple_boolify (tree expr)
   4532 {
   4533   tree type = TREE_TYPE (expr);
   4534   location_t loc = EXPR_LOCATION (expr);
   4535 
   4536   if (TREE_CODE (expr) == NE_EXPR
   4537       && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
   4538       && integer_zerop (TREE_OPERAND (expr, 1)))
   4539     {
   4540       tree call = TREE_OPERAND (expr, 0);
   4541       tree fn = get_callee_fndecl (call);
   4542 
   4543       /* For __builtin_expect ((long) (x), y) recurse into x as well
   4544 	 if x is truth_value_p.  */
   4545       if (fn
   4546 	  && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
   4547 	  && call_expr_nargs (call) == 2)
   4548 	{
   4549 	  tree arg = CALL_EXPR_ARG (call, 0);
   4550 	  if (arg)
   4551 	    {
   4552 	      if (TREE_CODE (arg) == NOP_EXPR
   4553 		  && TREE_TYPE (arg) == TREE_TYPE (call))
   4554 		arg = TREE_OPERAND (arg, 0);
   4555 	      if (truth_value_p (TREE_CODE (arg)))
   4556 		{
   4557 		  arg = gimple_boolify (arg);
   4558 		  CALL_EXPR_ARG (call, 0)
   4559 		    = fold_convert_loc (loc, TREE_TYPE (call), arg);
   4560 		}
   4561 	    }
   4562 	}
   4563     }
   4564 
   4565   switch (TREE_CODE (expr))
   4566     {
   4567     case TRUTH_AND_EXPR:
   4568     case TRUTH_OR_EXPR:
   4569     case TRUTH_XOR_EXPR:
   4570     case TRUTH_ANDIF_EXPR:
   4571     case TRUTH_ORIF_EXPR:
   4572       /* Also boolify the arguments of truth exprs.  */
   4573       TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
   4574       /* FALLTHRU */
   4575 
   4576     case TRUTH_NOT_EXPR:
   4577       TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
   4578 
   4579       /* These expressions always produce boolean results.  */
   4580       if (TREE_CODE (type) != BOOLEAN_TYPE)
   4581 	TREE_TYPE (expr) = boolean_type_node;
   4582       return expr;
   4583 
   4584     case ANNOTATE_EXPR:
   4585       switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
   4586 	{
   4587 	case annot_expr_ivdep_kind:
   4588 	case annot_expr_unroll_kind:
   4589 	case annot_expr_no_vector_kind:
   4590 	case annot_expr_vector_kind:
   4591 	case annot_expr_parallel_kind:
   4592 	case annot_expr_maybe_infinite_kind:
   4593 	  TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
   4594 	  if (TREE_CODE (type) != BOOLEAN_TYPE)
   4595 	    TREE_TYPE (expr) = boolean_type_node;
   4596 	  return expr;
   4597 	default:
   4598 	  gcc_unreachable ();
   4599 	}
   4600 
   4601     default:
   4602       if (COMPARISON_CLASS_P (expr))
   4603 	{
   4604 	  /* These expressions always produce boolean results.  */
   4605 	  if (TREE_CODE (type) != BOOLEAN_TYPE)
   4606 	    TREE_TYPE (expr) = boolean_type_node;
   4607 	  return expr;
   4608 	}
   4609       /* Other expressions that get here must have boolean values, but
   4610 	 might need to be converted to the appropriate mode.  */
   4611       if (TREE_CODE (type) == BOOLEAN_TYPE)
   4612 	return expr;
   4613       return fold_convert_loc (loc, boolean_type_node, expr);
   4614     }
   4615 }
   4616 
   4617 /* Given a conditional expression *EXPR_P without side effects, gimplify
   4618    its operands.  New statements are inserted to PRE_P.  */
   4619 
   4620 static enum gimplify_status
   4621 gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
   4622 {
   4623   tree expr = *expr_p, cond;
   4624   enum gimplify_status ret, tret;
   4625   enum tree_code code;
   4626 
   4627   cond = gimple_boolify (COND_EXPR_COND (expr));
   4628 
   4629   /* We need to handle && and || specially, as their gimplification
   4630      creates pure cond_expr, thus leading to an infinite cycle otherwise.  */
   4631   code = TREE_CODE (cond);
   4632   if (code == TRUTH_ANDIF_EXPR)
   4633     TREE_SET_CODE (cond, TRUTH_AND_EXPR);
   4634   else if (code == TRUTH_ORIF_EXPR)
   4635     TREE_SET_CODE (cond, TRUTH_OR_EXPR);
   4636   ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_val, fb_rvalue);
   4637   COND_EXPR_COND (*expr_p) = cond;
   4638 
   4639   tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
   4640 			is_gimple_val, fb_rvalue);
   4641   ret = MIN (ret, tret);
   4642   tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
   4643 			is_gimple_val, fb_rvalue);
   4644 
   4645   return MIN (ret, tret);
   4646 }
   4647 
   4648 /* Return true if evaluating EXPR could trap.
   4649    EXPR is GENERIC, while tree_could_trap_p can be called
   4650    only on GIMPLE.  */
   4651 
   4652 bool
   4653 generic_expr_could_trap_p (tree expr)
   4654 {
   4655   unsigned i, n;
   4656 
   4657   if (!expr || is_gimple_val (expr))
   4658     return false;
   4659 
   4660   if (!EXPR_P (expr) || tree_could_trap_p (expr))
   4661     return true;
   4662 
   4663   n = TREE_OPERAND_LENGTH (expr);
   4664   for (i = 0; i < n; i++)
   4665     if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
   4666       return true;
   4667 
   4668   return false;
   4669 }
   4670 
   4671 /* Associate the condition STMT with the discriminator UID.  STMTs that are
   4672    broken down with ANDIF/ORIF from the same Boolean expression should be given
   4673    the same UID; 'if (a && b && c) { if (d || e) ... } ...' should yield the
   4674    { a: 1, b: 1, c: 1, d: 2, e: 2 } when gimplification is done.  This is used
   4675    for condition coverage.  */
   4676 static void
   4677 gimple_associate_condition_with_expr (struct function *fn, gcond *stmt,
   4678 				      unsigned uid)
   4679 {
   4680   if (!condition_coverage_flag)
   4681     return;
   4682 
   4683   if (!fn->cond_uids)
   4684     fn->cond_uids = new hash_map <gcond*, unsigned> ();
   4685 
   4686   fn->cond_uids->put (stmt, uid);
   4687 }
   4688 
   4689 /*  Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
   4690     into
   4691 
   4692     if (p)			if (p)
   4693       t1 = a;			  a;
   4694     else		or	else
   4695       t1 = b;			  b;
   4696     t1;
   4697 
   4698     The second form is used when *EXPR_P is of type void.
   4699 
   4700     PRE_P points to the list where side effects that must happen before
   4701       *EXPR_P should be stored.  */
   4702 
   4703 static enum gimplify_status
   4704 gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
   4705 {
   4706   tree expr = *expr_p;
   4707   tree type = TREE_TYPE (expr);
   4708   location_t loc = EXPR_LOCATION (expr);
   4709   tree tmp, arm1, arm2;
   4710   enum gimplify_status ret;
   4711   tree label_true, label_false, label_cont;
   4712   bool have_then_clause_p, have_else_clause_p;
   4713   gcond *cond_stmt;
   4714   enum tree_code pred_code;
   4715   gimple_seq seq = NULL;
   4716 
   4717   /* If this COND_EXPR has a value, copy the values into a temporary within
   4718      the arms.  */
   4719   if (!VOID_TYPE_P (type))
   4720     {
   4721       tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
   4722       tree result;
   4723 
   4724       /* If either an rvalue is ok or we do not require an lvalue, create the
   4725 	 temporary.  But we cannot do that if the type is addressable.  */
   4726       if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
   4727 	  && !TREE_ADDRESSABLE (type))
   4728 	{
   4729 	  if (gimplify_ctxp->allow_rhs_cond_expr
   4730 	      /* If either branch has side effects or could trap, it can't be
   4731 		 evaluated unconditionally.  */
   4732 	      && !TREE_SIDE_EFFECTS (then_)
   4733 	      && !generic_expr_could_trap_p (then_)
   4734 	      && !TREE_SIDE_EFFECTS (else_)
   4735 	      && !generic_expr_could_trap_p (else_))
   4736 	    return gimplify_pure_cond_expr (expr_p, pre_p);
   4737 
   4738 	  tmp = create_tmp_var (type, "iftmp");
   4739 	  result = tmp;
   4740 	}
   4741 
   4742       /* Otherwise, only create and copy references to the values.  */
   4743       else
   4744 	{
   4745 	  type = build_pointer_type (type);
   4746 
   4747 	  if (!VOID_TYPE_P (TREE_TYPE (then_)))
   4748 	    then_ = build_fold_addr_expr_loc (loc, then_);
   4749 
   4750 	  if (!VOID_TYPE_P (TREE_TYPE (else_)))
   4751 	    else_ = build_fold_addr_expr_loc (loc, else_);
   4752 
   4753 	  expr
   4754 	    = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
   4755 
   4756 	  tmp = create_tmp_var (type, "iftmp");
   4757 	  result = build_simple_mem_ref_loc (loc, tmp);
   4758 	}
   4759 
   4760       /* Build the new then clause, `tmp = then_;'.  But don't build the
   4761 	 assignment if the value is void; in C++ it can be if it's a throw.  */
   4762       if (!VOID_TYPE_P (TREE_TYPE (then_)))
   4763 	TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
   4764 
   4765       /* Similarly, build the new else clause, `tmp = else_;'.  */
   4766       if (!VOID_TYPE_P (TREE_TYPE (else_)))
   4767 	TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
   4768 
   4769       TREE_TYPE (expr) = void_type_node;
   4770       recalculate_side_effects (expr);
   4771 
   4772       /* Move the COND_EXPR to the prequeue.  */
   4773       gimplify_stmt (&expr, pre_p);
   4774 
   4775       *expr_p = result;
   4776       return GS_ALL_DONE;
   4777     }
   4778 
   4779   /* Remove any COMPOUND_EXPR so the following cases will be caught.  */
   4780   STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
   4781   if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
   4782     gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
   4783 
   4784   /* Make sure the condition has BOOLEAN_TYPE.  */
   4785   TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
   4786 
   4787   /* Break apart && and || conditions.  */
   4788   if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
   4789       || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
   4790     {
   4791       expr = shortcut_cond_expr (expr, next_cond_uid ());
   4792 
   4793       if (expr != *expr_p)
   4794 	{
   4795 	  *expr_p = expr;
   4796 
   4797 	  /* We can't rely on gimplify_expr to re-gimplify the expanded
   4798 	     form properly, as cleanups might cause the target labels to be
   4799 	     wrapped in a TRY_FINALLY_EXPR.  To prevent that, we need to
   4800 	     set up a conditional context.  */
   4801 	  gimple_push_condition ();
   4802 	  gimplify_stmt (expr_p, &seq);
   4803 	  gimple_pop_condition (pre_p);
   4804 	  gimple_seq_add_seq (pre_p, seq);
   4805 
   4806 	  return GS_ALL_DONE;
   4807 	}
   4808     }
   4809 
   4810   /* Now do the normal gimplification.  */
   4811 
   4812   /* Gimplify condition.  */
   4813   ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
   4814 		       is_gimple_condexpr_for_cond, fb_rvalue);
   4815   if (ret == GS_ERROR)
   4816     return GS_ERROR;
   4817   gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
   4818 
   4819   gimple_push_condition ();
   4820 
   4821   have_then_clause_p = have_else_clause_p = false;
   4822   label_true = find_goto_label (TREE_OPERAND (expr, 1));
   4823   if (label_true
   4824       && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
   4825       /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
   4826 	 have different locations, otherwise we end up with incorrect
   4827 	 location information on the branches.  */
   4828       && (optimize
   4829 	  || !EXPR_HAS_LOCATION (expr)
   4830 	  || !rexpr_has_location (label_true)
   4831 	  || EXPR_LOCATION (expr) == rexpr_location (label_true)))
   4832     {
   4833       have_then_clause_p = true;
   4834       label_true = GOTO_DESTINATION (label_true);
   4835     }
   4836   else
   4837     label_true = create_artificial_label (UNKNOWN_LOCATION);
   4838   label_false = find_goto_label (TREE_OPERAND (expr, 2));
   4839   if (label_false
   4840       && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
   4841       /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
   4842 	 have different locations, otherwise we end up with incorrect
   4843 	 location information on the branches.  */
   4844       && (optimize
   4845 	  || !EXPR_HAS_LOCATION (expr)
   4846 	  || !rexpr_has_location (label_false)
   4847 	  || EXPR_LOCATION (expr) == rexpr_location (label_false)))
   4848     {
   4849       have_else_clause_p = true;
   4850       label_false = GOTO_DESTINATION (label_false);
   4851     }
   4852   else
   4853     label_false = create_artificial_label (UNKNOWN_LOCATION);
   4854 
   4855   unsigned cond_uid = EXPR_COND_UID (expr);
   4856   if (cond_uid == 0)
   4857     cond_uid = next_cond_uid ();
   4858 
   4859   gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
   4860 				 &arm2);
   4861   cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
   4862 				 label_false);
   4863   gimple_set_location (cond_stmt, EXPR_LOCATION (expr));
   4864   gimple_associate_condition_with_expr (cfun, cond_stmt, cond_uid);
   4865   copy_warning (cond_stmt, COND_EXPR_COND (expr));
   4866   gimplify_seq_add_stmt (&seq, cond_stmt);
   4867   gimple_stmt_iterator gsi = gsi_last (seq);
   4868   maybe_fold_stmt (&gsi);
   4869 
   4870   label_cont = NULL_TREE;
   4871   if (!have_then_clause_p)
   4872     {
   4873       /* For if (...) {} else { code; } put label_true after
   4874 	 the else block.  */
   4875       if (TREE_OPERAND (expr, 1) == NULL_TREE
   4876 	  && !have_else_clause_p
   4877 	  && TREE_OPERAND (expr, 2) != NULL_TREE)
   4878 	{
   4879 	  /* For if (0) {} else { code; } tell -Wimplicit-fallthrough
   4880 	     handling that label_cont == label_true can be only reached
   4881 	     through fallthrough from { code; }.  */
   4882 	  if (integer_zerop (COND_EXPR_COND (expr)))
   4883 	    UNUSED_LABEL_P (label_true) = 1;
   4884 	  label_cont = label_true;
   4885 	}
   4886       else
   4887 	{
   4888 	  bool then_side_effects
   4889 	    = (TREE_OPERAND (expr, 1)
   4890 	       && TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)));
   4891 	  gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
   4892 	  have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
   4893 	  /* For if (...) { code; } else {} or
   4894 	     if (...) { code; } else goto label; or
   4895 	     if (...) { code; return; } else { ... }
   4896 	     label_cont isn't needed.  */
   4897 	  if (!have_else_clause_p
   4898 	      && TREE_OPERAND (expr, 2) != NULL_TREE
   4899 	      && gimple_seq_may_fallthru (seq))
   4900 	    {
   4901 	      gimple *g;
   4902 	      label_cont = create_artificial_label (UNKNOWN_LOCATION);
   4903 
   4904 	      /* For if (0) { non-side-effect-code } else { code }
   4905 		 tell -Wimplicit-fallthrough handling that label_cont can
   4906 		 be only reached through fallthrough from { code }.  */
   4907 	      if (integer_zerop (COND_EXPR_COND (expr)))
   4908 		{
   4909 		  UNUSED_LABEL_P (label_true) = 1;
   4910 		  if (!then_side_effects)
   4911 		    UNUSED_LABEL_P (label_cont) = 1;
   4912 		}
   4913 
   4914 	      g = gimple_build_goto (label_cont);
   4915 
   4916 	      /* GIMPLE_COND's are very low level; they have embedded
   4917 		 gotos.  This particular embedded goto should not be marked
   4918 		 with the location of the original COND_EXPR, as it would
   4919 		 correspond to the COND_EXPR's condition, not the ELSE or the
   4920 		 THEN arms.  To avoid marking it with the wrong location, flag
   4921 		 it as "no location".  */
   4922 	      gimple_set_do_not_emit_location (g);
   4923 
   4924 	      gimplify_seq_add_stmt (&seq, g);
   4925 	    }
   4926 	}
   4927     }
   4928   if (!have_else_clause_p)
   4929     {
   4930       /* For if (1) { code } or if (1) { code } else { non-side-effect-code }
   4931 	 tell -Wimplicit-fallthrough handling that label_false can be only
   4932 	 reached through fallthrough from { code }.  */
   4933       if (integer_nonzerop (COND_EXPR_COND (expr))
   4934 	  && (TREE_OPERAND (expr, 2) == NULL_TREE
   4935 	      || !TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2))))
   4936 	UNUSED_LABEL_P (label_false) = 1;
   4937       gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
   4938       have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
   4939     }
   4940   if (label_cont)
   4941     gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
   4942 
   4943   gimple_pop_condition (pre_p);
   4944   gimple_seq_add_seq (pre_p, seq);
   4945 
   4946   if (ret == GS_ERROR)
   4947     ; /* Do nothing.  */
   4948   else if (have_then_clause_p || have_else_clause_p)
   4949     ret = GS_ALL_DONE;
   4950   else
   4951     {
   4952       /* Both arms are empty; replace the COND_EXPR with its predicate.  */
   4953       expr = TREE_OPERAND (expr, 0);
   4954       gimplify_stmt (&expr, pre_p);
   4955     }
   4956 
   4957   *expr_p = NULL;
   4958   return ret;
   4959 }
   4960 
   4961 /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
   4962    to be marked addressable.
   4963 
   4964    We cannot rely on such an expression being directly markable if a temporary
   4965    has been created by the gimplification.  In this case, we create another
   4966    temporary and initialize it with a copy, which will become a store after we
   4967    mark it addressable.  This can happen if the front-end passed us something
   4968    that it could not mark addressable yet, like a Fortran pass-by-reference
   4969    parameter (int) floatvar.  */
   4970 
   4971 static void
   4972 prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
   4973 {
   4974   while (handled_component_p (*expr_p))
   4975     expr_p = &TREE_OPERAND (*expr_p, 0);
   4976 
   4977   /* Do not allow an SSA name as the temporary.  */
   4978   if (is_gimple_reg (*expr_p))
   4979     *expr_p = internal_get_tmp_var (*expr_p, seq_p, NULL, false, false, true);
   4980 }
   4981 
   4982 /* A subroutine of gimplify_modify_expr.  Replace a MODIFY_EXPR with
   4983    a call to __builtin_memcpy.  */
   4984 
   4985 static enum gimplify_status
   4986 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
   4987     				gimple_seq *seq_p)
   4988 {
   4989   tree t, to, to_ptr, from, from_ptr;
   4990   gcall *gs;
   4991   location_t loc = EXPR_LOCATION (*expr_p);
   4992 
   4993   to = TREE_OPERAND (*expr_p, 0);
   4994   from = TREE_OPERAND (*expr_p, 1);
   4995   gcc_assert (ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (to)))
   4996 	      && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (from))));
   4997 
   4998   /* Mark the RHS addressable.  Beware that it may not be possible to do so
   4999      directly if a temporary has been created by the gimplification.  */
   5000   prepare_gimple_addressable (&from, seq_p);
   5001 
   5002   mark_addressable (from);
   5003   from_ptr = build_fold_addr_expr_loc (loc, from);
   5004   gimplify_arg (&from_ptr, seq_p, loc);
   5005 
   5006   mark_addressable (to);
   5007   to_ptr = build_fold_addr_expr_loc (loc, to);
   5008   gimplify_arg (&to_ptr, seq_p, loc);
   5009 
   5010   t = builtin_decl_implicit (BUILT_IN_MEMCPY);
   5011 
   5012   gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
   5013   gimple_call_set_alloca_for_var (gs, true);
   5014 
   5015   if (want_value)
   5016     {
   5017       /* tmp = memcpy() */
   5018       t = create_tmp_var (TREE_TYPE (to_ptr));
   5019       gimple_call_set_lhs (gs, t);
   5020       gimplify_seq_add_stmt (seq_p, gs);
   5021 
   5022       *expr_p = build_simple_mem_ref (t);
   5023       return GS_ALL_DONE;
   5024     }
   5025 
   5026   gimplify_seq_add_stmt (seq_p, gs);
   5027   *expr_p = NULL;
   5028   return GS_ALL_DONE;
   5029 }
   5030 
   5031 /* A subroutine of gimplify_modify_expr.  Replace a MODIFY_EXPR with
   5032    a call to __builtin_memset.  In this case we know that the RHS is
   5033    a CONSTRUCTOR with an empty element list.  */
   5034 
   5035 static enum gimplify_status
   5036 gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
   5037     				gimple_seq *seq_p)
   5038 {
   5039   tree t, from, to, to_ptr;
   5040   gcall *gs;
   5041   location_t loc = EXPR_LOCATION (*expr_p);
   5042 
   5043   /* Assert our assumptions, to abort instead of producing wrong code
   5044      silently if they are not met.  Beware that the RHS CONSTRUCTOR might
   5045      not be immediately exposed.  */
   5046   from = TREE_OPERAND (*expr_p, 1);
   5047   if (TREE_CODE (from) == WITH_SIZE_EXPR)
   5048     from = TREE_OPERAND (from, 0);
   5049 
   5050   gcc_assert (TREE_CODE (from) == CONSTRUCTOR
   5051 	      && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
   5052 
   5053   /* Now proceed.  */
   5054   to = TREE_OPERAND (*expr_p, 0);
   5055   gcc_assert (ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (to))));
   5056 
   5057   to_ptr = build_fold_addr_expr_loc (loc, to);
   5058   gimplify_arg (&to_ptr, seq_p, loc);
   5059   t = builtin_decl_implicit (BUILT_IN_MEMSET);
   5060 
   5061   gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
   5062 
   5063   if (want_value)
   5064     {
   5065       /* tmp = memset() */
   5066       t = create_tmp_var (TREE_TYPE (to_ptr));
   5067       gimple_call_set_lhs (gs, t);
   5068       gimplify_seq_add_stmt (seq_p, gs);
   5069 
   5070       *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
   5071       return GS_ALL_DONE;
   5072     }
   5073 
   5074   gimplify_seq_add_stmt (seq_p, gs);
   5075   *expr_p = NULL;
   5076   return GS_ALL_DONE;
   5077 }
   5078 
   5079 /* A subroutine of gimplify_init_ctor_preeval.  Called via walk_tree,
   5080    determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
   5081    assignment.  Return non-null if we detect a potential overlap.  */
   5082 
   5083 struct gimplify_init_ctor_preeval_data
   5084 {
   5085   /* The base decl of the lhs object.  May be NULL, in which case we
   5086      have to assume the lhs is indirect.  */
   5087   tree lhs_base_decl;
   5088 
   5089   /* The alias set of the lhs object.  */
   5090   alias_set_type lhs_alias_set;
   5091 };
   5092 
   5093 static tree
   5094 gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
   5095 {
   5096   struct gimplify_init_ctor_preeval_data *data
   5097     = (struct gimplify_init_ctor_preeval_data *) xdata;
   5098   tree t = *tp;
   5099 
   5100   /* If we find the base object, obviously we have overlap.  */
   5101   if (data->lhs_base_decl == t)
   5102     return t;
   5103 
   5104   /* If the constructor component is indirect, determine if we have a
   5105      potential overlap with the lhs.  The only bits of information we
   5106      have to go on at this point are addressability and alias sets.  */
   5107   if ((INDIRECT_REF_P (t)
   5108        || TREE_CODE (t) == MEM_REF)
   5109       && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
   5110       && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
   5111     return t;
   5112 
   5113   /* If the constructor component is a call, determine if it can hide a
   5114      potential overlap with the lhs through an INDIRECT_REF like above.
   5115      ??? Ugh - this is completely broken.  In fact this whole analysis
   5116      doesn't look conservative.  */
   5117   if (TREE_CODE (t) == CALL_EXPR)
   5118     {
   5119       tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
   5120 
   5121       for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
   5122 	if (POINTER_TYPE_P (TREE_VALUE (type))
   5123 	    && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
   5124 	    && alias_sets_conflict_p (data->lhs_alias_set,
   5125 				      get_alias_set
   5126 				        (TREE_TYPE (TREE_VALUE (type)))))
   5127 	  return t;
   5128     }
   5129 
   5130   if (IS_TYPE_OR_DECL_P (t))
   5131     *walk_subtrees = 0;
   5132   return NULL;
   5133 }
   5134 
   5135 /* A subroutine of gimplify_init_constructor.  Pre-evaluate EXPR,
   5136    force values that overlap with the lhs (as described by *DATA)
   5137    into temporaries.  */
   5138 
   5139 static void
   5140 gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   5141 			    struct gimplify_init_ctor_preeval_data *data)
   5142 {
   5143   enum gimplify_status one;
   5144 
   5145   /* If the value is constant, then there's nothing to pre-evaluate.  */
   5146   if (TREE_CONSTANT (*expr_p))
   5147     {
   5148       /* Ensure it does not have side effects, it might contain a reference to
   5149 	 the object we're initializing.  */
   5150       gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
   5151       return;
   5152     }
   5153 
   5154   /* If the type has non-trivial constructors, we can't pre-evaluate.  */
   5155   if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
   5156     return;
   5157 
   5158   /* Recurse for nested constructors.  */
   5159   if (TREE_CODE (*expr_p) == CONSTRUCTOR)
   5160     {
   5161       unsigned HOST_WIDE_INT ix;
   5162       constructor_elt *ce;
   5163       vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
   5164 
   5165       FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
   5166 	gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
   5167 
   5168       return;
   5169     }
   5170 
   5171   /* If this is a variable sized type, we must remember the size.  */
   5172   maybe_with_size_expr (expr_p);
   5173 
   5174   /* Gimplify the constructor element to something appropriate for the rhs
   5175      of a MODIFY_EXPR.  Given that we know the LHS is an aggregate, we know
   5176      the gimplifier will consider this a store to memory.  Doing this
   5177      gimplification now means that we won't have to deal with complicated
   5178      language-specific trees, nor trees like SAVE_EXPR that can induce
   5179      exponential search behavior.  */
   5180   one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
   5181   if (one == GS_ERROR)
   5182     {
   5183       *expr_p = NULL;
   5184       return;
   5185     }
   5186 
   5187   /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
   5188      with the lhs, since "a = { .x=a }" doesn't make sense.  This will
   5189      always be true for all scalars, since is_gimple_mem_rhs insists on a
   5190      temporary variable for them.  */
   5191   if (DECL_P (*expr_p))
   5192     return;
   5193 
   5194   /* If this is of variable size, we have no choice but to assume it doesn't
   5195      overlap since we can't make a temporary for it.  */
   5196   if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
   5197     return;
   5198 
   5199   /* Otherwise, we must search for overlap ...  */
   5200   if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
   5201     return;
   5202 
   5203   /* ... and if found, force the value into a temporary.  */
   5204   *expr_p = get_formal_tmp_var (*expr_p, pre_p);
   5205 }
   5206 
   5207 /* A subroutine of gimplify_init_ctor_eval.  Create a loop for
   5208    a RANGE_EXPR in a CONSTRUCTOR for an array.
   5209 
   5210       var = lower;
   5211     loop_entry:
   5212       object[var] = value;
   5213       if (var == upper)
   5214 	goto loop_exit;
   5215       var = var + 1;
   5216       goto loop_entry;
   5217     loop_exit:
   5218 
   5219    We increment var _after_ the loop exit check because we might otherwise
   5220    fail if upper == TYPE_MAX_VALUE (type for upper).
   5221 
   5222    Note that we never have to deal with SAVE_EXPRs here, because this has
   5223    already been taken care of for us, in gimplify_init_ctor_preeval().  */
   5224 
   5225 static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
   5226 				     gimple_seq *, bool);
   5227 
   5228 static void
   5229 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
   5230 			       tree value, tree array_elt_type,
   5231 			       gimple_seq *pre_p, bool cleared)
   5232 {
   5233   tree loop_entry_label, loop_exit_label, fall_thru_label;
   5234   tree var, var_type, cref, tmp;
   5235 
   5236   loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
   5237   loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
   5238   fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
   5239 
   5240   /* Create and initialize the index variable.  */
   5241   var_type = TREE_TYPE (upper);
   5242   var = create_tmp_var (var_type);
   5243   gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
   5244 
   5245   /* Add the loop entry label.  */
   5246   gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
   5247 
   5248   /* Build the reference.  */
   5249   cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
   5250 		 var, NULL_TREE, NULL_TREE);
   5251 
   5252   /* If we are a constructor, just call gimplify_init_ctor_eval to do
   5253      the store.  Otherwise just assign value to the reference.  */
   5254 
   5255   if (TREE_CODE (value) == CONSTRUCTOR)
   5256     /* NB we might have to call ourself recursively through
   5257        gimplify_init_ctor_eval if the value is a constructor.  */
   5258     gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
   5259 			     pre_p, cleared);
   5260   else
   5261     {
   5262       if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue)
   5263 	  != GS_ERROR)
   5264 	gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
   5265     }
   5266 
   5267   /* We exit the loop when the index var is equal to the upper bound.  */
   5268   gimplify_seq_add_stmt (pre_p,
   5269 			 gimple_build_cond (EQ_EXPR, var, upper,
   5270 					    loop_exit_label, fall_thru_label));
   5271 
   5272   gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
   5273 
   5274   /* Otherwise, increment the index var...  */
   5275   tmp = build2 (PLUS_EXPR, var_type, var,
   5276 		fold_convert (var_type, integer_one_node));
   5277   gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
   5278 
   5279   /* ...and jump back to the loop entry.  */
   5280   gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
   5281 
   5282   /* Add the loop exit label.  */
   5283   gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
   5284 }
   5285 
   5286 /* A subroutine of gimplify_init_constructor.  Generate individual
   5287    MODIFY_EXPRs for a CONSTRUCTOR.  OBJECT is the LHS against which the
   5288    assignments should happen.  ELTS is the CONSTRUCTOR_ELTS of the
   5289    CONSTRUCTOR.  CLEARED is true if the entire LHS object has been
   5290    zeroed first.  */
   5291 
   5292 static void
   5293 gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
   5294 			 gimple_seq *pre_p, bool cleared)
   5295 {
   5296   tree array_elt_type = NULL;
   5297   unsigned HOST_WIDE_INT ix;
   5298   tree purpose, value;
   5299 
   5300   if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
   5301     array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
   5302 
   5303   FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
   5304     {
   5305       tree cref;
   5306 
   5307       /* NULL values are created above for gimplification errors.  */
   5308       if (value == NULL)
   5309 	continue;
   5310 
   5311       if (cleared && initializer_zerop (value))
   5312 	continue;
   5313 
   5314       /* ??? Here's to hoping the front end fills in all of the indices,
   5315 	 so we don't have to figure out what's missing ourselves.  */
   5316       gcc_assert (purpose);
   5317 
   5318       /* Skip zero-sized fields, unless value has side-effects.  This can
   5319 	 happen with calls to functions returning a empty type, which
   5320 	 we shouldn't discard.  As a number of downstream passes don't
   5321 	 expect sets of empty type fields, we rely on the gimplification of
   5322 	 the MODIFY_EXPR we make below to drop the assignment statement.  */
   5323       if (!TREE_SIDE_EFFECTS (value)
   5324 	  && TREE_CODE (purpose) == FIELD_DECL
   5325 	  && is_empty_type (TREE_TYPE (purpose)))
   5326 	continue;
   5327 
   5328       /* If we have a RANGE_EXPR, we have to build a loop to assign the
   5329 	 whole range.  */
   5330       if (TREE_CODE (purpose) == RANGE_EXPR)
   5331 	{
   5332 	  tree lower = TREE_OPERAND (purpose, 0);
   5333 	  tree upper = TREE_OPERAND (purpose, 1);
   5334 
   5335 	  /* If the lower bound is equal to upper, just treat it as if
   5336 	     upper was the index.  */
   5337 	  if (simple_cst_equal (lower, upper))
   5338 	    purpose = upper;
   5339 	  else
   5340 	    {
   5341 	      gimplify_init_ctor_eval_range (object, lower, upper, value,
   5342 					     array_elt_type, pre_p, cleared);
   5343 	      continue;
   5344 	    }
   5345 	}
   5346 
   5347       if (array_elt_type)
   5348 	{
   5349 	  /* Do not use bitsizetype for ARRAY_REF indices.  */
   5350 	  if (TYPE_DOMAIN (TREE_TYPE (object)))
   5351 	    purpose
   5352 	      = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
   5353 			      purpose);
   5354 	  cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
   5355 			 purpose, NULL_TREE, NULL_TREE);
   5356 	}
   5357       else
   5358 	{
   5359 	  gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
   5360 	  cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
   5361 			 unshare_expr (object), purpose, NULL_TREE);
   5362 	}
   5363 
   5364       if (TREE_CODE (value) == CONSTRUCTOR
   5365 	  && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
   5366 	gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
   5367 				 pre_p, cleared);
   5368       else
   5369 	{
   5370 	  tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
   5371 	  gimplify_and_add (init, pre_p);
   5372 	  ggc_free (init);
   5373 	}
   5374     }
   5375 }
   5376 
   5377 /* Return the appropriate RHS predicate for this LHS.  */
   5378 
   5379 gimple_predicate
   5380 rhs_predicate_for (tree lhs)
   5381 {
   5382   if (is_gimple_reg (lhs))
   5383     return is_gimple_reg_rhs_or_call;
   5384   else
   5385     return is_gimple_mem_rhs_or_call;
   5386 }
   5387 
   5388 /* Return the initial guess for an appropriate RHS predicate for this LHS,
   5389    before the LHS has been gimplified.  */
   5390 
   5391 static gimple_predicate
   5392 initial_rhs_predicate_for (tree lhs)
   5393 {
   5394   if (is_gimple_reg_type (TREE_TYPE (lhs)))
   5395     return is_gimple_reg_rhs_or_call;
   5396   else
   5397     return is_gimple_mem_rhs_or_call;
   5398 }
   5399 
   5400 /* Gimplify a C99 compound literal expression.  This just means adding
   5401    the DECL_EXPR before the current statement and using its anonymous
   5402    decl instead.  */
   5403 
   5404 static enum gimplify_status
   5405 gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
   5406 				bool (*gimple_test_f) (tree),
   5407 				fallback_t fallback)
   5408 {
   5409   tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
   5410   tree decl = DECL_EXPR_DECL (decl_s);
   5411   tree init = DECL_INITIAL (decl);
   5412   /* Mark the decl as addressable if the compound literal
   5413      expression is addressable now, otherwise it is marked too late
   5414      after we gimplify the initialization expression.  */
   5415   if (TREE_ADDRESSABLE (*expr_p))
   5416     TREE_ADDRESSABLE (decl) = 1;
   5417   /* Otherwise, if we don't need an lvalue and have a literal directly
   5418      substitute it.  Check if it matches the gimple predicate, as
   5419      otherwise we'd generate a new temporary, and we can as well just
   5420      use the decl we already have.  */
   5421   else if (!TREE_ADDRESSABLE (decl)
   5422 	   && !TREE_THIS_VOLATILE (decl)
   5423 	   && init
   5424 	   && (fallback & fb_lvalue) == 0
   5425 	   && gimple_test_f (init))
   5426     {
   5427       *expr_p = init;
   5428       return GS_OK;
   5429     }
   5430 
   5431   /* If the decl is not addressable, then it is being used in some
   5432      expression or on the right hand side of a statement, and it can
   5433      be put into a readonly data section.  */
   5434   if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
   5435     TREE_READONLY (decl) = 1;
   5436 
   5437   /* This decl isn't mentioned in the enclosing block, so add it to the
   5438      list of temps.  FIXME it seems a bit of a kludge to say that
   5439      anonymous artificial vars aren't pushed, but everything else is.  */
   5440   if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
   5441     gimple_add_tmp_var (decl);
   5442 
   5443   gimplify_and_add (decl_s, pre_p);
   5444   *expr_p = decl;
   5445   return GS_OK;
   5446 }
   5447 
   5448 /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
   5449    return a new CONSTRUCTOR if something changed.  */
   5450 
   5451 static tree
   5452 optimize_compound_literals_in_ctor (tree orig_ctor)
   5453 {
   5454   tree ctor = orig_ctor;
   5455   vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
   5456   unsigned int idx, num = vec_safe_length (elts);
   5457 
   5458   for (idx = 0; idx < num; idx++)
   5459     {
   5460       tree value = (*elts)[idx].value;
   5461       tree newval = value;
   5462       if (TREE_CODE (value) == CONSTRUCTOR)
   5463 	newval = optimize_compound_literals_in_ctor (value);
   5464       else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
   5465 	{
   5466 	  tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
   5467 	  tree decl = DECL_EXPR_DECL (decl_s);
   5468 	  tree init = DECL_INITIAL (decl);
   5469 
   5470 	  if (!TREE_ADDRESSABLE (value)
   5471 	      && !TREE_ADDRESSABLE (decl)
   5472 	      && init
   5473 	      && TREE_CODE (init) == CONSTRUCTOR)
   5474 	    newval = optimize_compound_literals_in_ctor (init);
   5475 	}
   5476       if (newval == value)
   5477 	continue;
   5478 
   5479       if (ctor == orig_ctor)
   5480 	{
   5481 	  ctor = copy_node (orig_ctor);
   5482 	  CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
   5483 	  elts = CONSTRUCTOR_ELTS (ctor);
   5484 	}
   5485       (*elts)[idx].value = newval;
   5486     }
   5487   return ctor;
   5488 }
   5489 
   5490 /* A subroutine of gimplify_modify_expr.  Break out elements of a
   5491    CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
   5492 
   5493    Note that we still need to clear any elements that don't have explicit
   5494    initializers, so if not all elements are initialized we keep the
   5495    original MODIFY_EXPR, we just remove all of the constructor elements.
   5496 
   5497    If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
   5498    GS_ERROR if we would have to create a temporary when gimplifying
   5499    this constructor.  Otherwise, return GS_OK.
   5500 
   5501    If NOTIFY_TEMP_CREATION is false, just do the gimplification.  */
   5502 
   5503 static enum gimplify_status
   5504 gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   5505 			   bool want_value, bool notify_temp_creation)
   5506 {
   5507   tree object, ctor, type;
   5508   enum gimplify_status ret;
   5509   vec<constructor_elt, va_gc> *elts;
   5510   bool cleared = false;
   5511   bool is_empty_ctor = false;
   5512   bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR);
   5513 
   5514   gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
   5515 
   5516   if (!notify_temp_creation)
   5517     {
   5518       ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   5519 			   is_gimple_lvalue, fb_lvalue);
   5520       if (ret == GS_ERROR)
   5521 	return ret;
   5522     }
   5523 
   5524   object = TREE_OPERAND (*expr_p, 0);
   5525   ctor = TREE_OPERAND (*expr_p, 1)
   5526     = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
   5527   type = TREE_TYPE (ctor);
   5528   elts = CONSTRUCTOR_ELTS (ctor);
   5529   ret = GS_ALL_DONE;
   5530 
   5531   switch (TREE_CODE (type))
   5532     {
   5533     case RECORD_TYPE:
   5534     case UNION_TYPE:
   5535     case QUAL_UNION_TYPE:
   5536     case ARRAY_TYPE:
   5537       {
   5538 	/* Use readonly data for initializers of this or smaller size
   5539 	   regardless of the num_nonzero_elements / num_unique_nonzero_elements
   5540 	   ratio.  */
   5541 	const HOST_WIDE_INT min_unique_size = 64;
   5542 	/* If num_nonzero_elements / num_unique_nonzero_elements ratio
   5543 	   is smaller than this, use readonly data.  */
   5544 	const int unique_nonzero_ratio = 8;
   5545 	/* True if a single access of the object must be ensured.  This is the
   5546 	   case if the target is volatile, the type is non-addressable and more
   5547 	   than one field need to be assigned.  */
   5548 	const bool ensure_single_access
   5549 	  = TREE_THIS_VOLATILE (object)
   5550 	    && !TREE_ADDRESSABLE (type)
   5551 	    && vec_safe_length (elts) > 1;
   5552 	struct gimplify_init_ctor_preeval_data preeval_data;
   5553 	HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
   5554 	HOST_WIDE_INT num_unique_nonzero_elements;
   5555 	bool complete_p, valid_const_initializer;
   5556 
   5557 	/* Aggregate types must lower constructors to initialization of
   5558 	   individual elements.  The exception is that a CONSTRUCTOR node
   5559 	   with no elements indicates zero-initialization of the whole.  */
   5560 	if (vec_safe_is_empty (elts))
   5561 	  {
   5562 	    if (notify_temp_creation)
   5563 	      return GS_OK;
   5564 
   5565 	    /* The var will be initialized and so appear on lhs of
   5566 	       assignment, it can't be TREE_READONLY anymore.  */
   5567 	    if (VAR_P (object))
   5568 	      TREE_READONLY (object) = 0;
   5569 
   5570 	    is_empty_ctor = true;
   5571 	    break;
   5572 	  }
   5573 
   5574 	/* Fetch information about the constructor to direct later processing.
   5575 	   We might want to make static versions of it in various cases, and
   5576 	   can only do so if it known to be a valid constant initializer.  */
   5577 	valid_const_initializer
   5578 	  = categorize_ctor_elements (ctor, &num_nonzero_elements,
   5579 				      &num_unique_nonzero_elements,
   5580 				      &num_ctor_elements, &complete_p);
   5581 
   5582 	/* If a const aggregate variable is being initialized, then it
   5583 	   should never be a lose to promote the variable to be static.  */
   5584 	if (valid_const_initializer
   5585 	    && num_nonzero_elements > 1
   5586 	    && TREE_READONLY (object)
   5587 	    && VAR_P (object)
   5588 	    && !DECL_REGISTER (object)
   5589 	    && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)
   5590 		|| DECL_MERGEABLE (object))
   5591 	    /* For ctors that have many repeated nonzero elements
   5592 	       represented through RANGE_EXPRs, prefer initializing
   5593 	       those through runtime loops over copies of large amounts
   5594 	       of data from readonly data section.  */
   5595 	    && (num_unique_nonzero_elements
   5596 		> num_nonzero_elements / unique_nonzero_ratio
   5597 		|| ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
   5598 		    <= (unsigned HOST_WIDE_INT) min_unique_size)))
   5599 	  {
   5600 	    if (notify_temp_creation)
   5601 	      return GS_ERROR;
   5602 
   5603 	    DECL_INITIAL (object) = ctor;
   5604 	    TREE_STATIC (object) = 1;
   5605 	    if (!DECL_NAME (object) || DECL_NAMELESS (object))
   5606 	      DECL_NAME (object) = create_tmp_var_name ("C");
   5607 	    walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
   5608 
   5609 	    /* ??? C++ doesn't automatically append a .<number> to the
   5610 	       assembler name, and even when it does, it looks at FE private
   5611 	       data structures to figure out what that number should be,
   5612 	       which are not set for this variable.  I suppose this is
   5613 	       important for local statics for inline functions, which aren't
   5614 	       "local" in the object file sense.  So in order to get a unique
   5615 	       TU-local symbol, we must invoke the lhd version now.  */
   5616 	    lhd_set_decl_assembler_name (object);
   5617 
   5618 	    *expr_p = NULL_TREE;
   5619 	    break;
   5620 	  }
   5621 
   5622 	/* The var will be initialized and so appear on lhs of
   5623 	   assignment, it can't be TREE_READONLY anymore.  */
   5624 	if (VAR_P (object) && !notify_temp_creation)
   5625 	  TREE_READONLY (object) = 0;
   5626 
   5627 	/* If there are "lots" of initialized elements, even discounting
   5628 	   those that are not address constants (and thus *must* be
   5629 	   computed at runtime), then partition the constructor into
   5630 	   constant and non-constant parts.  Block copy the constant
   5631 	   parts in, then generate code for the non-constant parts.  */
   5632 	/* TODO.  There's code in cp/typeck.cc to do this.  */
   5633 
   5634 	if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
   5635 	  /* store_constructor will ignore the clearing of variable-sized
   5636 	     objects.  Initializers for such objects must explicitly set
   5637 	     every field that needs to be set.  */
   5638 	  cleared = false;
   5639 	else if (!complete_p)
   5640 	  /* If the constructor isn't complete, clear the whole object
   5641 	     beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
   5642 
   5643 	     ??? This ought not to be needed.  For any element not present
   5644 	     in the initializer, we should simply set them to zero.  Except
   5645 	     we'd need to *find* the elements that are not present, and that
   5646 	     requires trickery to avoid quadratic compile-time behavior in
   5647 	     large cases or excessive memory use in small cases.  */
   5648 	  cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
   5649 	else if (num_ctor_elements - num_nonzero_elements
   5650 		 > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
   5651 		 && num_nonzero_elements < num_ctor_elements / 4)
   5652 	  /* If there are "lots" of zeros, it's more efficient to clear
   5653 	     the memory and then set the nonzero elements.  */
   5654 	  cleared = true;
   5655 	else if (ensure_single_access && num_nonzero_elements == 0)
   5656 	  /* If a single access to the target must be ensured and all elements
   5657 	     are zero, then it's optimal to clear whatever their number.  */
   5658 	  cleared = true;
   5659 	else
   5660 	  cleared = false;
   5661 
   5662 	/* If there are "lots" of initialized elements, and all of them
   5663 	   are valid address constants, then the entire initializer can
   5664 	   be dropped to memory, and then memcpy'd out.  Don't do this
   5665 	   for sparse arrays, though, as it's more efficient to follow
   5666 	   the standard CONSTRUCTOR behavior of memset followed by
   5667 	   individual element initialization.  Also don't do this for small
   5668 	   all-zero initializers (which aren't big enough to merit
   5669 	   clearing), and don't try to make bitwise copies of
   5670 	   TREE_ADDRESSABLE types.  */
   5671 	if (valid_const_initializer
   5672 	    && complete_p
   5673 	    && !(cleared || num_nonzero_elements == 0)
   5674 	    && !TREE_ADDRESSABLE (type))
   5675 	  {
   5676 	    HOST_WIDE_INT size = int_size_in_bytes (type);
   5677 	    unsigned int align;
   5678 
   5679 	    /* ??? We can still get unbounded array types, at least
   5680 	       from the C++ front end.  This seems wrong, but attempt
   5681 	       to work around it for now.  */
   5682 	    if (size < 0)
   5683 	      {
   5684 		size = int_size_in_bytes (TREE_TYPE (object));
   5685 		if (size >= 0)
   5686 		  TREE_TYPE (ctor) = type = TREE_TYPE (object);
   5687 	      }
   5688 
   5689 	    /* Find the maximum alignment we can assume for the object.  */
   5690 	    /* ??? Make use of DECL_OFFSET_ALIGN.  */
   5691 	    if (DECL_P (object))
   5692 	      align = DECL_ALIGN (object);
   5693 	    else
   5694 	      align = TYPE_ALIGN (type);
   5695 
   5696 	    /* Do a block move either if the size is so small as to make
   5697 	       each individual move a sub-unit move on average, or if it
   5698 	       is so large as to make individual moves inefficient.  */
   5699 	    if (size > 0
   5700 		&& num_nonzero_elements > 1
   5701 		/* For ctors that have many repeated nonzero elements
   5702 		   represented through RANGE_EXPRs, prefer initializing
   5703 		   those through runtime loops over copies of large amounts
   5704 		   of data from readonly data section.  */
   5705 		&& (num_unique_nonzero_elements
   5706 		    > num_nonzero_elements / unique_nonzero_ratio
   5707 		    || size <= min_unique_size)
   5708 		&& (size < num_nonzero_elements
   5709 		    || !can_move_by_pieces (size, align)))
   5710 	      {
   5711 		if (notify_temp_creation)
   5712 		  return GS_ERROR;
   5713 
   5714 		walk_tree (&ctor, force_labels_r, NULL, NULL);
   5715 		ctor = tree_output_constant_def (ctor);
   5716 		if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
   5717 		  ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
   5718 		TREE_OPERAND (*expr_p, 1) = ctor;
   5719 
   5720 		/* This is no longer an assignment of a CONSTRUCTOR, but
   5721 		   we still may have processing to do on the LHS.  So
   5722 		   pretend we didn't do anything here to let that happen.  */
   5723 		return GS_UNHANDLED;
   5724 	      }
   5725 	  }
   5726 
   5727 	/* If a single access to the target must be ensured and there are
   5728 	   nonzero elements or the zero elements are not assigned en masse,
   5729 	   initialize the target from a temporary.  */
   5730 	if (ensure_single_access && (num_nonzero_elements > 0 || !cleared))
   5731 	  {
   5732 	    if (notify_temp_creation)
   5733 	      return GS_ERROR;
   5734 
   5735 	    tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
   5736 	    TREE_OPERAND (*expr_p, 0) = temp;
   5737 	    *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
   5738 			      *expr_p,
   5739 			      build2 (MODIFY_EXPR, void_type_node,
   5740 				      object, temp));
   5741 	    return GS_OK;
   5742 	  }
   5743 
   5744 	if (notify_temp_creation)
   5745 	  return GS_OK;
   5746 
   5747 	/* If there are nonzero elements and if needed, pre-evaluate to capture
   5748 	   elements overlapping with the lhs into temporaries.  We must do this
   5749 	   before clearing to fetch the values before they are zeroed-out.  */
   5750 	if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
   5751 	  {
   5752 	    preeval_data.lhs_base_decl = get_base_address (object);
   5753 	    if (!DECL_P (preeval_data.lhs_base_decl))
   5754 	      preeval_data.lhs_base_decl = NULL;
   5755 	    preeval_data.lhs_alias_set = get_alias_set (object);
   5756 
   5757 	    gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
   5758 					pre_p, post_p, &preeval_data);
   5759 	  }
   5760 
   5761 	bool ctor_has_side_effects_p
   5762 	  = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
   5763 
   5764 	if (cleared)
   5765 	  {
   5766 	    /* Zap the CONSTRUCTOR element list, which simplifies this case.
   5767 	       Note that we still have to gimplify, in order to handle the
   5768 	       case of variable sized types.  Avoid shared tree structures.  */
   5769 	    CONSTRUCTOR_ELTS (ctor) = NULL;
   5770 	    TREE_SIDE_EFFECTS (ctor) = 0;
   5771 	    object = unshare_expr (object);
   5772 	    gimplify_stmt (expr_p, pre_p);
   5773 	  }
   5774 
   5775 	/* If we have not block cleared the object, or if there are nonzero
   5776 	   elements in the constructor, or if the constructor has side effects,
   5777 	   add assignments to the individual scalar fields of the object.  */
   5778 	if (!cleared
   5779 	    || num_nonzero_elements > 0
   5780 	    || ctor_has_side_effects_p)
   5781 	  gimplify_init_ctor_eval (object, elts, pre_p, cleared);
   5782 
   5783 	*expr_p = NULL_TREE;
   5784       }
   5785       break;
   5786 
   5787     case COMPLEX_TYPE:
   5788       {
   5789 	tree r, i;
   5790 
   5791 	if (notify_temp_creation)
   5792 	  return GS_OK;
   5793 
   5794 	/* Extract the real and imaginary parts out of the ctor.  */
   5795 	gcc_assert (elts->length () == 2);
   5796 	r = (*elts)[0].value;
   5797 	i = (*elts)[1].value;
   5798 	if (r == NULL || i == NULL)
   5799 	  {
   5800 	    tree zero = build_zero_cst (TREE_TYPE (type));
   5801 	    if (r == NULL)
   5802 	      r = zero;
   5803 	    if (i == NULL)
   5804 	      i = zero;
   5805 	  }
   5806 
   5807 	/* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
   5808 	   represent creation of a complex value.  */
   5809 	if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
   5810 	  {
   5811 	    ctor = build_complex (type, r, i);
   5812 	    TREE_OPERAND (*expr_p, 1) = ctor;
   5813 	  }
   5814 	else
   5815 	  {
   5816 	    ctor = build2 (COMPLEX_EXPR, type, r, i);
   5817 	    TREE_OPERAND (*expr_p, 1) = ctor;
   5818 	    ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
   5819 				 pre_p,
   5820 				 post_p,
   5821 				 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
   5822 				 fb_rvalue);
   5823 	  }
   5824       }
   5825       break;
   5826 
   5827     case VECTOR_TYPE:
   5828       {
   5829 	unsigned HOST_WIDE_INT ix;
   5830 	constructor_elt *ce;
   5831 
   5832 	if (notify_temp_creation)
   5833 	  return GS_OK;
   5834 
   5835 	/* Vector types use CONSTRUCTOR all the way through gimple
   5836 	   compilation as a general initializer.  */
   5837 	FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
   5838 	  {
   5839 	    enum gimplify_status tret;
   5840 	    tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
   5841 				  fb_rvalue);
   5842 	    if (tret == GS_ERROR)
   5843 	      ret = GS_ERROR;
   5844 	    else if (TREE_STATIC (ctor)
   5845 		     && !initializer_constant_valid_p (ce->value,
   5846 						       TREE_TYPE (ce->value)))
   5847 	      TREE_STATIC (ctor) = 0;
   5848 	  }
   5849 	recompute_constructor_flags (ctor);
   5850 
   5851 	/* Go ahead and simplify constant constructors to VECTOR_CST.  */
   5852 	if (TREE_CONSTANT (ctor))
   5853 	  {
   5854 	    bool constant_p = true;
   5855 	    tree value;
   5856 
   5857 	    /* Even when ctor is constant, it might contain non-*_CST
   5858 	       elements, such as addresses or trapping values like
   5859 	       1.0/0.0 - 1.0/0.0.  Such expressions don't belong
   5860 	       in VECTOR_CST nodes.  */
   5861 	    FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
   5862 	      if (!CONSTANT_CLASS_P (value))
   5863 		{
   5864 		  constant_p = false;
   5865 		  break;
   5866 		}
   5867 
   5868 	    if (constant_p)
   5869 	      {
   5870 		TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
   5871 		break;
   5872 	      }
   5873 	  }
   5874 
   5875 	if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
   5876 	  TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
   5877       }
   5878       break;
   5879 
   5880     default:
   5881       /* So how did we get a CONSTRUCTOR for a scalar type?  */
   5882       gcc_unreachable ();
   5883     }
   5884 
   5885   if (ret == GS_ERROR)
   5886     return GS_ERROR;
   5887   /* If we have gimplified both sides of the initializer but have
   5888      not emitted an assignment, do so now.   */
   5889   if (*expr_p
   5890       /* If the type is an empty type, we don't need to emit the
   5891 	 assignment. */
   5892       && !is_empty_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
   5893     {
   5894       tree lhs = TREE_OPERAND (*expr_p, 0);
   5895       tree rhs = TREE_OPERAND (*expr_p, 1);
   5896       if (want_value && object == lhs)
   5897 	lhs = unshare_expr (lhs);
   5898       gassign *init = gimple_build_assign (lhs, rhs);
   5899       gimplify_seq_add_stmt (pre_p, init);
   5900     }
   5901   if (want_value)
   5902     {
   5903       *expr_p = object;
   5904       ret = GS_OK;
   5905     }
   5906   else
   5907     {
   5908       *expr_p = NULL;
   5909       ret = GS_ALL_DONE;
   5910     }
   5911 
   5912   /* If the user requests to initialize automatic variables, we
   5913      should initialize paddings inside the variable.  Add a call to
   5914      __builtin_clear_pading (&object, 0, for_auto_init = true) to
   5915      initialize paddings of object always to zero regardless of
   5916      INIT_TYPE.  Note, we will not insert this call if the aggregate
   5917      variable has be completely cleared already or it's initialized
   5918      with an empty constructor.  We cannot insert this call if the
   5919      variable is a gimple register since __builtin_clear_padding will take
   5920      the address of the variable.  As a result, if a long double/_Complex long
   5921      double variable will be spilled into stack later, its padding cannot
   5922      be cleared with __builtin_clear_padding.  We should clear its padding
   5923      when it is spilled into memory.  */
   5924   if (is_init_expr
   5925       && !is_gimple_reg (object)
   5926       && clear_padding_type_may_have_padding_p (type)
   5927       && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor)
   5928 	  || !AGGREGATE_TYPE_P (type))
   5929       && is_var_need_auto_init (object))
   5930     gimple_add_padding_init_for_auto_var (object, false, pre_p);
   5931 
   5932   return ret;
   5933 }
   5934 
   5935 /* Given a pointer value OP0, return a simplified version of an
   5936    indirection through OP0, or NULL_TREE if no simplification is
   5937    possible.  This may only be applied to a rhs of an expression.
   5938    Note that the resulting type may be different from the type pointed
   5939    to in the sense that it is still compatible from the langhooks
   5940    point of view. */
   5941 
   5942 static tree
   5943 gimple_fold_indirect_ref_rhs (tree t)
   5944 {
   5945   return gimple_fold_indirect_ref (t);
   5946 }
   5947 
   5948 /* Subroutine of gimplify_modify_expr to do simplifications of
   5949    MODIFY_EXPRs based on the code of the RHS.  We loop for as long as
   5950    something changes.  */
   5951 
   5952 static enum gimplify_status
   5953 gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
   5954 			  gimple_seq *pre_p, gimple_seq *post_p,
   5955 			  bool want_value)
   5956 {
   5957   enum gimplify_status ret = GS_UNHANDLED;
   5958   bool changed;
   5959 
   5960   do
   5961     {
   5962       changed = false;
   5963       switch (TREE_CODE (*from_p))
   5964 	{
   5965 	case VAR_DECL:
   5966 	  /* If we're assigning from a read-only variable initialized with
   5967 	     a constructor and not volatile, do the direct assignment from
   5968 	     the constructor, but only if the target is not volatile either
   5969 	     since this latter assignment might end up being done on a per
   5970 	     field basis.  However, if the target is volatile and the type
   5971 	     is aggregate and non-addressable, gimplify_init_constructor
   5972 	     knows that it needs to ensure a single access to the target
   5973 	     and it will return GS_OK only in this case.  */
   5974 	  if (TREE_READONLY (*from_p)
   5975 	      && DECL_INITIAL (*from_p)
   5976 	      && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR
   5977 	      && !TREE_THIS_VOLATILE (*from_p)
   5978 	      && (!TREE_THIS_VOLATILE (*to_p)
   5979 		  || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p))
   5980 		      && !TREE_ADDRESSABLE (TREE_TYPE (*to_p)))))
   5981 	    {
   5982 	      tree old_from = *from_p;
   5983 	      enum gimplify_status subret;
   5984 
   5985 	      /* Move the constructor into the RHS.  */
   5986 	      *from_p = unshare_expr (DECL_INITIAL (*from_p));
   5987 
   5988 	      /* Let's see if gimplify_init_constructor will need to put
   5989 		 it in memory.  */
   5990 	      subret = gimplify_init_constructor (expr_p, NULL, NULL,
   5991 						  false, true);
   5992 	      if (subret == GS_ERROR)
   5993 		{
   5994 		  /* If so, revert the change.  */
   5995 		  *from_p = old_from;
   5996 		}
   5997 	      else
   5998 		{
   5999 		  ret = GS_OK;
   6000 		  changed = true;
   6001 		}
   6002 	    }
   6003 	  break;
   6004 	case INDIRECT_REF:
   6005 	  if (!TREE_ADDRESSABLE (TREE_TYPE (*from_p)))
   6006 	    /* If we have code like
   6007 
   6008 	     *(const A*)(A*)&x
   6009 
   6010 	     where the type of "x" is a (possibly cv-qualified variant
   6011 	     of "A"), treat the entire expression as identical to "x".
   6012 	     This kind of code arises in C++ when an object is bound
   6013 	     to a const reference, and if "x" is a TARGET_EXPR we want
   6014 	     to take advantage of the optimization below.  But not if
   6015 	     the type is TREE_ADDRESSABLE; then C++17 says that the
   6016 	     TARGET_EXPR needs to be a temporary.  */
   6017 	    if (tree t
   6018 		= gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0)))
   6019 	      {
   6020 		bool volatile_p = TREE_THIS_VOLATILE (*from_p);
   6021 		if (TREE_THIS_VOLATILE (t) != volatile_p)
   6022 		  {
   6023 		    if (DECL_P (t))
   6024 		      t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
   6025 						    build_fold_addr_expr (t));
   6026 		    if (REFERENCE_CLASS_P (t))
   6027 		      TREE_THIS_VOLATILE (t) = volatile_p;
   6028 		  }
   6029 		*from_p = t;
   6030 		ret = GS_OK;
   6031 		changed = true;
   6032 	      }
   6033 	  break;
   6034 
   6035 	case TARGET_EXPR:
   6036 	  {
   6037 	    /* If we are initializing something from a TARGET_EXPR, strip the
   6038 	       TARGET_EXPR and initialize it directly, if possible.  This can't
   6039 	       be done if the initializer is void, since that implies that the
   6040 	       temporary is set in some non-trivial way.
   6041 
   6042 	       ??? What about code that pulls out the temp and uses it
   6043 	       elsewhere? I think that such code never uses the TARGET_EXPR as
   6044 	       an initializer.  If I'm wrong, we'll die because the temp won't
   6045 	       have any RTL.  In that case, I guess we'll need to replace
   6046 	       references somehow.  */
   6047 	    tree init = TARGET_EXPR_INITIAL (*from_p);
   6048 
   6049 	    if (init
   6050 		&& (TREE_CODE (*expr_p) != MODIFY_EXPR
   6051 		    || !TARGET_EXPR_NO_ELIDE (*from_p))
   6052 		&& !VOID_TYPE_P (TREE_TYPE (init)))
   6053 	      {
   6054 		*from_p = init;
   6055 		ret = GS_OK;
   6056 		changed = true;
   6057 	      }
   6058 	  }
   6059 	  break;
   6060 
   6061 	case COMPOUND_EXPR:
   6062 	  /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
   6063 	     caught.  */
   6064 	  gimplify_compound_expr (from_p, pre_p, true);
   6065 	  ret = GS_OK;
   6066 	  changed = true;
   6067 	  break;
   6068 
   6069 	case CONSTRUCTOR:
   6070 	  /* If we already made some changes, let the front end have a
   6071 	     crack at this before we break it down.  */
   6072 	  if (ret != GS_UNHANDLED)
   6073 	    break;
   6074 
   6075 	  /* If we're initializing from a CONSTRUCTOR, break this into
   6076 	     individual MODIFY_EXPRs.  */
   6077 	  ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
   6078 					   false);
   6079 	  return ret;
   6080 
   6081 	case COND_EXPR:
   6082 	  /* If we're assigning to a non-register type, push the assignment
   6083 	     down into the branches.  This is mandatory for ADDRESSABLE types,
   6084 	     since we cannot generate temporaries for such, but it saves a
   6085 	     copy in other cases as well.  */
   6086 	  if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
   6087 	    {
   6088 	      /* This code should mirror the code in gimplify_cond_expr. */
   6089 	      enum tree_code code = TREE_CODE (*expr_p);
   6090 	      tree cond = *from_p;
   6091 	      tree result = *to_p;
   6092 
   6093 	      ret = gimplify_expr (&result, pre_p, post_p,
   6094 				   is_gimple_lvalue, fb_lvalue);
   6095 	      if (ret != GS_ERROR)
   6096 		ret = GS_OK;
   6097 
   6098 	      /* If we are going to write RESULT more than once, clear
   6099 		 TREE_READONLY flag, otherwise we might incorrectly promote
   6100 		 the variable to static const and initialize it at compile
   6101 		 time in one of the branches.  */
   6102 	      if (VAR_P (result)
   6103 		  && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
   6104 		  && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
   6105 		TREE_READONLY (result) = 0;
   6106 	      if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
   6107 		TREE_OPERAND (cond, 1)
   6108 		  = build2 (code, void_type_node, result,
   6109 			    TREE_OPERAND (cond, 1));
   6110 	      if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
   6111 		TREE_OPERAND (cond, 2)
   6112 		  = build2 (code, void_type_node, unshare_expr (result),
   6113 			    TREE_OPERAND (cond, 2));
   6114 
   6115 	      TREE_TYPE (cond) = void_type_node;
   6116 	      recalculate_side_effects (cond);
   6117 
   6118 	      if (want_value)
   6119 		{
   6120 		  gimplify_and_add (cond, pre_p);
   6121 		  *expr_p = unshare_expr (result);
   6122 		}
   6123 	      else
   6124 		*expr_p = cond;
   6125 	      return ret;
   6126 	    }
   6127 	  break;
   6128 
   6129 	case CALL_EXPR:
   6130 	  /* For calls that return in memory, give *to_p as the CALL_EXPR's
   6131 	     return slot so that we don't generate a temporary.  */
   6132 	  if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
   6133 	      && aggregate_value_p (*from_p, *from_p))
   6134 	    {
   6135 	      bool use_target;
   6136 
   6137 	      if (!(rhs_predicate_for (*to_p))(*from_p))
   6138 		/* If we need a temporary, *to_p isn't accurate.  */
   6139 		use_target = false;
   6140 	      /* It's OK to use the return slot directly unless it's an NRV. */
   6141 	      else if (TREE_CODE (*to_p) == RESULT_DECL
   6142 		       && DECL_NAME (*to_p) == NULL_TREE
   6143 		       && needs_to_live_in_memory (*to_p))
   6144 		use_target = true;
   6145 	      else if (is_gimple_reg_type (TREE_TYPE (*to_p))
   6146 		       || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
   6147 		/* Don't force regs into memory.  */
   6148 		use_target = false;
   6149 	      else if (TREE_CODE (*expr_p) == INIT_EXPR)
   6150 		/* It's OK to use the target directly if it's being
   6151 		   initialized. */
   6152 		use_target = true;
   6153 	      else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
   6154 		       != INTEGER_CST)
   6155 		/* Always use the target and thus RSO for variable-sized types.
   6156 		   GIMPLE cannot deal with a variable-sized assignment
   6157 		   embedded in a call statement.  */
   6158 		use_target = true;
   6159 	      else if (TREE_CODE (*to_p) != SSA_NAME
   6160 		      && (!is_gimple_variable (*to_p)
   6161 			  || needs_to_live_in_memory (*to_p)))
   6162 		/* Don't use the original target if it's already addressable;
   6163 		   if its address escapes, and the called function uses the
   6164 		   NRV optimization, a conforming program could see *to_p
   6165 		   change before the called function returns; see c++/19317.
   6166 		   When optimizing, the return_slot pass marks more functions
   6167 		   as safe after we have escape info.  */
   6168 		use_target = false;
   6169 	      else
   6170 		use_target = true;
   6171 
   6172 	      if (use_target)
   6173 		{
   6174 		  CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
   6175 		  mark_addressable (*to_p);
   6176 		}
   6177 	    }
   6178 	  break;
   6179 
   6180 	case WITH_SIZE_EXPR:
   6181 	  /* Likewise for calls that return an aggregate of non-constant size,
   6182 	     since we would not be able to generate a temporary at all.  */
   6183 	  if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
   6184 	    {
   6185 	      *from_p = TREE_OPERAND (*from_p, 0);
   6186 	      /* We don't change ret in this case because the
   6187 		 WITH_SIZE_EXPR might have been added in
   6188 		 gimplify_modify_expr, so returning GS_OK would lead to an
   6189 		 infinite loop.  */
   6190 	      changed = true;
   6191 	    }
   6192 	  break;
   6193 
   6194 	  /* If we're initializing from a container, push the initialization
   6195 	     inside it.  */
   6196 	case CLEANUP_POINT_EXPR:
   6197 	case BIND_EXPR:
   6198 	case STATEMENT_LIST:
   6199 	  {
   6200 	    tree wrap = *from_p;
   6201 	    tree t;
   6202 
   6203 	    ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
   6204 				 fb_lvalue);
   6205 	    if (ret != GS_ERROR)
   6206 	      ret = GS_OK;
   6207 
   6208 	    t = voidify_wrapper_expr (wrap, *expr_p);
   6209 	    gcc_assert (t == *expr_p);
   6210 
   6211 	    if (want_value)
   6212 	      {
   6213 		gimplify_and_add (wrap, pre_p);
   6214 		*expr_p = unshare_expr (*to_p);
   6215 	      }
   6216 	    else
   6217 	      *expr_p = wrap;
   6218 	    return GS_OK;
   6219 	  }
   6220 
   6221 	case NOP_EXPR:
   6222 	  /* Pull out compound literal expressions from a NOP_EXPR.
   6223 	     Those are created in the C FE to drop qualifiers during
   6224 	     lvalue conversion.  */
   6225 	  if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
   6226 	      && tree_ssa_useless_type_conversion (*from_p))
   6227 	    {
   6228 	      *from_p = TREE_OPERAND (*from_p, 0);
   6229 	      ret = GS_OK;
   6230 	      changed = true;
   6231 	    }
   6232 	  break;
   6233 
   6234 	case COMPOUND_LITERAL_EXPR:
   6235 	  {
   6236 	    tree complit = TREE_OPERAND (*expr_p, 1);
   6237 	    tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
   6238 	    tree decl = DECL_EXPR_DECL (decl_s);
   6239 	    tree init = DECL_INITIAL (decl);
   6240 
   6241 	    /* struct T x = (struct T) { 0, 1, 2 } can be optimized
   6242 	       into struct T x = { 0, 1, 2 } if the address of the
   6243 	       compound literal has never been taken.  */
   6244 	    if (!TREE_ADDRESSABLE (complit)
   6245 		&& !TREE_ADDRESSABLE (decl)
   6246 		&& init)
   6247 	      {
   6248 		*expr_p = copy_node (*expr_p);
   6249 		TREE_OPERAND (*expr_p, 1) = init;
   6250 		return GS_OK;
   6251 	      }
   6252 	  }
   6253 
   6254 	default:
   6255 	  break;
   6256 	}
   6257     }
   6258   while (changed);
   6259 
   6260   return ret;
   6261 }
   6262 
   6263 
   6264 /* Return true if T looks like a valid GIMPLE statement.  */
   6265 
   6266 static bool
   6267 is_gimple_stmt (tree t)
   6268 {
   6269   const enum tree_code code = TREE_CODE (t);
   6270 
   6271   switch (code)
   6272     {
   6273     case NOP_EXPR:
   6274       /* The only valid NOP_EXPR is the empty statement.  */
   6275       return IS_EMPTY_STMT (t);
   6276 
   6277     case BIND_EXPR:
   6278     case COND_EXPR:
   6279       /* These are only valid if they're void.  */
   6280       return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
   6281 
   6282     case SWITCH_EXPR:
   6283     case GOTO_EXPR:
   6284     case RETURN_EXPR:
   6285     case LABEL_EXPR:
   6286     case CASE_LABEL_EXPR:
   6287     case TRY_CATCH_EXPR:
   6288     case TRY_FINALLY_EXPR:
   6289     case EH_FILTER_EXPR:
   6290     case CATCH_EXPR:
   6291     case ASM_EXPR:
   6292     case STATEMENT_LIST:
   6293     case OACC_PARALLEL:
   6294     case OACC_KERNELS:
   6295     case OACC_SERIAL:
   6296     case OACC_DATA:
   6297     case OACC_HOST_DATA:
   6298     case OACC_DECLARE:
   6299     case OACC_UPDATE:
   6300     case OACC_ENTER_DATA:
   6301     case OACC_EXIT_DATA:
   6302     case OACC_CACHE:
   6303     case OMP_PARALLEL:
   6304     case OMP_FOR:
   6305     case OMP_SIMD:
   6306     case OMP_DISTRIBUTE:
   6307     case OMP_LOOP:
   6308     case OACC_LOOP:
   6309     case OMP_SCAN:
   6310     case OMP_SCOPE:
   6311     case OMP_SECTIONS:
   6312     case OMP_SECTION:
   6313     case OMP_STRUCTURED_BLOCK:
   6314     case OMP_SINGLE:
   6315     case OMP_MASTER:
   6316     case OMP_MASKED:
   6317     case OMP_TASKGROUP:
   6318     case OMP_ORDERED:
   6319     case OMP_CRITICAL:
   6320     case OMP_TASK:
   6321     case OMP_TARGET:
   6322     case OMP_TARGET_DATA:
   6323     case OMP_TARGET_UPDATE:
   6324     case OMP_TARGET_ENTER_DATA:
   6325     case OMP_TARGET_EXIT_DATA:
   6326     case OMP_TASKLOOP:
   6327     case OMP_TEAMS:
   6328       /* These are always void.  */
   6329       return true;
   6330 
   6331     case CALL_EXPR:
   6332     case MODIFY_EXPR:
   6333     case PREDICT_EXPR:
   6334       /* These are valid regardless of their type.  */
   6335       return true;
   6336 
   6337     default:
   6338       return false;
   6339     }
   6340 }
   6341 
   6342 
   6343 /* Promote partial stores to COMPLEX variables to total stores.  *EXPR_P is
   6344    a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
   6345 
   6346    IMPORTANT NOTE: This promotion is performed by introducing a load of the
   6347    other, unmodified part of the complex object just before the total store.
   6348    As a consequence, if the object is still uninitialized, an undefined value
   6349    will be loaded into a register, which may result in a spurious exception
   6350    if the register is floating-point and the value happens to be a signaling
   6351    NaN for example.  Then the fully-fledged complex operations lowering pass
   6352    followed by a DCE pass are necessary in order to fix things up.  */
   6353 
   6354 static enum gimplify_status
   6355 gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
   6356                                    bool want_value)
   6357 {
   6358   enum tree_code code, ocode;
   6359   tree lhs, rhs, new_rhs, other, realpart, imagpart;
   6360 
   6361   lhs = TREE_OPERAND (*expr_p, 0);
   6362   rhs = TREE_OPERAND (*expr_p, 1);
   6363   code = TREE_CODE (lhs);
   6364   lhs = TREE_OPERAND (lhs, 0);
   6365 
   6366   ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
   6367   other = build1 (ocode, TREE_TYPE (rhs), lhs);
   6368   suppress_warning (other);
   6369   other = get_formal_tmp_var (other, pre_p);
   6370 
   6371   realpart = code == REALPART_EXPR ? rhs : other;
   6372   imagpart = code == REALPART_EXPR ? other : rhs;
   6373 
   6374   if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
   6375     new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
   6376   else
   6377     new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
   6378 
   6379   gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
   6380   *expr_p = (want_value) ? rhs : NULL_TREE;
   6381 
   6382   return GS_ALL_DONE;
   6383 }
   6384 
   6385 /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
   6386 
   6387       modify_expr
   6388 	      : varname '=' rhs
   6389 	      | '*' ID '=' rhs
   6390 
   6391     PRE_P points to the list where side effects that must happen before
   6392 	*EXPR_P should be stored.
   6393 
   6394     POST_P points to the list where side effects that must happen after
   6395 	*EXPR_P should be stored.
   6396 
   6397     WANT_VALUE is nonzero iff we want to use the value of this expression
   6398 	in another expression.  */
   6399 
   6400 static enum gimplify_status
   6401 gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   6402 		      bool want_value)
   6403 {
   6404   tree *from_p = &TREE_OPERAND (*expr_p, 1);
   6405   tree *to_p = &TREE_OPERAND (*expr_p, 0);
   6406   enum gimplify_status ret = GS_UNHANDLED;
   6407   gimple *assign;
   6408   location_t loc = EXPR_LOCATION (*expr_p);
   6409   gimple_stmt_iterator gsi;
   6410 
   6411   if (error_operand_p (*from_p) || error_operand_p (*to_p))
   6412     return GS_ERROR;
   6413 
   6414   gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
   6415 	      || TREE_CODE (*expr_p) == INIT_EXPR);
   6416 
   6417   /* Trying to simplify a clobber using normal logic doesn't work,
   6418      so handle it here.  */
   6419   if (TREE_CLOBBER_P (*from_p))
   6420     {
   6421       ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
   6422       if (ret == GS_ERROR)
   6423 	return ret;
   6424       gcc_assert (!want_value);
   6425       if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
   6426 	{
   6427 	  tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
   6428 					       pre_p, post_p);
   6429 	  *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
   6430 	}
   6431       gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
   6432       *expr_p = NULL;
   6433       return GS_ALL_DONE;
   6434     }
   6435 
   6436   /* Convert initialization from an empty variable-size CONSTRUCTOR to
   6437      memset.  */
   6438   if (TREE_TYPE (*from_p) != error_mark_node
   6439       && TYPE_SIZE_UNIT (TREE_TYPE (*from_p))
   6440       && !poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (*from_p)))
   6441       && TREE_CODE (*from_p) == CONSTRUCTOR
   6442       && CONSTRUCTOR_NELTS (*from_p) == 0)
   6443     {
   6444       maybe_with_size_expr (from_p);
   6445       gcc_assert (TREE_CODE (*from_p) == WITH_SIZE_EXPR);
   6446       return gimplify_modify_expr_to_memset (expr_p,
   6447 					     TREE_OPERAND (*from_p, 1),
   6448 					     want_value, pre_p);
   6449     }
   6450 
   6451   /* Insert pointer conversions required by the middle-end that are not
   6452      required by the frontend.  This fixes middle-end type checking for
   6453      for example gcc.dg/redecl-6.c.  */
   6454   if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
   6455     {
   6456       STRIP_USELESS_TYPE_CONVERSION (*from_p);
   6457       if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
   6458 	*from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
   6459     }
   6460 
   6461   /* See if any simplifications can be done based on what the RHS is.  */
   6462   ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
   6463 				  want_value);
   6464   if (ret != GS_UNHANDLED)
   6465     return ret;
   6466 
   6467   /* For empty types only gimplify the left hand side and right hand
   6468      side as statements and throw away the assignment.  Do this after
   6469      gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
   6470      types properly.  */
   6471   if (is_empty_type (TREE_TYPE (*from_p))
   6472       && !want_value
   6473       /* Don't do this for calls that return addressable types, expand_call
   6474 	 relies on those having a lhs.  */
   6475       && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
   6476 	   && TREE_CODE (*from_p) == CALL_EXPR))
   6477     {
   6478       gimplify_stmt (from_p, pre_p);
   6479       gimplify_stmt (to_p, pre_p);
   6480       *expr_p = NULL_TREE;
   6481       return GS_ALL_DONE;
   6482     }
   6483 
   6484   /* If the value being copied is of variable width, compute the length
   6485      of the copy into a WITH_SIZE_EXPR.   Note that we need to do this
   6486      before gimplifying any of the operands so that we can resolve any
   6487      PLACEHOLDER_EXPRs in the size.  Also note that the RTL expander uses
   6488      the size of the expression to be copied, not of the destination, so
   6489      that is what we must do here.  */
   6490   maybe_with_size_expr (from_p);
   6491 
   6492   /* As a special case, we have to temporarily allow for assignments
   6493      with a CALL_EXPR on the RHS.  Since in GIMPLE a function call is
   6494      a toplevel statement, when gimplifying the GENERIC expression
   6495      MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
   6496      GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
   6497 
   6498      Instead, we need to create the tuple GIMPLE_CALL <a, foo>.  To
   6499      prevent gimplify_expr from trying to create a new temporary for
   6500      foo's LHS, we tell it that it should only gimplify until it
   6501      reaches the CALL_EXPR.  On return from gimplify_expr, the newly
   6502      created GIMPLE_CALL <foo> will be the last statement in *PRE_P
   6503      and all we need to do here is set 'a' to be its LHS.  */
   6504 
   6505   /* Gimplify the RHS first for C++17 and bug 71104.  */
   6506   gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
   6507   ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
   6508   if (ret == GS_ERROR)
   6509     return ret;
   6510 
   6511   /* Then gimplify the LHS.  */
   6512   /* If we gimplified the RHS to a CALL_EXPR and that call may return
   6513      twice we have to make sure to gimplify into non-SSA as otherwise
   6514      the abnormal edge added later will make those defs not dominate
   6515      their uses.
   6516      ???  Technically this applies only to the registers used in the
   6517      resulting non-register *TO_P.  */
   6518   bool saved_into_ssa = gimplify_ctxp->into_ssa;
   6519   if (saved_into_ssa
   6520       && TREE_CODE (*from_p) == CALL_EXPR
   6521       && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
   6522     gimplify_ctxp->into_ssa = false;
   6523   ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
   6524   gimplify_ctxp->into_ssa = saved_into_ssa;
   6525   if (ret == GS_ERROR)
   6526     return ret;
   6527 
   6528   /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
   6529      guess for the predicate was wrong.  */
   6530   gimple_predicate final_pred = rhs_predicate_for (*to_p);
   6531   if (final_pred != initial_pred)
   6532     {
   6533       ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
   6534       if (ret == GS_ERROR)
   6535 	return ret;
   6536     }
   6537 
   6538   /* In case of va_arg internal fn wrappped in a WITH_SIZE_EXPR, add the type
   6539      size as argument to the call.  */
   6540   if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
   6541     {
   6542       tree call = TREE_OPERAND (*from_p, 0);
   6543       tree vlasize = TREE_OPERAND (*from_p, 1);
   6544 
   6545       if (TREE_CODE (call) == CALL_EXPR
   6546 	  && CALL_EXPR_IFN (call) == IFN_VA_ARG)
   6547 	{
   6548 	  int nargs = call_expr_nargs (call);
   6549 	  tree type = TREE_TYPE (call);
   6550 	  tree ap = CALL_EXPR_ARG (call, 0);
   6551 	  tree tag = CALL_EXPR_ARG (call, 1);
   6552 	  tree aptag = CALL_EXPR_ARG (call, 2);
   6553 	  tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
   6554 						       IFN_VA_ARG, type,
   6555 						       nargs + 1, ap, tag,
   6556 						       aptag, vlasize);
   6557 	  TREE_OPERAND (*from_p, 0) = newcall;
   6558 	}
   6559     }
   6560 
   6561   /* Now see if the above changed *from_p to something we handle specially.  */
   6562   ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
   6563 				  want_value);
   6564   if (ret != GS_UNHANDLED)
   6565     return ret;
   6566 
   6567   /* If we've got a variable sized assignment between two lvalues (i.e. does
   6568      not involve a call), then we can make things a bit more straightforward
   6569      by converting the assignment to memcpy or memset.  */
   6570   if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
   6571     {
   6572       tree from = TREE_OPERAND (*from_p, 0);
   6573       tree size = TREE_OPERAND (*from_p, 1);
   6574 
   6575       if (TREE_CODE (from) == CONSTRUCTOR)
   6576 	return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
   6577       else if (is_gimple_addressable (from)
   6578 	       && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (*to_p)))
   6579 	       && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (from))))
   6580 	{
   6581 	  *from_p = from;
   6582 	  return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
   6583 	      					 pre_p);
   6584 	}
   6585     }
   6586 
   6587   /* Transform partial stores to non-addressable complex variables into
   6588      total stores.  This allows us to use real instead of virtual operands
   6589      for these variables, which improves optimization.  */
   6590   if ((TREE_CODE (*to_p) == REALPART_EXPR
   6591        || TREE_CODE (*to_p) == IMAGPART_EXPR)
   6592       && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
   6593     return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
   6594 
   6595   /* Try to alleviate the effects of the gimplification creating artificial
   6596      temporaries (see for example is_gimple_reg_rhs) on the debug info, but
   6597      make sure not to create DECL_DEBUG_EXPR links across functions.  */
   6598   if (!gimplify_ctxp->into_ssa
   6599       && VAR_P (*from_p)
   6600       && DECL_IGNORED_P (*from_p)
   6601       && DECL_P (*to_p)
   6602       && !DECL_IGNORED_P (*to_p)
   6603       && decl_function_context (*to_p) == current_function_decl
   6604       && decl_function_context (*from_p) == current_function_decl)
   6605     {
   6606       if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
   6607 	DECL_NAME (*from_p)
   6608 	  = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
   6609       DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
   6610       SET_DECL_DEBUG_EXPR (*from_p, *to_p);
   6611    }
   6612 
   6613   if (want_value && TREE_THIS_VOLATILE (*to_p))
   6614     *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
   6615 
   6616   if (TREE_CODE (*from_p) == CALL_EXPR)
   6617     {
   6618       /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
   6619 	 instead of a GIMPLE_ASSIGN.  */
   6620       gcall *call_stmt;
   6621       if (CALL_EXPR_FN (*from_p) == NULL_TREE)
   6622 	{
   6623 	  /* Gimplify internal functions created in the FEs.  */
   6624 	  int nargs = call_expr_nargs (*from_p), i;
   6625 	  enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
   6626 	  auto_vec<tree> vargs (nargs);
   6627 
   6628 	  for (i = 0; i < nargs; i++)
   6629 	    {
   6630 	      gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
   6631 			    EXPR_LOCATION (*from_p));
   6632 	      vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
   6633 	    }
   6634 	  call_stmt = gimple_build_call_internal_vec (ifn, vargs);
   6635 	  gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
   6636 	  gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
   6637 	}
   6638       else
   6639 	{
   6640 	  tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
   6641 	  CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
   6642 	  STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
   6643 	  tree fndecl = get_callee_fndecl (*from_p);
   6644 	  if (fndecl
   6645 	      && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
   6646 	      && call_expr_nargs (*from_p) == 3)
   6647 	    call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
   6648 						    CALL_EXPR_ARG (*from_p, 0),
   6649 						    CALL_EXPR_ARG (*from_p, 1),
   6650 						    CALL_EXPR_ARG (*from_p, 2));
   6651 	  else
   6652 	    {
   6653 	      call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
   6654 	    }
   6655 	}
   6656       notice_special_calls (call_stmt);
   6657       if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
   6658 	gimple_call_set_lhs (call_stmt, *to_p);
   6659       else if (TREE_CODE (*to_p) == SSA_NAME)
   6660 	/* The above is somewhat premature, avoid ICEing later for a
   6661 	   SSA name w/o a definition.  We may have uses in the GIMPLE IL.
   6662 	   ???  This doesn't make it a default-def.  */
   6663 	SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
   6664 
   6665       assign = call_stmt;
   6666     }
   6667   else
   6668     {
   6669       assign = gimple_build_assign (*to_p, *from_p);
   6670       gimple_set_location (assign, EXPR_LOCATION (*expr_p));
   6671       if (COMPARISON_CLASS_P (*from_p))
   6672 	copy_warning (assign, *from_p);
   6673     }
   6674 
   6675   if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
   6676     {
   6677       /* We should have got an SSA name from the start.  */
   6678       gcc_assert (TREE_CODE (*to_p) == SSA_NAME
   6679 		  || ! gimple_in_ssa_p (cfun));
   6680     }
   6681 
   6682   gimplify_seq_add_stmt (pre_p, assign);
   6683   gsi = gsi_last (*pre_p);
   6684   maybe_fold_stmt (&gsi);
   6685 
   6686   if (want_value)
   6687     {
   6688       *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
   6689       return GS_OK;
   6690     }
   6691   else
   6692     *expr_p = NULL;
   6693 
   6694   return GS_ALL_DONE;
   6695 }
   6696 
   6697 /* Gimplify a comparison between two variable-sized objects.  Do this
   6698    with a call to BUILT_IN_MEMCMP.  */
   6699 
   6700 static enum gimplify_status
   6701 gimplify_variable_sized_compare (tree *expr_p)
   6702 {
   6703   location_t loc = EXPR_LOCATION (*expr_p);
   6704   tree op0 = TREE_OPERAND (*expr_p, 0);
   6705   tree op1 = TREE_OPERAND (*expr_p, 1);
   6706   tree t, arg, dest, src, expr;
   6707 
   6708   arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
   6709   arg = unshare_expr (arg);
   6710   arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
   6711   src = build_fold_addr_expr_loc (loc, op1);
   6712   dest = build_fold_addr_expr_loc (loc, op0);
   6713   t = builtin_decl_implicit (BUILT_IN_MEMCMP);
   6714   t = build_call_expr_loc (loc, t, 3, dest, src, arg);
   6715 
   6716   expr
   6717     = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
   6718   SET_EXPR_LOCATION (expr, loc);
   6719   *expr_p = expr;
   6720 
   6721   return GS_OK;
   6722 }
   6723 
   6724 /* Gimplify a comparison between two aggregate objects of integral scalar
   6725    mode as a comparison between the bitwise equivalent scalar values.  */
   6726 
   6727 static enum gimplify_status
   6728 gimplify_scalar_mode_aggregate_compare (tree *expr_p)
   6729 {
   6730   location_t loc = EXPR_LOCATION (*expr_p);
   6731   tree op0 = TREE_OPERAND (*expr_p, 0);
   6732   tree op1 = TREE_OPERAND (*expr_p, 1);
   6733 
   6734   tree type = TREE_TYPE (op0);
   6735   tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
   6736 
   6737   op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
   6738   op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
   6739 
   6740   *expr_p
   6741     = fold_build2_loc (loc, TREE_CODE (*expr_p), TREE_TYPE (*expr_p), op0, op1);
   6742 
   6743   return GS_OK;
   6744 }
   6745 
   6746 /* Gimplify an expression sequence.  This function gimplifies each
   6747    expression and rewrites the original expression with the last
   6748    expression of the sequence in GIMPLE form.
   6749 
   6750    PRE_P points to the list where the side effects for all the
   6751        expressions in the sequence will be emitted.
   6752 
   6753    WANT_VALUE is true when the result of the last COMPOUND_EXPR is used.  */
   6754 
   6755 static enum gimplify_status
   6756 gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
   6757 {
   6758   tree t = *expr_p;
   6759 
   6760   do
   6761     {
   6762       tree *sub_p = &TREE_OPERAND (t, 0);
   6763 
   6764       if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
   6765 	gimplify_compound_expr (sub_p, pre_p, false);
   6766       else
   6767 	gimplify_stmt (sub_p, pre_p);
   6768 
   6769       t = TREE_OPERAND (t, 1);
   6770     }
   6771   while (TREE_CODE (t) == COMPOUND_EXPR);
   6772 
   6773   *expr_p = t;
   6774   if (want_value)
   6775     return GS_OK;
   6776   else
   6777     {
   6778       gimplify_stmt (expr_p, pre_p);
   6779       return GS_ALL_DONE;
   6780     }
   6781 }
   6782 
   6783 /* Gimplify a SAVE_EXPR node.  EXPR_P points to the expression to
   6784    gimplify.  After gimplification, EXPR_P will point to a new temporary
   6785    that holds the original value of the SAVE_EXPR node.
   6786 
   6787    PRE_P points to the list where side effects that must happen before
   6788    *EXPR_P should be stored.  */
   6789 
   6790 static enum gimplify_status
   6791 gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
   6792 {
   6793   enum gimplify_status ret = GS_ALL_DONE;
   6794   tree val;
   6795 
   6796   gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
   6797   val = TREE_OPERAND (*expr_p, 0);
   6798 
   6799   if (val && TREE_TYPE (val) == error_mark_node)
   6800     return GS_ERROR;
   6801 
   6802   /* If the SAVE_EXPR has not been resolved, then evaluate it once.  */
   6803   if (!SAVE_EXPR_RESOLVED_P (*expr_p))
   6804     {
   6805       /* The operand may be a void-valued expression.  It is
   6806 	 being executed only for its side-effects.  */
   6807       if (TREE_TYPE (val) == void_type_node)
   6808 	{
   6809 	  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   6810 			       is_gimple_stmt, fb_none);
   6811 	  val = NULL;
   6812 	}
   6813       else
   6814 	/* The temporary may not be an SSA name as later abnormal and EH
   6815 	   control flow may invalidate use/def domination.  When in SSA
   6816 	   form then assume there are no such issues and SAVE_EXPRs only
   6817 	   appear via GENERIC foldings.  */
   6818 	val = get_initialized_tmp_var (val, pre_p, post_p,
   6819 				       gimple_in_ssa_p (cfun));
   6820 
   6821       TREE_OPERAND (*expr_p, 0) = val;
   6822       SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
   6823     }
   6824 
   6825   *expr_p = val;
   6826 
   6827   return ret;
   6828 }
   6829 
   6830 /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
   6831 
   6832       unary_expr
   6833 	      : ...
   6834 	      | '&' varname
   6835 	      ...
   6836 
   6837     PRE_P points to the list where side effects that must happen before
   6838 	*EXPR_P should be stored.
   6839 
   6840     POST_P points to the list where side effects that must happen after
   6841 	*EXPR_P should be stored.  */
   6842 
   6843 static enum gimplify_status
   6844 gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
   6845 {
   6846   tree expr = *expr_p;
   6847   tree op0 = TREE_OPERAND (expr, 0);
   6848   enum gimplify_status ret;
   6849   location_t loc = EXPR_LOCATION (*expr_p);
   6850 
   6851   switch (TREE_CODE (op0))
   6852     {
   6853     case INDIRECT_REF:
   6854     do_indirect_ref:
   6855       /* Check if we are dealing with an expression of the form '&*ptr'.
   6856 	 While the front end folds away '&*ptr' into 'ptr', these
   6857 	 expressions may be generated internally by the compiler (e.g.,
   6858 	 builtins like __builtin_va_end).  */
   6859       /* Caution: the silent array decomposition semantics we allow for
   6860 	 ADDR_EXPR means we can't always discard the pair.  */
   6861       /* Gimplification of the ADDR_EXPR operand may drop
   6862 	 cv-qualification conversions, so make sure we add them if
   6863 	 needed.  */
   6864       {
   6865 	tree op00 = TREE_OPERAND (op0, 0);
   6866 	tree t_expr = TREE_TYPE (expr);
   6867 	tree t_op00 = TREE_TYPE (op00);
   6868 
   6869         if (!useless_type_conversion_p (t_expr, t_op00))
   6870 	  op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
   6871         *expr_p = op00;
   6872         ret = GS_OK;
   6873       }
   6874       break;
   6875 
   6876     case VIEW_CONVERT_EXPR:
   6877       /* Take the address of our operand and then convert it to the type of
   6878 	 this ADDR_EXPR.
   6879 
   6880 	 ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
   6881 	 all clear.  The impact of this transformation is even less clear.  */
   6882 
   6883       /* If the operand is a useless conversion, look through it.  Doing so
   6884 	 guarantees that the ADDR_EXPR and its operand will remain of the
   6885 	 same type.  */
   6886       if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
   6887 	op0 = TREE_OPERAND (op0, 0);
   6888 
   6889       *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
   6890 				  build_fold_addr_expr_loc (loc,
   6891 							TREE_OPERAND (op0, 0)));
   6892       ret = GS_OK;
   6893       break;
   6894 
   6895     case MEM_REF:
   6896       if (integer_zerop (TREE_OPERAND (op0, 1)))
   6897 	goto do_indirect_ref;
   6898 
   6899       /* fall through */
   6900 
   6901     default:
   6902       /* If we see a call to a declared builtin or see its address
   6903 	 being taken (we can unify those cases here) then we can mark
   6904 	 the builtin for implicit generation by GCC.  */
   6905       if (TREE_CODE (op0) == FUNCTION_DECL
   6906 	  && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
   6907 	  && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
   6908 	set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
   6909 
   6910       /* We use fb_either here because the C frontend sometimes takes
   6911 	 the address of a call that returns a struct; see
   6912 	 gcc.dg/c99-array-lval-1.c.  The gimplifier will correctly make
   6913 	 the implied temporary explicit.  */
   6914 
   6915       /* Make the operand addressable.  */
   6916       ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
   6917 			   is_gimple_addressable, fb_either);
   6918       if (ret == GS_ERROR)
   6919 	break;
   6920 
   6921       /* Then mark it.  Beware that it may not be possible to do so directly
   6922 	 if a temporary has been created by the gimplification.  */
   6923       prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
   6924 
   6925       op0 = TREE_OPERAND (expr, 0);
   6926 
   6927       /* For various reasons, the gimplification of the expression
   6928 	 may have made a new INDIRECT_REF.  */
   6929       if (INDIRECT_REF_P (op0)
   6930 	  || (TREE_CODE (op0) == MEM_REF
   6931 	      && integer_zerop (TREE_OPERAND (op0, 1))))
   6932 	goto do_indirect_ref;
   6933 
   6934       mark_addressable (TREE_OPERAND (expr, 0));
   6935 
   6936       /* The FEs may end up building ADDR_EXPRs early on a decl with
   6937 	 an incomplete type.  Re-build ADDR_EXPRs in canonical form
   6938 	 here.  */
   6939       if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
   6940 	*expr_p = build_fold_addr_expr (op0);
   6941 
   6942       /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly.  */
   6943       if (TREE_CODE (*expr_p) == ADDR_EXPR)
   6944 	recompute_tree_invariant_for_addr_expr (*expr_p);
   6945 
   6946       /* If we re-built the ADDR_EXPR add a conversion to the original type
   6947          if required.  */
   6948       if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
   6949 	*expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
   6950 
   6951       break;
   6952     }
   6953 
   6954   return ret;
   6955 }
   6956 
   6957 /* Gimplify the operands of an ASM_EXPR.  Input operands should be a gimple
   6958    value; output operands should be a gimple lvalue.  */
   6959 
   6960 static enum gimplify_status
   6961 gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
   6962 {
   6963   tree expr;
   6964   int noutputs;
   6965   const char **oconstraints;
   6966   int i;
   6967   tree link;
   6968   const char *constraint;
   6969   bool allows_mem, allows_reg, is_inout;
   6970   enum gimplify_status ret, tret;
   6971   gasm *stmt;
   6972   vec<tree, va_gc> *inputs;
   6973   vec<tree, va_gc> *outputs;
   6974   vec<tree, va_gc> *clobbers;
   6975   vec<tree, va_gc> *labels;
   6976   tree link_next;
   6977 
   6978   expr = *expr_p;
   6979   noutputs = list_length (ASM_OUTPUTS (expr));
   6980   oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
   6981 
   6982   inputs = NULL;
   6983   outputs = NULL;
   6984   clobbers = NULL;
   6985   labels = NULL;
   6986 
   6987   ret = GS_ALL_DONE;
   6988   link_next = NULL_TREE;
   6989   for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
   6990     {
   6991       bool ok;
   6992       size_t constraint_len;
   6993 
   6994       link_next = TREE_CHAIN (link);
   6995 
   6996       oconstraints[i]
   6997 	= constraint
   6998 	= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
   6999       constraint_len = strlen (constraint);
   7000       if (constraint_len == 0)
   7001         continue;
   7002 
   7003       ok = parse_output_constraint (&constraint, i, 0, 0,
   7004 				    &allows_mem, &allows_reg, &is_inout);
   7005       if (!ok)
   7006 	{
   7007 	  ret = GS_ERROR;
   7008 	  is_inout = false;
   7009 	}
   7010 
   7011       /* If we can't make copies, we can only accept memory.
   7012 	 Similarly for VLAs.  */
   7013       tree outtype = TREE_TYPE (TREE_VALUE (link));
   7014       if (outtype != error_mark_node
   7015 	  && (TREE_ADDRESSABLE (outtype)
   7016 	      || !COMPLETE_TYPE_P (outtype)
   7017 	      || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype))))
   7018 	{
   7019 	  if (allows_mem)
   7020 	    allows_reg = 0;
   7021 	  else
   7022 	    {
   7023 	      error ("impossible constraint in %<asm%>");
   7024 	      error ("non-memory output %d must stay in memory", i);
   7025 	      return GS_ERROR;
   7026 	    }
   7027 	}
   7028 
   7029       if (!allows_reg && allows_mem)
   7030 	mark_addressable (TREE_VALUE (link));
   7031 
   7032       tree orig = TREE_VALUE (link);
   7033       tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
   7034 			    is_inout ? is_gimple_min_lval : is_gimple_lvalue,
   7035 			    fb_lvalue | fb_mayfail);
   7036       if (tret == GS_ERROR)
   7037 	{
   7038 	  if (orig != error_mark_node)
   7039 	    error ("invalid lvalue in %<asm%> output %d", i);
   7040 	  ret = tret;
   7041 	}
   7042 
   7043       /* If the gimplified operand is a register we do not allow memory.  */
   7044       if (allows_reg
   7045 	  && allows_mem
   7046 	  && (is_gimple_reg (TREE_VALUE (link))
   7047 	      || (handled_component_p (TREE_VALUE (link))
   7048 		  && is_gimple_reg (TREE_OPERAND (TREE_VALUE (link), 0)))))
   7049 	allows_mem = 0;
   7050 
   7051       /* If the constraint does not allow memory make sure we gimplify
   7052          it to a register if it is not already but its base is.  This
   7053 	 happens for complex and vector components.  */
   7054       if (!allows_mem)
   7055 	{
   7056 	  tree op = TREE_VALUE (link);
   7057 	  if (! is_gimple_val (op)
   7058 	      && is_gimple_reg_type (TREE_TYPE (op))
   7059 	      && is_gimple_reg (get_base_address (op)))
   7060 	    {
   7061 	      tree tem = create_tmp_reg (TREE_TYPE (op));
   7062 	      tree ass;
   7063 	      if (is_inout)
   7064 		{
   7065 		  ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
   7066 				tem, unshare_expr (op));
   7067 		  gimplify_and_add (ass, pre_p);
   7068 		}
   7069 	      ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
   7070 	      gimplify_and_add (ass, post_p);
   7071 
   7072 	      TREE_VALUE (link) = tem;
   7073 	      tret = GS_OK;
   7074 	    }
   7075 	}
   7076 
   7077       vec_safe_push (outputs, link);
   7078       TREE_CHAIN (link) = NULL_TREE;
   7079 
   7080       if (is_inout)
   7081 	{
   7082 	  /* An input/output operand.  To give the optimizers more
   7083 	     flexibility, split it into separate input and output
   7084  	     operands.  */
   7085 	  tree input;
   7086 	  /* Buffer big enough to format a 32-bit UINT_MAX into.  */
   7087 	  char buf[11];
   7088 
   7089 	  /* Turn the in/out constraint into an output constraint.  */
   7090 	  char *p = xstrdup (constraint);
   7091 	  p[0] = '=';
   7092 	  TREE_PURPOSE (link) = unshare_expr (TREE_PURPOSE (link));
   7093 	  TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
   7094 
   7095 	  /* And add a matching input constraint.  */
   7096 	  if (allows_reg)
   7097 	    {
   7098 	      sprintf (buf, "%u", i);
   7099 
   7100 	      /* If there are multiple alternatives in the constraint,
   7101 		 handle each of them individually.  Those that allow register
   7102 		 will be replaced with operand number, the others will stay
   7103 		 unchanged.  */
   7104 	      if (strchr (p, ',') != NULL)
   7105 		{
   7106 		  size_t len = 0, buflen = strlen (buf);
   7107 		  char *beg, *end, *str, *dst;
   7108 
   7109 		  for (beg = p + 1;;)
   7110 		    {
   7111 		      end = strchr (beg, ',');
   7112 		      if (end == NULL)
   7113 			end = strchr (beg, '\0');
   7114 		      if ((size_t) (end - beg) < buflen)
   7115 			len += buflen + 1;
   7116 		      else
   7117 			len += end - beg + 1;
   7118 		      if (*end)
   7119 			beg = end + 1;
   7120 		      else
   7121 			break;
   7122 		    }
   7123 
   7124 		  str = (char *) alloca (len);
   7125 		  for (beg = p + 1, dst = str;;)
   7126 		    {
   7127 		      const char *tem;
   7128 		      bool mem_p, reg_p, inout_p;
   7129 
   7130 		      end = strchr (beg, ',');
   7131 		      if (end)
   7132 			*end = '\0';
   7133 		      beg[-1] = '=';
   7134 		      tem = beg - 1;
   7135 		      parse_output_constraint (&tem, i, 0, 0,
   7136 					       &mem_p, &reg_p, &inout_p);
   7137 		      if (dst != str)
   7138 			*dst++ = ',';
   7139 		      if (reg_p)
   7140 			{
   7141 			  memcpy (dst, buf, buflen);
   7142 			  dst += buflen;
   7143 			}
   7144 		      else
   7145 			{
   7146 			  if (end)
   7147 			    len = end - beg;
   7148 			  else
   7149 			    len = strlen (beg);
   7150 			  memcpy (dst, beg, len);
   7151 			  dst += len;
   7152 			}
   7153 		      if (end)
   7154 			beg = end + 1;
   7155 		      else
   7156 			break;
   7157 		    }
   7158 		  *dst = '\0';
   7159 		  input = build_string (dst - str, str);
   7160 		}
   7161 	      else
   7162 		input = build_string (strlen (buf), buf);
   7163 	    }
   7164 	  else
   7165 	    input = build_string (constraint_len - 1, constraint + 1);
   7166 
   7167 	  free (p);
   7168 
   7169 	  input = build_tree_list (build_tree_list (NULL_TREE, input),
   7170 				   unshare_expr (TREE_VALUE (link)));
   7171 	  ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
   7172 	}
   7173     }
   7174 
   7175   link_next = NULL_TREE;
   7176   for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
   7177     {
   7178       link_next = TREE_CHAIN (link);
   7179       constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
   7180       parse_input_constraint (&constraint, 0, 0, noutputs, 0,
   7181 			      oconstraints, &allows_mem, &allows_reg);
   7182 
   7183       /* If we can't make copies, we can only accept memory.  */
   7184       tree intype = TREE_TYPE (TREE_VALUE (link));
   7185       if (intype != error_mark_node
   7186 	  && (TREE_ADDRESSABLE (intype)
   7187 	      || !COMPLETE_TYPE_P (intype)
   7188 	      || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype))))
   7189 	{
   7190 	  if (allows_mem)
   7191 	    allows_reg = 0;
   7192 	  else
   7193 	    {
   7194 	      error ("impossible constraint in %<asm%>");
   7195 	      error ("non-memory input %d must stay in memory", i);
   7196 	      return GS_ERROR;
   7197 	    }
   7198 	}
   7199 
   7200       /* If the operand is a memory input, it should be an lvalue.  */
   7201       if (!allows_reg && allows_mem)
   7202 	{
   7203 	  tree inputv = TREE_VALUE (link);
   7204 	  STRIP_NOPS (inputv);
   7205 	  if (TREE_CODE (inputv) == PREDECREMENT_EXPR
   7206 	      || TREE_CODE (inputv) == PREINCREMENT_EXPR
   7207 	      || TREE_CODE (inputv) == POSTDECREMENT_EXPR
   7208 	      || TREE_CODE (inputv) == POSTINCREMENT_EXPR
   7209 	      || TREE_CODE (inputv) == MODIFY_EXPR)
   7210 	    TREE_VALUE (link) = error_mark_node;
   7211 	  tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
   7212 				is_gimple_lvalue, fb_lvalue | fb_mayfail);
   7213 	  if (tret != GS_ERROR)
   7214 	    {
   7215 	      /* Unlike output operands, memory inputs are not guaranteed
   7216 		 to be lvalues by the FE, and while the expressions are
   7217 		 marked addressable there, if it is e.g. a statement
   7218 		 expression, temporaries in it might not end up being
   7219 		 addressable.  They might be already used in the IL and thus
   7220 		 it is too late to make them addressable now though.  */
   7221 	      tree x = TREE_VALUE (link);
   7222 	      while (handled_component_p (x))
   7223 		x = TREE_OPERAND (x, 0);
   7224 	      if (TREE_CODE (x) == MEM_REF
   7225 		  && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
   7226 		x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
   7227 	      if ((VAR_P (x)
   7228 		   || TREE_CODE (x) == PARM_DECL
   7229 		   || TREE_CODE (x) == RESULT_DECL)
   7230 		  && !TREE_ADDRESSABLE (x)
   7231 		  && is_gimple_reg (x))
   7232 		{
   7233 		  warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
   7234 					       input_location), 0,
   7235 			      "memory input %d is not directly addressable",
   7236 			      i);
   7237 		  prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
   7238 		}
   7239 	    }
   7240 	  mark_addressable (TREE_VALUE (link));
   7241 	  if (tret == GS_ERROR)
   7242 	    {
   7243 	      if (inputv != error_mark_node)
   7244 		error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
   7245 			  "memory input %d is not directly addressable", i);
   7246 	      ret = tret;
   7247 	    }
   7248 	}
   7249       else
   7250 	{
   7251 	  tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
   7252 				is_gimple_asm_val, fb_rvalue);
   7253 	  if (tret == GS_ERROR)
   7254 	    ret = tret;
   7255 	}
   7256 
   7257       TREE_CHAIN (link) = NULL_TREE;
   7258       vec_safe_push (inputs, link);
   7259     }
   7260 
   7261   link_next = NULL_TREE;
   7262   for (link = ASM_CLOBBERS (expr); link; ++i, link = link_next)
   7263     {
   7264       link_next = TREE_CHAIN (link);
   7265       TREE_CHAIN (link) = NULL_TREE;
   7266       vec_safe_push (clobbers, link);
   7267     }
   7268 
   7269   link_next = NULL_TREE;
   7270   for (link = ASM_LABELS (expr); link; ++i, link = link_next)
   7271     {
   7272       link_next = TREE_CHAIN (link);
   7273       TREE_CHAIN (link) = NULL_TREE;
   7274       vec_safe_push (labels, link);
   7275     }
   7276 
   7277   /* Do not add ASMs with errors to the gimple IL stream.  */
   7278   if (ret != GS_ERROR)
   7279     {
   7280       stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
   7281 				   inputs, outputs, clobbers, labels);
   7282 
   7283       /* asm is volatile if it was marked by the user as volatile or
   7284 	 there are no outputs or this is an asm goto.  */
   7285       gimple_asm_set_volatile (stmt,
   7286 			       ASM_VOLATILE_P (expr)
   7287 			       || noutputs == 0
   7288 			       || labels);
   7289       gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
   7290       gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
   7291 
   7292       gimplify_seq_add_stmt (pre_p, stmt);
   7293     }
   7294 
   7295   return ret;
   7296 }
   7297 
   7298 /* Gimplify a CLEANUP_POINT_EXPR.  Currently this works by adding
   7299    GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
   7300    gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
   7301    return to this function.
   7302 
   7303    FIXME should we complexify the prequeue handling instead?  Or use flags
   7304    for all the cleanups and let the optimizer tighten them up?  The current
   7305    code seems pretty fragile; it will break on a cleanup within any
   7306    non-conditional nesting.  But any such nesting would be broken, anyway;
   7307    we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
   7308    and continues out of it.  We can do that at the RTL level, though, so
   7309    having an optimizer to tighten up try/finally regions would be a Good
   7310    Thing.  */
   7311 
   7312 static enum gimplify_status
   7313 gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
   7314 {
   7315   gimple_stmt_iterator iter;
   7316   gimple_seq body_sequence = NULL;
   7317 
   7318   tree temp = voidify_wrapper_expr (*expr_p, NULL);
   7319 
   7320   /* We only care about the number of conditions between the innermost
   7321      CLEANUP_POINT_EXPR and the cleanup.  So save and reset the count and
   7322      any cleanups collected outside the CLEANUP_POINT_EXPR.  */
   7323   int old_conds = gimplify_ctxp->conditions;
   7324   gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
   7325   bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
   7326   gimplify_ctxp->conditions = 0;
   7327   gimplify_ctxp->conditional_cleanups = NULL;
   7328   gimplify_ctxp->in_cleanup_point_expr = true;
   7329 
   7330   gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
   7331 
   7332   gimplify_ctxp->conditions = old_conds;
   7333   gimplify_ctxp->conditional_cleanups = old_cleanups;
   7334   gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
   7335 
   7336   for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
   7337     {
   7338       gimple *wce = gsi_stmt (iter);
   7339 
   7340       if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
   7341 	{
   7342 	  if (gsi_one_before_end_p (iter))
   7343 	    {
   7344               /* Note that gsi_insert_seq_before and gsi_remove do not
   7345                  scan operands, unlike some other sequence mutators.  */
   7346 	      if (!gimple_wce_cleanup_eh_only (wce))
   7347 		gsi_insert_seq_before_without_update (&iter,
   7348 						      gimple_wce_cleanup (wce),
   7349 						      GSI_SAME_STMT);
   7350 	      gsi_remove (&iter, true);
   7351 	      break;
   7352 	    }
   7353 	  else
   7354 	    {
   7355 	      gtry *gtry;
   7356 	      gimple_seq seq;
   7357 	      enum gimple_try_flags kind;
   7358 
   7359 	      if (gimple_wce_cleanup_eh_only (wce))
   7360 		kind = GIMPLE_TRY_CATCH;
   7361 	      else
   7362 		kind = GIMPLE_TRY_FINALLY;
   7363 	      seq = gsi_split_seq_after (iter);
   7364 
   7365 	      gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
   7366               /* Do not use gsi_replace here, as it may scan operands.
   7367                  We want to do a simple structural modification only.  */
   7368 	      gsi_set_stmt (&iter, gtry);
   7369 	      iter = gsi_start (gtry->eval);
   7370 	    }
   7371 	}
   7372       else
   7373 	gsi_next (&iter);
   7374     }
   7375 
   7376   gimplify_seq_add_seq (pre_p, body_sequence);
   7377   if (temp)
   7378     {
   7379       *expr_p = temp;
   7380       return GS_OK;
   7381     }
   7382   else
   7383     {
   7384       *expr_p = NULL;
   7385       return GS_ALL_DONE;
   7386     }
   7387 }
   7388 
   7389 /* Insert a cleanup marker for gimplify_cleanup_point_expr.  CLEANUP
   7390    is the cleanup action required.  EH_ONLY is true if the cleanup should
   7391    only be executed if an exception is thrown, not on normal exit.
   7392    If FORCE_UNCOND is true perform the cleanup unconditionally;  this is
   7393    only valid for clobbers.  */
   7394 
   7395 static void
   7396 gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
   7397 		     bool force_uncond = false)
   7398 {
   7399   gimple *wce;
   7400   gimple_seq cleanup_stmts = NULL;
   7401 
   7402   /* Errors can result in improperly nested cleanups.  Which results in
   7403      confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR.  */
   7404   if (seen_error ())
   7405     return;
   7406 
   7407   if (gimple_conditional_context ())
   7408     {
   7409       /* If we're in a conditional context, this is more complex.  We only
   7410 	 want to run the cleanup if we actually ran the initialization that
   7411 	 necessitates it, but we want to run it after the end of the
   7412 	 conditional context.  So we wrap the try/finally around the
   7413 	 condition and use a flag to determine whether or not to actually
   7414 	 run the destructor.  Thus
   7415 
   7416 	   test ? f(A()) : 0
   7417 
   7418 	 becomes (approximately)
   7419 
   7420 	   flag = 0;
   7421 	   try {
   7422 	     if (test) { A::A(temp); flag = 1; val = f(temp); }
   7423 	     else { val = 0; }
   7424 	   } finally {
   7425 	     if (flag) A::~A(temp);
   7426 	   }
   7427 	   val
   7428       */
   7429       if (force_uncond)
   7430 	{
   7431 	  gimplify_stmt (&cleanup, &cleanup_stmts);
   7432 	  wce = gimple_build_wce (cleanup_stmts);
   7433 	  gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
   7434 	}
   7435       else
   7436 	{
   7437 	  tree flag = create_tmp_var (boolean_type_node, "cleanup");
   7438 	  gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
   7439 	  gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
   7440 
   7441 	  cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
   7442 	  gimplify_stmt (&cleanup, &cleanup_stmts);
   7443 	  wce = gimple_build_wce (cleanup_stmts);
   7444 	  gimple_wce_set_cleanup_eh_only (wce, eh_only);
   7445 
   7446 	  gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
   7447 	  gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
   7448 	  gimplify_seq_add_stmt (pre_p, ftrue);
   7449 
   7450 	  /* Because of this manipulation, and the EH edges that jump
   7451 	     threading cannot redirect, the temporary (VAR) will appear
   7452 	     to be used uninitialized.  Don't warn.  */
   7453 	  suppress_warning (var, OPT_Wuninitialized);
   7454 	}
   7455     }
   7456   else
   7457     {
   7458       gimplify_stmt (&cleanup, &cleanup_stmts);
   7459       wce = gimple_build_wce (cleanup_stmts);
   7460       gimple_wce_set_cleanup_eh_only (wce, eh_only);
   7461       gimplify_seq_add_stmt (pre_p, wce);
   7462     }
   7463 }
   7464 
   7465 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR.  */
   7466 
   7467 static enum gimplify_status
   7468 gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
   7469 {
   7470   tree targ = *expr_p;
   7471   tree temp = TARGET_EXPR_SLOT (targ);
   7472   tree init = TARGET_EXPR_INITIAL (targ);
   7473   enum gimplify_status ret;
   7474 
   7475   bool unpoison_empty_seq = false;
   7476   gimple_stmt_iterator unpoison_it;
   7477 
   7478   if (init)
   7479     {
   7480       gimple_seq init_pre_p = NULL;
   7481 
   7482       /* TARGET_EXPR temps aren't part of the enclosing block, so add it
   7483 	 to the temps list.  Handle also variable length TARGET_EXPRs.  */
   7484       if (!poly_int_tree_p (DECL_SIZE (temp)))
   7485 	{
   7486 	  if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
   7487 	    gimplify_type_sizes (TREE_TYPE (temp), &init_pre_p);
   7488 	  /* FIXME: this is correct only when the size of the type does
   7489 	     not depend on expressions evaluated in init.  */
   7490 	  gimplify_vla_decl (temp, &init_pre_p);
   7491 	}
   7492       else
   7493 	{
   7494 	  /* Save location where we need to place unpoisoning.  It's possible
   7495 	     that a variable will be converted to needs_to_live_in_memory.  */
   7496 	  unpoison_it = gsi_last (*pre_p);
   7497 	  unpoison_empty_seq = gsi_end_p (unpoison_it);
   7498 
   7499 	  gimple_add_tmp_var (temp);
   7500 	}
   7501 
   7502       /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
   7503 	 expression is supposed to initialize the slot.  */
   7504       if (VOID_TYPE_P (TREE_TYPE (init)))
   7505 	ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
   7506 			     fb_none);
   7507       else
   7508 	{
   7509 	  tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
   7510 	  init = init_expr;
   7511 	  ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
   7512 			       fb_none);
   7513 	  init = NULL;
   7514 	  ggc_free (init_expr);
   7515 	}
   7516       if (ret == GS_ERROR)
   7517 	{
   7518 	  /* PR c++/28266 Make sure this is expanded only once. */
   7519 	  TARGET_EXPR_INITIAL (targ) = NULL_TREE;
   7520 	  return GS_ERROR;
   7521 	}
   7522 
   7523       if (init)
   7524 	gimplify_and_add (init, &init_pre_p);
   7525 
   7526       /* Add a clobber for the temporary going out of scope, like
   7527 	 gimplify_bind_expr.  But only if we did not promote the
   7528 	 temporary to static storage.  */
   7529       if (gimplify_ctxp->in_cleanup_point_expr
   7530 	  && !TREE_STATIC (temp)
   7531 	  && needs_to_live_in_memory (temp))
   7532 	{
   7533 	  if (flag_stack_reuse == SR_ALL)
   7534 	    {
   7535 	      tree clobber = build_clobber (TREE_TYPE (temp),
   7536 					    CLOBBER_STORAGE_END);
   7537 	      clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
   7538 	      gimple_push_cleanup (temp, clobber, false, pre_p, true);
   7539 	    }
   7540 	  if (asan_poisoned_variables
   7541 	      && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
   7542 	      && !TREE_STATIC (temp)
   7543 	      && dbg_cnt (asan_use_after_scope)
   7544 	      && !gimplify_omp_ctxp)
   7545 	    {
   7546 	      tree asan_cleanup = build_asan_poison_call_expr (temp);
   7547 	      if (asan_cleanup)
   7548 		{
   7549 		  if (unpoison_empty_seq)
   7550 		    unpoison_it = gsi_start (*pre_p);
   7551 
   7552 		  asan_poison_variable (temp, false, &unpoison_it,
   7553 					unpoison_empty_seq);
   7554 		  gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
   7555 		}
   7556 	    }
   7557 	}
   7558 
   7559       gimple_seq_add_seq (pre_p, init_pre_p);
   7560 
   7561       /* If needed, push the cleanup for the temp.  */
   7562       if (TARGET_EXPR_CLEANUP (targ))
   7563 	gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
   7564 			     CLEANUP_EH_ONLY (targ), pre_p);
   7565 
   7566       /* Only expand this once.  */
   7567       TREE_OPERAND (targ, 3) = init;
   7568       TARGET_EXPR_INITIAL (targ) = NULL_TREE;
   7569     }
   7570   else
   7571     /* We should have expanded this before.  */
   7572     gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
   7573 
   7574   *expr_p = temp;
   7575   return GS_OK;
   7576 }
   7577 
   7578 /* Gimplification of expression trees.  */
   7579 
   7580 /* Gimplify an expression which appears at statement context.  The
   7581    corresponding GIMPLE statements are added to *SEQ_P.  If *SEQ_P is
   7582    NULL, a new sequence is allocated.
   7583 
   7584    Return true if we actually added a statement to the queue.  */
   7585 
   7586 bool
   7587 gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
   7588 {
   7589   gimple_seq_node last;
   7590 
   7591   last = gimple_seq_last (*seq_p);
   7592   gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
   7593   return last != gimple_seq_last (*seq_p);
   7594 }
   7595 
   7596 /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
   7597    to CTX.  If entries already exist, force them to be some flavor of private.
   7598    If there is no enclosing parallel, do nothing.  */
   7599 
   7600 void
   7601 omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
   7602 {
   7603   splay_tree_node n;
   7604 
   7605   if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
   7606     return;
   7607 
   7608   do
   7609     {
   7610       n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
   7611       if (n != NULL)
   7612 	{
   7613 	  if (n->value & GOVD_SHARED)
   7614 	    n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
   7615 	  else if (n->value & GOVD_MAP)
   7616 	    n->value |= GOVD_MAP_TO_ONLY;
   7617 	  else
   7618 	    return;
   7619 	}
   7620       else if ((ctx->region_type & ORT_TARGET) != 0)
   7621 	{
   7622 	  if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
   7623 	    omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
   7624 	  else
   7625 	    omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
   7626 	}
   7627       else if (ctx->region_type != ORT_WORKSHARE
   7628 	       && ctx->region_type != ORT_TASKGROUP
   7629 	       && ctx->region_type != ORT_SIMD
   7630 	       && ctx->region_type != ORT_ACC
   7631 	       && !(ctx->region_type & ORT_TARGET_DATA))
   7632 	omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
   7633 
   7634       ctx = ctx->outer_context;
   7635     }
   7636   while (ctx);
   7637 }
   7638 
   7639 /* Similarly for each of the type sizes of TYPE.  */
   7640 
   7641 static void
   7642 omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
   7643 {
   7644   if (type == NULL || type == error_mark_node)
   7645     return;
   7646   type = TYPE_MAIN_VARIANT (type);
   7647 
   7648   if (ctx->privatized_types->add (type))
   7649     return;
   7650 
   7651   switch (TREE_CODE (type))
   7652     {
   7653     case INTEGER_TYPE:
   7654     case ENUMERAL_TYPE:
   7655     case BOOLEAN_TYPE:
   7656     case REAL_TYPE:
   7657     case FIXED_POINT_TYPE:
   7658       omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
   7659       omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
   7660       break;
   7661 
   7662     case ARRAY_TYPE:
   7663       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
   7664       omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
   7665       break;
   7666 
   7667     case RECORD_TYPE:
   7668     case UNION_TYPE:
   7669     case QUAL_UNION_TYPE:
   7670       {
   7671 	tree field;
   7672 	for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
   7673 	  if (TREE_CODE (field) == FIELD_DECL)
   7674 	    {
   7675 	      omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
   7676 	      omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
   7677 	    }
   7678       }
   7679       break;
   7680 
   7681     case POINTER_TYPE:
   7682     case REFERENCE_TYPE:
   7683       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
   7684       break;
   7685 
   7686     default:
   7687       break;
   7688     }
   7689 
   7690   omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
   7691   omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
   7692   lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
   7693 }
   7694 
   7695 /* Add an entry for DECL in the OMP context CTX with FLAGS.  */
   7696 
   7697 static void
   7698 omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
   7699 {
   7700   splay_tree_node n;
   7701   unsigned int nflags;
   7702   tree t;
   7703 
   7704   if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
   7705     return;
   7706 
   7707   /* Never elide decls whose type has TREE_ADDRESSABLE set.  This means
   7708      there are constructors involved somewhere.  Exception is a shared clause,
   7709      there is nothing privatized in that case.  */
   7710   if ((flags & GOVD_SHARED) == 0
   7711       && (TREE_ADDRESSABLE (TREE_TYPE (decl))
   7712 	  || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
   7713     flags |= GOVD_SEEN;
   7714 
   7715   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
   7716   if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
   7717     {
   7718       /* We shouldn't be re-adding the decl with the same data
   7719 	 sharing class.  */
   7720       gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
   7721       nflags = n->value | flags;
   7722       /* The only combination of data sharing classes we should see is
   7723 	 FIRSTPRIVATE and LASTPRIVATE.  However, OpenACC permits
   7724 	 reduction variables to be used in data sharing clauses.  */
   7725       gcc_assert ((ctx->region_type & ORT_ACC) != 0
   7726 		  || ((nflags & GOVD_DATA_SHARE_CLASS)
   7727 		      == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
   7728 		  || (flags & GOVD_DATA_SHARE_CLASS) == 0);
   7729       n->value = nflags;
   7730       return;
   7731     }
   7732 
   7733   /* When adding a variable-sized variable, we have to handle all sorts
   7734      of additional bits of data: the pointer replacement variable, and
   7735      the parameters of the type.  */
   7736   if (DECL_SIZE (decl) && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
   7737     {
   7738       /* Add the pointer replacement variable as PRIVATE if the variable
   7739 	 replacement is private, else FIRSTPRIVATE since we'll need the
   7740 	 address of the original variable either for SHARED, or for the
   7741 	 copy into or out of the context.  */
   7742       if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
   7743 	{
   7744 	  if (flags & GOVD_MAP)
   7745 	    nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
   7746 	  else if (flags & GOVD_PRIVATE)
   7747 	    nflags = GOVD_PRIVATE;
   7748 	  else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
   7749 		    && (flags & GOVD_FIRSTPRIVATE))
   7750 		   || (ctx->region_type == ORT_TARGET_DATA
   7751 		       && (flags & GOVD_DATA_SHARE_CLASS) == 0))
   7752 	    nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
   7753 	  else
   7754 	    nflags = GOVD_FIRSTPRIVATE;
   7755 	  nflags |= flags & GOVD_SEEN;
   7756 	  t = DECL_VALUE_EXPR (decl);
   7757 	  gcc_assert (INDIRECT_REF_P (t));
   7758 	  t = TREE_OPERAND (t, 0);
   7759 	  gcc_assert (DECL_P (t));
   7760 	  omp_add_variable (ctx, t, nflags);
   7761 	}
   7762 
   7763       /* Add all of the variable and type parameters (which should have
   7764 	 been gimplified to a formal temporary) as FIRSTPRIVATE.  */
   7765       omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
   7766       omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
   7767       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
   7768 
   7769       /* The variable-sized variable itself is never SHARED, only some form
   7770 	 of PRIVATE.  The sharing would take place via the pointer variable
   7771 	 which we remapped above.  */
   7772       if (flags & GOVD_SHARED)
   7773 	flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
   7774 		| (flags & (GOVD_SEEN | GOVD_EXPLICIT));
   7775 
   7776       /* We're going to make use of the TYPE_SIZE_UNIT at least in the
   7777 	 alloca statement we generate for the variable, so make sure it
   7778 	 is available.  This isn't automatically needed for the SHARED
   7779 	 case, since we won't be allocating local storage then.
   7780 	 For local variables TYPE_SIZE_UNIT might not be gimplified yet,
   7781 	 in this case omp_notice_variable will be called later
   7782 	 on when it is gimplified.  */
   7783       else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
   7784 	       && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
   7785 	omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
   7786     }
   7787   else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
   7788 	   && omp_privatize_by_reference (decl))
   7789     {
   7790       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
   7791 
   7792       /* Similar to the direct variable sized case above, we'll need the
   7793 	 size of references being privatized.  */
   7794       if ((flags & GOVD_SHARED) == 0)
   7795 	{
   7796 	  t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
   7797 	  if (t && DECL_P (t))
   7798 	    omp_notice_variable (ctx, t, true);
   7799 	}
   7800     }
   7801 
   7802   if (n != NULL)
   7803     n->value |= flags;
   7804   else
   7805     splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
   7806 
   7807   /* For reductions clauses in OpenACC loop directives, by default create a
   7808      copy clause on the enclosing parallel construct for carrying back the
   7809      results.  */
   7810   if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
   7811     {
   7812       struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
   7813       while (outer_ctx)
   7814 	{
   7815 	  n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
   7816 	  if (n != NULL)
   7817 	    {
   7818 	      /* Ignore local variables and explicitly declared clauses.  */
   7819 	      if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
   7820 		break;
   7821 	      else if (outer_ctx->region_type == ORT_ACC_KERNELS)
   7822 		{
   7823 		  /* According to the OpenACC spec, such a reduction variable
   7824 		     should already have a copy map on a kernels construct,
   7825 		     verify that here.  */
   7826 		  gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
   7827 			      && (n->value & GOVD_MAP));
   7828 		}
   7829 	      else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
   7830 		{
   7831 		  /* Remove firstprivate and make it a copy map.  */
   7832 		  n->value &= ~GOVD_FIRSTPRIVATE;
   7833 		  n->value |= GOVD_MAP;
   7834 		}
   7835 	    }
   7836 	  else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
   7837 	    {
   7838 	      splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
   7839 				 GOVD_MAP | GOVD_SEEN);
   7840 	      break;
   7841 	    }
   7842 	  outer_ctx = outer_ctx->outer_context;
   7843 	}
   7844     }
   7845 }
   7846 
   7847 /* Notice a threadprivate variable DECL used in OMP context CTX.
   7848    This just prints out diagnostics about threadprivate variable uses
   7849    in untied tasks.  If DECL2 is non-NULL, prevent this warning
   7850    on that variable.  */
   7851 
   7852 static bool
   7853 omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
   7854 				   tree decl2)
   7855 {
   7856   splay_tree_node n;
   7857   struct gimplify_omp_ctx *octx;
   7858 
   7859   for (octx = ctx; octx; octx = octx->outer_context)
   7860     if ((octx->region_type & ORT_TARGET) != 0
   7861 	|| octx->order_concurrent)
   7862       {
   7863 	n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
   7864 	if (n == NULL)
   7865 	  {
   7866 	    if (octx->order_concurrent)
   7867 	      {
   7868 		error ("threadprivate variable %qE used in a region with"
   7869 		       " %<order(concurrent)%> clause", DECL_NAME (decl));
   7870 		inform (octx->location, "enclosing region");
   7871 	      }
   7872 	    else
   7873 	      {
   7874 		error ("threadprivate variable %qE used in target region",
   7875 		       DECL_NAME (decl));
   7876 		inform (octx->location, "enclosing target region");
   7877 	      }
   7878 	    splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
   7879 	  }
   7880 	if (decl2)
   7881 	  splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
   7882       }
   7883 
   7884   if (ctx->region_type != ORT_UNTIED_TASK)
   7885     return false;
   7886   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
   7887   if (n == NULL)
   7888     {
   7889       error ("threadprivate variable %qE used in untied task",
   7890 	     DECL_NAME (decl));
   7891       inform (ctx->location, "enclosing task");
   7892       splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
   7893     }
   7894   if (decl2)
   7895     splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
   7896   return false;
   7897 }
   7898 
   7899 /* Return true if global var DECL is device resident.  */
   7900 
   7901 static bool
   7902 device_resident_p (tree decl)
   7903 {
   7904   tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
   7905 
   7906   if (!attr)
   7907     return false;
   7908 
   7909   for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
   7910     {
   7911       tree c = TREE_VALUE (t);
   7912       if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
   7913 	return true;
   7914     }
   7915 
   7916   return false;
   7917 }
   7918 
   7919 /* Return true if DECL has an ACC DECLARE attribute.  */
   7920 
   7921 static bool
   7922 is_oacc_declared (tree decl)
   7923 {
   7924   tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
   7925   tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
   7926   return declared != NULL_TREE;
   7927 }
   7928 
   7929 /* Determine outer default flags for DECL mentioned in an OMP region
   7930    but not declared in an enclosing clause.
   7931 
   7932    ??? Some compiler-generated variables (like SAVE_EXPRs) could be
   7933    remapped firstprivate instead of shared.  To some extent this is
   7934    addressed in omp_firstprivatize_type_sizes, but not
   7935    effectively.  */
   7936 
   7937 static unsigned
   7938 omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
   7939 		    bool in_code, unsigned flags)
   7940 {
   7941   enum omp_clause_default_kind default_kind = ctx->default_kind;
   7942   enum omp_clause_default_kind kind;
   7943 
   7944   kind = lang_hooks.decls.omp_predetermined_sharing (decl);
   7945   if (ctx->region_type & ORT_TASK)
   7946     {
   7947       tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH);
   7948 
   7949       /* The event-handle specified by a detach clause should always be firstprivate,
   7950 	 regardless of the current default.  */
   7951       if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl)
   7952 	kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
   7953     }
   7954   if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
   7955     default_kind = kind;
   7956   else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
   7957     default_kind = OMP_CLAUSE_DEFAULT_SHARED;
   7958   /* For C/C++ default({,first}private), variables with static storage duration
   7959      declared in a namespace or global scope and referenced in construct
   7960      must be explicitly specified, i.e. acts as default(none).  */
   7961   else if ((default_kind == OMP_CLAUSE_DEFAULT_PRIVATE
   7962 	    || default_kind == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
   7963 	   && VAR_P (decl)
   7964 	   && is_global_var (decl)
   7965 	   && (DECL_FILE_SCOPE_P (decl)
   7966 	       || (DECL_CONTEXT (decl)
   7967 		   && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
   7968 	   && !lang_GNU_Fortran ())
   7969     default_kind = OMP_CLAUSE_DEFAULT_NONE;
   7970 
   7971   switch (default_kind)
   7972     {
   7973     case OMP_CLAUSE_DEFAULT_NONE:
   7974       {
   7975 	const char *rtype;
   7976 
   7977 	if (ctx->region_type & ORT_PARALLEL)
   7978 	  rtype = "parallel";
   7979 	else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
   7980 	  rtype = "taskloop";
   7981 	else if (ctx->region_type & ORT_TASK)
   7982 	  rtype = "task";
   7983 	else if (ctx->region_type & ORT_TEAMS)
   7984 	  rtype = "teams";
   7985 	else
   7986 	  gcc_unreachable ();
   7987 
   7988 	error ("%qE not specified in enclosing %qs",
   7989 	       DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
   7990 	inform (ctx->location, "enclosing %qs", rtype);
   7991       }
   7992       /* FALLTHRU */
   7993     case OMP_CLAUSE_DEFAULT_SHARED:
   7994       flags |= GOVD_SHARED;
   7995       break;
   7996     case OMP_CLAUSE_DEFAULT_PRIVATE:
   7997       flags |= GOVD_PRIVATE;
   7998       break;
   7999     case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
   8000       flags |= GOVD_FIRSTPRIVATE;
   8001       break;
   8002     case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
   8003       /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED.  */
   8004       gcc_assert ((ctx->region_type & ORT_TASK) != 0);
   8005       if (struct gimplify_omp_ctx *octx = ctx->outer_context)
   8006 	{
   8007 	  omp_notice_variable (octx, decl, in_code);
   8008 	  for (; octx; octx = octx->outer_context)
   8009 	    {
   8010 	      splay_tree_node n2;
   8011 
   8012 	      n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
   8013 	      if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
   8014 		  && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
   8015 		continue;
   8016 	      if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
   8017 		{
   8018 		  flags |= GOVD_FIRSTPRIVATE;
   8019 		  goto found_outer;
   8020 		}
   8021 	      if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
   8022 		{
   8023 		  flags |= GOVD_SHARED;
   8024 		  goto found_outer;
   8025 		}
   8026 	    }
   8027 	}
   8028 
   8029       if (TREE_CODE (decl) == PARM_DECL
   8030 	  || (!is_global_var (decl)
   8031 	      && DECL_CONTEXT (decl) == current_function_decl))
   8032 	flags |= GOVD_FIRSTPRIVATE;
   8033       else
   8034 	flags |= GOVD_SHARED;
   8035     found_outer:
   8036       break;
   8037 
   8038     default:
   8039       gcc_unreachable ();
   8040     }
   8041 
   8042   return flags;
   8043 }
   8044 
   8045 /* Return string name for types of OpenACC constructs from ORT_* values.  */
   8046 
   8047 static const char *
   8048 oacc_region_type_name (enum omp_region_type region_type)
   8049 {
   8050   switch (region_type)
   8051     {
   8052     case ORT_ACC_DATA:
   8053       return "data";
   8054     case ORT_ACC_PARALLEL:
   8055       return "parallel";
   8056     case ORT_ACC_KERNELS:
   8057       return "kernels";
   8058     case ORT_ACC_SERIAL:
   8059       return "serial";
   8060     default:
   8061       gcc_unreachable ();
   8062     }
   8063 }
   8064 
   8065 /* Determine outer default flags for DECL mentioned in an OACC region
   8066    but not declared in an enclosing clause.  */
   8067 
   8068 static unsigned
   8069 oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
   8070 {
   8071   struct gimplify_omp_ctx *ctx_default = ctx;
   8072   /* If no 'default' clause appears on this compute construct...  */
   8073   if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_SHARED)
   8074     {
   8075       /* ..., see if one appears on a lexically containing 'data'
   8076 	 construct.  */
   8077       while ((ctx_default = ctx_default->outer_context))
   8078 	{
   8079 	  if (ctx_default->region_type == ORT_ACC_DATA
   8080 	      && ctx_default->default_kind != OMP_CLAUSE_DEFAULT_SHARED)
   8081 	    break;
   8082 	}
   8083       /* If not, reset.  */
   8084       if (!ctx_default)
   8085 	ctx_default = ctx;
   8086     }
   8087 
   8088   bool on_device = false;
   8089   bool is_private = false;
   8090   bool declared = is_oacc_declared (decl);
   8091   tree type = TREE_TYPE (decl);
   8092 
   8093   if (omp_privatize_by_reference (decl))
   8094     type = TREE_TYPE (type);
   8095 
   8096   /* For Fortran COMMON blocks, only used variables in those blocks are
   8097      transfered and remapped.  The block itself will have a private clause to
   8098      avoid transfering the data twice.
   8099      The hook evaluates to false by default.  For a variable in Fortran's COMMON
   8100      or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
   8101      the variables in such a COMMON/EQUIVALENCE block shall be privatized not
   8102      the whole block.  For C++ and Fortran, it can also be true under certain
   8103      other conditions, if DECL_HAS_VALUE_EXPR.  */
   8104   if (RECORD_OR_UNION_TYPE_P (type))
   8105     is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
   8106 
   8107   if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
   8108       && is_global_var (decl)
   8109       && device_resident_p (decl)
   8110       && !is_private)
   8111     {
   8112       on_device = true;
   8113       flags |= GOVD_MAP_TO_ONLY;
   8114     }
   8115 
   8116   switch (ctx->region_type)
   8117     {
   8118     case ORT_ACC_KERNELS:
   8119       if (is_private)
   8120 	flags |= GOVD_FIRSTPRIVATE;
   8121       else if (AGGREGATE_TYPE_P (type))
   8122 	{
   8123 	  /* Aggregates default to 'present_or_copy', or 'present'.  */
   8124 	  if (ctx_default->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
   8125 	    flags |= GOVD_MAP;
   8126 	  else
   8127 	    flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
   8128 	}
   8129       else
   8130 	/* Scalars default to 'copy'.  */
   8131 	flags |= GOVD_MAP | GOVD_MAP_FORCE;
   8132 
   8133       break;
   8134 
   8135     case ORT_ACC_PARALLEL:
   8136     case ORT_ACC_SERIAL:
   8137       if (is_private)
   8138 	flags |= GOVD_FIRSTPRIVATE;
   8139       else if (on_device || declared)
   8140 	flags |= GOVD_MAP;
   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 'firstprivate'.  */
   8151 	flags |= GOVD_FIRSTPRIVATE;
   8152 
   8153       break;
   8154 
   8155     default:
   8156       gcc_unreachable ();
   8157     }
   8158 
   8159   if (DECL_ARTIFICIAL (decl))
   8160     ; /* We can get compiler-generated decls, and should not complain
   8161 	 about them.  */
   8162   else if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_NONE)
   8163     {
   8164       error ("%qE not specified in enclosing OpenACC %qs construct",
   8165 	     DECL_NAME (lang_hooks.decls.omp_report_decl (decl)),
   8166 	     oacc_region_type_name (ctx->region_type));
   8167       if (ctx_default != ctx)
   8168 	inform (ctx->location, "enclosing OpenACC %qs construct and",
   8169 		oacc_region_type_name (ctx->region_type));
   8170       inform (ctx_default->location,
   8171 	      "enclosing OpenACC %qs construct with %qs clause",
   8172 	      oacc_region_type_name (ctx_default->region_type),
   8173 	      "default(none)");
   8174     }
   8175   else if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
   8176     ; /* Handled above.  */
   8177   else
   8178     gcc_checking_assert (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
   8179 
   8180   return flags;
   8181 }
   8182 
   8183 /* Record the fact that DECL was used within the OMP context CTX.
   8184    IN_CODE is true when real code uses DECL, and false when we should
   8185    merely emit default(none) errors.  Return true if DECL is going to
   8186    be remapped and thus DECL shouldn't be gimplified into its
   8187    DECL_VALUE_EXPR (if any).  */
   8188 
   8189 static bool
   8190 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
   8191 {
   8192   splay_tree_node n;
   8193   unsigned flags = in_code ? GOVD_SEEN : 0;
   8194   bool ret = false, shared;
   8195 
   8196   if (error_operand_p (decl))
   8197     return false;
   8198 
   8199   if (DECL_ARTIFICIAL (decl))
   8200     {
   8201       tree attr = lookup_attribute ("omp allocate var", DECL_ATTRIBUTES (decl));
   8202       if (attr)
   8203 	decl = TREE_VALUE (TREE_VALUE (attr));
   8204     }
   8205 
   8206   if (ctx->region_type == ORT_NONE)
   8207     return lang_hooks.decls.omp_disregard_value_expr (decl, false);
   8208 
   8209   if (is_global_var (decl))
   8210     {
   8211       /* Threadprivate variables are predetermined.  */
   8212       if (DECL_THREAD_LOCAL_P (decl))
   8213 	return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
   8214 
   8215       if (DECL_HAS_VALUE_EXPR_P (decl))
   8216 	{
   8217 	  if (ctx->region_type & ORT_ACC)
   8218 	    /* For OpenACC, defer expansion of value to avoid transfering
   8219 	       privatized common block data instead of im-/explicitly transfered
   8220 	       variables which are in common blocks.  */
   8221 	    ;
   8222 	  else
   8223 	    {
   8224 	      tree value = get_base_address (DECL_VALUE_EXPR (decl));
   8225 
   8226 	      if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
   8227 		return omp_notice_threadprivate_variable (ctx, decl, value);
   8228 	    }
   8229 	}
   8230 
   8231       if (gimplify_omp_ctxp->outer_context == NULL
   8232 	  && VAR_P (decl)
   8233 	  && oacc_get_fn_attrib (current_function_decl))
   8234 	{
   8235 	  location_t loc = DECL_SOURCE_LOCATION (decl);
   8236 
   8237 	  if (lookup_attribute ("omp declare target link",
   8238 				DECL_ATTRIBUTES (decl)))
   8239 	    {
   8240 	      error_at (loc,
   8241 			"%qE with %<link%> clause used in %<routine%> function",
   8242 			DECL_NAME (decl));
   8243 	      return false;
   8244 	    }
   8245 	  else if (!lookup_attribute ("omp declare target",
   8246 				      DECL_ATTRIBUTES (decl)))
   8247 	    {
   8248 	      error_at (loc,
   8249 			"%qE requires a %<declare%> directive for use "
   8250 			"in a %<routine%> function", DECL_NAME (decl));
   8251 	      return false;
   8252 	    }
   8253 	}
   8254     }
   8255 
   8256   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
   8257   if ((ctx->region_type & ORT_TARGET) != 0)
   8258     {
   8259       if (n == NULL)
   8260 	{
   8261 	  unsigned nflags = flags;
   8262 	  if ((ctx->region_type & ORT_ACC) == 0)
   8263 	    {
   8264 	      bool is_declare_target = false;
   8265 	      if (is_global_var (decl)
   8266 		  && varpool_node::get_create (decl)->offloadable)
   8267 		{
   8268 		  struct gimplify_omp_ctx *octx;
   8269 		  for (octx = ctx->outer_context;
   8270 		       octx; octx = octx->outer_context)
   8271 		    {
   8272 		      n = splay_tree_lookup (octx->variables,
   8273 					     (splay_tree_key)decl);
   8274 		      if (n
   8275 			  && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
   8276 			  && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
   8277 			break;
   8278 		    }
   8279 		  is_declare_target = octx == NULL;
   8280 		}
   8281 	      if (!is_declare_target)
   8282 		{
   8283 		  int gdmk;
   8284 		  enum omp_clause_defaultmap_kind kind;
   8285 		  if (lang_hooks.decls.omp_allocatable_p (decl))
   8286 		    gdmk = GDMK_ALLOCATABLE;
   8287 		  else if (lang_hooks.decls.omp_scalar_target_p (decl))
   8288 		    gdmk = GDMK_SCALAR_TARGET;
   8289 		  else if (lang_hooks.decls.omp_scalar_p (decl, false))
   8290 		    gdmk = GDMK_SCALAR;
   8291 		  else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
   8292 			   || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
   8293 			       && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
   8294 				   == POINTER_TYPE)))
   8295 		    gdmk = GDMK_POINTER;
   8296 		  else
   8297 		    gdmk = GDMK_AGGREGATE;
   8298 		  kind = lang_hooks.decls.omp_predetermined_mapping (decl);
   8299 		  if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
   8300 		    {
   8301 		      if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
   8302 			nflags |= GOVD_FIRSTPRIVATE;
   8303 		      else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
   8304 			nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
   8305 		      else
   8306 			gcc_unreachable ();
   8307 		    }
   8308 		  else if (ctx->defaultmap[gdmk] == 0)
   8309 		    {
   8310 		      tree d = lang_hooks.decls.omp_report_decl (decl);
   8311 		      error ("%qE not specified in enclosing %<target%>",
   8312 			     DECL_NAME (d));
   8313 		      inform (ctx->location, "enclosing %<target%>");
   8314 		    }
   8315 		  else if (ctx->defaultmap[gdmk]
   8316 			   & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
   8317 		    nflags |= ctx->defaultmap[gdmk];
   8318 		  else if (ctx->defaultmap[gdmk] & GOVD_MAP_FORCE_PRESENT)
   8319 		    {
   8320 		      gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
   8321 		      nflags |= ctx->defaultmap[gdmk] | GOVD_MAP_ALLOC_ONLY;
   8322 		    }
   8323 		  else
   8324 		    {
   8325 		      gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
   8326 		      nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
   8327 		    }
   8328 		}
   8329 	    }
   8330 
   8331 	  struct gimplify_omp_ctx *octx = ctx->outer_context;
   8332 	  if ((ctx->region_type & ORT_ACC) && octx)
   8333 	    {
   8334 	      /* Look in outer OpenACC contexts, to see if there's a
   8335 		 data attribute for this variable.  */
   8336 	      omp_notice_variable (octx, decl, in_code);
   8337 
   8338 	      for (; octx; octx = octx->outer_context)
   8339 		{
   8340 		  if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
   8341 		    break;
   8342 		  splay_tree_node n2
   8343 		    = splay_tree_lookup (octx->variables,
   8344 					 (splay_tree_key) decl);
   8345 		  if (n2)
   8346 		    {
   8347 		      if (octx->region_type == ORT_ACC_HOST_DATA)
   8348 		        error ("variable %qE declared in enclosing "
   8349 			       "%<host_data%> region", DECL_NAME (decl));
   8350 		      nflags |= GOVD_MAP;
   8351 		      if (octx->region_type == ORT_ACC_DATA
   8352 			  && (n2->value & GOVD_MAP_0LEN_ARRAY))
   8353 			nflags |= GOVD_MAP_0LEN_ARRAY;
   8354 		      goto found_outer;
   8355 		    }
   8356 		}
   8357 	    }
   8358 
   8359 	  if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
   8360 			  | GOVD_MAP_ALLOC_ONLY)) == flags)
   8361 	    {
   8362 	      tree type = TREE_TYPE (decl);
   8363 
   8364 	      if (gimplify_omp_ctxp->target_firstprivatize_array_bases
   8365 		  && omp_privatize_by_reference (decl))
   8366 		type = TREE_TYPE (type);
   8367 	      if (!omp_mappable_type (type))
   8368 		{
   8369 		  error ("%qD referenced in target region does not have "
   8370 			 "a mappable type", decl);
   8371 		  nflags |= GOVD_MAP | GOVD_EXPLICIT;
   8372 		}
   8373 	      else
   8374 		{
   8375 		  if ((ctx->region_type & ORT_ACC) != 0)
   8376 		    nflags = oacc_default_clause (ctx, decl, flags);
   8377 		  else
   8378 		    nflags |= GOVD_MAP;
   8379 		}
   8380 	    }
   8381 	found_outer:
   8382 	  omp_add_variable (ctx, decl, nflags);
   8383 	  if (ctx->region_type & ORT_ACC)
   8384 	    /* For OpenACC, as remarked above, defer expansion.  */
   8385 	    shared = false;
   8386 	  else
   8387 	    shared = (nflags & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0;
   8388 	  ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
   8389 	}
   8390       else
   8391 	{
   8392 	  if (ctx->region_type & ORT_ACC)
   8393 	    /* For OpenACC, as remarked above, defer expansion.  */
   8394 	    shared = false;
   8395 	  else
   8396 	    shared = ((n->value | flags)
   8397 		      & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0;
   8398 	  ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
   8399 	  /* If nothing changed, there's nothing left to do.  */
   8400 	  if ((n->value & flags) == flags)
   8401 	    return ret;
   8402 	  flags |= n->value;
   8403 	  n->value = flags;
   8404 	}
   8405       goto do_outer;
   8406     }
   8407 
   8408   if (n == NULL)
   8409     {
   8410       if (ctx->region_type == ORT_WORKSHARE
   8411 	  || ctx->region_type == ORT_TASKGROUP
   8412 	  || ctx->region_type == ORT_SIMD
   8413 	  || ctx->region_type == ORT_ACC
   8414 	  || (ctx->region_type & ORT_TARGET_DATA) != 0)
   8415 	goto do_outer;
   8416 
   8417       flags = omp_default_clause (ctx, decl, in_code, flags);
   8418 
   8419       if ((flags & GOVD_PRIVATE)
   8420 	  && lang_hooks.decls.omp_private_outer_ref (decl))
   8421 	flags |= GOVD_PRIVATE_OUTER_REF;
   8422 
   8423       omp_add_variable (ctx, decl, flags);
   8424 
   8425       shared = (flags & GOVD_SHARED) != 0;
   8426       ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
   8427       goto do_outer;
   8428     }
   8429 
   8430   /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
   8431      lb, b or incr expressions, those shouldn't be turned into simd arrays.  */
   8432   if (ctx->region_type == ORT_SIMD
   8433       && ctx->in_for_exprs
   8434       && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
   8435 	  == GOVD_PRIVATE))
   8436     flags &= ~GOVD_SEEN;
   8437 
   8438   if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
   8439       && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
   8440       && DECL_SIZE (decl))
   8441     {
   8442       if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
   8443 	{
   8444 	  splay_tree_node n2;
   8445 	  tree t = DECL_VALUE_EXPR (decl);
   8446 	  gcc_assert (INDIRECT_REF_P (t));
   8447 	  t = TREE_OPERAND (t, 0);
   8448 	  gcc_assert (DECL_P (t));
   8449 	  n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
   8450 	  n2->value |= GOVD_SEEN;
   8451 	}
   8452       else if (omp_privatize_by_reference (decl)
   8453 	       && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
   8454 	       && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
   8455 		   != INTEGER_CST))
   8456 	{
   8457 	  splay_tree_node n2;
   8458 	  tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
   8459 	  gcc_assert (DECL_P (t));
   8460 	  n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
   8461 	  if (n2)
   8462 	    omp_notice_variable (ctx, t, true);
   8463 	}
   8464     }
   8465 
   8466   if (ctx->region_type & ORT_ACC)
   8467     /* For OpenACC, as remarked above, defer expansion.  */
   8468     shared = false;
   8469   else
   8470     shared = ((flags | n->value) & GOVD_SHARED) != 0;
   8471   ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
   8472 
   8473   /* If nothing changed, there's nothing left to do.  */
   8474   if ((n->value & flags) == flags)
   8475     return ret;
   8476   flags |= n->value;
   8477   n->value = flags;
   8478 
   8479  do_outer:
   8480   /* If the variable is private in the current context, then we don't
   8481      need to propagate anything to an outer context.  */
   8482   if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
   8483     return ret;
   8484   if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
   8485       == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
   8486     return ret;
   8487   if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
   8488 		| GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
   8489       == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
   8490     return ret;
   8491   if (ctx->outer_context
   8492       && omp_notice_variable (ctx->outer_context, decl, in_code))
   8493     return true;
   8494   return ret;
   8495 }
   8496 
   8497 /* Verify that DECL is private within CTX.  If there's specific information
   8498    to the contrary in the innermost scope, generate an error.  */
   8499 
   8500 static bool
   8501 omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
   8502 {
   8503   splay_tree_node n;
   8504 
   8505   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
   8506   if (n != NULL)
   8507     {
   8508       if (n->value & GOVD_SHARED)
   8509 	{
   8510 	  if (ctx == gimplify_omp_ctxp)
   8511 	    {
   8512 	      if (simd)
   8513 		error ("iteration variable %qE is predetermined linear",
   8514 		       DECL_NAME (decl));
   8515 	      else
   8516 		error ("iteration variable %qE should be private",
   8517 		       DECL_NAME (decl));
   8518 	      n->value = GOVD_PRIVATE;
   8519 	      return true;
   8520 	    }
   8521 	  else
   8522 	    return false;
   8523 	}
   8524       else if ((n->value & GOVD_EXPLICIT) != 0
   8525 	       && (ctx == gimplify_omp_ctxp
   8526 		   || (ctx->region_type == ORT_COMBINED_PARALLEL
   8527 		       && gimplify_omp_ctxp->outer_context == ctx)))
   8528 	{
   8529 	  if ((n->value & GOVD_FIRSTPRIVATE) != 0)
   8530 	    error ("iteration variable %qE should not be firstprivate",
   8531 		   DECL_NAME (decl));
   8532 	  else if ((n->value & GOVD_REDUCTION) != 0)
   8533 	    error ("iteration variable %qE should not be reduction",
   8534 		   DECL_NAME (decl));
   8535 	  else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
   8536 	    error ("iteration variable %qE should not be linear",
   8537 		   DECL_NAME (decl));
   8538 	}
   8539       return (ctx == gimplify_omp_ctxp
   8540 	      || (ctx->region_type == ORT_COMBINED_PARALLEL
   8541 		  && gimplify_omp_ctxp->outer_context == ctx));
   8542     }
   8543 
   8544   if (ctx->region_type != ORT_WORKSHARE
   8545       && ctx->region_type != ORT_TASKGROUP
   8546       && ctx->region_type != ORT_SIMD
   8547       && ctx->region_type != ORT_ACC)
   8548     return false;
   8549   else if (ctx->outer_context)
   8550     return omp_is_private (ctx->outer_context, decl, simd);
   8551   return false;
   8552 }
   8553 
   8554 /* Return true if DECL is private within a parallel region
   8555    that binds to the current construct's context or in parallel
   8556    region's REDUCTION clause.  */
   8557 
   8558 static bool
   8559 omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
   8560 {
   8561   splay_tree_node n;
   8562 
   8563   do
   8564     {
   8565       ctx = ctx->outer_context;
   8566       if (ctx == NULL)
   8567 	{
   8568 	  if (is_global_var (decl))
   8569 	    return false;
   8570 
   8571 	  /* References might be private, but might be shared too,
   8572 	     when checking for copyprivate, assume they might be
   8573 	     private, otherwise assume they might be shared.  */
   8574 	  if (copyprivate)
   8575 	    return true;
   8576 
   8577 	  if (omp_privatize_by_reference (decl))
   8578 	    return false;
   8579 
   8580 	  /* Treat C++ privatized non-static data members outside
   8581 	     of the privatization the same.  */
   8582 	  if (omp_member_access_dummy_var (decl))
   8583 	    return false;
   8584 
   8585 	  return true;
   8586 	}
   8587 
   8588       n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   8589 
   8590       if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
   8591 	  && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
   8592 	{
   8593 	  if ((ctx->region_type & ORT_TARGET_DATA) != 0
   8594 	      || n == NULL
   8595 	      || (n->value & GOVD_MAP) == 0)
   8596 	    continue;
   8597 	  return false;
   8598 	}
   8599 
   8600       if (n != NULL)
   8601 	{
   8602 	  if ((n->value & GOVD_LOCAL) != 0
   8603 	      && omp_member_access_dummy_var (decl))
   8604 	    return false;
   8605 	  return (n->value & GOVD_SHARED) == 0;
   8606 	}
   8607 
   8608       if (ctx->region_type == ORT_WORKSHARE
   8609 	  || ctx->region_type == ORT_TASKGROUP
   8610 	  || ctx->region_type == ORT_SIMD
   8611 	  || ctx->region_type == ORT_ACC)
   8612 	continue;
   8613 
   8614       break;
   8615     }
   8616   while (1);
   8617   return false;
   8618 }
   8619 
   8620 /* Callback for walk_tree to find a DECL_EXPR for the given DECL.  */
   8621 
   8622 static tree
   8623 find_decl_expr (tree *tp, int *walk_subtrees, void *data)
   8624 {
   8625   tree t = *tp;
   8626 
   8627   /* If this node has been visited, unmark it and keep looking.  */
   8628   if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
   8629     return t;
   8630 
   8631   if (IS_TYPE_OR_DECL_P (t))
   8632     *walk_subtrees = 0;
   8633   return NULL_TREE;
   8634 }
   8635 
   8636 
   8637 /* Gimplify the affinity clause but effectively ignore it.
   8638    Generate:
   8639      var = begin;
   8640      if ((step > 1) ? var <= end : var > end)
   8641        locatator_var_expr;  */
   8642 
   8643 static void
   8644 gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p)
   8645 {
   8646   tree last_iter = NULL_TREE;
   8647   tree last_bind = NULL_TREE;
   8648   tree label = NULL_TREE;
   8649   tree *last_body = NULL;
   8650   for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
   8651     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
   8652       {
   8653 	tree t = OMP_CLAUSE_DECL (c);
   8654 	if (TREE_CODE (t) == TREE_LIST
   8655 		    && TREE_PURPOSE (t)
   8656 		    && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
   8657 	  {
   8658 	    if (TREE_VALUE (t) == null_pointer_node)
   8659 	      continue;
   8660 	    if (TREE_PURPOSE (t) != last_iter)
   8661 	      {
   8662 		if (last_bind)
   8663 		  {
   8664 		    append_to_statement_list (label, last_body);
   8665 		    gimplify_and_add (last_bind, pre_p);
   8666 		    last_bind = NULL_TREE;
   8667 		  }
   8668 		for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
   8669 		  {
   8670 		    if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
   8671 				       is_gimple_val, fb_rvalue) == GS_ERROR
   8672 			|| gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
   8673 					  is_gimple_val, fb_rvalue) == GS_ERROR
   8674 			|| gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
   8675 					  is_gimple_val, fb_rvalue) == GS_ERROR
   8676 			|| (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
   8677 					   is_gimple_val, fb_rvalue)
   8678 			    == GS_ERROR))
   8679 		      return;
   8680 		  }
   8681 	    last_iter = TREE_PURPOSE (t);
   8682 	    tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
   8683 	    last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
   8684 				NULL, block);
   8685 	    last_body = &BIND_EXPR_BODY (last_bind);
   8686 	    tree cond = NULL_TREE;
   8687 	    location_t loc = OMP_CLAUSE_LOCATION (c);
   8688 	    for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
   8689 	      {
   8690 		tree var = TREE_VEC_ELT (it, 0);
   8691 		tree begin = TREE_VEC_ELT (it, 1);
   8692 		tree end = TREE_VEC_ELT (it, 2);
   8693 		tree step = TREE_VEC_ELT (it, 3);
   8694 		loc = DECL_SOURCE_LOCATION (var);
   8695 		tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
   8696 				       var, begin);
   8697 		append_to_statement_list_force (tem, last_body);
   8698 
   8699 		tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
   8700 			       step, build_zero_cst (TREE_TYPE (step)));
   8701 		tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node,
   8702 					      var, end);
   8703 		tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
   8704 					      var, end);
   8705 		cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node,
   8706 					 cond1, cond2, cond3);
   8707 		if (cond)
   8708 		  cond = fold_build2_loc (loc, TRUTH_AND_EXPR,
   8709 					  boolean_type_node, cond, cond1);
   8710 		else
   8711 		  cond = cond1;
   8712 	      }
   8713 	    tree cont_label = create_artificial_label (loc);
   8714 	    label = build1 (LABEL_EXPR, void_type_node, cont_label);
   8715 	    tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
   8716 					void_node,
   8717 					build_and_jump (&cont_label));
   8718 	    append_to_statement_list_force (tem, last_body);
   8719 	      }
   8720 	    if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
   8721 	      {
   8722 		append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0),
   8723 					  last_body);
   8724 		TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
   8725 	      }
   8726 	    if (error_operand_p (TREE_VALUE (t)))
   8727 	      return;
   8728 	    append_to_statement_list_force (TREE_VALUE (t), last_body);
   8729 	    TREE_VALUE (t) = null_pointer_node;
   8730 	  }
   8731 	else
   8732 	  {
   8733 	    if (last_bind)
   8734 	      {
   8735 		append_to_statement_list (label, last_body);
   8736 		gimplify_and_add (last_bind, pre_p);
   8737 		last_bind = NULL_TREE;
   8738 	      }
   8739 	    if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
   8740 	      {
   8741 		gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
   8742 			       NULL, is_gimple_val, fb_rvalue);
   8743 		OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
   8744 	      }
   8745 	    if (error_operand_p (OMP_CLAUSE_DECL (c)))
   8746 	      return;
   8747 	    if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
   8748 			       is_gimple_lvalue, fb_lvalue) == GS_ERROR)
   8749 	      return;
   8750 	    gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p);
   8751 	  }
   8752       }
   8753   if (last_bind)
   8754     {
   8755       append_to_statement_list (label, last_body);
   8756       gimplify_and_add (last_bind, pre_p);
   8757     }
   8758   return;
   8759 }
   8760 
   8761 /* If *LIST_P contains any OpenMP depend clauses with iterators,
   8762    lower all the depend clauses by populating corresponding depend
   8763    array.  Returns 0 if there are no such depend clauses, or
   8764    2 if all depend clauses should be removed, 1 otherwise.  */
   8765 
   8766 static int
   8767 gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
   8768 {
   8769   tree c;
   8770   gimple *g;
   8771   size_t n[5] = { 0, 0, 0, 0, 0 };
   8772   bool unused[5];
   8773   tree counts[5] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
   8774   tree last_iter = NULL_TREE, last_count = NULL_TREE;
   8775   size_t i, j;
   8776   location_t first_loc = UNKNOWN_LOCATION;
   8777 
   8778   for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
   8779     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
   8780       {
   8781 	switch (OMP_CLAUSE_DEPEND_KIND (c))
   8782 	  {
   8783 	  case OMP_CLAUSE_DEPEND_IN:
   8784 	    i = 2;
   8785 	    break;
   8786 	  case OMP_CLAUSE_DEPEND_OUT:
   8787 	  case OMP_CLAUSE_DEPEND_INOUT:
   8788 	    i = 0;
   8789 	    break;
   8790 	  case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
   8791 	    i = 1;
   8792 	    break;
   8793 	  case OMP_CLAUSE_DEPEND_DEPOBJ:
   8794 	    i = 3;
   8795 	    break;
   8796 	  case OMP_CLAUSE_DEPEND_INOUTSET:
   8797 	    i = 4;
   8798 	    break;
   8799 	  default:
   8800 	    gcc_unreachable ();
   8801 	  }
   8802 	tree t = OMP_CLAUSE_DECL (c);
   8803 	if (first_loc == UNKNOWN_LOCATION)
   8804 	  first_loc = OMP_CLAUSE_LOCATION (c);
   8805 	if (TREE_CODE (t) == TREE_LIST
   8806 	    && TREE_PURPOSE (t)
   8807 	    && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
   8808 	  {
   8809 	    if (TREE_PURPOSE (t) != last_iter)
   8810 	      {
   8811 		tree tcnt = size_one_node;
   8812 		for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
   8813 		  {
   8814 		    if (gimplify_expr (&TREE_VEC_ELT (it, 1), pre_p, NULL,
   8815 				       is_gimple_val, fb_rvalue) == GS_ERROR
   8816 			|| gimplify_expr (&TREE_VEC_ELT (it, 2), pre_p, NULL,
   8817 					  is_gimple_val, fb_rvalue) == GS_ERROR
   8818 			|| gimplify_expr (&TREE_VEC_ELT (it, 3), pre_p, NULL,
   8819 					  is_gimple_val, fb_rvalue) == GS_ERROR
   8820 			|| (gimplify_expr (&TREE_VEC_ELT (it, 4), pre_p, NULL,
   8821 					   is_gimple_val, fb_rvalue)
   8822 			    == GS_ERROR))
   8823 		      return 2;
   8824 		    tree var = TREE_VEC_ELT (it, 0);
   8825 		    tree begin = TREE_VEC_ELT (it, 1);
   8826 		    tree end = TREE_VEC_ELT (it, 2);
   8827 		    tree step = TREE_VEC_ELT (it, 3);
   8828 		    tree orig_step = TREE_VEC_ELT (it, 4);
   8829 		    tree type = TREE_TYPE (var);
   8830 		    tree stype = TREE_TYPE (step);
   8831 		    location_t loc = DECL_SOURCE_LOCATION (var);
   8832 		    tree endmbegin;
   8833 		    /* Compute count for this iterator as
   8834 		       orig_step > 0
   8835 		       ? (begin < end ? (end - begin + (step - 1)) / step : 0)
   8836 		       : (begin > end ? (end - begin + (step + 1)) / step : 0)
   8837 		       and compute product of those for the entire depend
   8838 		       clause.  */
   8839 		    if (POINTER_TYPE_P (type))
   8840 		      endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR,
   8841 						   stype, end, begin);
   8842 		    else
   8843 		      endmbegin = fold_build2_loc (loc, MINUS_EXPR, type,
   8844 						   end, begin);
   8845 		    tree stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype,
   8846 						   step,
   8847 						   build_int_cst (stype, 1));
   8848 		    tree stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
   8849 						   build_int_cst (stype, 1));
   8850 		    tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
   8851 						unshare_expr (endmbegin),
   8852 						stepm1);
   8853 		    pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
   8854 					   pos, step);
   8855 		    tree neg = fold_build2_loc (loc, PLUS_EXPR, stype,
   8856 						endmbegin, stepp1);
   8857 		    if (TYPE_UNSIGNED (stype))
   8858 		      {
   8859 			neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
   8860 			step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
   8861 		      }
   8862 		    neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype,
   8863 					   neg, step);
   8864 		    step = NULL_TREE;
   8865 		    tree cond = fold_build2_loc (loc, LT_EXPR,
   8866 						 boolean_type_node,
   8867 						 begin, end);
   8868 		    pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
   8869 					   build_int_cst (stype, 0));
   8870 		    cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node,
   8871 					    end, begin);
   8872 		    neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
   8873 					   build_int_cst (stype, 0));
   8874 		    tree osteptype = TREE_TYPE (orig_step);
   8875 		    cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
   8876 					    orig_step,
   8877 					    build_int_cst (osteptype, 0));
   8878 		    tree cnt = fold_build3_loc (loc, COND_EXPR, stype,
   8879 						cond, pos, neg);
   8880 		    cnt = fold_convert_loc (loc, sizetype, cnt);
   8881 		    if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
   8882 				       fb_rvalue) == GS_ERROR)
   8883 		      return 2;
   8884 		    tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
   8885 		  }
   8886 		if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val,
   8887 				   fb_rvalue) == GS_ERROR)
   8888 		  return 2;
   8889 		last_iter = TREE_PURPOSE (t);
   8890 		last_count = tcnt;
   8891 	      }
   8892 	    if (counts[i] == NULL_TREE)
   8893 	      counts[i] = last_count;
   8894 	    else
   8895 	      counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
   8896 					  PLUS_EXPR, counts[i], last_count);
   8897 	  }
   8898 	else
   8899 	  n[i]++;
   8900       }
   8901   for (i = 0; i < 5; i++)
   8902     if (counts[i])
   8903       break;
   8904   if (i == 5)
   8905     return 0;
   8906 
   8907   tree total = size_zero_node;
   8908   for (i = 0; i < 5; i++)
   8909     {
   8910       unused[i] = counts[i] == NULL_TREE && n[i] == 0;
   8911       if (counts[i] == NULL_TREE)
   8912 	counts[i] = size_zero_node;
   8913       if (n[i])
   8914 	counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
   8915       if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
   8916 			 fb_rvalue) == GS_ERROR)
   8917 	return 2;
   8918       total = size_binop (PLUS_EXPR, total, counts[i]);
   8919     }
   8920 
   8921   if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
   8922       == GS_ERROR)
   8923     return 2;
   8924   bool is_old = unused[1] && unused[3] && unused[4];
   8925   tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
   8926 			     size_int (is_old ? 1 : 4));
   8927   if (!unused[4])
   8928     totalpx = size_binop (PLUS_EXPR, totalpx,
   8929 			  size_binop (MULT_EXPR, counts[4], size_int (2)));
   8930   tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
   8931   tree array = create_tmp_var_raw (type);
   8932   TREE_ADDRESSABLE (array) = 1;
   8933   if (!poly_int_tree_p (totalpx))
   8934     {
   8935       if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
   8936 	gimplify_type_sizes (TREE_TYPE (array), pre_p);
   8937       if (gimplify_omp_ctxp)
   8938 	{
   8939 	  struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   8940 	  while (ctx
   8941 		 && (ctx->region_type == ORT_WORKSHARE
   8942 		     || ctx->region_type == ORT_TASKGROUP
   8943 		     || ctx->region_type == ORT_SIMD
   8944 		     || ctx->region_type == ORT_ACC))
   8945 	    ctx = ctx->outer_context;
   8946 	  if (ctx)
   8947 	    omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
   8948 	}
   8949       gimplify_vla_decl (array, pre_p);
   8950     }
   8951   else
   8952     gimple_add_tmp_var (array);
   8953   tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
   8954 		   NULL_TREE);
   8955   tree tem;
   8956   if (!is_old)
   8957     {
   8958       tem = build2 (MODIFY_EXPR, void_type_node, r,
   8959 		    build_int_cst (ptr_type_node, 0));
   8960       gimplify_and_add (tem, pre_p);
   8961       r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
   8962 		  NULL_TREE);
   8963     }
   8964   tem = build2 (MODIFY_EXPR, void_type_node, r,
   8965 		fold_convert (ptr_type_node, total));
   8966   gimplify_and_add (tem, pre_p);
   8967   for (i = 1; i < (is_old ? 2 : 4); i++)
   8968     {
   8969       r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
   8970 		  NULL_TREE, NULL_TREE);
   8971       tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
   8972       gimplify_and_add (tem, pre_p);
   8973     }
   8974 
   8975   tree cnts[6];
   8976   for (j = 5; j; j--)
   8977     if (!unused[j - 1])
   8978       break;
   8979   for (i = 0; i < 5; i++)
   8980     {
   8981       if (i && (i >= j || unused[i - 1]))
   8982 	{
   8983 	  cnts[i] = cnts[i - 1];
   8984 	  continue;
   8985 	}
   8986       cnts[i] = create_tmp_var (sizetype);
   8987       if (i == 0)
   8988 	g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
   8989       else
   8990 	{
   8991 	  tree t;
   8992 	  if (is_old)
   8993 	    t = size_binop (PLUS_EXPR, counts[0], size_int (2));
   8994 	  else
   8995 	    t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
   8996 	  if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
   8997 	      == GS_ERROR)
   8998 	    return 2;
   8999 	  g = gimple_build_assign (cnts[i], t);
   9000 	}
   9001       gimple_seq_add_stmt (pre_p, g);
   9002     }
   9003   if (unused[4])
   9004     cnts[5] = NULL_TREE;
   9005   else
   9006     {
   9007       tree t = size_binop (PLUS_EXPR, total, size_int (5));
   9008       cnts[5] = create_tmp_var (sizetype);
   9009       g = gimple_build_assign (cnts[i], t);
   9010       gimple_seq_add_stmt (pre_p, g);
   9011     }
   9012 
   9013   last_iter = NULL_TREE;
   9014   tree last_bind = NULL_TREE;
   9015   tree *last_body = NULL;
   9016   for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
   9017     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
   9018       {
   9019 	switch (OMP_CLAUSE_DEPEND_KIND (c))
   9020 	  {
   9021 	  case OMP_CLAUSE_DEPEND_IN:
   9022 	    i = 2;
   9023 	    break;
   9024 	  case OMP_CLAUSE_DEPEND_OUT:
   9025 	  case OMP_CLAUSE_DEPEND_INOUT:
   9026 	    i = 0;
   9027 	    break;
   9028 	  case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
   9029 	    i = 1;
   9030 	    break;
   9031 	  case OMP_CLAUSE_DEPEND_DEPOBJ:
   9032 	    i = 3;
   9033 	    break;
   9034 	  case OMP_CLAUSE_DEPEND_INOUTSET:
   9035 	    i = 4;
   9036 	    break;
   9037 	  default:
   9038 	    gcc_unreachable ();
   9039 	  }
   9040 	tree t = OMP_CLAUSE_DECL (c);
   9041 	if (TREE_CODE (t) == TREE_LIST
   9042 	    && TREE_PURPOSE (t)
   9043 	    && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
   9044 	  {
   9045 	    if (TREE_PURPOSE (t) != last_iter)
   9046 	      {
   9047 		if (last_bind)
   9048 		  gimplify_and_add (last_bind, pre_p);
   9049 		tree block = TREE_VEC_ELT (TREE_PURPOSE (t), 5);
   9050 		last_bind = build3 (BIND_EXPR, void_type_node,
   9051 				    BLOCK_VARS (block), NULL, block);
   9052 		TREE_SIDE_EFFECTS (last_bind) = 1;
   9053 		SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
   9054 		tree *p = &BIND_EXPR_BODY (last_bind);
   9055 		for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
   9056 		  {
   9057 		    tree var = TREE_VEC_ELT (it, 0);
   9058 		    tree begin = TREE_VEC_ELT (it, 1);
   9059 		    tree end = TREE_VEC_ELT (it, 2);
   9060 		    tree step = TREE_VEC_ELT (it, 3);
   9061 		    tree orig_step = TREE_VEC_ELT (it, 4);
   9062 		    tree type = TREE_TYPE (var);
   9063 		    location_t loc = DECL_SOURCE_LOCATION (var);
   9064 		    /* Emit:
   9065 		       var = begin;
   9066 		       goto cond_label;
   9067 		       beg_label:
   9068 		       ...
   9069 		       var = var + step;
   9070 		       cond_label:
   9071 		       if (orig_step > 0) {
   9072 			 if (var < end) goto beg_label;
   9073 		       } else {
   9074 			 if (var > end) goto beg_label;
   9075 		       }
   9076 		       for each iterator, with inner iterators added to
   9077 		       the ... above.  */
   9078 		    tree beg_label = create_artificial_label (loc);
   9079 		    tree cond_label = NULL_TREE;
   9080 		    tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
   9081 				      var, begin);
   9082 		    append_to_statement_list_force (tem, p);
   9083 		    tem = build_and_jump (&cond_label);
   9084 		    append_to_statement_list_force (tem, p);
   9085 		    tem = build1 (LABEL_EXPR, void_type_node, beg_label);
   9086 		    append_to_statement_list (tem, p);
   9087 		    tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
   9088 					NULL_TREE, NULL_TREE);
   9089 		    TREE_SIDE_EFFECTS (bind) = 1;
   9090 		    SET_EXPR_LOCATION (bind, loc);
   9091 		    append_to_statement_list_force (bind, p);
   9092 		    if (POINTER_TYPE_P (type))
   9093 		      tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
   9094 					var, fold_convert_loc (loc, sizetype,
   9095 							       step));
   9096 		    else
   9097 		      tem = build2_loc (loc, PLUS_EXPR, type, var, step);
   9098 		    tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
   9099 				      var, tem);
   9100 		    append_to_statement_list_force (tem, p);
   9101 		    tem = build1 (LABEL_EXPR, void_type_node, cond_label);
   9102 		    append_to_statement_list (tem, p);
   9103 		    tree cond = fold_build2_loc (loc, LT_EXPR,
   9104 						 boolean_type_node,
   9105 						 var, end);
   9106 		    tree pos
   9107 		      = fold_build3_loc (loc, COND_EXPR, void_type_node,
   9108 					 cond, build_and_jump (&beg_label),
   9109 					 void_node);
   9110 		    cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
   9111 					    var, end);
   9112 		    tree neg
   9113 		      = fold_build3_loc (loc, COND_EXPR, void_type_node,
   9114 					 cond, build_and_jump (&beg_label),
   9115 					 void_node);
   9116 		    tree osteptype = TREE_TYPE (orig_step);
   9117 		    cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
   9118 					    orig_step,
   9119 					    build_int_cst (osteptype, 0));
   9120 		    tem = fold_build3_loc (loc, COND_EXPR, void_type_node,
   9121 					   cond, pos, neg);
   9122 		    append_to_statement_list_force (tem, p);
   9123 		    p = &BIND_EXPR_BODY (bind);
   9124 		  }
   9125 		last_body = p;
   9126 	      }
   9127 	    last_iter = TREE_PURPOSE (t);
   9128 	    if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
   9129 	      {
   9130 		append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
   9131 					  0), last_body);
   9132 		TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
   9133 	      }
   9134 	    if (error_operand_p (TREE_VALUE (t)))
   9135 	      return 2;
   9136 	    if (TREE_VALUE (t) != null_pointer_node)
   9137 	      TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
   9138 	    if (i == 4)
   9139 	      {
   9140 		r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
   9141 			    NULL_TREE, NULL_TREE);
   9142 		tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5],
   9143 				  NULL_TREE, NULL_TREE);
   9144 		r2 = build_fold_addr_expr_with_type (r2, ptr_type_node);
   9145 		tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   9146 				  void_type_node, r, r2);
   9147 		append_to_statement_list_force (tem, last_body);
   9148 		tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   9149 				  void_type_node, cnts[i],
   9150 				  size_binop (PLUS_EXPR, cnts[i],
   9151 					      size_int (1)));
   9152 		append_to_statement_list_force (tem, last_body);
   9153 		i = 5;
   9154 	      }
   9155 	    r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
   9156 			NULL_TREE, NULL_TREE);
   9157 	    tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   9158 			      void_type_node, r, TREE_VALUE (t));
   9159 	    append_to_statement_list_force (tem, last_body);
   9160 	    if (i == 5)
   9161 	      {
   9162 		r = build4 (ARRAY_REF, ptr_type_node, array,
   9163 			    size_binop (PLUS_EXPR, cnts[i], size_int (1)),
   9164 			    NULL_TREE, NULL_TREE);
   9165 		tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
   9166 		tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   9167 				  void_type_node, r, tem);
   9168 		append_to_statement_list_force (tem, last_body);
   9169 	      }
   9170 	    tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   9171 			      void_type_node, cnts[i],
   9172 			      size_binop (PLUS_EXPR, cnts[i],
   9173 					  size_int (1 + (i == 5))));
   9174 	    append_to_statement_list_force (tem, last_body);
   9175 	    TREE_VALUE (t) = null_pointer_node;
   9176 	  }
   9177 	else
   9178 	  {
   9179 	    if (last_bind)
   9180 	      {
   9181 		gimplify_and_add (last_bind, pre_p);
   9182 		last_bind = NULL_TREE;
   9183 	      }
   9184 	    if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
   9185 	      {
   9186 		gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
   9187 			       NULL, is_gimple_val, fb_rvalue);
   9188 		OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
   9189 	      }
   9190 	    if (error_operand_p (OMP_CLAUSE_DECL (c)))
   9191 	      return 2;
   9192 	    if (OMP_CLAUSE_DECL (c) != null_pointer_node)
   9193 	      OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
   9194 	    if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
   9195 			       is_gimple_val, fb_rvalue) == GS_ERROR)
   9196 	      return 2;
   9197 	    if (i == 4)
   9198 	      {
   9199 		r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
   9200 			    NULL_TREE, NULL_TREE);
   9201 		tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5],
   9202 				  NULL_TREE, NULL_TREE);
   9203 		r2 = build_fold_addr_expr_with_type (r2, ptr_type_node);
   9204 		tem = build2 (MODIFY_EXPR, void_type_node, r, r2);
   9205 		gimplify_and_add (tem, pre_p);
   9206 		g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR,
   9207 							      cnts[i],
   9208 							      size_int (1)));
   9209 		gimple_seq_add_stmt (pre_p, g);
   9210 		i = 5;
   9211 	      }
   9212 	    r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
   9213 			NULL_TREE, NULL_TREE);
   9214 	    tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
   9215 	    gimplify_and_add (tem, pre_p);
   9216 	    if (i == 5)
   9217 	      {
   9218 		r = build4 (ARRAY_REF, ptr_type_node, array,
   9219 			    size_binop (PLUS_EXPR, cnts[i], size_int (1)),
   9220 			    NULL_TREE, NULL_TREE);
   9221 		tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
   9222 		tem = build2 (MODIFY_EXPR, void_type_node, r, tem);
   9223 		append_to_statement_list_force (tem, last_body);
   9224 		gimplify_and_add (tem, pre_p);
   9225 	      }
   9226 	    g = gimple_build_assign (cnts[i],
   9227 				     size_binop (PLUS_EXPR, cnts[i],
   9228 						 size_int (1 + (i == 5))));
   9229 	    gimple_seq_add_stmt (pre_p, g);
   9230 	  }
   9231       }
   9232   if (last_bind)
   9233     gimplify_and_add (last_bind, pre_p);
   9234   tree cond = boolean_false_node;
   9235   if (is_old)
   9236     {
   9237       if (!unused[0])
   9238 	cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
   9239 			   size_binop_loc (first_loc, PLUS_EXPR, counts[0],
   9240 					   size_int (2)));
   9241       if (!unused[2])
   9242 	cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
   9243 			   build2_loc (first_loc, NE_EXPR, boolean_type_node,
   9244 				       cnts[2],
   9245 				       size_binop_loc (first_loc, PLUS_EXPR,
   9246 						       totalpx,
   9247 						       size_int (1))));
   9248     }
   9249   else
   9250     {
   9251       tree prev = size_int (5);
   9252       for (i = 0; i < 5; i++)
   9253 	{
   9254 	  if (unused[i])
   9255 	    continue;
   9256 	  prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
   9257 	  cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
   9258 			     build2_loc (first_loc, NE_EXPR, boolean_type_node,
   9259 					 cnts[i], unshare_expr (prev)));
   9260 	}
   9261     }
   9262   tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
   9263 		    build_call_expr_loc (first_loc,
   9264 					 builtin_decl_explicit (BUILT_IN_TRAP),
   9265 					 0), void_node);
   9266   gimplify_and_add (tem, pre_p);
   9267   c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
   9268   OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
   9269   OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
   9270   OMP_CLAUSE_CHAIN (c) = *list_p;
   9271   *list_p = c;
   9272   return 1;
   9273 }
   9274 
   9275 /* True if mapping node C maps, or unmaps, a (Fortran) array descriptor.  */
   9276 
   9277 static bool
   9278 omp_map_clause_descriptor_p (tree c)
   9279 {
   9280   if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
   9281     return false;
   9282 
   9283   if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
   9284     return true;
   9285 
   9286   if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_RELEASE
   9287        || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DELETE)
   9288       && OMP_CLAUSE_RELEASE_DESCRIPTOR (c))
   9289     return true;
   9290 
   9291   return false;
   9292 }
   9293 
   9294 /* For a set of mappings describing an array section pointed to by a struct
   9295    (or derived type, etc.) component, create an "alloc" or "release" node to
   9296    insert into a list following a GOMP_MAP_STRUCT node.  For some types of
   9297    mapping (e.g. Fortran arrays with descriptors), an additional mapping may
   9298    be created that is inserted into the list of mapping nodes attached to the
   9299    directive being processed -- not part of the sorted list of nodes after
   9300    GOMP_MAP_STRUCT.
   9301 
   9302    CODE is the code of the directive being processed.  GRP_START and GRP_END
   9303    are the first and last of two or three nodes representing this array section
   9304    mapping (e.g. a data movement node like GOMP_MAP_{TO,FROM}, optionally a
   9305    GOMP_MAP_TO_PSET, and finally a GOMP_MAP_ALWAYS_POINTER).  EXTRA_NODE is
   9306    filled with the additional node described above, if needed.
   9307 
   9308    This function does not add the new nodes to any lists itself.  It is the
   9309    responsibility of the caller to do that.  */
   9310 
   9311 static tree
   9312 build_omp_struct_comp_nodes (enum tree_code code, tree grp_start, tree grp_end,
   9313 			     tree *extra_node)
   9314 {
   9315   enum gomp_map_kind mkind
   9316     = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
   9317       ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
   9318 
   9319   gcc_assert (grp_start != grp_end);
   9320 
   9321   tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
   9322   OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
   9323   OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (grp_end));
   9324   OMP_CLAUSE_CHAIN (c2) = NULL_TREE;
   9325   tree grp_mid = NULL_TREE;
   9326   if (OMP_CLAUSE_CHAIN (grp_start) != grp_end)
   9327     grp_mid = OMP_CLAUSE_CHAIN (grp_start);
   9328 
   9329   if (grp_mid && omp_map_clause_descriptor_p (grp_mid))
   9330     OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (grp_mid);
   9331   else
   9332     OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
   9333 
   9334   if (grp_mid
   9335       && OMP_CLAUSE_CODE (grp_mid) == OMP_CLAUSE_MAP
   9336       && OMP_CLAUSE_MAP_KIND (grp_mid) == GOMP_MAP_ALWAYS_POINTER)
   9337     {
   9338       tree c3
   9339 	= build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
   9340       OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
   9341       OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (grp_mid));
   9342       OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
   9343       OMP_CLAUSE_CHAIN (c3) = NULL_TREE;
   9344 
   9345       *extra_node = c3;
   9346     }
   9347   else
   9348     *extra_node = NULL_TREE;
   9349 
   9350   return c2;
   9351 }
   9352 
   9353 /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
   9354    and set *BITPOSP and *POFFSETP to the bit offset of the access.
   9355    If BASE_REF is non-NULL and the containing object is a reference, set
   9356    *BASE_REF to that reference before dereferencing the object.
   9357    If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
   9358    has array type, else return NULL.  */
   9359 
   9360 static tree
   9361 extract_base_bit_offset (tree base, poly_int64 *bitposp,
   9362 			 poly_offset_int *poffsetp,
   9363 			 bool *variable_offset)
   9364 {
   9365   tree offset;
   9366   poly_int64 bitsize, bitpos;
   9367   machine_mode mode;
   9368   int unsignedp, reversep, volatilep = 0;
   9369   poly_offset_int poffset;
   9370 
   9371   STRIP_NOPS (base);
   9372 
   9373   base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
   9374 			      &unsignedp, &reversep, &volatilep);
   9375 
   9376   STRIP_NOPS (base);
   9377 
   9378   if (offset && poly_int_tree_p (offset))
   9379     {
   9380       poffset = wi::to_poly_offset (offset);
   9381       *variable_offset = false;
   9382     }
   9383   else
   9384     {
   9385       poffset = 0;
   9386       *variable_offset = (offset != NULL_TREE);
   9387     }
   9388 
   9389   if (maybe_ne (bitpos, 0))
   9390     poffset += bits_to_bytes_round_down (bitpos);
   9391 
   9392   *bitposp = bitpos;
   9393   *poffsetp = poffset;
   9394 
   9395   return base;
   9396 }
   9397 
   9398 /* Used for topological sorting of mapping groups.  UNVISITED means we haven't
   9399    started processing the group yet.  The TEMPORARY mark is used when we first
   9400    encounter a group on a depth-first traversal, and the PERMANENT mark is used
   9401    when we have processed all the group's children (i.e. all the base pointers
   9402    referred to by the group's mapping nodes, recursively).  */
   9403 
   9404 enum omp_tsort_mark {
   9405   UNVISITED,
   9406   TEMPORARY,
   9407   PERMANENT
   9408 };
   9409 
   9410 /* Hash for trees based on operand_equal_p.  Like tree_operand_hash
   9411    but ignores side effects in the equality comparisons.  */
   9412 
   9413 struct tree_operand_hash_no_se : tree_operand_hash
   9414 {
   9415   static inline bool equal (const value_type &,
   9416 			    const compare_type &);
   9417 };
   9418 
   9419 inline bool
   9420 tree_operand_hash_no_se::equal (const value_type &t1,
   9421 				const compare_type &t2)
   9422 {
   9423   return operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS);
   9424 }
   9425 
   9426 /* A group of OMP_CLAUSE_MAP nodes that correspond to a single "map"
   9427    clause.  */
   9428 
   9429 struct omp_mapping_group {
   9430   tree *grp_start;
   9431   tree grp_end;
   9432   omp_tsort_mark mark;
   9433   /* If we've removed the group but need to reindex, mark the group as
   9434      deleted.  */
   9435   bool deleted;
   9436   /* The group points to an already-created "GOMP_MAP_STRUCT
   9437      GOMP_MAP_ATTACH_DETACH" pair.  */
   9438   bool reprocess_struct;
   9439   /* The group should use "zero-length" allocations for pointers that are not
   9440      mapped "to" on the same directive.  */
   9441   bool fragile;
   9442   struct omp_mapping_group *sibling;
   9443   struct omp_mapping_group *next;
   9444 };
   9445 
   9446 DEBUG_FUNCTION void
   9447 debug_mapping_group (omp_mapping_group *grp)
   9448 {
   9449   tree tmp = OMP_CLAUSE_CHAIN (grp->grp_end);
   9450   OMP_CLAUSE_CHAIN (grp->grp_end) = NULL;
   9451   debug_generic_expr (*grp->grp_start);
   9452   OMP_CLAUSE_CHAIN (grp->grp_end) = tmp;
   9453 }
   9454 
   9455 /* Return the OpenMP "base pointer" of an expression EXPR, or NULL if there
   9456    isn't one.  */
   9457 
   9458 static tree
   9459 omp_get_base_pointer (tree expr)
   9460 {
   9461   while (TREE_CODE (expr) == ARRAY_REF
   9462 	 || TREE_CODE (expr) == COMPONENT_REF)
   9463     expr = TREE_OPERAND (expr, 0);
   9464 
   9465   if (INDIRECT_REF_P (expr)
   9466       || (TREE_CODE (expr) == MEM_REF
   9467 	  && integer_zerop (TREE_OPERAND (expr, 1))))
   9468     {
   9469       expr = TREE_OPERAND (expr, 0);
   9470       while (TREE_CODE (expr) == COMPOUND_EXPR)
   9471 	expr = TREE_OPERAND (expr, 1);
   9472       if (TREE_CODE (expr) == POINTER_PLUS_EXPR)
   9473 	expr = TREE_OPERAND (expr, 0);
   9474       if (TREE_CODE (expr) == SAVE_EXPR)
   9475 	expr = TREE_OPERAND (expr, 0);
   9476       STRIP_NOPS (expr);
   9477       return expr;
   9478     }
   9479 
   9480   return NULL_TREE;
   9481 }
   9482 
   9483 /* An attach or detach operation depends directly on the address being
   9484    attached/detached.  Return that address, or none if there are no
   9485    attachments/detachments.  */
   9486 
   9487 static tree
   9488 omp_get_attachment (omp_mapping_group *grp)
   9489 {
   9490   tree node = *grp->grp_start;
   9491 
   9492   switch (OMP_CLAUSE_MAP_KIND (node))
   9493     {
   9494     case GOMP_MAP_TO:
   9495     case GOMP_MAP_FROM:
   9496     case GOMP_MAP_TOFROM:
   9497     case GOMP_MAP_ALWAYS_FROM:
   9498     case GOMP_MAP_ALWAYS_TO:
   9499     case GOMP_MAP_ALWAYS_TOFROM:
   9500     case GOMP_MAP_FORCE_FROM:
   9501     case GOMP_MAP_FORCE_TO:
   9502     case GOMP_MAP_FORCE_TOFROM:
   9503     case GOMP_MAP_FORCE_PRESENT:
   9504     case GOMP_MAP_PRESENT_ALLOC:
   9505     case GOMP_MAP_PRESENT_FROM:
   9506     case GOMP_MAP_PRESENT_TO:
   9507     case GOMP_MAP_PRESENT_TOFROM:
   9508     case GOMP_MAP_ALWAYS_PRESENT_FROM:
   9509     case GOMP_MAP_ALWAYS_PRESENT_TO:
   9510     case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   9511     case GOMP_MAP_ALLOC:
   9512     case GOMP_MAP_RELEASE:
   9513     case GOMP_MAP_DELETE:
   9514     case GOMP_MAP_FORCE_ALLOC:
   9515       if (node == grp->grp_end)
   9516 	return NULL_TREE;
   9517 
   9518       node = OMP_CLAUSE_CHAIN (node);
   9519       if (node && omp_map_clause_descriptor_p (node))
   9520 	{
   9521 	  gcc_assert (node != grp->grp_end);
   9522 	  node = OMP_CLAUSE_CHAIN (node);
   9523 	}
   9524       if (node)
   9525 	switch (OMP_CLAUSE_MAP_KIND (node))
   9526 	  {
   9527 	  case GOMP_MAP_POINTER:
   9528 	  case GOMP_MAP_ALWAYS_POINTER:
   9529 	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
   9530 	  case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   9531 	  case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
   9532 	    return NULL_TREE;
   9533 
   9534 	  case GOMP_MAP_ATTACH_DETACH:
   9535 	  case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   9536 	  case GOMP_MAP_DETACH:
   9537 	    return OMP_CLAUSE_DECL (node);
   9538 
   9539 	  default:
   9540 	    internal_error ("unexpected mapping node");
   9541 	  }
   9542       return error_mark_node;
   9543 
   9544     case GOMP_MAP_TO_PSET:
   9545       gcc_assert (node != grp->grp_end);
   9546       node = OMP_CLAUSE_CHAIN (node);
   9547       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH
   9548 	  || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DETACH)
   9549 	return OMP_CLAUSE_DECL (node);
   9550       else
   9551 	internal_error ("unexpected mapping node");
   9552       return error_mark_node;
   9553 
   9554     case GOMP_MAP_ATTACH:
   9555     case GOMP_MAP_DETACH:
   9556       node = OMP_CLAUSE_CHAIN (node);
   9557       if (!node || *grp->grp_start == grp->grp_end)
   9558 	return OMP_CLAUSE_DECL (*grp->grp_start);
   9559       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
   9560 	  || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   9561 	return OMP_CLAUSE_DECL (*grp->grp_start);
   9562       else
   9563 	internal_error ("unexpected mapping node");
   9564       return error_mark_node;
   9565 
   9566     case GOMP_MAP_STRUCT:
   9567     case GOMP_MAP_STRUCT_UNORD:
   9568     case GOMP_MAP_FORCE_DEVICEPTR:
   9569     case GOMP_MAP_DEVICE_RESIDENT:
   9570     case GOMP_MAP_LINK:
   9571     case GOMP_MAP_IF_PRESENT:
   9572     case GOMP_MAP_FIRSTPRIVATE:
   9573     case GOMP_MAP_FIRSTPRIVATE_INT:
   9574     case GOMP_MAP_USE_DEVICE_PTR:
   9575     case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   9576       return NULL_TREE;
   9577 
   9578     default:
   9579       internal_error ("unexpected mapping node");
   9580     }
   9581 
   9582   return error_mark_node;
   9583 }
   9584 
   9585 /* Given a pointer START_P to the start of a group of related (e.g. pointer)
   9586    mappings, return the chain pointer to the end of that group in the list.  */
   9587 
   9588 static tree *
   9589 omp_group_last (tree *start_p)
   9590 {
   9591   tree c = *start_p, nc, *grp_last_p = start_p;
   9592 
   9593   gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP);
   9594 
   9595   nc = OMP_CLAUSE_CHAIN (c);
   9596 
   9597   if (!nc || OMP_CLAUSE_CODE (nc) != OMP_CLAUSE_MAP)
   9598     return grp_last_p;
   9599 
   9600   switch (OMP_CLAUSE_MAP_KIND (c))
   9601     {
   9602     default:
   9603       while (nc
   9604 	     && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
   9605 	     && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
   9606 		 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER
   9607 		 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH_DETACH
   9608 		 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_POINTER
   9609 		 || (OMP_CLAUSE_MAP_KIND (nc)
   9610 		     == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)
   9611 		 || (OMP_CLAUSE_MAP_KIND (nc)
   9612 		     == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)
   9613 		 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH
   9614 		 || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ALWAYS_POINTER
   9615 		 || omp_map_clause_descriptor_p (nc)))
   9616 	{
   9617 	  tree nc2 = OMP_CLAUSE_CHAIN (nc);
   9618 	  if (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH)
   9619 	    {
   9620 	      /* In the specific case we're doing "exit data" on an array
   9621 		 slice of a reference-to-pointer struct component, we will see
   9622 		 DETACH followed by ATTACH_DETACH here.  We want to treat that
   9623 		 as a single group. In other cases DETACH might represent a
   9624 		 stand-alone "detach" clause, so we don't want to consider
   9625 		 that part of the group.  */
   9626 	      if (nc2
   9627 		  && OMP_CLAUSE_CODE (nc2) == OMP_CLAUSE_MAP
   9628 		  && OMP_CLAUSE_MAP_KIND (nc2) == GOMP_MAP_ATTACH_DETACH)
   9629 		goto consume_two_nodes;
   9630 	      else
   9631 		break;
   9632 	    }
   9633 	  if (nc2
   9634 	      && OMP_CLAUSE_CODE (nc2) == OMP_CLAUSE_MAP
   9635 	      && (OMP_CLAUSE_MAP_KIND (nc)
   9636 		  == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)
   9637 	      && OMP_CLAUSE_MAP_KIND (nc2) == GOMP_MAP_ATTACH)
   9638 	    {
   9639 	    consume_two_nodes:
   9640 	      grp_last_p = &OMP_CLAUSE_CHAIN (nc);
   9641 	      c = nc2;
   9642 	      nc = OMP_CLAUSE_CHAIN (nc2);
   9643 	    }
   9644 	  else
   9645 	    {
   9646 	      grp_last_p = &OMP_CLAUSE_CHAIN (c);
   9647 	      c = nc;
   9648 	      nc = nc2;
   9649 	    }
   9650 	}
   9651       break;
   9652 
   9653     case GOMP_MAP_ATTACH:
   9654     case GOMP_MAP_DETACH:
   9655       /* This is a weird artifact of how directives are parsed: bare attach or
   9656 	 detach clauses get a subsequent (meaningless) FIRSTPRIVATE_POINTER or
   9657 	 FIRSTPRIVATE_REFERENCE node.  FIXME.  */
   9658       if (nc
   9659 	  && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
   9660 	  && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
   9661 	      || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER))
   9662 	grp_last_p = &OMP_CLAUSE_CHAIN (c);
   9663       break;
   9664 
   9665     case GOMP_MAP_TO_PSET:
   9666       if (OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
   9667 	  && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH
   9668 	      || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH))
   9669 	grp_last_p = &OMP_CLAUSE_CHAIN (c);
   9670       break;
   9671 
   9672     case GOMP_MAP_STRUCT:
   9673     case GOMP_MAP_STRUCT_UNORD:
   9674       {
   9675 	unsigned HOST_WIDE_INT num_mappings
   9676 	  = tree_to_uhwi (OMP_CLAUSE_SIZE (c));
   9677 	if (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER
   9678 	    || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
   9679 	    || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH_DETACH)
   9680 	  grp_last_p = &OMP_CLAUSE_CHAIN (*grp_last_p);
   9681 	for (unsigned i = 0; i < num_mappings; i++)
   9682 	  grp_last_p = &OMP_CLAUSE_CHAIN (*grp_last_p);
   9683       }
   9684       break;
   9685     }
   9686 
   9687   return grp_last_p;
   9688 }
   9689 
   9690 /* Walk through LIST_P, and return a list of groups of mappings found (e.g.
   9691    OMP_CLAUSE_MAP with GOMP_MAP_{TO/FROM/TOFROM} followed by one or two
   9692    associated GOMP_MAP_POINTER mappings).  Return a vector of omp_mapping_group
   9693    if we have more than one such group, else return NULL.  */
   9694 
   9695 static void
   9696 omp_gather_mapping_groups_1 (tree *list_p, vec<omp_mapping_group> *groups,
   9697 			     tree gather_sentinel)
   9698 {
   9699   for (tree *cp = list_p;
   9700        *cp && *cp != gather_sentinel;
   9701        cp = &OMP_CLAUSE_CHAIN (*cp))
   9702     {
   9703       if (OMP_CLAUSE_CODE (*cp) != OMP_CLAUSE_MAP)
   9704 	continue;
   9705 
   9706       tree *grp_last_p = omp_group_last (cp);
   9707       omp_mapping_group grp;
   9708 
   9709       grp.grp_start = cp;
   9710       grp.grp_end = *grp_last_p;
   9711       grp.mark = UNVISITED;
   9712       grp.sibling = NULL;
   9713       grp.deleted = false;
   9714       grp.reprocess_struct = false;
   9715       grp.fragile = false;
   9716       grp.next = NULL;
   9717       groups->safe_push (grp);
   9718 
   9719       cp = grp_last_p;
   9720     }
   9721 }
   9722 
   9723 static vec<omp_mapping_group> *
   9724 omp_gather_mapping_groups (tree *list_p)
   9725 {
   9726   vec<omp_mapping_group> *groups = new vec<omp_mapping_group> ();
   9727 
   9728   omp_gather_mapping_groups_1 (list_p, groups, NULL_TREE);
   9729 
   9730   if (groups->length () > 0)
   9731     return groups;
   9732   else
   9733     {
   9734       delete groups;
   9735       return NULL;
   9736     }
   9737 }
   9738 
   9739 /* A pointer mapping group GRP may define a block of memory starting at some
   9740    base address, and maybe also define a firstprivate pointer or firstprivate
   9741    reference that points to that block.  The return value is a node containing
   9742    the former, and the *FIRSTPRIVATE pointer is set if we have the latter.
   9743    If we define several base pointers, i.e. for a GOMP_MAP_STRUCT mapping,
   9744    return the number of consecutive chained nodes in CHAINED.  */
   9745 
   9746 static tree
   9747 omp_group_base (omp_mapping_group *grp, unsigned int *chained,
   9748 		tree *firstprivate)
   9749 {
   9750   tree node = *grp->grp_start;
   9751 
   9752   *firstprivate = NULL_TREE;
   9753   *chained = 1;
   9754 
   9755   switch (OMP_CLAUSE_MAP_KIND (node))
   9756     {
   9757     case GOMP_MAP_TO:
   9758     case GOMP_MAP_FROM:
   9759     case GOMP_MAP_TOFROM:
   9760     case GOMP_MAP_ALWAYS_FROM:
   9761     case GOMP_MAP_ALWAYS_TO:
   9762     case GOMP_MAP_ALWAYS_TOFROM:
   9763     case GOMP_MAP_FORCE_FROM:
   9764     case GOMP_MAP_FORCE_TO:
   9765     case GOMP_MAP_FORCE_TOFROM:
   9766     case GOMP_MAP_FORCE_PRESENT:
   9767     case GOMP_MAP_PRESENT_ALLOC:
   9768     case GOMP_MAP_PRESENT_FROM:
   9769     case GOMP_MAP_PRESENT_TO:
   9770     case GOMP_MAP_PRESENT_TOFROM:
   9771     case GOMP_MAP_ALWAYS_PRESENT_FROM:
   9772     case GOMP_MAP_ALWAYS_PRESENT_TO:
   9773     case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   9774     case GOMP_MAP_ALLOC:
   9775     case GOMP_MAP_RELEASE:
   9776     case GOMP_MAP_DELETE:
   9777     case GOMP_MAP_FORCE_ALLOC:
   9778     case GOMP_MAP_IF_PRESENT:
   9779       if (node == grp->grp_end)
   9780 	return node;
   9781 
   9782       node = OMP_CLAUSE_CHAIN (node);
   9783       if (!node)
   9784 	internal_error ("unexpected mapping node");
   9785       if (omp_map_clause_descriptor_p (node))
   9786 	{
   9787 	  if (node == grp->grp_end)
   9788 	    return *grp->grp_start;
   9789 	  node = OMP_CLAUSE_CHAIN (node);
   9790 	}
   9791       switch (OMP_CLAUSE_MAP_KIND (node))
   9792 	{
   9793 	case GOMP_MAP_POINTER:
   9794 	case GOMP_MAP_FIRSTPRIVATE_POINTER:
   9795 	case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   9796 	case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
   9797 	  *firstprivate = OMP_CLAUSE_DECL (node);
   9798 	  return *grp->grp_start;
   9799 
   9800 	case GOMP_MAP_ALWAYS_POINTER:
   9801 	case GOMP_MAP_ATTACH_DETACH:
   9802 	case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   9803 	case GOMP_MAP_DETACH:
   9804 	  return *grp->grp_start;
   9805 
   9806 	default:
   9807 	  internal_error ("unexpected mapping node");
   9808 	}
   9809       return error_mark_node;
   9810 
   9811     case GOMP_MAP_TO_PSET:
   9812       gcc_assert (node != grp->grp_end);
   9813       node = OMP_CLAUSE_CHAIN (node);
   9814       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH
   9815 	  || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DETACH)
   9816 	return NULL_TREE;
   9817       else
   9818 	internal_error ("unexpected mapping node");
   9819       return error_mark_node;
   9820 
   9821     case GOMP_MAP_ATTACH:
   9822     case GOMP_MAP_DETACH:
   9823       node = OMP_CLAUSE_CHAIN (node);
   9824       if (!node || *grp->grp_start == grp->grp_end)
   9825 	return NULL_TREE;
   9826       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
   9827 	  || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   9828 	{
   9829 	  /* We're mapping the base pointer itself in a bare attach or detach
   9830 	     node.  This is a side effect of how parsing works, and the mapping
   9831 	     will be removed anyway (at least for enter/exit data directives).
   9832 	     We should ignore the mapping here.  FIXME.  */
   9833 	  return NULL_TREE;
   9834 	}
   9835       else
   9836 	internal_error ("unexpected mapping node");
   9837       return error_mark_node;
   9838 
   9839     case GOMP_MAP_STRUCT:
   9840     case GOMP_MAP_STRUCT_UNORD:
   9841       {
   9842 	unsigned HOST_WIDE_INT num_mappings
   9843 	  = tree_to_uhwi (OMP_CLAUSE_SIZE (node));
   9844 	node = OMP_CLAUSE_CHAIN (node);
   9845 	if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
   9846 	    || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   9847 	  {
   9848 	    *firstprivate = OMP_CLAUSE_DECL (node);
   9849 	    node = OMP_CLAUSE_CHAIN (node);
   9850 	  }
   9851 	else if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH_DETACH)
   9852 	  node = OMP_CLAUSE_CHAIN (node);
   9853 	*chained = num_mappings;
   9854 	return node;
   9855       }
   9856 
   9857     case GOMP_MAP_FORCE_DEVICEPTR:
   9858     case GOMP_MAP_DEVICE_RESIDENT:
   9859     case GOMP_MAP_LINK:
   9860     case GOMP_MAP_FIRSTPRIVATE:
   9861     case GOMP_MAP_FIRSTPRIVATE_INT:
   9862     case GOMP_MAP_USE_DEVICE_PTR:
   9863     case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   9864       return NULL_TREE;
   9865 
   9866     case GOMP_MAP_FIRSTPRIVATE_POINTER:
   9867     case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   9868     case GOMP_MAP_POINTER:
   9869     case GOMP_MAP_ALWAYS_POINTER:
   9870     case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
   9871       /* These shouldn't appear by themselves.  */
   9872       if (!seen_error ())
   9873 	internal_error ("unexpected pointer mapping node");
   9874       return error_mark_node;
   9875 
   9876     default:
   9877       gcc_unreachable ();
   9878     }
   9879 
   9880   return error_mark_node;
   9881 }
   9882 
   9883 /* Given a vector of omp_mapping_groups, build a hash table so we can look up
   9884    nodes by tree_operand_hash_no_se.  */
   9885 
   9886 static void
   9887 omp_index_mapping_groups_1 (hash_map<tree_operand_hash_no_se,
   9888 				     omp_mapping_group *> *grpmap,
   9889 			    vec<omp_mapping_group> *groups,
   9890 			    tree reindex_sentinel)
   9891 {
   9892   omp_mapping_group *grp;
   9893   unsigned int i;
   9894   bool reindexing = reindex_sentinel != NULL_TREE, above_hwm = false;
   9895 
   9896   FOR_EACH_VEC_ELT (*groups, i, grp)
   9897     {
   9898       if (reindexing && *grp->grp_start == reindex_sentinel)
   9899 	above_hwm = true;
   9900 
   9901       if (reindexing && !above_hwm)
   9902 	continue;
   9903 
   9904       if (grp->reprocess_struct)
   9905 	continue;
   9906 
   9907       tree fpp;
   9908       unsigned int chained;
   9909       tree node = omp_group_base (grp, &chained, &fpp);
   9910 
   9911       if (node == error_mark_node || (!node && !fpp))
   9912 	continue;
   9913 
   9914       for (unsigned j = 0;
   9915 	   node && j < chained;
   9916 	   node = OMP_CLAUSE_CHAIN (node), j++)
   9917 	{
   9918 	  tree decl = OMP_CLAUSE_DECL (node);
   9919 	  /* Sometimes we see zero-offset MEM_REF instead of INDIRECT_REF,
   9920 	     meaning node-hash lookups don't work.  This is a workaround for
   9921 	     that, but ideally we should just create the INDIRECT_REF at
   9922 	     source instead.  FIXME.  */
   9923 	  if (TREE_CODE (decl) == MEM_REF
   9924 	      && integer_zerop (TREE_OPERAND (decl, 1)))
   9925 	    decl = build_fold_indirect_ref (TREE_OPERAND (decl, 0));
   9926 
   9927 	  omp_mapping_group **prev = grpmap->get (decl);
   9928 
   9929 	  if (prev && *prev == grp)
   9930 	    /* Empty.  */;
   9931 	  else if (prev)
   9932 	    {
   9933 	      /* Mapping the same thing twice is normally diagnosed as an error,
   9934 		 but can happen under some circumstances, e.g. in pr99928-16.c,
   9935 		 the directive:
   9936 
   9937 		 #pragma omp target simd reduction(+:a[:3]) \
   9938 					 map(always, tofrom: a[:6])
   9939 		 ...
   9940 
   9941 		 will result in two "a[0]" mappings (of different sizes).  */
   9942 
   9943 	      grp->sibling = (*prev)->sibling;
   9944 	      (*prev)->sibling = grp;
   9945 	    }
   9946 	  else
   9947 	    grpmap->put (decl, grp);
   9948 	}
   9949 
   9950       if (!fpp)
   9951 	continue;
   9952 
   9953       omp_mapping_group **prev = grpmap->get (fpp);
   9954       if (prev && *prev != grp)
   9955 	{
   9956 	  grp->sibling = (*prev)->sibling;
   9957 	  (*prev)->sibling = grp;
   9958 	}
   9959       else
   9960 	grpmap->put (fpp, grp);
   9961     }
   9962 }
   9963 
   9964 static hash_map<tree_operand_hash_no_se, omp_mapping_group *> *
   9965 omp_index_mapping_groups (vec<omp_mapping_group> *groups)
   9966 {
   9967   hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap
   9968     = new hash_map<tree_operand_hash_no_se, omp_mapping_group *>;
   9969 
   9970   omp_index_mapping_groups_1 (grpmap, groups, NULL_TREE);
   9971 
   9972   return grpmap;
   9973 }
   9974 
   9975 /* Rebuild group map from partially-processed clause list (during
   9976    omp_build_struct_sibling_lists).  We have already processed nodes up until
   9977    a high-water mark (HWM).  This is a bit tricky because the list is being
   9978    reordered as it is scanned, but we know:
   9979 
   9980    1. The list after HWM has not been touched yet, so we can reindex it safely.
   9981 
   9982    2. The list before and including HWM has been altered, but remains
   9983       well-formed throughout the sibling-list building operation.
   9984 
   9985    so, we can do the reindex operation in two parts, on the processed and
   9986    then the unprocessed halves of the list.  */
   9987 
   9988 static hash_map<tree_operand_hash_no_se, omp_mapping_group *> *
   9989 omp_reindex_mapping_groups (tree *list_p,
   9990 			    vec<omp_mapping_group> *groups,
   9991 			    vec<omp_mapping_group> *processed_groups,
   9992 			    tree sentinel)
   9993 {
   9994   hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap
   9995     = new hash_map<tree_operand_hash_no_se, omp_mapping_group *>;
   9996 
   9997   processed_groups->truncate (0);
   9998 
   9999   omp_gather_mapping_groups_1 (list_p, processed_groups, sentinel);
   10000   omp_index_mapping_groups_1 (grpmap, processed_groups, NULL_TREE);
   10001   if (sentinel)
   10002     omp_index_mapping_groups_1 (grpmap, groups, sentinel);
   10003 
   10004   return grpmap;
   10005 }
   10006 
   10007 /* Find the immediately-containing struct for a component ref (etc.)
   10008    expression EXPR.  */
   10009 
   10010 static tree
   10011 omp_containing_struct (tree expr)
   10012 {
   10013   tree expr0 = expr;
   10014 
   10015   STRIP_NOPS (expr);
   10016 
   10017   /* Note: don't strip NOPs unless we're also stripping off array refs or a
   10018      component ref.  */
   10019   if (TREE_CODE (expr) != ARRAY_REF && TREE_CODE (expr) != COMPONENT_REF)
   10020     return expr0;
   10021 
   10022   while (TREE_CODE (expr) == ARRAY_REF)
   10023     expr = TREE_OPERAND (expr, 0);
   10024 
   10025   if (TREE_CODE (expr) == COMPONENT_REF)
   10026     expr = TREE_OPERAND (expr, 0);
   10027 
   10028   return expr;
   10029 }
   10030 
   10031 /* Return TRUE if DECL describes a component that is part of a whole structure
   10032    that is mapped elsewhere in GRPMAP.  *MAPPED_BY_GROUP is set to the group
   10033    that maps that structure, if present.  */
   10034 
   10035 static bool
   10036 omp_mapped_by_containing_struct (hash_map<tree_operand_hash_no_se,
   10037 					  omp_mapping_group *> *grpmap,
   10038 				 tree decl,
   10039 				 omp_mapping_group **mapped_by_group)
   10040 {
   10041   tree wsdecl = NULL_TREE;
   10042 
   10043   *mapped_by_group = NULL;
   10044 
   10045   while (true)
   10046     {
   10047       wsdecl = omp_containing_struct (decl);
   10048       if (wsdecl == decl)
   10049 	break;
   10050       omp_mapping_group **wholestruct = grpmap->get (wsdecl);
   10051       if (!wholestruct
   10052 	  && TREE_CODE (wsdecl) == MEM_REF
   10053 	  && integer_zerop (TREE_OPERAND (wsdecl, 1)))
   10054 	{
   10055 	  tree deref = TREE_OPERAND (wsdecl, 0);
   10056 	  deref = build_fold_indirect_ref (deref);
   10057 	  wholestruct = grpmap->get (deref);
   10058 	}
   10059       if (wholestruct)
   10060 	{
   10061 	  *mapped_by_group = *wholestruct;
   10062 	  return true;
   10063 	}
   10064       decl = wsdecl;
   10065     }
   10066 
   10067   return false;
   10068 }
   10069 
   10070 /* Helper function for omp_tsort_mapping_groups.  Returns TRUE on success, or
   10071    FALSE on error.  */
   10072 
   10073 static bool
   10074 omp_tsort_mapping_groups_1 (omp_mapping_group ***outlist,
   10075 			    vec<omp_mapping_group> *groups,
   10076 			    hash_map<tree_operand_hash_no_se,
   10077 				     omp_mapping_group *> *grpmap,
   10078 			    omp_mapping_group *grp)
   10079 {
   10080   if (grp->mark == PERMANENT)
   10081     return true;
   10082   if (grp->mark == TEMPORARY)
   10083     {
   10084       fprintf (stderr, "when processing group:\n");
   10085       debug_mapping_group (grp);
   10086       internal_error ("base pointer cycle detected");
   10087       return false;
   10088     }
   10089   grp->mark = TEMPORARY;
   10090 
   10091   tree attaches_to = omp_get_attachment (grp);
   10092 
   10093   if (attaches_to)
   10094     {
   10095       omp_mapping_group **basep = grpmap->get (attaches_to);
   10096 
   10097       if (basep && *basep != grp)
   10098 	{
   10099 	  for (omp_mapping_group *w = *basep; w; w = w->sibling)
   10100 	    if (!omp_tsort_mapping_groups_1 (outlist, groups, grpmap, w))
   10101 	      return false;
   10102 	}
   10103     }
   10104 
   10105   tree decl = OMP_CLAUSE_DECL (*grp->grp_start);
   10106 
   10107   while (decl)
   10108     {
   10109       tree base = omp_get_base_pointer (decl);
   10110 
   10111       if (!base)
   10112 	break;
   10113 
   10114       omp_mapping_group **innerp = grpmap->get (base);
   10115       omp_mapping_group *wholestruct;
   10116 
   10117       /* We should treat whole-structure mappings as if all (pointer, in this
   10118 	 case) members are mapped as individual list items.  Check if we have
   10119 	 such a whole-structure mapping, if we don't have an explicit reference
   10120 	 to the pointer member itself.  */
   10121       if (!innerp
   10122 	  && TREE_CODE (base) == COMPONENT_REF
   10123 	  && omp_mapped_by_containing_struct (grpmap, base, &wholestruct))
   10124 	innerp = &wholestruct;
   10125 
   10126       if (innerp && *innerp != grp)
   10127 	{
   10128 	  for (omp_mapping_group *w = *innerp; w; w = w->sibling)
   10129 	    if (!omp_tsort_mapping_groups_1 (outlist, groups, grpmap, w))
   10130 	      return false;
   10131 	  break;
   10132 	}
   10133 
   10134       decl = base;
   10135     }
   10136 
   10137   grp->mark = PERMANENT;
   10138 
   10139   /* Emit grp to output list.  */
   10140 
   10141   **outlist = grp;
   10142   *outlist = &grp->next;
   10143 
   10144   return true;
   10145 }
   10146 
   10147 /* Topologically sort GROUPS, so that OMP 5.0-defined base pointers come
   10148    before mappings that use those pointers.  This is an implementation of the
   10149    depth-first search algorithm, described e.g. at:
   10150 
   10151      https://en.wikipedia.org/wiki/Topological_sorting
   10152 */
   10153 
   10154 static omp_mapping_group *
   10155 omp_tsort_mapping_groups (vec<omp_mapping_group> *groups,
   10156 			  hash_map<tree_operand_hash_no_se, omp_mapping_group *>
   10157 			    *grpmap,
   10158 			  bool enter_exit_data)
   10159 {
   10160   omp_mapping_group *grp, *outlist = NULL, **cursor;
   10161   unsigned int i;
   10162   bool saw_runtime_implicit = false;
   10163 
   10164   cursor = &outlist;
   10165 
   10166   FOR_EACH_VEC_ELT (*groups, i, grp)
   10167     {
   10168       if (grp->mark != PERMANENT)
   10169 	{
   10170 	  if (OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start))
   10171 	    {
   10172 	      saw_runtime_implicit = true;
   10173 	      continue;
   10174 	    }
   10175 	  if (!omp_tsort_mapping_groups_1 (&cursor, groups, grpmap, grp))
   10176 	    return NULL;
   10177 	}
   10178     }
   10179 
   10180   if (!saw_runtime_implicit)
   10181     return outlist;
   10182 
   10183   FOR_EACH_VEC_ELT (*groups, i, grp)
   10184     {
   10185       if (grp->mark != PERMANENT
   10186 	  && OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start))
   10187 	{
   10188 	  /* Clear the flag for enter/exit data because it is currently
   10189 	     meaningless for those operations in libgomp.  */
   10190 	  if (enter_exit_data)
   10191 	    OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start) = 0;
   10192 
   10193 	  if (!omp_tsort_mapping_groups_1 (&cursor, groups, grpmap, grp))
   10194 	    return NULL;
   10195 	}
   10196     }
   10197 
   10198   return outlist;
   10199 }
   10200 
   10201 /* Split INLIST into three parts:
   10202 
   10203      - "present" alloc/to/from groups
   10204      - other to/from groups
   10205      - other alloc/release/delete groups
   10206 
   10207    These sub-lists are then concatenated together to form the final list.
   10208    Each sub-list retains the order of the original list.
   10209    Note that ATTACH nodes are later moved to the end of the list in
   10210    gimplify_adjust_omp_clauses, for target regions.  */
   10211 
   10212 static omp_mapping_group *
   10213 omp_segregate_mapping_groups (omp_mapping_group *inlist)
   10214 {
   10215   omp_mapping_group *ard_groups = NULL, *tf_groups = NULL;
   10216   omp_mapping_group *p_groups = NULL;
   10217   omp_mapping_group **ard_tail = &ard_groups, **tf_tail = &tf_groups;
   10218   omp_mapping_group **p_tail = &p_groups;
   10219 
   10220   for (omp_mapping_group *w = inlist; w;)
   10221     {
   10222       tree c = *w->grp_start;
   10223       omp_mapping_group *next = w->next;
   10224 
   10225       gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP);
   10226 
   10227       switch (OMP_CLAUSE_MAP_KIND (c))
   10228 	{
   10229 	case GOMP_MAP_ALLOC:
   10230 	case GOMP_MAP_RELEASE:
   10231 	case GOMP_MAP_DELETE:
   10232 	  *ard_tail = w;
   10233 	  w->next = NULL;
   10234 	  ard_tail = &w->next;
   10235 	  break;
   10236 
   10237 	/* These map types are all semantically identical, so are moved into a
   10238 	   single group.  They will each be changed into GOMP_MAP_FORCE_PRESENT
   10239 	   in gimplify_adjust_omp_clauses.  */
   10240 	case GOMP_MAP_PRESENT_ALLOC:
   10241 	case GOMP_MAP_PRESENT_FROM:
   10242 	case GOMP_MAP_PRESENT_TO:
   10243 	case GOMP_MAP_PRESENT_TOFROM:
   10244 	  *p_tail = w;
   10245 	  w->next = NULL;
   10246 	  p_tail = &w->next;
   10247 	  break;
   10248 
   10249 	default:
   10250 	  *tf_tail = w;
   10251 	  w->next = NULL;
   10252 	  tf_tail = &w->next;
   10253 	}
   10254 
   10255       w = next;
   10256     }
   10257 
   10258   /* Now splice the lists together...  */
   10259   *tf_tail = ard_groups;
   10260   *p_tail = tf_groups;
   10261 
   10262   return p_groups;
   10263 }
   10264 
   10265 /* Given a list LIST_P containing groups of mappings given by GROUPS, reorder
   10266    those groups based on the output list of omp_tsort_mapping_groups --
   10267    singly-linked, threaded through each element's NEXT pointer starting at
   10268    HEAD.  Each list element appears exactly once in that linked list.
   10269 
   10270    Each element of GROUPS may correspond to one or several mapping nodes.
   10271    Node groups are kept together, and in the reordered list, the positions of
   10272    the original groups are reused for the positions of the reordered list.
   10273    Hence if we have e.g.
   10274 
   10275      {to ptr ptr} firstprivate {tofrom ptr} ...
   10276       ^             ^           ^
   10277       first group  non-"map"    second group
   10278 
   10279    and say the second group contains a base pointer for the first so must be
   10280    moved before it, the resulting list will contain:
   10281 
   10282      {tofrom ptr} firstprivate {to ptr ptr} ...
   10283       ^ prev. second group      ^ prev. first group
   10284 */
   10285 
   10286 static tree *
   10287 omp_reorder_mapping_groups (vec<omp_mapping_group> *groups,
   10288 			    omp_mapping_group *head,
   10289 			    tree *list_p)
   10290 {
   10291   omp_mapping_group *grp;
   10292   unsigned int i;
   10293   unsigned numgroups = groups->length ();
   10294   auto_vec<tree> old_heads (numgroups);
   10295   auto_vec<tree *> old_headps (numgroups);
   10296   auto_vec<tree> new_heads (numgroups);
   10297   auto_vec<tree> old_succs (numgroups);
   10298   bool map_at_start = (list_p == (*groups)[0].grp_start);
   10299 
   10300   tree *new_grp_tail = NULL;
   10301 
   10302   /* Stash the start & end nodes of each mapping group before we start
   10303      modifying the list.  */
   10304   FOR_EACH_VEC_ELT (*groups, i, grp)
   10305     {
   10306       old_headps.quick_push (grp->grp_start);
   10307       old_heads.quick_push (*grp->grp_start);
   10308       old_succs.quick_push (OMP_CLAUSE_CHAIN (grp->grp_end));
   10309     }
   10310 
   10311   /* And similarly, the heads of the groups in the order we want to rearrange
   10312      the list to.  */
   10313   for (omp_mapping_group *w = head; w; w = w->next)
   10314     new_heads.quick_push (*w->grp_start);
   10315 
   10316   FOR_EACH_VEC_ELT (*groups, i, grp)
   10317     {
   10318       gcc_assert (head);
   10319 
   10320       if (new_grp_tail && old_succs[i - 1] == old_heads[i])
   10321 	{
   10322 	  /* a {b c d} {e f g} h i j   (original)
   10323 	     -->
   10324 	     a {k l m} {e f g} h i j   (inserted new group on last iter)
   10325 	     -->
   10326 	     a {k l m} {n o p} h i j   (this time, chain last group to new one)
   10327 		      ^new_grp_tail
   10328 	  */
   10329 	  *new_grp_tail = new_heads[i];
   10330 	}
   10331       else if (new_grp_tail)
   10332 	{
   10333 	  /* a {b c d} e {f g h} i j k   (original)
   10334 	     -->
   10335 	     a {l m n} e {f g h} i j k   (gap after last iter's group)
   10336 	     -->
   10337 	     a {l m n} e {o p q} h i j   (chain last group to old successor)
   10338 		      ^new_grp_tail
   10339 	   */
   10340 	  *new_grp_tail = old_succs[i - 1];
   10341 	  *old_headps[i] = new_heads[i];
   10342 	}
   10343       else
   10344 	{
   10345 	  /* The first inserted group -- point to new group, and leave end
   10346 	     open.
   10347 	     a {b c d} e f
   10348 	     -->
   10349 	     a {g h i...
   10350 	  */
   10351 	  *grp->grp_start = new_heads[i];
   10352 	}
   10353 
   10354       new_grp_tail = &OMP_CLAUSE_CHAIN (head->grp_end);
   10355 
   10356       head = head->next;
   10357     }
   10358 
   10359   if (new_grp_tail)
   10360     *new_grp_tail = old_succs[numgroups - 1];
   10361 
   10362   gcc_assert (!head);
   10363 
   10364   return map_at_start ? (*groups)[0].grp_start : list_p;
   10365 }
   10366 
   10367 /* DECL is supposed to have lastprivate semantics in the outer contexts
   10368    of combined/composite constructs, starting with OCTX.
   10369    Add needed lastprivate, shared or map clause if no data sharing or
   10370    mapping clause are present.  IMPLICIT_P is true if it is an implicit
   10371    clause (IV on simd), in which case the lastprivate will not be
   10372    copied to some constructs.  */
   10373 
   10374 static void
   10375 omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx,
   10376 					       tree decl, bool implicit_p)
   10377 {
   10378   struct gimplify_omp_ctx *orig_octx = octx;
   10379   for (; octx; octx = octx->outer_context)
   10380     {
   10381       if ((octx->region_type == ORT_COMBINED_PARALLEL
   10382 	   || (octx->region_type & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS)
   10383 	  && splay_tree_lookup (octx->variables,
   10384 				(splay_tree_key) decl) == NULL)
   10385 	{
   10386 	  omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
   10387 	  continue;
   10388 	}
   10389       if ((octx->region_type & ORT_TASK) != 0
   10390 	  && octx->combined_loop
   10391 	  && splay_tree_lookup (octx->variables,
   10392 				(splay_tree_key) decl) == NULL)
   10393 	{
   10394 	  omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
   10395 	  continue;
   10396 	}
   10397       if (implicit_p
   10398 	  && octx->region_type == ORT_WORKSHARE
   10399 	  && octx->combined_loop
   10400 	  && splay_tree_lookup (octx->variables,
   10401 				(splay_tree_key) decl) == NULL
   10402 	  && octx->outer_context
   10403 	  && octx->outer_context->region_type == ORT_COMBINED_PARALLEL
   10404 	  && splay_tree_lookup (octx->outer_context->variables,
   10405 				(splay_tree_key) decl) == NULL)
   10406 	{
   10407 	  octx = octx->outer_context;
   10408 	  omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
   10409 	  continue;
   10410 	}
   10411       if ((octx->region_type == ORT_WORKSHARE || octx->region_type == ORT_ACC)
   10412 	  && octx->combined_loop
   10413 	  && splay_tree_lookup (octx->variables,
   10414 				(splay_tree_key) decl) == NULL
   10415 	  && !omp_check_private (octx, decl, false))
   10416 	{
   10417 	  omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
   10418 	  continue;
   10419 	}
   10420       if (octx->region_type == ORT_COMBINED_TARGET)
   10421 	{
   10422 	  splay_tree_node n = splay_tree_lookup (octx->variables,
   10423 						 (splay_tree_key) decl);
   10424 	  if (n == NULL)
   10425 	    {
   10426 	      omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
   10427 	      octx = octx->outer_context;
   10428 	    }
   10429 	  else if (!implicit_p
   10430 		   && (n->value & GOVD_FIRSTPRIVATE_IMPLICIT))
   10431 	    {
   10432 	      n->value &= ~(GOVD_FIRSTPRIVATE
   10433 			    | GOVD_FIRSTPRIVATE_IMPLICIT
   10434 			    | GOVD_EXPLICIT);
   10435 	      omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
   10436 	      octx = octx->outer_context;
   10437 	    }
   10438 	}
   10439       break;
   10440     }
   10441   if (octx && (implicit_p || octx != orig_octx))
   10442     omp_notice_variable (octx, decl, true);
   10443 }
   10444 
   10445 /* We might have indexed several groups for DECL, e.g. a "TO" mapping and also
   10446    a "FIRSTPRIVATE" mapping.  Return the one that isn't firstprivate, etc.  */
   10447 
   10448 static omp_mapping_group *
   10449 omp_get_nonfirstprivate_group (hash_map<tree_operand_hash_no_se,
   10450 					omp_mapping_group *> *grpmap,
   10451 			       tree decl, bool allow_deleted = false)
   10452 {
   10453   omp_mapping_group **to_group_p = grpmap->get (decl);
   10454 
   10455   if (!to_group_p)
   10456     return NULL;
   10457 
   10458   omp_mapping_group *to_group = *to_group_p;
   10459 
   10460   for (; to_group; to_group = to_group->sibling)
   10461     {
   10462       tree grp_end = to_group->grp_end;
   10463       switch (OMP_CLAUSE_MAP_KIND (grp_end))
   10464 	{
   10465 	case GOMP_MAP_FIRSTPRIVATE_POINTER:
   10466 	case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   10467 	  break;
   10468 
   10469 	default:
   10470 	  if (allow_deleted || !to_group->deleted)
   10471 	    return to_group;
   10472 	}
   10473     }
   10474 
   10475   return NULL;
   10476 }
   10477 
   10478 /* Return TRUE if the directive (whose clauses are described by the hash table
   10479    of mapping groups, GRPMAP) maps DECL explicitly.  If TO_SPECIFICALLY is
   10480    true, only count TO mappings.  If ALLOW_DELETED is true, ignore the
   10481    "deleted" flag for groups.  If CONTAINED_IN_STRUCT is true, also return
   10482    TRUE if DECL is mapped as a member of a whole-struct mapping.  */
   10483 
   10484 static bool
   10485 omp_directive_maps_explicitly (hash_map<tree_operand_hash_no_se,
   10486 					omp_mapping_group *> *grpmap,
   10487 			       tree decl, omp_mapping_group **base_group,
   10488 			       bool to_specifically, bool allow_deleted,
   10489 			       bool contained_in_struct)
   10490 {
   10491   omp_mapping_group *decl_group
   10492     = omp_get_nonfirstprivate_group (grpmap, decl, allow_deleted);
   10493 
   10494   *base_group = NULL;
   10495 
   10496   if (decl_group)
   10497     {
   10498       tree grp_first = *decl_group->grp_start;
   10499       /* We might be called during omp_build_struct_sibling_lists, when
   10500 	 GOMP_MAP_STRUCT might have been inserted at the start of the group.
   10501 	 Skip over that, and also possibly the node after it.  */
   10502       if (OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_STRUCT
   10503 	  || OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_STRUCT_UNORD)
   10504 	{
   10505 	  grp_first = OMP_CLAUSE_CHAIN (grp_first);
   10506 	  if (OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_FIRSTPRIVATE_POINTER
   10507 	      || (OMP_CLAUSE_MAP_KIND (grp_first)
   10508 		  == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   10509 	      || OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_ATTACH_DETACH)
   10510 	    grp_first = OMP_CLAUSE_CHAIN (grp_first);
   10511 	}
   10512       enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first);
   10513       if (!to_specifically
   10514 	  || GOMP_MAP_COPY_TO_P (first_kind)
   10515 	  || first_kind == GOMP_MAP_ALLOC)
   10516 	{
   10517 	  *base_group = decl_group;
   10518 	  return true;
   10519 	}
   10520     }
   10521 
   10522   if (contained_in_struct
   10523       && omp_mapped_by_containing_struct (grpmap, decl, base_group))
   10524     return true;
   10525 
   10526   return false;
   10527 }
   10528 
   10529 /* If we have mappings INNER and OUTER, where INNER is a component access and
   10530    OUTER is a mapping of the whole containing struct, check that the mappings
   10531    are compatible.  We'll be deleting the inner mapping, so we need to make
   10532    sure the outer mapping does (at least) the same transfers to/from the device
   10533    as the inner mapping.  */
   10534 
   10535 bool
   10536 omp_check_mapping_compatibility (location_t loc,
   10537 				 omp_mapping_group *outer,
   10538 				 omp_mapping_group *inner)
   10539 {
   10540   tree first_outer = *outer->grp_start, first_inner = *inner->grp_start;
   10541 
   10542   gcc_assert (OMP_CLAUSE_CODE (first_outer) == OMP_CLAUSE_MAP);
   10543   gcc_assert (OMP_CLAUSE_CODE (first_inner) == OMP_CLAUSE_MAP);
   10544 
   10545   enum gomp_map_kind outer_kind = OMP_CLAUSE_MAP_KIND (first_outer);
   10546   enum gomp_map_kind inner_kind = OMP_CLAUSE_MAP_KIND (first_inner);
   10547 
   10548   if (outer_kind == inner_kind)
   10549     return true;
   10550 
   10551   switch (outer_kind)
   10552     {
   10553     case GOMP_MAP_ALWAYS_TO:
   10554       if (inner_kind == GOMP_MAP_FORCE_PRESENT
   10555 	  || inner_kind == GOMP_MAP_ALLOC
   10556 	  || inner_kind == GOMP_MAP_TO)
   10557 	return true;
   10558       break;
   10559 
   10560     case GOMP_MAP_ALWAYS_FROM:
   10561       if (inner_kind == GOMP_MAP_FORCE_PRESENT
   10562 	  || inner_kind == GOMP_MAP_RELEASE
   10563 	  || inner_kind == GOMP_MAP_FROM)
   10564 	return true;
   10565       break;
   10566 
   10567     case GOMP_MAP_TO:
   10568       if (inner_kind == GOMP_MAP_FORCE_PRESENT
   10569 	  || inner_kind == GOMP_MAP_ALLOC)
   10570 	return true;
   10571       break;
   10572 
   10573     case GOMP_MAP_FROM:
   10574       if (inner_kind == GOMP_MAP_RELEASE
   10575 	  || inner_kind == GOMP_MAP_FORCE_PRESENT)
   10576 	return true;
   10577       break;
   10578 
   10579     case GOMP_MAP_ALWAYS_TOFROM:
   10580     case GOMP_MAP_TOFROM:
   10581       if (inner_kind == GOMP_MAP_FORCE_PRESENT
   10582 	  || inner_kind == GOMP_MAP_ALLOC
   10583 	  || inner_kind == GOMP_MAP_TO
   10584 	  || inner_kind == GOMP_MAP_FROM
   10585 	  || inner_kind == GOMP_MAP_TOFROM)
   10586 	return true;
   10587       break;
   10588 
   10589     default:
   10590       ;
   10591     }
   10592 
   10593   error_at (loc, "data movement for component %qE is not compatible with "
   10594 	    "movement for struct %qE", OMP_CLAUSE_DECL (first_inner),
   10595 	    OMP_CLAUSE_DECL (first_outer));
   10596 
   10597   return false;
   10598 }
   10599 
   10600 /* This function handles several cases where clauses on a mapping directive
   10601    can interact with each other.
   10602 
   10603    If we have a FIRSTPRIVATE_POINTER node and we're also mapping the pointer
   10604    on the same directive, change the mapping of the first node to
   10605    ATTACH_DETACH.  We should have detected that this will happen already in
   10606    c-omp.cc:c_omp_adjust_map_clauses and marked the appropriate decl
   10607    as addressable.  (If we didn't, bail out.)
   10608 
   10609    If we have a FIRSTPRIVATE_REFERENCE (for a reference to pointer) and we're
   10610    mapping the base pointer also, we may need to change the mapping type to
   10611    ATTACH_DETACH and synthesize an alloc node for the reference itself.
   10612 
   10613    If we have an ATTACH_DETACH node, this is an array section with a pointer
   10614    base.  If we're mapping the base on the same directive too, we can drop its
   10615    mapping.  However, if we have a reference to pointer, make other appropriate
   10616    adjustments to the mapping nodes instead.
   10617 
   10618    If we have an ATTACH_DETACH node with a Fortran pointer-set (array
   10619    descriptor) mapping for a derived-type component, and we're also mapping the
   10620    whole of the derived-type variable on another clause, the pointer-set
   10621    mapping is removed.
   10622 
   10623    If we have a component access but we're also mapping the whole of the
   10624    containing struct, drop the former access.
   10625 
   10626    If the expression is a component access, and we're also mapping a base
   10627    pointer used in that component access in the same expression, change the
   10628    mapping type of the latter to ALLOC (ready for processing by
   10629    omp_build_struct_sibling_lists).  */
   10630 
   10631 void
   10632 omp_resolve_clause_dependencies (enum tree_code code,
   10633 				 vec<omp_mapping_group> *groups,
   10634 				 hash_map<tree_operand_hash_no_se,
   10635 					  omp_mapping_group *> *grpmap)
   10636 {
   10637   int i;
   10638   omp_mapping_group *grp;
   10639   bool repair_chain = false;
   10640 
   10641   FOR_EACH_VEC_ELT (*groups, i, grp)
   10642     {
   10643       tree grp_end = grp->grp_end;
   10644       tree decl = OMP_CLAUSE_DECL (grp_end);
   10645 
   10646       gcc_assert (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP);
   10647 
   10648       switch (OMP_CLAUSE_MAP_KIND (grp_end))
   10649 	{
   10650 	case GOMP_MAP_FIRSTPRIVATE_POINTER:
   10651 	  {
   10652 	    omp_mapping_group *to_group
   10653 	      = omp_get_nonfirstprivate_group (grpmap, decl);
   10654 
   10655 	    if (!to_group || to_group == grp)
   10656 	      continue;
   10657 
   10658 	    tree grp_first = *to_group->grp_start;
   10659 	    enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first);
   10660 
   10661 	    if ((GOMP_MAP_COPY_TO_P (first_kind)
   10662 		 || first_kind == GOMP_MAP_ALLOC)
   10663 		&& (OMP_CLAUSE_MAP_KIND (to_group->grp_end)
   10664 		    != GOMP_MAP_FIRSTPRIVATE_POINTER))
   10665 	      {
   10666 		gcc_assert (TREE_ADDRESSABLE (OMP_CLAUSE_DECL (grp_end)));
   10667 		OMP_CLAUSE_SET_MAP_KIND (grp_end, GOMP_MAP_ATTACH_DETACH);
   10668 	      }
   10669 	  }
   10670 	  break;
   10671 
   10672 	case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   10673 	  {
   10674 	    tree ptr = build_fold_indirect_ref (decl);
   10675 
   10676 	    omp_mapping_group *to_group
   10677 	      = omp_get_nonfirstprivate_group (grpmap, ptr);
   10678 
   10679 	    if (!to_group || to_group == grp)
   10680 	      continue;
   10681 
   10682 	    tree grp_first = *to_group->grp_start;
   10683 	    enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first);
   10684 
   10685 	    if (GOMP_MAP_COPY_TO_P (first_kind)
   10686 		|| first_kind == GOMP_MAP_ALLOC)
   10687 	      {
   10688 		OMP_CLAUSE_SET_MAP_KIND (grp_end, GOMP_MAP_ATTACH_DETACH);
   10689 		OMP_CLAUSE_DECL (grp_end) = ptr;
   10690 		if ((OMP_CLAUSE_CHAIN (*to_group->grp_start)
   10691 		     == to_group->grp_end)
   10692 		    && (OMP_CLAUSE_MAP_KIND (to_group->grp_end)
   10693 			== GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   10694 		  {
   10695 		    gcc_assert (TREE_ADDRESSABLE
   10696 				  (OMP_CLAUSE_DECL (to_group->grp_end)));
   10697 		    OMP_CLAUSE_SET_MAP_KIND (to_group->grp_end,
   10698 					     GOMP_MAP_ATTACH_DETACH);
   10699 
   10700 		    location_t loc = OMP_CLAUSE_LOCATION (to_group->grp_end);
   10701 		    tree alloc
   10702 		      = build_omp_clause (loc, OMP_CLAUSE_MAP);
   10703 		    OMP_CLAUSE_SET_MAP_KIND (alloc, GOMP_MAP_ALLOC);
   10704 		    tree tmp = build_fold_addr_expr (OMP_CLAUSE_DECL
   10705 						      (to_group->grp_end));
   10706 		    tree char_ptr_type = build_pointer_type (char_type_node);
   10707 		    OMP_CLAUSE_DECL (alloc)
   10708 		      = build2 (MEM_REF, char_type_node,
   10709 				tmp,
   10710 				build_int_cst (char_ptr_type, 0));
   10711 		    OMP_CLAUSE_SIZE (alloc) = TYPE_SIZE_UNIT (TREE_TYPE (tmp));
   10712 
   10713 		    OMP_CLAUSE_CHAIN (alloc)
   10714 		      = OMP_CLAUSE_CHAIN (*to_group->grp_start);
   10715 		    OMP_CLAUSE_CHAIN (*to_group->grp_start) = alloc;
   10716 		  }
   10717 	      }
   10718 	  }
   10719 	  break;
   10720 
   10721 	case GOMP_MAP_ATTACH_DETACH:
   10722 	case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   10723 	  {
   10724 	    tree base_ptr, referenced_ptr_node = NULL_TREE;
   10725 
   10726 	    while (TREE_CODE (decl) == ARRAY_REF)
   10727 	      decl = TREE_OPERAND (decl, 0);
   10728 
   10729 	    if (TREE_CODE (decl) == INDIRECT_REF)
   10730 	      decl = TREE_OPERAND (decl, 0);
   10731 
   10732 	    /* Only component accesses.  */
   10733 	    if (DECL_P (decl))
   10734 	      continue;
   10735 
   10736 	    /* We want the pointer itself when checking if the base pointer is
   10737 	       mapped elsewhere in the same directive -- if we have a
   10738 	       reference to the pointer, don't use that.  */
   10739 
   10740 	    if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
   10741 		&& TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
   10742 	      {
   10743 		referenced_ptr_node = OMP_CLAUSE_CHAIN (*grp->grp_start);
   10744 		base_ptr = OMP_CLAUSE_DECL (referenced_ptr_node);
   10745 	      }
   10746 	    else
   10747 	      base_ptr = decl;
   10748 
   10749 	    gomp_map_kind zlas_kind
   10750 	      = (code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
   10751 		? GOMP_MAP_DETACH : GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION;
   10752 
   10753 	    if (TREE_CODE (TREE_TYPE (base_ptr)) == POINTER_TYPE)
   10754 	      {
   10755 		/* If we map the base TO, and we're doing an attachment, we can
   10756 		   skip the TO mapping altogether and create an ALLOC mapping
   10757 		   instead, since the attachment will overwrite the device
   10758 		   pointer in that location immediately anyway.  Otherwise,
   10759 		   change our mapping to
   10760 		   GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION in case the
   10761 		   attachment target has not been copied to the device already
   10762 		   by some earlier directive.  */
   10763 
   10764 		bool base_mapped_to = false;
   10765 
   10766 		omp_mapping_group *base_group;
   10767 
   10768 		if (omp_directive_maps_explicitly (grpmap, base_ptr,
   10769 						   &base_group, false, true,
   10770 						   false))
   10771 		  {
   10772 		    if (referenced_ptr_node)
   10773 		      {
   10774 			base_mapped_to = true;
   10775 			if ((OMP_CLAUSE_MAP_KIND (base_group->grp_end)
   10776 			     == GOMP_MAP_ATTACH_DETACH)
   10777 			    && (OMP_CLAUSE_CHAIN (*base_group->grp_start)
   10778 				== base_group->grp_end))
   10779 			  {
   10780 			    OMP_CLAUSE_CHAIN (*base_group->grp_start)
   10781 			      = OMP_CLAUSE_CHAIN (base_group->grp_end);
   10782 			    base_group->grp_end = *base_group->grp_start;
   10783 			    repair_chain = true;
   10784 			  }
   10785 		      }
   10786 		    else
   10787 		      {
   10788 			base_group->deleted = true;
   10789 			OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end) = 1;
   10790 		      }
   10791 		  }
   10792 
   10793 		/* We're dealing with a reference to a pointer, and we are
   10794 		   attaching both the reference and the pointer.  We know the
   10795 		   reference itself is on the target, because we are going to
   10796 		   create an ALLOC node for it in accumulate_sibling_list.  The
   10797 		   pointer might be on the target already or it might not, but
   10798 		   if it isn't then it's not an error, so use
   10799 		   GOMP_MAP_ATTACH_ZLAS for it.  */
   10800 		if (!base_mapped_to && referenced_ptr_node)
   10801 		  OMP_CLAUSE_SET_MAP_KIND (referenced_ptr_node, zlas_kind);
   10802 
   10803 		omp_mapping_group *struct_group;
   10804 		tree desc;
   10805 		if ((desc = OMP_CLAUSE_CHAIN (*grp->grp_start))
   10806 		    && omp_map_clause_descriptor_p (desc)
   10807 		    && omp_mapped_by_containing_struct (grpmap, decl,
   10808 							&struct_group))
   10809 		  /* If we have a pointer set but we're mapping (or unmapping)
   10810 		     the whole of the containing struct, we can remove the
   10811 		     pointer set mapping.  */
   10812 		  OMP_CLAUSE_CHAIN (*grp->grp_start) = OMP_CLAUSE_CHAIN (desc);
   10813 	      }
   10814 	    else if (TREE_CODE (TREE_TYPE (base_ptr)) == REFERENCE_TYPE
   10815 		     && (TREE_CODE (TREE_TYPE (TREE_TYPE (base_ptr)))
   10816 			 == ARRAY_TYPE)
   10817 		     && OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION
   10818 			  (*grp->grp_start))
   10819 	      OMP_CLAUSE_SET_MAP_KIND (grp->grp_end, zlas_kind);
   10820 	  }
   10821 	  break;
   10822 
   10823 	case GOMP_MAP_ATTACH:
   10824 	  /* Ignore standalone attach here.  */
   10825 	  break;
   10826 
   10827 	default:
   10828 	  {
   10829 	    omp_mapping_group *struct_group;
   10830 	    if (omp_mapped_by_containing_struct (grpmap, decl, &struct_group)
   10831 		&& *grp->grp_start == grp_end)
   10832 	      {
   10833 		omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end),
   10834 						 struct_group, grp);
   10835 		/* Remove the whole of this mapping -- redundant.  */
   10836 		grp->deleted = true;
   10837 	      }
   10838 
   10839 	    tree base = decl;
   10840 	    while ((base = omp_get_base_pointer (base)))
   10841 	      {
   10842 		omp_mapping_group *base_group;
   10843 
   10844 		if (omp_directive_maps_explicitly (grpmap, base, &base_group,
   10845 						   true, true, false))
   10846 		  {
   10847 		    tree grp_first = *base_group->grp_start;
   10848 		    OMP_CLAUSE_SET_MAP_KIND (grp_first, GOMP_MAP_ALLOC);
   10849 		  }
   10850 	      }
   10851 	  }
   10852 	}
   10853     }
   10854 
   10855   if (repair_chain)
   10856     {
   10857       /* Group start pointers may have become detached from the
   10858 	 OMP_CLAUSE_CHAIN of previous groups if elements were removed from the
   10859 	 end of those groups.  Fix that now.  */
   10860       tree *new_next = NULL;
   10861       FOR_EACH_VEC_ELT (*groups, i, grp)
   10862 	{
   10863 	  if (new_next)
   10864 	    grp->grp_start = new_next;
   10865 
   10866 	  new_next = &OMP_CLAUSE_CHAIN (grp->grp_end);
   10867 	}
   10868     }
   10869 }
   10870 
   10871 /* Similar to omp_resolve_clause_dependencies, but for OpenACC.  The only
   10872    clause dependencies we handle for now are struct element mappings and
   10873    whole-struct mappings on the same directive, and duplicate clause
   10874    detection.  */
   10875 
   10876 void
   10877 oacc_resolve_clause_dependencies (vec<omp_mapping_group> *groups,
   10878 				  hash_map<tree_operand_hash_no_se,
   10879 					   omp_mapping_group *> *grpmap)
   10880 {
   10881   int i;
   10882   omp_mapping_group *grp;
   10883   hash_set<tree_operand_hash> *seen_components = NULL;
   10884   hash_set<tree_operand_hash> *shown_error = NULL;
   10885 
   10886   FOR_EACH_VEC_ELT (*groups, i, grp)
   10887     {
   10888       tree grp_end = grp->grp_end;
   10889       tree decl = OMP_CLAUSE_DECL (grp_end);
   10890 
   10891       gcc_assert (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP);
   10892 
   10893       if (DECL_P (grp_end))
   10894 	continue;
   10895 
   10896       tree c = OMP_CLAUSE_DECL (*grp->grp_start);
   10897       while (TREE_CODE (c) == ARRAY_REF)
   10898 	c = TREE_OPERAND (c, 0);
   10899       if (TREE_CODE (c) != COMPONENT_REF)
   10900 	continue;
   10901       if (!seen_components)
   10902 	seen_components = new hash_set<tree_operand_hash> ();
   10903       if (!shown_error)
   10904 	shown_error = new hash_set<tree_operand_hash> ();
   10905       if (seen_components->contains (c)
   10906 	  && !shown_error->contains (c))
   10907 	{
   10908 	  error_at (OMP_CLAUSE_LOCATION (grp_end),
   10909 		    "%qE appears more than once in map clauses",
   10910 		    OMP_CLAUSE_DECL (grp_end));
   10911 	  shown_error->add (c);
   10912 	}
   10913       else
   10914 	seen_components->add (c);
   10915 
   10916       omp_mapping_group *struct_group;
   10917       if (omp_mapped_by_containing_struct (grpmap, decl, &struct_group)
   10918 	  && *grp->grp_start == grp_end)
   10919 	{
   10920 	  omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end),
   10921 					   struct_group, grp);
   10922 	  /* Remove the whole of this mapping -- redundant.  */
   10923 	  grp->deleted = true;
   10924 	}
   10925     }
   10926 
   10927   if (seen_components)
   10928     delete seen_components;
   10929   if (shown_error)
   10930     delete shown_error;
   10931 }
   10932 
   10933 /* Link node NEWNODE so it is pointed to by chain INSERT_AT.  NEWNODE's chain
   10934    is linked to the previous node pointed to by INSERT_AT.  */
   10935 
   10936 static tree *
   10937 omp_siblist_insert_node_after (tree newnode, tree *insert_at)
   10938 {
   10939   OMP_CLAUSE_CHAIN (newnode) = *insert_at;
   10940   *insert_at = newnode;
   10941   return &OMP_CLAUSE_CHAIN (newnode);
   10942 }
   10943 
   10944 /* Move NODE (which is currently pointed to by the chain OLD_POS) so it is
   10945    pointed to by chain MOVE_AFTER instead.  */
   10946 
   10947 static void
   10948 omp_siblist_move_node_after (tree node, tree *old_pos, tree *move_after)
   10949 {
   10950   gcc_assert (node == *old_pos);
   10951   *old_pos = OMP_CLAUSE_CHAIN (node);
   10952   OMP_CLAUSE_CHAIN (node) = *move_after;
   10953   *move_after = node;
   10954 }
   10955 
   10956 /* Move nodes from FIRST_PTR (pointed to by previous node's chain) to
   10957    LAST_NODE to after MOVE_AFTER chain.  Similar to below function, but no
   10958    new nodes are prepended to the list before splicing into the new position.
   10959    Return the position we should continue scanning the list at, or NULL to
   10960    stay where we were.  */
   10961 
   10962 static tree *
   10963 omp_siblist_move_nodes_after (tree *first_ptr, tree last_node,
   10964 			      tree *move_after)
   10965 {
   10966   if (first_ptr == move_after)
   10967     return NULL;
   10968 
   10969   tree tmp = *first_ptr;
   10970   *first_ptr = OMP_CLAUSE_CHAIN (last_node);
   10971   OMP_CLAUSE_CHAIN (last_node) = *move_after;
   10972   *move_after = tmp;
   10973 
   10974   return first_ptr;
   10975 }
   10976 
   10977 /* Concatenate two lists described by [FIRST_NEW, LAST_NEW_TAIL] and
   10978    [FIRST_PTR, LAST_NODE], and insert them in the OMP clause list after chain
   10979    pointer MOVE_AFTER.
   10980 
   10981    The latter list was previously part of the OMP clause list, and the former
   10982    (prepended) part is comprised of new nodes.
   10983 
   10984    We start with a list of nodes starting with a struct mapping node.  We
   10985    rearrange the list so that new nodes starting from FIRST_NEW and whose last
   10986    node's chain is LAST_NEW_TAIL comes directly after MOVE_AFTER, followed by
   10987    the group of mapping nodes we are currently processing (from the chain
   10988    FIRST_PTR to LAST_NODE).  The return value is the pointer to the next chain
   10989    we should continue processing from, or NULL to stay where we were.
   10990 
   10991    The transformation (in the case where MOVE_AFTER and FIRST_PTR are
   10992    different) is worked through below.  Here we are processing LAST_NODE, and
   10993    FIRST_PTR points at the preceding mapping clause:
   10994 
   10995   #. mapping node		chain
   10996   ---------------------------------------------------
   10997   A. struct_node		[->B]
   10998   B. comp_1			[->C]
   10999   C. comp_2			[->D (move_after)]
   11000   D. map_to_3			[->E]
   11001   E. attach_3			[->F (first_ptr)]
   11002   F. map_to_4			[->G (continue_at)]
   11003   G. attach_4 (last_node)	[->H]
   11004   H. ...
   11005 
   11006      *last_new_tail = *first_ptr;
   11007 
   11008   I. new_node (first_new)	[->F (last_new_tail)]
   11009 
   11010      *first_ptr = OMP_CLAUSE_CHAIN (last_node)
   11011 
   11012   #. mapping node		chain
   11013   ----------------------------------------------------
   11014   A. struct_node		[->B]
   11015   B. comp_1			[->C]
   11016   C. comp_2			[->D (move_after)]
   11017   D. map_to_3			[->E]
   11018   E. attach_3			[->H (first_ptr)]
   11019   F. map_to_4			[->G (continue_at)]
   11020   G. attach_4 (last_node)	[->H]
   11021   H. ...
   11022 
   11023   I. new_node (first_new)	[->F  (last_new_tail)]
   11024 
   11025      OMP_CLAUSE_CHAIN (last_node) = *move_after;
   11026 
   11027   #. mapping node		chain
   11028   ---------------------------------------------------
   11029   A. struct_node		[->B]
   11030   B. comp_1			[->C]
   11031   C. comp_2			[->D (move_after)]
   11032   D. map_to_3			[->E]
   11033   E. attach_3			[->H (continue_at)]
   11034   F. map_to_4			[->G]
   11035   G. attach_4 (last_node)	[->D]
   11036   H. ...
   11037 
   11038   I. new_node (first_new)	[->F  (last_new_tail)]
   11039 
   11040      *move_after = first_new;
   11041 
   11042   #. mapping node		chain
   11043   ---------------------------------------------------
   11044   A. struct_node		[->B]
   11045   B. comp_1			[->C]
   11046   C. comp_2			[->I (move_after)]
   11047   D. map_to_3			[->E]
   11048   E. attach_3			[->H (continue_at)]
   11049   F. map_to_4			[->G]
   11050   G. attach_4 (last_node)	[->D]
   11051   H. ...
   11052   I. new_node (first_new)	[->F (last_new_tail)]
   11053 
   11054   or, in order:
   11055 
   11056   #. mapping node		chain
   11057   ---------------------------------------------------
   11058   A. struct_node		[->B]
   11059   B. comp_1			[->C]
   11060   C. comp_2			[->I (move_after)]
   11061   I. new_node (first_new)	[->F (last_new_tail)]
   11062   F. map_to_4			[->G]
   11063   G. attach_4 (last_node)	[->D]
   11064   D. map_to_3			[->E]
   11065   E. attach_3			[->H (continue_at)]
   11066   H. ...
   11067 */
   11068 
   11069 static tree *
   11070 omp_siblist_move_concat_nodes_after (tree first_new, tree *last_new_tail,
   11071 				     tree *first_ptr, tree last_node,
   11072 				     tree *move_after)
   11073 {
   11074   tree *continue_at = NULL;
   11075   *last_new_tail = *first_ptr;
   11076   if (first_ptr == move_after)
   11077     *move_after = first_new;
   11078   else
   11079     {
   11080       *first_ptr = OMP_CLAUSE_CHAIN (last_node);
   11081       continue_at = first_ptr;
   11082       OMP_CLAUSE_CHAIN (last_node) = *move_after;
   11083       *move_after = first_new;
   11084     }
   11085   return continue_at;
   11086 }
   11087 
   11088 static omp_addr_token *
   11089 omp_first_chained_access_token (vec<omp_addr_token *> &addr_tokens)
   11090 {
   11091   using namespace omp_addr_tokenizer;
   11092   int idx = addr_tokens.length () - 1;
   11093   gcc_assert (idx >= 0);
   11094   if (addr_tokens[idx]->type != ACCESS_METHOD)
   11095     return addr_tokens[idx];
   11096   while (idx > 0 && addr_tokens[idx - 1]->type == ACCESS_METHOD)
   11097     idx--;
   11098   return addr_tokens[idx];
   11099 }
   11100 
   11101 /* Mapping struct members causes an additional set of nodes to be created,
   11102    starting with GOMP_MAP_STRUCT followed by a number of mappings equal to the
   11103    number of members being mapped, in order of ascending position (address or
   11104    bitwise).
   11105 
   11106    We scan through the list of mapping clauses, calling this function for each
   11107    struct member mapping we find, and build up the list of mappings after the
   11108    initial GOMP_MAP_STRUCT node.  For pointer members, these will be
   11109    newly-created ALLOC nodes.  For non-pointer members, the existing mapping is
   11110    moved into place in the sorted list.
   11111 
   11112      struct {
   11113        int *a;
   11114        int *b;
   11115        int c;
   11116        int *d;
   11117      };
   11118 
   11119      #pragma (acc|omp directive) copy(struct.a[0:n], struct.b[0:n], struct.c,
   11120 				      struct.d[0:n])
   11121 
   11122      GOMP_MAP_STRUCT (4)
   11123      [GOMP_MAP_FIRSTPRIVATE_REFERENCE -- for refs to structs]
   11124      GOMP_MAP_ALLOC  (struct.a)
   11125      GOMP_MAP_ALLOC  (struct.b)
   11126      GOMP_MAP_TO     (struct.c)
   11127      GOMP_MAP_ALLOC  (struct.d)
   11128      ...
   11129 
   11130    In the case where we are mapping references to pointers, or in Fortran if
   11131    we are mapping an array with a descriptor, additional nodes may be created
   11132    after the struct node list also.
   11133 
   11134    The return code is either a pointer to the next node to process (if the
   11135    list has been rearranged), else NULL to continue with the next node in the
   11136    original list.  */
   11137 
   11138 static tree *
   11139 omp_accumulate_sibling_list (enum omp_region_type region_type,
   11140 			     enum tree_code code,
   11141 			     hash_map<tree_operand_hash, tree>
   11142 			       *&struct_map_to_clause,
   11143 			     hash_map<tree_operand_hash_no_se,
   11144 				      omp_mapping_group *> *group_map,
   11145 			     tree *grp_start_p, tree grp_end,
   11146 			     vec<omp_addr_token *> &addr_tokens, tree **inner,
   11147 			     bool *fragile_p, bool reprocessing_struct,
   11148 			     tree **added_tail)
   11149 {
   11150   using namespace omp_addr_tokenizer;
   11151   poly_offset_int coffset;
   11152   poly_int64 cbitpos;
   11153   tree ocd = OMP_CLAUSE_DECL (grp_end);
   11154   bool openmp = !(region_type & ORT_ACC);
   11155   bool target = (region_type & ORT_TARGET) != 0;
   11156   tree *continue_at = NULL;
   11157 
   11158   while (TREE_CODE (ocd) == ARRAY_REF)
   11159     ocd = TREE_OPERAND (ocd, 0);
   11160 
   11161   if (*fragile_p)
   11162     {
   11163       omp_mapping_group *to_group
   11164 	= omp_get_nonfirstprivate_group (group_map, ocd, true);
   11165 
   11166       if (to_group)
   11167 	return NULL;
   11168     }
   11169 
   11170   omp_addr_token *last_token = omp_first_chained_access_token (addr_tokens);
   11171   if (last_token->type == ACCESS_METHOD)
   11172     {
   11173       switch (last_token->u.access_kind)
   11174 	{
   11175 	case ACCESS_REF:
   11176 	case ACCESS_REF_TO_POINTER:
   11177 	case ACCESS_REF_TO_POINTER_OFFSET:
   11178 	case ACCESS_INDEXED_REF_TO_ARRAY:
   11179 	  /* We may see either a bare reference or a dereferenced
   11180 	     "convert_from_reference"-like one here.  Handle either way.  */
   11181 	  if (TREE_CODE (ocd) == INDIRECT_REF)
   11182 	    ocd = TREE_OPERAND (ocd, 0);
   11183 	  gcc_assert (TREE_CODE (TREE_TYPE (ocd)) == REFERENCE_TYPE);
   11184 	  break;
   11185 
   11186 	default:
   11187 	  ;
   11188 	}
   11189     }
   11190 
   11191   bool variable_offset;
   11192   tree base
   11193     = extract_base_bit_offset (ocd, &cbitpos, &coffset, &variable_offset);
   11194 
   11195   int base_token;
   11196   for (base_token = addr_tokens.length () - 1; base_token >= 0; base_token--)
   11197     {
   11198       if (addr_tokens[base_token]->type == ARRAY_BASE
   11199 	  || addr_tokens[base_token]->type == STRUCTURE_BASE)
   11200 	break;
   11201     }
   11202 
   11203   /* The two expressions in the assertion below aren't quite the same: if we
   11204      have 'struct_base_decl access_indexed_array' for something like
   11205      "myvar[2].x" then base will be "myvar" and addr_tokens[base_token]->expr
   11206      will be "myvar[2]" -- the actual base of the structure.
   11207      The former interpretation leads to a strange situation where we get
   11208        struct(myvar) alloc(myvar[2].ptr1)
   11209      That is, the array of structures is kind of treated as one big structure
   11210      for the purposes of gathering sibling lists, etc.  */
   11211   /* gcc_assert (base == addr_tokens[base_token]->expr);  */
   11212 
   11213   bool attach_detach = ((OMP_CLAUSE_MAP_KIND (grp_end)
   11214 			 == GOMP_MAP_ATTACH_DETACH)
   11215 			|| (OMP_CLAUSE_MAP_KIND (grp_end)
   11216 			    == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION));
   11217   bool has_descriptor = false;
   11218   if (OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end)
   11219     {
   11220       tree grp_mid = OMP_CLAUSE_CHAIN (*grp_start_p);
   11221       if (grp_mid && omp_map_clause_descriptor_p (grp_mid))
   11222 	has_descriptor = true;
   11223     }
   11224 
   11225   if (!struct_map_to_clause || struct_map_to_clause->get (base) == NULL)
   11226     {
   11227       enum gomp_map_kind str_kind = GOMP_MAP_STRUCT;
   11228 
   11229       if (struct_map_to_clause == NULL)
   11230 	struct_map_to_clause = new hash_map<tree_operand_hash, tree>;
   11231 
   11232       if (variable_offset)
   11233 	str_kind = GOMP_MAP_STRUCT_UNORD;
   11234 
   11235       tree l = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
   11236 
   11237       OMP_CLAUSE_SET_MAP_KIND (l, str_kind);
   11238       OMP_CLAUSE_DECL (l) = unshare_expr (base);
   11239       OMP_CLAUSE_SIZE (l) = size_int (1);
   11240 
   11241       struct_map_to_clause->put (base, l);
   11242 
   11243       /* On first iterating through the clause list, we insert the struct node
   11244 	 just before the component access node that triggers the initial
   11245 	 omp_accumulate_sibling_list call for a particular sibling list (and
   11246 	 it then forms the first entry in that list).  When reprocessing
   11247 	 struct bases that are themselves component accesses, we insert the
   11248 	 struct node on an off-side list to avoid inserting the new
   11249 	 GOMP_MAP_STRUCT into the middle of the old one.  */
   11250       tree *insert_node_pos = reprocessing_struct ? *added_tail : grp_start_p;
   11251 
   11252       if (has_descriptor)
   11253 	{
   11254 	  tree desc = OMP_CLAUSE_CHAIN (*grp_start_p);
   11255 	  if (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
   11256 	    OMP_CLAUSE_SET_MAP_KIND (desc, GOMP_MAP_RELEASE);
   11257 	  tree sc = *insert_node_pos;
   11258 	  OMP_CLAUSE_CHAIN (l) = desc;
   11259 	  OMP_CLAUSE_CHAIN (*grp_start_p) = OMP_CLAUSE_CHAIN (desc);
   11260 	  OMP_CLAUSE_CHAIN (desc) = sc;
   11261 	  *insert_node_pos = l;
   11262 	}
   11263       else if (attach_detach)
   11264 	{
   11265 	  tree extra_node;
   11266 	  tree alloc_node
   11267 	    = build_omp_struct_comp_nodes (code, *grp_start_p, grp_end,
   11268 					   &extra_node);
   11269 	  tree *tail;
   11270 	  OMP_CLAUSE_CHAIN (l) = alloc_node;
   11271 
   11272 	  if (extra_node)
   11273 	    {
   11274 	      OMP_CLAUSE_CHAIN (extra_node) = *insert_node_pos;
   11275 	      OMP_CLAUSE_CHAIN (alloc_node) = extra_node;
   11276 	      tail = &OMP_CLAUSE_CHAIN (extra_node);
   11277 	    }
   11278 	  else
   11279 	    {
   11280 	      OMP_CLAUSE_CHAIN (alloc_node) = *insert_node_pos;
   11281 	      tail = &OMP_CLAUSE_CHAIN (alloc_node);
   11282 	    }
   11283 
   11284 	  /* For OpenMP semantics, we don't want to implicitly allocate
   11285 	     space for the pointer here for non-compute regions (e.g. "enter
   11286 	     data").  A FRAGILE_P node is only being created so that
   11287 	     omp-low.cc is able to rewrite the struct properly.
   11288 	     For references (to pointers), we want to actually allocate the
   11289 	     space for the reference itself in the sorted list following the
   11290 	     struct node.
   11291 	     For pointers, we want to allocate space if we had an explicit
   11292 	     mapping of the attachment point, but not otherwise.  */
   11293 	  if (*fragile_p
   11294 	      || (openmp
   11295 		  && !target
   11296 		  && attach_detach
   11297 		  && TREE_CODE (TREE_TYPE (ocd)) == POINTER_TYPE
   11298 		  && !OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end)))
   11299 	    {
   11300 	      if (!lang_GNU_Fortran ())
   11301 	       /* In Fortran, pointers are dereferenced automatically, but may
   11302 		  be unassociated.  So we still want to allocate space for the
   11303 		  pointer (as the base for an attach operation that should be
   11304 		  present in the same directive's clause list also).  */
   11305 		OMP_CLAUSE_SIZE (alloc_node) = size_zero_node;
   11306 	      OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (alloc_node) = 1;
   11307 	    }
   11308 
   11309 	  *insert_node_pos = l;
   11310 
   11311 	  if (reprocessing_struct)
   11312 	    {
   11313 	      /* When reprocessing a struct node group used as the base of a
   11314 		 subcomponent access, if we have a reference-to-pointer base,
   11315 		 we will see:
   11316 		   struct(**ptr) attach(*ptr)
   11317 		 whereas for a non-reprocess-struct group, we see, e.g.:
   11318 		   tofrom(**ptr) attach(*ptr) attach(ptr)
   11319 		 and we create the "alloc" for the second "attach", i.e.
   11320 		 for the reference itself.  When reprocessing a struct group we
   11321 		 thus change the pointer attachment into a reference attachment
   11322 		 by stripping the indirection.  (The attachment of the
   11323 		 referenced pointer must happen elsewhere, either on the same
   11324 		 directive, or otherwise.)  */
   11325 	      tree adecl = OMP_CLAUSE_DECL (alloc_node);
   11326 
   11327 	      if ((TREE_CODE (adecl) == INDIRECT_REF
   11328 		   || (TREE_CODE (adecl) == MEM_REF
   11329 		       && integer_zerop (TREE_OPERAND (adecl, 1))))
   11330 		  && (TREE_CODE (TREE_TYPE (TREE_OPERAND (adecl, 0)))
   11331 		      == REFERENCE_TYPE)
   11332 		  && (TREE_CODE (TREE_TYPE (TREE_TYPE
   11333 			(TREE_OPERAND (adecl, 0)))) == POINTER_TYPE))
   11334 		OMP_CLAUSE_DECL (alloc_node) = TREE_OPERAND (adecl, 0);
   11335 
   11336 	      *added_tail = tail;
   11337 	    }
   11338 	}
   11339       else
   11340 	{
   11341 	  gcc_assert (*grp_start_p == grp_end);
   11342 	  if (reprocessing_struct)
   11343 	    {
   11344 	      /* If we don't have an attach/detach node, this is a
   11345 		 "target data" directive or similar, not an offload region.
   11346 		 Synthesize an "alloc" node using just the initiating
   11347 		 GOMP_MAP_STRUCT decl.  */
   11348 	      gomp_map_kind k = (code == OMP_TARGET_EXIT_DATA
   11349 				 || code == OACC_EXIT_DATA)
   11350 				? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
   11351 	      tree alloc_node
   11352 		= build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
   11353 				    OMP_CLAUSE_MAP);
   11354 	      OMP_CLAUSE_SET_MAP_KIND (alloc_node, k);
   11355 	      OMP_CLAUSE_DECL (alloc_node) = unshare_expr (last_token->expr);
   11356 	      OMP_CLAUSE_SIZE (alloc_node)
   11357 		= TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (alloc_node)));
   11358 
   11359 	      OMP_CLAUSE_CHAIN (alloc_node) = OMP_CLAUSE_CHAIN (l);
   11360 	      OMP_CLAUSE_CHAIN (l) = alloc_node;
   11361 	      *insert_node_pos = l;
   11362 	      *added_tail = &OMP_CLAUSE_CHAIN (alloc_node);
   11363 	    }
   11364 	  else
   11365 	    grp_start_p = omp_siblist_insert_node_after (l, insert_node_pos);
   11366 	}
   11367 
   11368       unsigned last_access = base_token + 1;
   11369 
   11370       while (last_access + 1 < addr_tokens.length ()
   11371 	     && addr_tokens[last_access + 1]->type == ACCESS_METHOD)
   11372 	last_access++;
   11373 
   11374       if ((region_type & ORT_TARGET)
   11375 	  && addr_tokens[base_token + 1]->type == ACCESS_METHOD)
   11376 	{
   11377 	  bool base_ref = false;
   11378 	  access_method_kinds access_kind
   11379 	    = addr_tokens[last_access]->u.access_kind;
   11380 
   11381 	  switch (access_kind)
   11382 	    {
   11383 	    case ACCESS_DIRECT:
   11384 	    case ACCESS_INDEXED_ARRAY:
   11385 	      return NULL;
   11386 
   11387 	    case ACCESS_REF:
   11388 	    case ACCESS_REF_TO_POINTER:
   11389 	    case ACCESS_REF_TO_POINTER_OFFSET:
   11390 	    case ACCESS_INDEXED_REF_TO_ARRAY:
   11391 	      base_ref = true;
   11392 	      break;
   11393 
   11394 	    default:
   11395 	      ;
   11396 	    }
   11397 	  tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
   11398 				      OMP_CLAUSE_MAP);
   11399 	  enum gomp_map_kind mkind;
   11400 	  omp_mapping_group *decl_group;
   11401 	  tree use_base;
   11402 	  switch (access_kind)
   11403 	    {
   11404 	    case ACCESS_POINTER:
   11405 	    case ACCESS_POINTER_OFFSET:
   11406 	      use_base = addr_tokens[last_access]->expr;
   11407 	      break;
   11408 	    case ACCESS_REF_TO_POINTER:
   11409 	    case ACCESS_REF_TO_POINTER_OFFSET:
   11410 	      use_base
   11411 		= build_fold_indirect_ref (addr_tokens[last_access]->expr);
   11412 	      break;
   11413 	    default:
   11414 	      use_base = addr_tokens[base_token]->expr;
   11415 	    }
   11416 	  bool mapped_to_p
   11417 	    = omp_directive_maps_explicitly (group_map, use_base, &decl_group,
   11418 					     true, false, true);
   11419 	  if (addr_tokens[base_token]->type == STRUCTURE_BASE
   11420 	      && DECL_P (addr_tokens[last_access]->expr)
   11421 	      && !mapped_to_p)
   11422 	    mkind = base_ref ? GOMP_MAP_FIRSTPRIVATE_REFERENCE
   11423 			     : GOMP_MAP_FIRSTPRIVATE_POINTER;
   11424 	  else
   11425 	    mkind = GOMP_MAP_ATTACH_DETACH;
   11426 
   11427 	  OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
   11428 	  /* If we have a reference to pointer base, we want to attach the
   11429 	     pointer here, not the reference.  The reference attachment happens
   11430 	     elsewhere.  */
   11431 	  bool ref_to_ptr
   11432 	    = (access_kind == ACCESS_REF_TO_POINTER
   11433 	       || access_kind == ACCESS_REF_TO_POINTER_OFFSET);
   11434 	  tree sdecl = addr_tokens[last_access]->expr;
   11435 	  tree sdecl_ptr = ref_to_ptr ? build_fold_indirect_ref (sdecl)
   11436 				      : sdecl;
   11437 	  /* For the FIRSTPRIVATE_REFERENCE after the struct node, we
   11438 	     want to use the reference itself for the decl, but we
   11439 	     still want to use the pointer to calculate the bias.  */
   11440 	  OMP_CLAUSE_DECL (c2) = (mkind == GOMP_MAP_ATTACH_DETACH)
   11441 				 ? sdecl_ptr : sdecl;
   11442 	  sdecl = sdecl_ptr;
   11443 	  tree baddr = build_fold_addr_expr (base);
   11444 	  baddr = fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end),
   11445 				    ptrdiff_type_node, baddr);
   11446 	  tree decladdr = fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end),
   11447 					    ptrdiff_type_node, sdecl);
   11448 	  OMP_CLAUSE_SIZE (c2)
   11449 	    = fold_build2_loc (OMP_CLAUSE_LOCATION (grp_end), MINUS_EXPR,
   11450 			       ptrdiff_type_node, baddr, decladdr);
   11451 	  /* Insert after struct node.  */
   11452 	  OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
   11453 	  OMP_CLAUSE_CHAIN (l) = c2;
   11454 
   11455 	  if (addr_tokens[base_token]->type == STRUCTURE_BASE
   11456 	      && (addr_tokens[base_token]->u.structure_base_kind
   11457 		  == BASE_COMPONENT_EXPR)
   11458 	      && mkind == GOMP_MAP_ATTACH_DETACH
   11459 	      && addr_tokens[last_access]->u.access_kind != ACCESS_REF)
   11460 	    {
   11461 	      *inner = insert_node_pos;
   11462 	      if (openmp)
   11463 		*fragile_p = true;
   11464 	      return NULL;
   11465 	    }
   11466 	}
   11467 
   11468       if (addr_tokens[base_token]->type == STRUCTURE_BASE
   11469 	  && (addr_tokens[base_token]->u.structure_base_kind
   11470 	      == BASE_COMPONENT_EXPR)
   11471 	  && addr_tokens[last_access]->u.access_kind == ACCESS_REF)
   11472 	*inner = insert_node_pos;
   11473 
   11474       return NULL;
   11475     }
   11476   else if (struct_map_to_clause)
   11477     {
   11478       tree *osc = struct_map_to_clause->get (base);
   11479       tree *sc = NULL, *scp = NULL;
   11480       bool unordered = false;
   11481 
   11482       if (osc && OMP_CLAUSE_MAP_KIND (*osc) == GOMP_MAP_STRUCT_UNORD)
   11483 	unordered = true;
   11484 
   11485       unsigned HOST_WIDE_INT i, elems = tree_to_uhwi (OMP_CLAUSE_SIZE (*osc));
   11486       sc = &OMP_CLAUSE_CHAIN (*osc);
   11487       /* The struct mapping might be immediately followed by a
   11488 	 FIRSTPRIVATE_POINTER,  FIRSTPRIVATE_REFERENCE or an ATTACH_DETACH --
   11489 	 if it's an indirect access or a reference, or if the structure base
   11490 	 is not a decl.  The FIRSTPRIVATE_* nodes are removed in omp-low.cc
   11491 	 after they have been processed there, and ATTACH_DETACH nodes are
   11492 	 recomputed and moved out of the GOMP_MAP_STRUCT construct once
   11493 	 sibling list building is complete.  */
   11494       if (OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_FIRSTPRIVATE_POINTER
   11495 	  || OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
   11496 	  || OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_ATTACH_DETACH)
   11497 	sc = &OMP_CLAUSE_CHAIN (*sc);
   11498       for (i = 0; i < elems; i++, sc = &OMP_CLAUSE_CHAIN (*sc))
   11499 	if (attach_detach && sc == grp_start_p)
   11500 	  break;
   11501 	else if (TREE_CODE (OMP_CLAUSE_DECL (*sc)) != COMPONENT_REF
   11502 		 && TREE_CODE (OMP_CLAUSE_DECL (*sc)) != INDIRECT_REF
   11503 		 && TREE_CODE (OMP_CLAUSE_DECL (*sc)) != ARRAY_REF)
   11504 	  break;
   11505 	else
   11506 	  {
   11507 	    tree sc_decl = OMP_CLAUSE_DECL (*sc);
   11508 	    poly_offset_int offset;
   11509 	    poly_int64 bitpos;
   11510 
   11511 	    if (TREE_CODE (sc_decl) == ARRAY_REF)
   11512 	      {
   11513 		while (TREE_CODE (sc_decl) == ARRAY_REF)
   11514 		  sc_decl = TREE_OPERAND (sc_decl, 0);
   11515 		if (TREE_CODE (sc_decl) != COMPONENT_REF
   11516 		    || TREE_CODE (TREE_TYPE (sc_decl)) != ARRAY_TYPE)
   11517 		  break;
   11518 	      }
   11519 	    else if (INDIRECT_REF_P (sc_decl)
   11520 		     && TREE_CODE (TREE_OPERAND (sc_decl, 0)) == COMPONENT_REF
   11521 		     && (TREE_CODE (TREE_TYPE (TREE_OPERAND (sc_decl, 0)))
   11522 			 == REFERENCE_TYPE))
   11523 	      sc_decl = TREE_OPERAND (sc_decl, 0);
   11524 
   11525 	    bool variable_offset2;
   11526 	    tree base2 = extract_base_bit_offset (sc_decl, &bitpos, &offset,
   11527 						  &variable_offset2);
   11528 	    if (!base2 || !operand_equal_p (base2, base, 0))
   11529 	      break;
   11530 	    if (scp)
   11531 	      continue;
   11532 	    if (variable_offset2)
   11533 	      {
   11534 		OMP_CLAUSE_SET_MAP_KIND (*osc, GOMP_MAP_STRUCT_UNORD);
   11535 		unordered = true;
   11536 		break;
   11537 	      }
   11538 	    else if ((region_type & ORT_ACC) != 0)
   11539 	      {
   11540 		/* For OpenACC, allow (ignore) duplicate struct accesses in
   11541 		   the middle of a mapping clause, e.g. "mystruct->foo" in:
   11542 		   copy(mystruct->foo->bar) copy(mystruct->foo->qux).  */
   11543 		if (reprocessing_struct
   11544 		    && known_eq (coffset, offset)
   11545 		    && known_eq (cbitpos, bitpos))
   11546 		  return NULL;
   11547 	      }
   11548 	    else if (known_eq (coffset, offset)
   11549 		     && known_eq (cbitpos, bitpos))
   11550 	      {
   11551 		/* Having two struct members at the same offset doesn't work,
   11552 		   so make sure we don't.  (We're allowed to ignore this.
   11553 		   Should we report the error?)  */
   11554 		/*error_at (OMP_CLAUSE_LOCATION (grp_end),
   11555 			  "duplicate struct member %qE in map clauses",
   11556 			  OMP_CLAUSE_DECL (grp_end));*/
   11557 		return NULL;
   11558 	      }
   11559 	    if (maybe_lt (coffset, offset)
   11560 		|| (known_eq (coffset, offset)
   11561 		    && maybe_lt (cbitpos, bitpos)))
   11562 	      {
   11563 		if (attach_detach)
   11564 		  scp = sc;
   11565 		else
   11566 		  break;
   11567 	      }
   11568 	  }
   11569 
   11570       /* If this is an unordered struct, just insert the new element at the
   11571 	 end of the list.  */
   11572       if (unordered)
   11573 	{
   11574 	  for (; i < elems; i++)
   11575 	    sc = &OMP_CLAUSE_CHAIN (*sc);
   11576 	  scp = NULL;
   11577 	}
   11578 
   11579       OMP_CLAUSE_SIZE (*osc)
   11580 	= size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc), size_one_node);
   11581 
   11582       if (reprocessing_struct)
   11583 	{
   11584 	  /* If we're reprocessing a struct node, we don't want to do most of
   11585 	     the list manipulation below.  We only need to handle the (pointer
   11586 	     or reference) attach/detach case.  */
   11587 	  tree extra_node, alloc_node;
   11588 	  if (has_descriptor)
   11589 	    gcc_unreachable ();
   11590 	  else if (attach_detach)
   11591 	    alloc_node = build_omp_struct_comp_nodes (code, *grp_start_p,
   11592 						      grp_end, &extra_node);
   11593 	  else
   11594 	    {
   11595 	      /* If we don't have an attach/detach node, this is a
   11596 		 "target data" directive or similar, not an offload region.
   11597 		 Synthesize an "alloc" node using just the initiating
   11598 		 GOMP_MAP_STRUCT decl.  */
   11599 	      gomp_map_kind k = (code == OMP_TARGET_EXIT_DATA
   11600 				 || code == OACC_EXIT_DATA)
   11601 				? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
   11602 	      alloc_node
   11603 		= build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
   11604 				    OMP_CLAUSE_MAP);
   11605 	      OMP_CLAUSE_SET_MAP_KIND (alloc_node, k);
   11606 	      OMP_CLAUSE_DECL (alloc_node) = unshare_expr (last_token->expr);
   11607 	      OMP_CLAUSE_SIZE (alloc_node)
   11608 		= TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (alloc_node)));
   11609 	    }
   11610 
   11611 	  if (scp)
   11612 	    omp_siblist_insert_node_after (alloc_node, scp);
   11613 	  else
   11614 	    {
   11615 	      tree *new_end = omp_siblist_insert_node_after (alloc_node, sc);
   11616 	      if (sc == *added_tail)
   11617 		*added_tail = new_end;
   11618 	    }
   11619 
   11620 	  return NULL;
   11621 	}
   11622 
   11623       if (has_descriptor)
   11624 	{
   11625 	  tree desc = OMP_CLAUSE_CHAIN (*grp_start_p);
   11626 	  if (code == OMP_TARGET_EXIT_DATA
   11627 	      || code == OACC_EXIT_DATA)
   11628 	    OMP_CLAUSE_SET_MAP_KIND (desc, GOMP_MAP_RELEASE);
   11629 	  omp_siblist_move_node_after (desc,
   11630 				       &OMP_CLAUSE_CHAIN (*grp_start_p),
   11631 				       scp ? scp : sc);
   11632 	}
   11633       else if (attach_detach)
   11634 	{
   11635 	  tree cl = NULL_TREE, extra_node;
   11636 	  tree alloc_node = build_omp_struct_comp_nodes (code, *grp_start_p,
   11637 							 grp_end, &extra_node);
   11638 	  tree *tail_chain = NULL;
   11639 
   11640 	  if (*fragile_p
   11641 	      || (openmp
   11642 		  && !target
   11643 		  && attach_detach
   11644 		  && TREE_CODE (TREE_TYPE (ocd)) == POINTER_TYPE
   11645 		  && !OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end)))
   11646 	    {
   11647 	      if (!lang_GNU_Fortran ())
   11648 		OMP_CLAUSE_SIZE (alloc_node) = size_zero_node;
   11649 	      OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (alloc_node) = 1;
   11650 	    }
   11651 
   11652 	  /* Here, we have:
   11653 
   11654 	     grp_end : the last (or only) node in this group.
   11655 	     grp_start_p : pointer to the first node in a pointer mapping group
   11656 			   up to and including GRP_END.
   11657 	     sc : pointer to the chain for the end of the struct component
   11658 		  list.
   11659 	     scp : pointer to the chain for the sorted position at which we
   11660 		   should insert in the middle of the struct component list
   11661 		   (else NULL to insert at end).
   11662 	     alloc_node : the "alloc" node for the structure (pointer-type)
   11663 			  component. We insert at SCP (if present), else SC
   11664 			  (the end of the struct component list).
   11665 	     extra_node : a newly-synthesized node for an additional indirect
   11666 			  pointer mapping or a Fortran pointer set, if needed.
   11667 	     cl : first node to prepend before grp_start_p.
   11668 	     tail_chain : pointer to chain of last prepended node.
   11669 
   11670 	     The general idea is we move the nodes for this struct mapping
   11671 	     together: the alloc node goes into the sorted list directly after
   11672 	     the struct mapping, and any extra nodes (together with the nodes
   11673 	     mapping arrays pointed to by struct components) get moved after
   11674 	     that list.  When SCP is NULL, we insert the nodes at SC, i.e. at
   11675 	     the end of the struct component mapping list.  It's important that
   11676 	     the alloc_node comes first in that case because it's part of the
   11677 	     sorted component mapping list (but subsequent nodes are not!).  */
   11678 
   11679 	  if (scp)
   11680 	    omp_siblist_insert_node_after (alloc_node, scp);
   11681 
   11682 	  /* Make [cl,tail_chain] a list of the alloc node (if we haven't
   11683 	     already inserted it) and the extra_node (if it is present).  The
   11684 	     list can be empty if we added alloc_node above and there is no
   11685 	     extra node.  */
   11686 	  if (scp && extra_node)
   11687 	    {
   11688 	      cl = extra_node;
   11689 	      tail_chain = &OMP_CLAUSE_CHAIN (extra_node);
   11690 	    }
   11691 	  else if (extra_node)
   11692 	    {
   11693 	      OMP_CLAUSE_CHAIN (alloc_node) = extra_node;
   11694 	      cl = alloc_node;
   11695 	      tail_chain = &OMP_CLAUSE_CHAIN (extra_node);
   11696 	    }
   11697 	  else if (!scp)
   11698 	    {
   11699 	      cl = alloc_node;
   11700 	      tail_chain = &OMP_CLAUSE_CHAIN (alloc_node);
   11701 	    }
   11702 
   11703 	  continue_at
   11704 	    = cl ? omp_siblist_move_concat_nodes_after (cl, tail_chain,
   11705 							grp_start_p, grp_end,
   11706 							sc)
   11707 		 : omp_siblist_move_nodes_after (grp_start_p, grp_end, sc);
   11708 	}
   11709       else if (*sc != grp_end)
   11710 	{
   11711 	  gcc_assert (*grp_start_p == grp_end);
   11712 
   11713 	  /* We are moving the current node back to a previous struct node:
   11714 	     the node that used to point to the current node will now point to
   11715 	     the next node.  */
   11716 	  continue_at = grp_start_p;
   11717 	  /* In the non-pointer case, the mapping clause itself is moved into
   11718 	     the correct position in the struct component list, which in this
   11719 	     case is just SC.  */
   11720 	  omp_siblist_move_node_after (*grp_start_p, grp_start_p, sc);
   11721 	}
   11722     }
   11723   return continue_at;
   11724 }
   11725 
   11726 /* Scan through GROUPS, and create sorted structure sibling lists without
   11727    gimplifying.  */
   11728 
   11729 static bool
   11730 omp_build_struct_sibling_lists (enum tree_code code,
   11731 				enum omp_region_type region_type,
   11732 				vec<omp_mapping_group> *groups,
   11733 				hash_map<tree_operand_hash_no_se,
   11734 					 omp_mapping_group *> **grpmap,
   11735 				tree *list_p)
   11736 {
   11737   using namespace omp_addr_tokenizer;
   11738   unsigned i;
   11739   omp_mapping_group *grp;
   11740   hash_map<tree_operand_hash, tree> *struct_map_to_clause = NULL;
   11741   bool success = true;
   11742   tree *new_next = NULL;
   11743   tree *tail = &OMP_CLAUSE_CHAIN ((*groups)[groups->length () - 1].grp_end);
   11744   tree added_nodes = NULL_TREE;
   11745   tree *added_tail = &added_nodes;
   11746   auto_vec<omp_mapping_group> pre_hwm_groups;
   11747 
   11748   FOR_EACH_VEC_ELT (*groups, i, grp)
   11749     {
   11750       tree c = grp->grp_end;
   11751       tree decl = OMP_CLAUSE_DECL (c);
   11752       tree grp_end = grp->grp_end;
   11753       auto_vec<omp_addr_token *> addr_tokens;
   11754       tree sentinel = OMP_CLAUSE_CHAIN (grp_end);
   11755 
   11756       if (new_next && !grp->reprocess_struct)
   11757 	grp->grp_start = new_next;
   11758 
   11759       new_next = NULL;
   11760 
   11761       tree *grp_start_p = grp->grp_start;
   11762 
   11763       if (DECL_P (decl))
   11764 	continue;
   11765 
   11766       /* Skip groups we marked for deletion in
   11767 	 {omp,oacc}_resolve_clause_dependencies.  */
   11768       if (grp->deleted)
   11769 	continue;
   11770 
   11771       if (OMP_CLAUSE_CHAIN (*grp_start_p)
   11772 	  && OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end)
   11773 	{
   11774 	  /* Don't process an array descriptor that isn't inside a derived type
   11775 	     as a struct (the GOMP_MAP_POINTER following will have the form
   11776 	     "var.data", but such mappings are handled specially).  */
   11777 	  tree grpmid = OMP_CLAUSE_CHAIN (*grp_start_p);
   11778 	  if (omp_map_clause_descriptor_p (grpmid)
   11779 	      && DECL_P (OMP_CLAUSE_DECL (grpmid)))
   11780 	    continue;
   11781 	}
   11782 
   11783       tree expr = decl;
   11784 
   11785       while (TREE_CODE (expr) == ARRAY_REF)
   11786 	expr = TREE_OPERAND (expr, 0);
   11787 
   11788       if (!omp_parse_expr (addr_tokens, expr))
   11789 	continue;
   11790 
   11791       omp_addr_token *last_token
   11792 	= omp_first_chained_access_token (addr_tokens);
   11793 
   11794       /* A mapping of a reference to a pointer member that doesn't specify an
   11795 	 array section, etc., like this:
   11796 	   *mystruct.ref_to_ptr
   11797 	 should not be processed by the struct sibling-list handling code --
   11798 	 it just transfers the referenced pointer.
   11799 
   11800 	 In contrast, the quite similar-looking construct:
   11801 	   *mystruct.ptr
   11802 	 which is equivalent to e.g.
   11803 	   mystruct.ptr[0]
   11804 	 *does* trigger sibling-list processing.
   11805 
   11806 	 An exception for the former case is for "fragile" groups where the
   11807 	 reference itself is not handled otherwise; this is subject to special
   11808 	 handling in omp_accumulate_sibling_list also.  */
   11809 
   11810       if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
   11811 	  && last_token->type == ACCESS_METHOD
   11812 	  && last_token->u.access_kind == ACCESS_REF
   11813 	  && !grp->fragile)
   11814 	continue;
   11815 
   11816       tree d = decl;
   11817       if (TREE_CODE (d) == ARRAY_REF)
   11818 	{
   11819 	  while (TREE_CODE (d) == ARRAY_REF)
   11820 	    d = TREE_OPERAND (d, 0);
   11821 	  if (TREE_CODE (d) == COMPONENT_REF
   11822 	      && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
   11823 	    decl = d;
   11824 	}
   11825       if (d == decl
   11826 	  && INDIRECT_REF_P (decl)
   11827 	  && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
   11828 	  && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
   11829 	      == REFERENCE_TYPE)
   11830 	  && (OMP_CLAUSE_MAP_KIND (c)
   11831 	      != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
   11832 	decl = TREE_OPERAND (decl, 0);
   11833 
   11834       STRIP_NOPS (decl);
   11835 
   11836       if (TREE_CODE (decl) != COMPONENT_REF)
   11837 	continue;
   11838 
   11839       /* If we're mapping the whole struct in another node, skip adding this
   11840 	 node to a sibling list.  */
   11841       omp_mapping_group *wholestruct;
   11842       if (omp_mapped_by_containing_struct (*grpmap, OMP_CLAUSE_DECL (c),
   11843 					   &wholestruct))
   11844 	continue;
   11845 
   11846       if (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
   11847 	  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
   11848 	  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
   11849 	  && code != OACC_UPDATE
   11850 	  && code != OMP_TARGET_UPDATE)
   11851 	{
   11852 	  if (error_operand_p (decl))
   11853 	    {
   11854 	      success = false;
   11855 	      goto error_out;
   11856 	    }
   11857 
   11858 	  tree stype = TREE_TYPE (decl);
   11859 	  if (TREE_CODE (stype) == REFERENCE_TYPE)
   11860 	    stype = TREE_TYPE (stype);
   11861 	  if (TYPE_SIZE_UNIT (stype) == NULL
   11862 	      || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
   11863 	    {
   11864 	      error_at (OMP_CLAUSE_LOCATION (c),
   11865 			"mapping field %qE of variable length "
   11866 			"structure", OMP_CLAUSE_DECL (c));
   11867 	      success = false;
   11868 	      goto error_out;
   11869 	    }
   11870 
   11871 	  tree *inner = NULL;
   11872 	  bool fragile_p = grp->fragile;
   11873 
   11874 	  new_next
   11875 	    = omp_accumulate_sibling_list (region_type, code,
   11876 					   struct_map_to_clause, *grpmap,
   11877 					   grp_start_p, grp_end, addr_tokens,
   11878 					   &inner, &fragile_p,
   11879 					   grp->reprocess_struct, &added_tail);
   11880 
   11881 	  if (inner)
   11882 	    {
   11883 	      omp_mapping_group newgrp;
   11884 	      newgrp.grp_start = inner;
   11885 	      if (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (*inner))
   11886 		  == GOMP_MAP_ATTACH_DETACH)
   11887 		newgrp.grp_end = OMP_CLAUSE_CHAIN (*inner);
   11888 	      else
   11889 		newgrp.grp_end = *inner;
   11890 	      newgrp.mark = UNVISITED;
   11891 	      newgrp.sibling = NULL;
   11892 	      newgrp.deleted = false;
   11893 	      newgrp.reprocess_struct = true;
   11894 	      newgrp.fragile = fragile_p;
   11895 	      newgrp.next = NULL;
   11896 	      groups->safe_push (newgrp);
   11897 
   11898 	      /* !!! Growing GROUPS might invalidate the pointers in the group
   11899 		 map.  Rebuild it here.  This is a bit inefficient, but
   11900 		 shouldn't happen very often.  */
   11901 	      delete (*grpmap);
   11902 	      *grpmap
   11903 		= omp_reindex_mapping_groups (list_p, groups, &pre_hwm_groups,
   11904 					      sentinel);
   11905 	    }
   11906 	}
   11907     }
   11908 
   11909   /* Delete groups marked for deletion above.  At this point the order of the
   11910      groups may no longer correspond to the order of the underlying list,
   11911      which complicates this a little.  First clear out OMP_CLAUSE_DECL for
   11912      deleted nodes...  */
   11913 
   11914   FOR_EACH_VEC_ELT (*groups, i, grp)
   11915     if (grp->deleted)
   11916       for (tree d = *grp->grp_start;
   11917 	   d != OMP_CLAUSE_CHAIN (grp->grp_end);
   11918 	   d = OMP_CLAUSE_CHAIN (d))
   11919 	OMP_CLAUSE_DECL (d) = NULL_TREE;
   11920 
   11921   /* ...then sweep through the list removing the now-empty nodes.  */
   11922 
   11923   tail = list_p;
   11924   while (*tail)
   11925     {
   11926       if (OMP_CLAUSE_CODE (*tail) == OMP_CLAUSE_MAP
   11927 	  && OMP_CLAUSE_DECL (*tail) == NULL_TREE)
   11928 	*tail = OMP_CLAUSE_CHAIN (*tail);
   11929       else
   11930 	tail = &OMP_CLAUSE_CHAIN (*tail);
   11931     }
   11932 
   11933   /* Tack on the struct nodes added during nested struct reprocessing.  */
   11934   if (added_nodes)
   11935     {
   11936       *tail = added_nodes;
   11937       tail = added_tail;
   11938     }
   11939 
   11940   /* Now we have finished building the struct sibling lists, reprocess
   11941      newly-added "attach" nodes: we need the address of the first
   11942      mapped element of each struct sibling list for the bias of the attach
   11943      operation -- not necessarily the base address of the whole struct.  */
   11944   if (struct_map_to_clause)
   11945     for (hash_map<tree_operand_hash, tree>::iterator iter
   11946 	   = struct_map_to_clause->begin ();
   11947 	 iter != struct_map_to_clause->end ();
   11948 	 ++iter)
   11949       {
   11950 	tree struct_node = (*iter).second;
   11951 	gcc_assert (OMP_CLAUSE_CODE (struct_node) == OMP_CLAUSE_MAP);
   11952 	tree attach = OMP_CLAUSE_CHAIN (struct_node);
   11953 
   11954 	if (OMP_CLAUSE_CODE (attach) != OMP_CLAUSE_MAP
   11955 	    || OMP_CLAUSE_MAP_KIND (attach) != GOMP_MAP_ATTACH_DETACH)
   11956 	  continue;
   11957 
   11958 	OMP_CLAUSE_SET_MAP_KIND (attach, GOMP_MAP_ATTACH);
   11959 
   11960 	/* Sanity check: the standalone attach node will not work if we have
   11961 	   an "enter data" operation (because for those, variables need to be
   11962 	   mapped separately and attach nodes must be grouped together with the
   11963 	   base they attach to).  We should only have created the
   11964 	   ATTACH_DETACH node after GOMP_MAP_STRUCT for a target region, so
   11965 	   this should never be true.  */
   11966 	gcc_assert ((region_type & ORT_TARGET) != 0);
   11967 
   11968 	/* This is the first sorted node in the struct sibling list.  Use it
   11969 	   to recalculate the correct bias to use.
   11970 	   (&first_node - attach_decl).
   11971 	   For GOMP_MAP_STRUCT_UNORD, we need e.g. the
   11972 	   min(min(min(first,second),third),fourth) element, because the
   11973 	   elements aren't in any particular order.  */
   11974 	tree lowest_addr;
   11975 	if (OMP_CLAUSE_MAP_KIND (struct_node) == GOMP_MAP_STRUCT_UNORD)
   11976 	  {
   11977 	    tree first_node = OMP_CLAUSE_CHAIN (attach);
   11978 	    unsigned HOST_WIDE_INT num_mappings
   11979 	      = tree_to_uhwi (OMP_CLAUSE_SIZE (struct_node));
   11980 	    lowest_addr = OMP_CLAUSE_DECL (first_node);
   11981 	    lowest_addr = build_fold_addr_expr (lowest_addr);
   11982 	    lowest_addr = fold_convert (pointer_sized_int_node, lowest_addr);
   11983 	    tree next_node = OMP_CLAUSE_CHAIN (first_node);
   11984 	    while (num_mappings > 1)
   11985 	      {
   11986 		tree tmp = OMP_CLAUSE_DECL (next_node);
   11987 		tmp = build_fold_addr_expr (tmp);
   11988 		tmp = fold_convert (pointer_sized_int_node, tmp);
   11989 		lowest_addr = fold_build2 (MIN_EXPR, pointer_sized_int_node,
   11990 					   lowest_addr, tmp);
   11991 		next_node = OMP_CLAUSE_CHAIN (next_node);
   11992 		num_mappings--;
   11993 	      }
   11994 	    lowest_addr = fold_convert (ptrdiff_type_node, lowest_addr);
   11995 	  }
   11996 	else
   11997 	  {
   11998 	    tree first_node = OMP_CLAUSE_DECL (OMP_CLAUSE_CHAIN (attach));
   11999 	    first_node = build_fold_addr_expr (first_node);
   12000 	    lowest_addr = fold_convert (ptrdiff_type_node, first_node);
   12001 	  }
   12002 	tree attach_decl = OMP_CLAUSE_DECL (attach);
   12003 	attach_decl = fold_convert (ptrdiff_type_node, attach_decl);
   12004 	OMP_CLAUSE_SIZE (attach)
   12005 	  = fold_build2 (MINUS_EXPR, ptrdiff_type_node, lowest_addr,
   12006 			 attach_decl);
   12007 
   12008 	/* Remove GOMP_MAP_ATTACH node from after struct node.  */
   12009 	OMP_CLAUSE_CHAIN (struct_node) = OMP_CLAUSE_CHAIN (attach);
   12010 	/* ...and re-insert it at the end of our clause list.  */
   12011 	*tail = attach;
   12012 	OMP_CLAUSE_CHAIN (attach) = NULL_TREE;
   12013 	tail = &OMP_CLAUSE_CHAIN (attach);
   12014       }
   12015 
   12016 error_out:
   12017   if (struct_map_to_clause)
   12018     delete struct_map_to_clause;
   12019 
   12020   return success;
   12021 }
   12022 
   12023 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
   12024    and previous omp contexts.  */
   12025 
   12026 static void
   12027 gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
   12028 			   enum omp_region_type region_type,
   12029 			   enum tree_code code)
   12030 {
   12031   using namespace omp_addr_tokenizer;
   12032   struct gimplify_omp_ctx *ctx, *outer_ctx;
   12033   tree c;
   12034   tree *orig_list_p = list_p;
   12035   int handled_depend_iterators = -1;
   12036   int nowait = -1;
   12037 
   12038   ctx = new_omp_context (region_type);
   12039   ctx->code = code;
   12040   outer_ctx = ctx->outer_context;
   12041   if (code == OMP_TARGET)
   12042     {
   12043       if (!lang_GNU_Fortran ())
   12044 	ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
   12045       ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
   12046       ctx->defaultmap[GDMK_SCALAR_TARGET] = (lang_GNU_Fortran ()
   12047 					     ? GOVD_MAP : GOVD_FIRSTPRIVATE);
   12048     }
   12049   if (!lang_GNU_Fortran ())
   12050     switch (code)
   12051       {
   12052       case OMP_TARGET:
   12053       case OMP_TARGET_DATA:
   12054       case OMP_TARGET_ENTER_DATA:
   12055       case OMP_TARGET_EXIT_DATA:
   12056       case OACC_DECLARE:
   12057       case OACC_HOST_DATA:
   12058       case OACC_PARALLEL:
   12059       case OACC_KERNELS:
   12060 	ctx->target_firstprivatize_array_bases = true;
   12061       default:
   12062 	break;
   12063       }
   12064 
   12065   vec<omp_mapping_group> *groups = NULL;
   12066   hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap = NULL;
   12067   unsigned grpnum = 0;
   12068   tree *grp_start_p = NULL, grp_end = NULL_TREE;
   12069 
   12070   if (code == OMP_TARGET
   12071       || code == OMP_TARGET_DATA
   12072       || code == OMP_TARGET_ENTER_DATA
   12073       || code == OMP_TARGET_EXIT_DATA
   12074       || code == OACC_DATA
   12075       || code == OACC_KERNELS
   12076       || code == OACC_PARALLEL
   12077       || code == OACC_SERIAL
   12078       || code == OACC_ENTER_DATA
   12079       || code == OACC_EXIT_DATA
   12080       || code == OACC_UPDATE
   12081       || code == OACC_DECLARE)
   12082     {
   12083       groups = omp_gather_mapping_groups (list_p);
   12084 
   12085       if (groups)
   12086 	grpmap = omp_index_mapping_groups (groups);
   12087     }
   12088 
   12089   while ((c = *list_p) != NULL)
   12090     {
   12091       bool remove = false;
   12092       bool notice_outer = true;
   12093       bool map_descriptor;
   12094       const char *check_non_private = NULL;
   12095       unsigned int flags;
   12096       tree decl;
   12097       auto_vec<omp_addr_token *, 10> addr_tokens;
   12098 
   12099       if (grp_end && c == OMP_CLAUSE_CHAIN (grp_end))
   12100 	{
   12101 	  grp_start_p = NULL;
   12102 	  grp_end = NULL_TREE;
   12103 	}
   12104 
   12105       switch (OMP_CLAUSE_CODE (c))
   12106 	{
   12107 	case OMP_CLAUSE_PRIVATE:
   12108 	  flags = GOVD_PRIVATE | GOVD_EXPLICIT;
   12109 	  if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
   12110 	    {
   12111 	      flags |= GOVD_PRIVATE_OUTER_REF;
   12112 	      OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
   12113 	    }
   12114 	  else
   12115 	    notice_outer = false;
   12116 	  goto do_add;
   12117 	case OMP_CLAUSE_SHARED:
   12118 	  flags = GOVD_SHARED | GOVD_EXPLICIT;
   12119 	  goto do_add;
   12120 	case OMP_CLAUSE_FIRSTPRIVATE:
   12121 	  flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
   12122 	  check_non_private = "firstprivate";
   12123 	  if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
   12124 	    {
   12125 	      gcc_assert (code == OMP_TARGET);
   12126 	      flags |= GOVD_FIRSTPRIVATE_IMPLICIT;
   12127 	    }
   12128 	  goto do_add;
   12129 	case OMP_CLAUSE_LASTPRIVATE:
   12130 	  if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   12131 	    switch (code)
   12132 	      {
   12133 	      case OMP_DISTRIBUTE:
   12134 		error_at (OMP_CLAUSE_LOCATION (c),
   12135 			  "conditional %<lastprivate%> clause on "
   12136 			  "%qs construct", "distribute");
   12137 		OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
   12138 		break;
   12139 	      case OMP_TASKLOOP:
   12140 		error_at (OMP_CLAUSE_LOCATION (c),
   12141 			  "conditional %<lastprivate%> clause on "
   12142 			  "%qs construct", "taskloop");
   12143 		OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
   12144 		break;
   12145 	      default:
   12146 		break;
   12147 	      }
   12148 	  flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
   12149 	  if (code != OMP_LOOP)
   12150 	    check_non_private = "lastprivate";
   12151 	  decl = OMP_CLAUSE_DECL (c);
   12152 	  if (error_operand_p (decl))
   12153 	    goto do_add;
   12154 	  if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
   12155 	      && !lang_hooks.decls.omp_scalar_p (decl, true))
   12156 	    {
   12157 	      error_at (OMP_CLAUSE_LOCATION (c),
   12158 			"non-scalar variable %qD in conditional "
   12159 			"%<lastprivate%> clause", decl);
   12160 	      OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
   12161 	    }
   12162 	  if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   12163 	    flags |= GOVD_LASTPRIVATE_CONDITIONAL;
   12164 	  omp_lastprivate_for_combined_outer_constructs (outer_ctx, decl,
   12165 							 false);
   12166 	  goto do_add;
   12167 	case OMP_CLAUSE_REDUCTION:
   12168 	  if (OMP_CLAUSE_REDUCTION_TASK (c))
   12169 	    {
   12170 	      if (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
   12171 		{
   12172 		  if (nowait == -1)
   12173 		    nowait = omp_find_clause (*list_p,
   12174 					      OMP_CLAUSE_NOWAIT) != NULL_TREE;
   12175 		  if (nowait
   12176 		      && (outer_ctx == NULL
   12177 			  || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
   12178 		    {
   12179 		      error_at (OMP_CLAUSE_LOCATION (c),
   12180 				"%<task%> reduction modifier on a construct "
   12181 				"with a %<nowait%> clause");
   12182 		      OMP_CLAUSE_REDUCTION_TASK (c) = 0;
   12183 		    }
   12184 		}
   12185 	      else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
   12186 		{
   12187 		  error_at (OMP_CLAUSE_LOCATION (c),
   12188 			    "invalid %<task%> reduction modifier on construct "
   12189 			    "other than %<parallel%>, %qs, %<sections%> or "
   12190 			    "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
   12191 		  OMP_CLAUSE_REDUCTION_TASK (c) = 0;
   12192 		}
   12193 	    }
   12194 	  if (OMP_CLAUSE_REDUCTION_INSCAN (c))
   12195 	    switch (code)
   12196 	      {
   12197 	      case OMP_SECTIONS:
   12198 		error_at (OMP_CLAUSE_LOCATION (c),
   12199 			  "%<inscan%> %<reduction%> clause on "
   12200 			  "%qs construct", "sections");
   12201 		OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   12202 		break;
   12203 	      case OMP_PARALLEL:
   12204 		error_at (OMP_CLAUSE_LOCATION (c),
   12205 			  "%<inscan%> %<reduction%> clause on "
   12206 			  "%qs construct", "parallel");
   12207 		OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   12208 		break;
   12209 	      case OMP_TEAMS:
   12210 		error_at (OMP_CLAUSE_LOCATION (c),
   12211 			  "%<inscan%> %<reduction%> clause on "
   12212 			  "%qs construct", "teams");
   12213 		OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   12214 		break;
   12215 	      case OMP_TASKLOOP:
   12216 		error_at (OMP_CLAUSE_LOCATION (c),
   12217 			  "%<inscan%> %<reduction%> clause on "
   12218 			  "%qs construct", "taskloop");
   12219 		OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   12220 		break;
   12221 	      case OMP_SCOPE:
   12222 		error_at (OMP_CLAUSE_LOCATION (c),
   12223 			  "%<inscan%> %<reduction%> clause on "
   12224 			  "%qs construct", "scope");
   12225 		OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   12226 		break;
   12227 	      default:
   12228 		break;
   12229 	      }
   12230 	  /* FALLTHRU */
   12231 	case OMP_CLAUSE_IN_REDUCTION:
   12232 	case OMP_CLAUSE_TASK_REDUCTION:
   12233 	  flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
   12234 	  /* OpenACC permits reductions on private variables.  */
   12235 	  if (!(region_type & ORT_ACC)
   12236 	      /* taskgroup is actually not a worksharing region.  */
   12237 	      && code != OMP_TASKGROUP)
   12238 	    check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
   12239 	  decl = OMP_CLAUSE_DECL (c);
   12240 	  if (TREE_CODE (decl) == MEM_REF)
   12241 	    {
   12242 	      tree type = TREE_TYPE (decl);
   12243 	      bool saved_into_ssa = gimplify_ctxp->into_ssa;
   12244 	      gimplify_ctxp->into_ssa = false;
   12245 	      if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
   12246 				 NULL, is_gimple_val, fb_rvalue, false)
   12247 		  == GS_ERROR)
   12248 		{
   12249 		  gimplify_ctxp->into_ssa = saved_into_ssa;
   12250 		  remove = true;
   12251 		  break;
   12252 		}
   12253 	      gimplify_ctxp->into_ssa = saved_into_ssa;
   12254 	      tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
   12255 	      if (DECL_P (v))
   12256 		{
   12257 		  omp_firstprivatize_variable (ctx, v);
   12258 		  omp_notice_variable (ctx, v, true);
   12259 		}
   12260 	      decl = TREE_OPERAND (decl, 0);
   12261 	      if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
   12262 		{
   12263 		  gimplify_ctxp->into_ssa = false;
   12264 		  if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
   12265 				     NULL, is_gimple_val, fb_rvalue, false)
   12266 		      == GS_ERROR)
   12267 		    {
   12268 		      gimplify_ctxp->into_ssa = saved_into_ssa;
   12269 		      remove = true;
   12270 		      break;
   12271 		    }
   12272 		  gimplify_ctxp->into_ssa = saved_into_ssa;
   12273 		  v = TREE_OPERAND (decl, 1);
   12274 		  if (DECL_P (v))
   12275 		    {
   12276 		      omp_firstprivatize_variable (ctx, v);
   12277 		      omp_notice_variable (ctx, v, true);
   12278 		    }
   12279 		  decl = TREE_OPERAND (decl, 0);
   12280 		}
   12281 	      if (TREE_CODE (decl) == ADDR_EXPR
   12282 		  || TREE_CODE (decl) == INDIRECT_REF)
   12283 		decl = TREE_OPERAND (decl, 0);
   12284 	    }
   12285 	  goto do_add_decl;
   12286 	case OMP_CLAUSE_LINEAR:
   12287 	  if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
   12288 			     is_gimple_val, fb_rvalue) == GS_ERROR)
   12289 	    {
   12290 	      remove = true;
   12291 	      break;
   12292 	    }
   12293 	  else
   12294 	    {
   12295 	      if (code == OMP_SIMD
   12296 		  && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
   12297 		{
   12298 		  struct gimplify_omp_ctx *octx = outer_ctx;
   12299 		  if (octx
   12300 		      && octx->region_type == ORT_WORKSHARE
   12301 		      && octx->combined_loop
   12302 		      && !octx->distribute)
   12303 		    {
   12304 		      if (octx->outer_context
   12305 			  && (octx->outer_context->region_type
   12306 			      == ORT_COMBINED_PARALLEL))
   12307 			octx = octx->outer_context->outer_context;
   12308 		      else
   12309 			octx = octx->outer_context;
   12310 		    }
   12311 		  if (octx
   12312 		      && octx->region_type == ORT_WORKSHARE
   12313 		      && octx->combined_loop
   12314 		      && octx->distribute)
   12315 		    {
   12316 		      error_at (OMP_CLAUSE_LOCATION (c),
   12317 				"%<linear%> clause for variable other than "
   12318 				"loop iterator specified on construct "
   12319 				"combined with %<distribute%>");
   12320 		      remove = true;
   12321 		      break;
   12322 		    }
   12323 		}
   12324 	      /* For combined #pragma omp parallel for simd, need to put
   12325 		 lastprivate and perhaps firstprivate too on the
   12326 		 parallel.  Similarly for #pragma omp for simd.  */
   12327 	      struct gimplify_omp_ctx *octx = outer_ctx;
   12328 	      bool taskloop_seen = false;
   12329 	      decl = NULL_TREE;
   12330 	      do
   12331 		{
   12332 		  if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
   12333 		      && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   12334 		    break;
   12335 		  decl = OMP_CLAUSE_DECL (c);
   12336 		  if (error_operand_p (decl))
   12337 		    {
   12338 		      decl = NULL_TREE;
   12339 		      break;
   12340 		    }
   12341 		  flags = GOVD_SEEN;
   12342 		  if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
   12343 		    flags |= GOVD_FIRSTPRIVATE;
   12344 		  if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   12345 		    flags |= GOVD_LASTPRIVATE;
   12346 		  if (octx
   12347 		      && octx->region_type == ORT_WORKSHARE
   12348 		      && octx->combined_loop)
   12349 		    {
   12350 		      if (octx->outer_context
   12351 			  && (octx->outer_context->region_type
   12352 			      == ORT_COMBINED_PARALLEL))
   12353 			octx = octx->outer_context;
   12354 		      else if (omp_check_private (octx, decl, false))
   12355 			break;
   12356 		    }
   12357 		  else if (octx
   12358 			   && (octx->region_type & ORT_TASK) != 0
   12359 			   && octx->combined_loop)
   12360 		    taskloop_seen = true;
   12361 		  else if (octx
   12362 			   && octx->region_type == ORT_COMBINED_PARALLEL
   12363 			   && ((ctx->region_type == ORT_WORKSHARE
   12364 				&& octx == outer_ctx)
   12365 			       || taskloop_seen))
   12366 		    flags = GOVD_SEEN | GOVD_SHARED;
   12367 		  else if (octx
   12368 			   && ((octx->region_type & ORT_COMBINED_TEAMS)
   12369 			       == ORT_COMBINED_TEAMS))
   12370 		    flags = GOVD_SEEN | GOVD_SHARED;
   12371 		  else if (octx
   12372 			   && octx->region_type == ORT_COMBINED_TARGET)
   12373 		    {
   12374 		      if (flags & GOVD_LASTPRIVATE)
   12375 			flags = GOVD_SEEN | GOVD_MAP;
   12376 		    }
   12377 		  else
   12378 		    break;
   12379 		  splay_tree_node on
   12380 		    = splay_tree_lookup (octx->variables,
   12381 					 (splay_tree_key) decl);
   12382 		  if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
   12383 		    {
   12384 		      octx = NULL;
   12385 		      break;
   12386 		    }
   12387 		  omp_add_variable (octx, decl, flags);
   12388 		  if (octx->outer_context == NULL)
   12389 		    break;
   12390 		  octx = octx->outer_context;
   12391 		}
   12392 	      while (1);
   12393 	      if (octx
   12394 		  && decl
   12395 		  && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
   12396 		      || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
   12397 		omp_notice_variable (octx, decl, true);
   12398 	    }
   12399 	  flags = GOVD_LINEAR | GOVD_EXPLICIT;
   12400 	  if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
   12401 	      && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   12402 	    {
   12403 	      notice_outer = false;
   12404 	      flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
   12405 	    }
   12406 	  goto do_add;
   12407 
   12408 	case OMP_CLAUSE_MAP:
   12409 	  if (!grp_start_p)
   12410 	    {
   12411 	      grp_start_p = list_p;
   12412 	      grp_end = (*groups)[grpnum].grp_end;
   12413 	      grpnum++;
   12414 	    }
   12415 	  decl = OMP_CLAUSE_DECL (c);
   12416 
   12417 	  if (error_operand_p (decl))
   12418 	    {
   12419 	      remove = true;
   12420 	      break;
   12421 	    }
   12422 
   12423 	  if (!omp_parse_expr (addr_tokens, decl))
   12424 	    {
   12425 	      remove = true;
   12426 	      break;
   12427 	    }
   12428 
   12429 	  if (remove)
   12430 	    break;
   12431 	  if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
   12432 	    {
   12433 	      struct gimplify_omp_ctx *octx;
   12434 	      for (octx = outer_ctx; octx; octx = octx->outer_context)
   12435 	        {
   12436 		  if (octx->region_type != ORT_ACC_HOST_DATA)
   12437 		    break;
   12438 		  splay_tree_node n2
   12439 		    = splay_tree_lookup (octx->variables,
   12440 					 (splay_tree_key) decl);
   12441 		  if (n2)
   12442 		    error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
   12443 			      "declared in enclosing %<host_data%> region",
   12444 			      DECL_NAME (decl));
   12445 		}
   12446 	    }
   12447 
   12448 	  map_descriptor = false;
   12449 
   12450 	  /* This condition checks if we're mapping an array descriptor that
   12451 	     isn't inside a derived type -- these have special handling, and
   12452 	     are not handled as structs in omp_build_struct_sibling_lists.
   12453 	     See that function for further details.  */
   12454 	  if (*grp_start_p != grp_end
   12455 	      && OMP_CLAUSE_CHAIN (*grp_start_p)
   12456 	      && OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end)
   12457 	    {
   12458 	      tree grp_mid = OMP_CLAUSE_CHAIN (*grp_start_p);
   12459 	      if (omp_map_clause_descriptor_p (grp_mid)
   12460 		  && DECL_P (OMP_CLAUSE_DECL (grp_mid)))
   12461 		map_descriptor = true;
   12462 	    }
   12463 	  else if (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP
   12464 		   && (OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_RELEASE
   12465 		       || OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_DELETE)
   12466 		   && OMP_CLAUSE_RELEASE_DESCRIPTOR (grp_end))
   12467 	    map_descriptor = true;
   12468 
   12469 	  /* Adding the decl for a struct access: we haven't created
   12470 	     GOMP_MAP_STRUCT nodes yet, so this statement needs to predict
   12471 	     whether they will be created in gimplify_adjust_omp_clauses.
   12472 	     NOTE: Technically we should probably look through DECL_VALUE_EXPR
   12473 	     here because something that looks like a DECL_P may actually be a
   12474 	     struct access, e.g. variables in a lambda closure
   12475 	     (__closure->__foo) or class members (this->foo). Currently in both
   12476 	     those cases we map the whole of the containing object (directly in
   12477 	     the C++ FE) though, so struct nodes are not created.  */
   12478 	  if (c == grp_end
   12479 	      && addr_tokens[0]->type == STRUCTURE_BASE
   12480 	      && addr_tokens[0]->u.structure_base_kind == BASE_DECL
   12481 	      && !map_descriptor)
   12482 	    {
   12483 	      gcc_assert (addr_tokens[1]->type == ACCESS_METHOD);
   12484 	      /* If we got to this struct via a chain of pointers, maybe we
   12485 		 want to map it implicitly instead.  */
   12486 	      if (omp_access_chain_p (addr_tokens, 1))
   12487 		break;
   12488 	      omp_mapping_group *wholestruct;
   12489 	      if (!(region_type & ORT_ACC)
   12490 		  && omp_mapped_by_containing_struct (grpmap,
   12491 						      OMP_CLAUSE_DECL (c),
   12492 						      &wholestruct))
   12493 		break;
   12494 	      decl = addr_tokens[1]->expr;
   12495 	      if (splay_tree_lookup (ctx->variables, (splay_tree_key) decl))
   12496 		break;
   12497 	      /* Standalone attach or detach clauses for a struct element
   12498 		 should not inhibit implicit mapping of the whole struct.  */
   12499 	      if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   12500 		  || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
   12501 		break;
   12502 	      flags = GOVD_MAP | GOVD_EXPLICIT;
   12503 
   12504 	      gcc_assert (addr_tokens[1]->u.access_kind != ACCESS_DIRECT
   12505 			  || TREE_ADDRESSABLE (decl));
   12506 	      goto do_add_decl;
   12507 	    }
   12508 
   12509 	  if (!DECL_P (decl))
   12510 	    {
   12511 	      tree d = decl, *pd;
   12512 	      if (TREE_CODE (d) == ARRAY_REF)
   12513 		{
   12514 		  while (TREE_CODE (d) == ARRAY_REF)
   12515 		    d = TREE_OPERAND (d, 0);
   12516 		  if (TREE_CODE (d) == COMPONENT_REF
   12517 		      && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
   12518 		    decl = d;
   12519 		}
   12520 	      pd = &OMP_CLAUSE_DECL (c);
   12521 	      if (d == decl
   12522 		  && TREE_CODE (decl) == INDIRECT_REF
   12523 		  && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
   12524 		  && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
   12525 		      == REFERENCE_TYPE)
   12526 		  && (OMP_CLAUSE_MAP_KIND (c)
   12527 		      != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
   12528 		{
   12529 		  pd = &TREE_OPERAND (decl, 0);
   12530 		  decl = TREE_OPERAND (decl, 0);
   12531 		}
   12532 
   12533 	      if (addr_tokens[0]->type == STRUCTURE_BASE
   12534 		  && addr_tokens[0]->u.structure_base_kind == BASE_DECL
   12535 		  && addr_tokens[1]->type == ACCESS_METHOD
   12536 		  && (addr_tokens[1]->u.access_kind == ACCESS_POINTER
   12537 		      || (addr_tokens[1]->u.access_kind
   12538 			  == ACCESS_POINTER_OFFSET))
   12539 		  && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)))
   12540 		{
   12541 		  tree base = addr_tokens[1]->expr;
   12542 		  splay_tree_node n
   12543 		    = splay_tree_lookup (ctx->variables,
   12544 					 (splay_tree_key) base);
   12545 		  n->value |= GOVD_SEEN;
   12546 		}
   12547 
   12548 	      if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
   12549 		{
   12550 		  /* Don't gimplify *pd fully at this point, as the base
   12551 		     will need to be adjusted during omp lowering.  */
   12552 		  auto_vec<tree, 10> expr_stack;
   12553 		  tree *p = pd;
   12554 		  while (handled_component_p (*p)
   12555 			 || TREE_CODE (*p) == INDIRECT_REF
   12556 			 || TREE_CODE (*p) == ADDR_EXPR
   12557 			 || TREE_CODE (*p) == MEM_REF
   12558 			 || TREE_CODE (*p) == NON_LVALUE_EXPR)
   12559 		    {
   12560 		      expr_stack.safe_push (*p);
   12561 		      p = &TREE_OPERAND (*p, 0);
   12562 		    }
   12563 		  for (int i = expr_stack.length () - 1; i >= 0; i--)
   12564 		    {
   12565 		      tree t = expr_stack[i];
   12566 		      if (TREE_CODE (t) == ARRAY_REF
   12567 			  || TREE_CODE (t) == ARRAY_RANGE_REF)
   12568 			{
   12569 			  if (TREE_OPERAND (t, 2) == NULL_TREE)
   12570 			    {
   12571 			      tree low = unshare_expr (array_ref_low_bound (t));
   12572 			      if (!is_gimple_min_invariant (low))
   12573 				{
   12574 				  TREE_OPERAND (t, 2) = low;
   12575 				  if (gimplify_expr (&TREE_OPERAND (t, 2),
   12576 						     pre_p, NULL,
   12577 						     is_gimple_reg,
   12578 						     fb_rvalue) == GS_ERROR)
   12579 				    remove = true;
   12580 				}
   12581 			    }
   12582 			  else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
   12583 						  NULL, is_gimple_reg,
   12584 						  fb_rvalue) == GS_ERROR)
   12585 			    remove = true;
   12586 			  if (TREE_OPERAND (t, 3) == NULL_TREE)
   12587 			    {
   12588 			      tree elmt_size = array_ref_element_size (t);
   12589 			      if (!is_gimple_min_invariant (elmt_size))
   12590 				{
   12591 				  elmt_size = unshare_expr (elmt_size);
   12592 				  tree elmt_type
   12593 				    = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t,
   12594 									  0)));
   12595 				  tree factor
   12596 				    = size_int (TYPE_ALIGN_UNIT (elmt_type));
   12597 				  elmt_size
   12598 				    = size_binop (EXACT_DIV_EXPR, elmt_size,
   12599 						  factor);
   12600 				  TREE_OPERAND (t, 3) = elmt_size;
   12601 				  if (gimplify_expr (&TREE_OPERAND (t, 3),
   12602 						     pre_p, NULL,
   12603 						     is_gimple_reg,
   12604 						     fb_rvalue) == GS_ERROR)
   12605 				    remove = true;
   12606 				}
   12607 			    }
   12608 			  else if (gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
   12609 						  NULL, is_gimple_reg,
   12610 						  fb_rvalue) == GS_ERROR)
   12611 			    remove = true;
   12612 			}
   12613 		      else if (TREE_CODE (t) == COMPONENT_REF)
   12614 			{
   12615 			  if (TREE_OPERAND (t, 2) == NULL_TREE)
   12616 			    {
   12617 			      tree offset = component_ref_field_offset (t);
   12618 			      if (!is_gimple_min_invariant (offset))
   12619 				{
   12620 				  offset = unshare_expr (offset);
   12621 				  tree field = TREE_OPERAND (t, 1);
   12622 				  tree factor
   12623 				    = size_int (DECL_OFFSET_ALIGN (field)
   12624 						/ BITS_PER_UNIT);
   12625 				  offset = size_binop (EXACT_DIV_EXPR, offset,
   12626 						       factor);
   12627 				  TREE_OPERAND (t, 2) = offset;
   12628 				  if (gimplify_expr (&TREE_OPERAND (t, 2),
   12629 						     pre_p, NULL,
   12630 						     is_gimple_reg,
   12631 						     fb_rvalue) == GS_ERROR)
   12632 				    remove = true;
   12633 				}
   12634 			    }
   12635 			  else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
   12636 						  NULL, is_gimple_reg,
   12637 						  fb_rvalue) == GS_ERROR)
   12638 			    remove = true;
   12639 			}
   12640 		    }
   12641 		  for (; expr_stack.length () > 0; )
   12642 		    {
   12643 		      tree t = expr_stack.pop ();
   12644 
   12645 		      if (TREE_CODE (t) == ARRAY_REF
   12646 			  || TREE_CODE (t) == ARRAY_RANGE_REF)
   12647 			{
   12648 			  if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))
   12649 			      && gimplify_expr (&TREE_OPERAND (t, 1), pre_p,
   12650 						NULL, is_gimple_val,
   12651 						fb_rvalue) == GS_ERROR)
   12652 			    remove = true;
   12653 			}
   12654 		    }
   12655 		}
   12656 	      break;
   12657 	    }
   12658 
   12659 	  if ((code == OMP_TARGET
   12660 	       || code == OMP_TARGET_DATA
   12661 	       || code == OMP_TARGET_ENTER_DATA
   12662 	       || code == OMP_TARGET_EXIT_DATA)
   12663 	      && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   12664 	    {
   12665 	      /* If we have attach/detach but the decl we have is a pointer to
   12666 		 pointer, we're probably mapping the "base level" array
   12667 		 implicitly.  Make sure we don't add the decl as if we mapped
   12668 		 it explicitly.  That is,
   12669 
   12670 		   int **arr;
   12671 		   [...]
   12672 		   #pragma omp target map(arr[a][b:c])
   12673 
   12674 		 should *not* map "arr" explicitly.  That way we get a
   12675 		 zero-length "alloc" mapping for it, and assuming it's been
   12676 		 mapped by some previous directive, etc., things work as they
   12677 		 should.  */
   12678 
   12679 	      tree basetype = TREE_TYPE (addr_tokens[0]->expr);
   12680 
   12681 	      if (TREE_CODE (basetype) == REFERENCE_TYPE)
   12682 		basetype = TREE_TYPE (basetype);
   12683 
   12684 	      if (code == OMP_TARGET
   12685 		  && addr_tokens[0]->type == ARRAY_BASE
   12686 		  && addr_tokens[0]->u.structure_base_kind == BASE_DECL
   12687 		  && TREE_CODE (basetype) == POINTER_TYPE
   12688 		  && TREE_CODE (TREE_TYPE (basetype)) == POINTER_TYPE)
   12689 		break;
   12690 	    }
   12691 
   12692 	  flags = GOVD_MAP | GOVD_EXPLICIT;
   12693 	  if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
   12694 	      || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM
   12695 	      || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_PRESENT_TO
   12696 	      || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_PRESENT_TOFROM)
   12697 	    flags |= GOVD_MAP_ALWAYS_TO;
   12698 
   12699 	  goto do_add;
   12700 
   12701 	case OMP_CLAUSE_AFFINITY:
   12702 	  gimplify_omp_affinity (list_p, pre_p);
   12703 	  remove = true;
   12704 	  break;
   12705 	case OMP_CLAUSE_DOACROSS:
   12706 	  if (OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
   12707 	    {
   12708 	      tree deps = OMP_CLAUSE_DECL (c);
   12709 	      while (deps && TREE_CODE (deps) == TREE_LIST)
   12710 		{
   12711 		  if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
   12712 		      && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
   12713 		    gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
   12714 				   pre_p, NULL, is_gimple_val, fb_rvalue);
   12715 		  deps = TREE_CHAIN (deps);
   12716 		}
   12717 	    }
   12718 	  else
   12719 	    gcc_assert (OMP_CLAUSE_DOACROSS_KIND (c)
   12720 			== OMP_CLAUSE_DOACROSS_SOURCE);
   12721 	  break;
   12722 	case OMP_CLAUSE_DEPEND:
   12723 	  if (handled_depend_iterators == -1)
   12724 	    handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
   12725 	  if (handled_depend_iterators)
   12726 	    {
   12727 	      if (handled_depend_iterators == 2)
   12728 		remove = true;
   12729 	      break;
   12730 	    }
   12731 	  if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
   12732 	    {
   12733 	      gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
   12734 			     NULL, is_gimple_val, fb_rvalue);
   12735 	      OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
   12736 	    }
   12737 	  if (error_operand_p (OMP_CLAUSE_DECL (c)))
   12738 	    {
   12739 	      remove = true;
   12740 	      break;
   12741 	    }
   12742 	  if (OMP_CLAUSE_DECL (c) != null_pointer_node)
   12743 	    {
   12744 	      OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
   12745 	      if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
   12746 				 is_gimple_val, fb_rvalue) == GS_ERROR)
   12747 		{
   12748 		  remove = true;
   12749 		  break;
   12750 		}
   12751 	    }
   12752 	  if (code == OMP_TASK)
   12753 	    ctx->has_depend = true;
   12754 	  break;
   12755 
   12756 	case OMP_CLAUSE_TO:
   12757 	case OMP_CLAUSE_FROM:
   12758 	case OMP_CLAUSE__CACHE_:
   12759 	  decl = OMP_CLAUSE_DECL (c);
   12760 	  if (error_operand_p (decl))
   12761 	    {
   12762 	      remove = true;
   12763 	      break;
   12764 	    }
   12765 	  if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
   12766 	    OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
   12767 				  : TYPE_SIZE_UNIT (TREE_TYPE (decl));
   12768 	  if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p,
   12769 			     NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
   12770 	    {
   12771 	      remove = true;
   12772 	      break;
   12773 	    }
   12774 	  if (!DECL_P (decl))
   12775 	    {
   12776 	      if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p,
   12777 				 NULL, is_gimple_lvalue, fb_lvalue)
   12778 		  == GS_ERROR)
   12779 		{
   12780 		  remove = true;
   12781 		  break;
   12782 		}
   12783 	      break;
   12784 	    }
   12785 	  goto do_notice;
   12786 
   12787 	case OMP_CLAUSE_USE_DEVICE_PTR:
   12788 	case OMP_CLAUSE_USE_DEVICE_ADDR:
   12789 	  flags = GOVD_EXPLICIT;
   12790 	  goto do_add;
   12791 
   12792 	case OMP_CLAUSE_HAS_DEVICE_ADDR:
   12793 	  decl = OMP_CLAUSE_DECL (c);
   12794 	  while (TREE_CODE (decl) == INDIRECT_REF
   12795 		 || TREE_CODE (decl) == ARRAY_REF)
   12796 	    decl = TREE_OPERAND (decl, 0);
   12797 	  flags = GOVD_EXPLICIT;
   12798 	  goto do_add_decl;
   12799 
   12800 	case OMP_CLAUSE_IS_DEVICE_PTR:
   12801 	  flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
   12802 	  goto do_add;
   12803 
   12804 	do_add:
   12805 	  decl = OMP_CLAUSE_DECL (c);
   12806 	do_add_decl:
   12807 	  if (error_operand_p (decl))
   12808 	    {
   12809 	      remove = true;
   12810 	      break;
   12811 	    }
   12812 	  if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
   12813 	    {
   12814 	      tree t = omp_member_access_dummy_var (decl);
   12815 	      if (t)
   12816 		{
   12817 		  tree v = DECL_VALUE_EXPR (decl);
   12818 		  DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
   12819 		  if (outer_ctx)
   12820 		    omp_notice_variable (outer_ctx, t, true);
   12821 		}
   12822 	    }
   12823 	  if (code == OACC_DATA
   12824 	      && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   12825 	      && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
   12826 	    flags |= GOVD_MAP_0LEN_ARRAY;
   12827 	  omp_add_variable (ctx, decl, flags);
   12828 	  if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   12829 	       || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
   12830 	       || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
   12831 	      && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
   12832 	    {
   12833 	      struct gimplify_omp_ctx *pctx
   12834 		= code == OMP_TARGET ? outer_ctx : ctx;
   12835 	      if (pctx)
   12836 		omp_add_variable (pctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
   12837 				  GOVD_LOCAL | GOVD_SEEN);
   12838 	      if (pctx
   12839 		  && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
   12840 		  && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
   12841 				find_decl_expr,
   12842 				OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
   12843 				NULL) == NULL_TREE)
   12844 		omp_add_variable (pctx,
   12845 				  OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
   12846 				  GOVD_LOCAL | GOVD_SEEN);
   12847 	      gimplify_omp_ctxp = pctx;
   12848 	      push_gimplify_context ();
   12849 
   12850 	      OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
   12851 	      OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
   12852 
   12853 	      gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
   12854 		  		&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
   12855 	      pop_gimplify_context
   12856 		(gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
   12857 	      push_gimplify_context ();
   12858 	      gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
   12859 		  		&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
   12860 	      pop_gimplify_context
   12861 		(gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
   12862 	      OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
   12863 	      OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
   12864 
   12865 	      gimplify_omp_ctxp = outer_ctx;
   12866 	    }
   12867 	  else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   12868 		   && OMP_CLAUSE_LASTPRIVATE_STMT (c))
   12869 	    {
   12870 	      gimplify_omp_ctxp = ctx;
   12871 	      push_gimplify_context ();
   12872 	      if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
   12873 		{
   12874 		  tree bind = build3 (BIND_EXPR, void_type_node, NULL,
   12875 				      NULL, NULL);
   12876 		  TREE_SIDE_EFFECTS (bind) = 1;
   12877 		  BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
   12878 		  OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
   12879 		}
   12880 	      gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
   12881 				&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
   12882 	      pop_gimplify_context
   12883 		(gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
   12884 	      OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
   12885 
   12886 	      gimplify_omp_ctxp = outer_ctx;
   12887 	    }
   12888 	  else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   12889 		   && OMP_CLAUSE_LINEAR_STMT (c))
   12890 	    {
   12891 	      gimplify_omp_ctxp = ctx;
   12892 	      push_gimplify_context ();
   12893 	      if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
   12894 		{
   12895 		  tree bind = build3 (BIND_EXPR, void_type_node, NULL,
   12896 				      NULL, NULL);
   12897 		  TREE_SIDE_EFFECTS (bind) = 1;
   12898 		  BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
   12899 		  OMP_CLAUSE_LINEAR_STMT (c) = bind;
   12900 		}
   12901 	      gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
   12902 				&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
   12903 	      pop_gimplify_context
   12904 		(gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
   12905 	      OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
   12906 
   12907 	      gimplify_omp_ctxp = outer_ctx;
   12908 	    }
   12909 	  if (notice_outer)
   12910 	    goto do_notice;
   12911 	  break;
   12912 
   12913 	case OMP_CLAUSE_COPYIN:
   12914 	case OMP_CLAUSE_COPYPRIVATE:
   12915 	  decl = OMP_CLAUSE_DECL (c);
   12916 	  if (error_operand_p (decl))
   12917 	    {
   12918 	      remove = true;
   12919 	      break;
   12920 	    }
   12921 	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
   12922 	      && !remove
   12923 	      && !omp_check_private (ctx, decl, true))
   12924 	    {
   12925 	      remove = true;
   12926 	      if (is_global_var (decl))
   12927 		{
   12928 		  if (DECL_THREAD_LOCAL_P (decl))
   12929 		    remove = false;
   12930 		  else if (DECL_HAS_VALUE_EXPR_P (decl))
   12931 		    {
   12932 		      tree value = get_base_address (DECL_VALUE_EXPR (decl));
   12933 
   12934 		      if (value
   12935 			  && DECL_P (value)
   12936 			  && DECL_THREAD_LOCAL_P (value))
   12937 			remove = false;
   12938 		    }
   12939 		}
   12940 	      if (remove)
   12941 		error_at (OMP_CLAUSE_LOCATION (c),
   12942 			  "copyprivate variable %qE is not threadprivate"
   12943 			  " or private in outer context", DECL_NAME (decl));
   12944 	    }
   12945 	do_notice:
   12946 	  if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   12947 	       || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
   12948 	       || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
   12949 	      && outer_ctx
   12950 	      && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
   12951 		   || (region_type == ORT_WORKSHARE
   12952 		       && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   12953 		       && (OMP_CLAUSE_REDUCTION_INSCAN (c)
   12954 			   || code == OMP_LOOP)))
   12955 	      && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
   12956 		  || (code == OMP_LOOP
   12957 		      && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   12958 		      && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
   12959 			  == ORT_COMBINED_TEAMS))))
   12960 	    {
   12961 	      splay_tree_node on
   12962 		= splay_tree_lookup (outer_ctx->variables,
   12963 				     (splay_tree_key)decl);
   12964 	      if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
   12965 		{
   12966 		  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   12967 		      && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
   12968 		      && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
   12969 			  || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
   12970 			      && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
   12971 				  == POINTER_TYPE))))
   12972 		    omp_firstprivatize_variable (outer_ctx, decl);
   12973 		  else
   12974 		    {
   12975 		      omp_add_variable (outer_ctx, decl,
   12976 					GOVD_SEEN | GOVD_SHARED);
   12977 		      if (outer_ctx->outer_context)
   12978 			omp_notice_variable (outer_ctx->outer_context, decl,
   12979 					     true);
   12980 		    }
   12981 		}
   12982 	    }
   12983 	  if (outer_ctx)
   12984 	    omp_notice_variable (outer_ctx, decl, true);
   12985 	  if (check_non_private
   12986 	      && (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
   12987 	      && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
   12988 		  || decl == OMP_CLAUSE_DECL (c)
   12989 		  || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
   12990 		      && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
   12991 			  == ADDR_EXPR
   12992 			  || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
   12993 			      == POINTER_PLUS_EXPR
   12994 			      && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
   12995 						(OMP_CLAUSE_DECL (c), 0), 0))
   12996 				  == ADDR_EXPR)))))
   12997 	      && omp_check_private (ctx, decl, false))
   12998 	    {
   12999 	      error ("%s variable %qE is private in outer context",
   13000 		     check_non_private, DECL_NAME (decl));
   13001 	      remove = true;
   13002 	    }
   13003 	  break;
   13004 
   13005 	case OMP_CLAUSE_DETACH:
   13006 	  flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
   13007 	  goto do_add;
   13008 
   13009 	case OMP_CLAUSE_IF:
   13010 	  if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
   13011 	      && OMP_CLAUSE_IF_MODIFIER (c) != code)
   13012 	    {
   13013 	      const char *p[2];
   13014 	      for (int i = 0; i < 2; i++)
   13015 		switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
   13016 		  {
   13017 		  case VOID_CST: p[i] = "cancel"; break;
   13018 		  case OMP_PARALLEL: p[i] = "parallel"; break;
   13019 		  case OMP_SIMD: p[i] = "simd"; break;
   13020 		  case OMP_TASK: p[i] = "task"; break;
   13021 		  case OMP_TASKLOOP: p[i] = "taskloop"; break;
   13022 		  case OMP_TARGET_DATA: p[i] = "target data"; break;
   13023 		  case OMP_TARGET: p[i] = "target"; break;
   13024 		  case OMP_TARGET_UPDATE: p[i] = "target update"; break;
   13025 		  case OMP_TARGET_ENTER_DATA:
   13026 		    p[i] = "target enter data"; break;
   13027 		  case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
   13028 		  default: gcc_unreachable ();
   13029 		  }
   13030 	      error_at (OMP_CLAUSE_LOCATION (c),
   13031 			"expected %qs %<if%> clause modifier rather than %qs",
   13032 			p[0], p[1]);
   13033 	      remove = true;
   13034 	    }
   13035 	  /* Fall through.  */
   13036 
   13037 	case OMP_CLAUSE_SELF:
   13038 	case OMP_CLAUSE_FINAL:
   13039 	  OMP_CLAUSE_OPERAND (c, 0)
   13040 	    = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
   13041 	  /* Fall through.  */
   13042 
   13043 	case OMP_CLAUSE_NUM_TEAMS:
   13044 	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
   13045 	      && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
   13046 	      && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
   13047 	    {
   13048 	      if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
   13049 		{
   13050 		  remove = true;
   13051 		  break;
   13052 		}
   13053 	      OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
   13054 		= get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c),
   13055 					   pre_p, NULL, true);
   13056 	    }
   13057 	  /* Fall through.  */
   13058 
   13059 	case OMP_CLAUSE_SCHEDULE:
   13060 	case OMP_CLAUSE_NUM_THREADS:
   13061 	case OMP_CLAUSE_THREAD_LIMIT:
   13062 	case OMP_CLAUSE_DIST_SCHEDULE:
   13063 	case OMP_CLAUSE_DEVICE:
   13064 	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE
   13065 	      && OMP_CLAUSE_DEVICE_ANCESTOR (c))
   13066 	    {
   13067 	      if (code != OMP_TARGET)
   13068 		{
   13069 		  error_at (OMP_CLAUSE_LOCATION (c),
   13070 			    "%<device%> clause with %<ancestor%> is only "
   13071 			    "allowed on %<target%> construct");
   13072 		  remove = true;
   13073 		  break;
   13074 		}
   13075 
   13076 	      tree clauses = *orig_list_p;
   13077 	      for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
   13078 		if (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEVICE
   13079 		    && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_FIRSTPRIVATE
   13080 		    && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_PRIVATE
   13081 		    && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEFAULTMAP
   13082 		    && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_MAP
   13083 		   )
   13084 		  {
   13085 		    error_at (OMP_CLAUSE_LOCATION (c),
   13086 			      "with %<ancestor%>, only the %<device%>, "
   13087 			      "%<firstprivate%>, %<private%>, %<defaultmap%>, "
   13088 			      "and %<map%> clauses may appear on the "
   13089 			      "construct");
   13090 		    remove = true;
   13091 		    break;
   13092 		  }
   13093 	    }
   13094 	  /* Fall through.  */
   13095 
   13096 	case OMP_CLAUSE_PRIORITY:
   13097 	case OMP_CLAUSE_GRAINSIZE:
   13098 	case OMP_CLAUSE_NUM_TASKS:
   13099 	case OMP_CLAUSE_FILTER:
   13100 	case OMP_CLAUSE_HINT:
   13101 	case OMP_CLAUSE_ASYNC:
   13102 	case OMP_CLAUSE_WAIT:
   13103 	case OMP_CLAUSE_NUM_GANGS:
   13104 	case OMP_CLAUSE_NUM_WORKERS:
   13105 	case OMP_CLAUSE_VECTOR_LENGTH:
   13106 	case OMP_CLAUSE_WORKER:
   13107 	case OMP_CLAUSE_VECTOR:
   13108 	  if (OMP_CLAUSE_OPERAND (c, 0)
   13109 	      && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0)))
   13110 	    {
   13111 	      if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0)))
   13112 		{
   13113 		  remove = true;
   13114 		  break;
   13115 		}
   13116 	      /* All these clauses care about value, not a particular decl,
   13117 		 so try to force it into a SSA_NAME or fresh temporary.  */
   13118 	      OMP_CLAUSE_OPERAND (c, 0)
   13119 		= get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0),
   13120 					   pre_p, NULL, true);
   13121 	    }
   13122 	  break;
   13123 
   13124 	case OMP_CLAUSE_GANG:
   13125 	  if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
   13126 			     is_gimple_val, fb_rvalue) == GS_ERROR)
   13127 	    remove = true;
   13128 	  if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
   13129 			     is_gimple_val, fb_rvalue) == GS_ERROR)
   13130 	    remove = true;
   13131 	  break;
   13132 
   13133 	case OMP_CLAUSE_NOWAIT:
   13134 	  nowait = 1;
   13135 	  break;
   13136 
   13137 	case OMP_CLAUSE_ORDERED:
   13138 	case OMP_CLAUSE_UNTIED:
   13139 	case OMP_CLAUSE_COLLAPSE:
   13140 	case OMP_CLAUSE_TILE:
   13141 	case OMP_CLAUSE_AUTO:
   13142 	case OMP_CLAUSE_SEQ:
   13143 	case OMP_CLAUSE_INDEPENDENT:
   13144 	case OMP_CLAUSE_MERGEABLE:
   13145 	case OMP_CLAUSE_PROC_BIND:
   13146 	case OMP_CLAUSE_SAFELEN:
   13147 	case OMP_CLAUSE_SIMDLEN:
   13148 	case OMP_CLAUSE_NOGROUP:
   13149 	case OMP_CLAUSE_THREADS:
   13150 	case OMP_CLAUSE_SIMD:
   13151 	case OMP_CLAUSE_BIND:
   13152 	case OMP_CLAUSE_IF_PRESENT:
   13153 	case OMP_CLAUSE_FINALIZE:
   13154 	  break;
   13155 
   13156 	case OMP_CLAUSE_ORDER:
   13157 	  ctx->order_concurrent = true;
   13158 	  break;
   13159 
   13160 	case OMP_CLAUSE_DEFAULTMAP:
   13161 	  enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
   13162 	  switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
   13163 	    {
   13164 	    case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
   13165 	    case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL:
   13166 	      gdmkmin = GDMK_SCALAR;
   13167 	      gdmkmax = GDMK_POINTER;
   13168 	      break;
   13169 	    case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
   13170 	      gdmkmin = GDMK_SCALAR;
   13171 	      gdmkmax = GDMK_SCALAR_TARGET;
   13172 	      break;
   13173 	    case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
   13174 	      gdmkmin = gdmkmax = GDMK_AGGREGATE;
   13175 	      break;
   13176 	    case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
   13177 	      gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
   13178 	      break;
   13179 	    case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
   13180 	      gdmkmin = gdmkmax = GDMK_POINTER;
   13181 	      break;
   13182 	    default:
   13183 	      gcc_unreachable ();
   13184 	    }
   13185 	  for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
   13186 	    switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
   13187 	      {
   13188 	      case OMP_CLAUSE_DEFAULTMAP_ALLOC:
   13189 		ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
   13190 		break;
   13191 	      case OMP_CLAUSE_DEFAULTMAP_TO:
   13192 		ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
   13193 		break;
   13194 	      case OMP_CLAUSE_DEFAULTMAP_FROM:
   13195 		ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
   13196 		break;
   13197 	      case OMP_CLAUSE_DEFAULTMAP_TOFROM:
   13198 		ctx->defaultmap[gdmk] = GOVD_MAP;
   13199 		break;
   13200 	      case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
   13201 		ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
   13202 		break;
   13203 	      case OMP_CLAUSE_DEFAULTMAP_NONE:
   13204 		ctx->defaultmap[gdmk] = 0;
   13205 		break;
   13206 	      case OMP_CLAUSE_DEFAULTMAP_PRESENT:
   13207 		ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
   13208 		break;
   13209 	      case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
   13210 		switch (gdmk)
   13211 		  {
   13212 		  case GDMK_SCALAR:
   13213 		    ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
   13214 		    break;
   13215 		  case GDMK_SCALAR_TARGET:
   13216 		    ctx->defaultmap[gdmk] = (lang_GNU_Fortran ()
   13217 					     ? GOVD_MAP : GOVD_FIRSTPRIVATE);
   13218 		    break;
   13219 		  case GDMK_AGGREGATE:
   13220 		  case GDMK_ALLOCATABLE:
   13221 		    ctx->defaultmap[gdmk] = GOVD_MAP;
   13222 		    break;
   13223 		  case GDMK_POINTER:
   13224 		    ctx->defaultmap[gdmk] = GOVD_MAP;
   13225 		    if (!lang_GNU_Fortran ())
   13226 		      ctx->defaultmap[gdmk] |= GOVD_MAP_0LEN_ARRAY;
   13227 		    break;
   13228 		  default:
   13229 		    gcc_unreachable ();
   13230 		  }
   13231 		break;
   13232 	      default:
   13233 		gcc_unreachable ();
   13234 	      }
   13235 	  break;
   13236 
   13237 	case OMP_CLAUSE_ALIGNED:
   13238 	  decl = OMP_CLAUSE_DECL (c);
   13239 	  if (error_operand_p (decl))
   13240 	    {
   13241 	      remove = true;
   13242 	      break;
   13243 	    }
   13244 	  if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
   13245 			     is_gimple_val, fb_rvalue) == GS_ERROR)
   13246 	    {
   13247 	      remove = true;
   13248 	      break;
   13249 	    }
   13250 	  if (!is_global_var (decl)
   13251 	      && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
   13252 	    omp_add_variable (ctx, decl, GOVD_ALIGNED);
   13253 	  break;
   13254 
   13255 	case OMP_CLAUSE_NONTEMPORAL:
   13256 	  decl = OMP_CLAUSE_DECL (c);
   13257 	  if (error_operand_p (decl))
   13258 	    {
   13259 	      remove = true;
   13260 	      break;
   13261 	    }
   13262 	  omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
   13263 	  break;
   13264 
   13265 	case OMP_CLAUSE_ALLOCATE:
   13266 	  decl = OMP_CLAUSE_DECL (c);
   13267 	  if (error_operand_p (decl))
   13268 	    {
   13269 	      remove = true;
   13270 	      break;
   13271 	    }
   13272 	  if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL,
   13273 			     is_gimple_val, fb_rvalue) == GS_ERROR)
   13274 	    {
   13275 	      remove = true;
   13276 	      break;
   13277 	    }
   13278 	  else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
   13279 		   || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
   13280 		       == INTEGER_CST))
   13281 	    ;
   13282 	  else if (code == OMP_TASKLOOP
   13283 		   || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
   13284 	    OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
   13285 	      = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
   13286 					 pre_p, NULL, false);
   13287 	  break;
   13288 
   13289 	case OMP_CLAUSE_DEFAULT:
   13290 	  ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
   13291 	  break;
   13292 
   13293 	case OMP_CLAUSE_INCLUSIVE:
   13294 	case OMP_CLAUSE_EXCLUSIVE:
   13295 	  decl = OMP_CLAUSE_DECL (c);
   13296 	  {
   13297 	    splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
   13298 						   (splay_tree_key) decl);
   13299 	    if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
   13300 	      {
   13301 		error_at (OMP_CLAUSE_LOCATION (c),
   13302 			  "%qD specified in %qs clause but not in %<inscan%> "
   13303 			  "%<reduction%> clause on the containing construct",
   13304 			  decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
   13305 		remove = true;
   13306 	      }
   13307 	    else
   13308 	      {
   13309 		n->value |= GOVD_REDUCTION_INSCAN;
   13310 		if (outer_ctx->region_type == ORT_SIMD
   13311 		    && outer_ctx->outer_context
   13312 		    && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
   13313 		  {
   13314 		    n = splay_tree_lookup (outer_ctx->outer_context->variables,
   13315 					   (splay_tree_key) decl);
   13316 		    if (n && (n->value & GOVD_REDUCTION) != 0)
   13317 		      n->value |= GOVD_REDUCTION_INSCAN;
   13318 		  }
   13319 	      }
   13320 	  }
   13321 	  break;
   13322 
   13323 	case OMP_CLAUSE_NOHOST:
   13324 	default:
   13325 	  gcc_unreachable ();
   13326 	}
   13327 
   13328       if (code == OACC_DATA
   13329 	  && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13330 	  && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   13331 	      || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   13332 	remove = true;
   13333       if (remove)
   13334 	*list_p = OMP_CLAUSE_CHAIN (c);
   13335       else
   13336 	list_p = &OMP_CLAUSE_CHAIN (c);
   13337     }
   13338 
   13339   if (groups)
   13340     {
   13341       delete grpmap;
   13342       delete groups;
   13343     }
   13344 
   13345   ctx->clauses = *orig_list_p;
   13346   gimplify_omp_ctxp = ctx;
   13347 }
   13348 
   13349 /* Return true if DECL is a candidate for shared to firstprivate
   13350    optimization.  We only consider non-addressable scalars, not
   13351    too big, and not references.  */
   13352 
   13353 static bool
   13354 omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
   13355 {
   13356   if (TREE_ADDRESSABLE (decl))
   13357     return false;
   13358   tree type = TREE_TYPE (decl);
   13359   if (!is_gimple_reg_type (type)
   13360       || TREE_CODE (type) == REFERENCE_TYPE
   13361       || TREE_ADDRESSABLE (type))
   13362     return false;
   13363   /* Don't optimize too large decls, as each thread/task will have
   13364      its own.  */
   13365   HOST_WIDE_INT len = int_size_in_bytes (type);
   13366   if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
   13367     return false;
   13368   if (omp_privatize_by_reference (decl))
   13369     return false;
   13370   return true;
   13371 }
   13372 
   13373 /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
   13374    For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
   13375    GOVD_WRITTEN in outer contexts.  */
   13376 
   13377 static void
   13378 omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
   13379 {
   13380   for (; ctx; ctx = ctx->outer_context)
   13381     {
   13382       splay_tree_node n = splay_tree_lookup (ctx->variables,
   13383 					     (splay_tree_key) decl);
   13384       if (n == NULL)
   13385 	continue;
   13386       else if (n->value & GOVD_SHARED)
   13387 	{
   13388 	  n->value |= GOVD_WRITTEN;
   13389 	  return;
   13390 	}
   13391       else if (n->value & GOVD_DATA_SHARE_CLASS)
   13392 	return;
   13393     }
   13394 }
   13395 
   13396 /* Helper callback for walk_gimple_seq to discover possible stores
   13397    to omp_shared_to_firstprivate_optimizable_decl_p decls and set
   13398    GOVD_WRITTEN if they are GOVD_SHARED in some outer context
   13399    for those.  */
   13400 
   13401 static tree
   13402 omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
   13403 {
   13404   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
   13405 
   13406   *walk_subtrees = 0;
   13407   if (!wi->is_lhs)
   13408     return NULL_TREE;
   13409 
   13410   tree op = *tp;
   13411   do
   13412     {
   13413       if (handled_component_p (op))
   13414 	op = TREE_OPERAND (op, 0);
   13415       else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
   13416 	       && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
   13417 	op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
   13418       else
   13419 	break;
   13420     }
   13421   while (1);
   13422   if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
   13423     return NULL_TREE;
   13424 
   13425   omp_mark_stores (gimplify_omp_ctxp, op);
   13426   return NULL_TREE;
   13427 }
   13428 
   13429 /* Helper callback for walk_gimple_seq to discover possible stores
   13430    to omp_shared_to_firstprivate_optimizable_decl_p decls and set
   13431    GOVD_WRITTEN if they are GOVD_SHARED in some outer context
   13432    for those.  */
   13433 
   13434 static tree
   13435 omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
   13436 		      bool *handled_ops_p,
   13437 		      struct walk_stmt_info *wi)
   13438 {
   13439   gimple *stmt = gsi_stmt (*gsi_p);
   13440   switch (gimple_code (stmt))
   13441     {
   13442     /* Don't recurse on OpenMP constructs for which
   13443        gimplify_adjust_omp_clauses already handled the bodies,
   13444        except handle gimple_omp_for_pre_body.  */
   13445     case GIMPLE_OMP_FOR:
   13446       *handled_ops_p = true;
   13447       if (gimple_omp_for_pre_body (stmt))
   13448 	walk_gimple_seq (gimple_omp_for_pre_body (stmt),
   13449 			 omp_find_stores_stmt, omp_find_stores_op, wi);
   13450       break;
   13451     case GIMPLE_OMP_PARALLEL:
   13452     case GIMPLE_OMP_TASK:
   13453     case GIMPLE_OMP_SECTIONS:
   13454     case GIMPLE_OMP_SINGLE:
   13455     case GIMPLE_OMP_SCOPE:
   13456     case GIMPLE_OMP_TARGET:
   13457     case GIMPLE_OMP_TEAMS:
   13458     case GIMPLE_OMP_CRITICAL:
   13459       *handled_ops_p = true;
   13460       break;
   13461     default:
   13462       break;
   13463     }
   13464   return NULL_TREE;
   13465 }
   13466 
   13467 struct gimplify_adjust_omp_clauses_data
   13468 {
   13469   tree *list_p;
   13470   gimple_seq *pre_p;
   13471 };
   13472 
   13473 /* For all variables that were not actually used within the context,
   13474    remove PRIVATE, SHARED, and FIRSTPRIVATE clauses.  */
   13475 
   13476 static int
   13477 gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
   13478 {
   13479   tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
   13480   gimple_seq *pre_p
   13481     = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
   13482   tree decl = (tree) n->key;
   13483   unsigned flags = n->value;
   13484   enum omp_clause_code code;
   13485   tree clause;
   13486   bool private_debug;
   13487 
   13488   if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
   13489       && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
   13490     flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
   13491   if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
   13492     return 0;
   13493   if ((flags & GOVD_SEEN) == 0)
   13494     return 0;
   13495   if (flags & GOVD_DEBUG_PRIVATE)
   13496     {
   13497       gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
   13498       private_debug = true;
   13499     }
   13500   else if (flags & GOVD_MAP)
   13501     private_debug = false;
   13502   else
   13503     private_debug
   13504       = lang_hooks.decls.omp_private_debug_clause (decl,
   13505 						   !!(flags & GOVD_SHARED));
   13506   if (private_debug)
   13507     code = OMP_CLAUSE_PRIVATE;
   13508   else if (flags & GOVD_MAP)
   13509     {
   13510       code = OMP_CLAUSE_MAP;
   13511       if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
   13512 	  && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
   13513 	{
   13514 	  error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
   13515 	  return 0;
   13516 	}
   13517       if (VAR_P (decl)
   13518 	  && DECL_IN_CONSTANT_POOL (decl)
   13519           && !lookup_attribute ("omp declare target",
   13520 				DECL_ATTRIBUTES (decl)))
   13521 	{
   13522 	  tree id = get_identifier ("omp declare target");
   13523 	  DECL_ATTRIBUTES (decl)
   13524 	    = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
   13525 	  varpool_node *node = varpool_node::get (decl);
   13526 	  if (node)
   13527 	    {
   13528 	      node->offloadable = 1;
   13529 	      if (ENABLE_OFFLOADING)
   13530 		g->have_offload = true;
   13531 	    }
   13532 	}
   13533     }
   13534   else if (flags & GOVD_SHARED)
   13535     {
   13536       if (is_global_var (decl))
   13537 	{
   13538 	  struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
   13539 	  while (ctx != NULL)
   13540 	    {
   13541 	      splay_tree_node on
   13542 		= splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   13543 	      if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
   13544 				      | GOVD_PRIVATE | GOVD_REDUCTION
   13545 				      | GOVD_LINEAR | GOVD_MAP)) != 0)
   13546 		break;
   13547 	      ctx = ctx->outer_context;
   13548 	    }
   13549 	  if (ctx == NULL)
   13550 	    return 0;
   13551 	}
   13552       code = OMP_CLAUSE_SHARED;
   13553       /* Don't optimize shared into firstprivate for read-only vars
   13554 	 on tasks with depend clause, we shouldn't try to copy them
   13555 	 until the dependencies are satisfied.  */
   13556       if (gimplify_omp_ctxp->has_depend)
   13557 	flags |= GOVD_WRITTEN;
   13558     }
   13559   else if (flags & GOVD_PRIVATE)
   13560     code = OMP_CLAUSE_PRIVATE;
   13561   else if (flags & GOVD_FIRSTPRIVATE)
   13562     {
   13563       code = OMP_CLAUSE_FIRSTPRIVATE;
   13564       if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
   13565 	  && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
   13566 	  && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
   13567 	{
   13568 	  error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
   13569 		 "%<target%> construct", decl);
   13570 	  return 0;
   13571 	}
   13572     }
   13573   else if (flags & GOVD_LASTPRIVATE)
   13574     code = OMP_CLAUSE_LASTPRIVATE;
   13575   else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
   13576     return 0;
   13577   else if (flags & GOVD_CONDTEMP)
   13578     {
   13579       code = OMP_CLAUSE__CONDTEMP_;
   13580       gimple_add_tmp_var (decl);
   13581     }
   13582   else
   13583     gcc_unreachable ();
   13584 
   13585   if (((flags & GOVD_LASTPRIVATE)
   13586        || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
   13587       && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   13588     omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
   13589 
   13590   tree chain = *list_p;
   13591   clause = build_omp_clause (input_location, code);
   13592   OMP_CLAUSE_DECL (clause) = decl;
   13593   OMP_CLAUSE_CHAIN (clause) = chain;
   13594   if (private_debug)
   13595     OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
   13596   else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
   13597     OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
   13598   else if (code == OMP_CLAUSE_SHARED
   13599 	   && (flags & GOVD_WRITTEN) == 0
   13600 	   && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   13601     OMP_CLAUSE_SHARED_READONLY (clause) = 1;
   13602   else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
   13603     OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
   13604   else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
   13605     {
   13606       tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
   13607       OMP_CLAUSE_DECL (nc) = decl;
   13608       if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
   13609 	  && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
   13610 	OMP_CLAUSE_DECL (clause)
   13611 	  = build_fold_indirect_ref_loc (input_location, decl);
   13612       OMP_CLAUSE_DECL (clause)
   13613 	= build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
   13614 		  build_int_cst (build_pointer_type (char_type_node), 0));
   13615       OMP_CLAUSE_SIZE (clause) = size_zero_node;
   13616       OMP_CLAUSE_SIZE (nc) = size_zero_node;
   13617       OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
   13618       OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
   13619       tree dtype = TREE_TYPE (decl);
   13620       if (TREE_CODE (dtype) == REFERENCE_TYPE)
   13621 	dtype = TREE_TYPE (dtype);
   13622       /* FIRSTPRIVATE_POINTER doesn't work well if we have a
   13623 	 multiply-indirected pointer.  If we have a reference to a pointer to
   13624 	 a pointer, it's possible that this should really be
   13625 	 GOMP_MAP_FIRSTPRIVATE_REFERENCE -- but that also doesn't work at the
   13626 	 moment, so stick with this.  (See PR113279 and testcases
   13627 	 baseptrs-{4,6}.C:ref2ptrptr_offset_decl_member_slice).  */
   13628       if (TREE_CODE (dtype) == POINTER_TYPE
   13629 	  && TREE_CODE (TREE_TYPE (dtype)) == POINTER_TYPE)
   13630 	OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
   13631       else
   13632 	OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
   13633       OMP_CLAUSE_CHAIN (nc) = chain;
   13634       OMP_CLAUSE_CHAIN (clause) = nc;
   13635       struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   13636       gimplify_omp_ctxp = ctx->outer_context;
   13637       gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
   13638 		     pre_p, NULL, is_gimple_val, fb_rvalue);
   13639       gimplify_omp_ctxp = ctx;
   13640     }
   13641   else if (code == OMP_CLAUSE_MAP)
   13642     {
   13643       int kind;
   13644       /* Not all combinations of these GOVD_MAP flags are actually valid.  */
   13645       switch (flags & (GOVD_MAP_TO_ONLY
   13646 		       | GOVD_MAP_FORCE
   13647 		       | GOVD_MAP_FORCE_PRESENT
   13648 		       | GOVD_MAP_ALLOC_ONLY
   13649 		       | GOVD_MAP_FROM_ONLY))
   13650 	{
   13651 	case 0:
   13652 	  kind = GOMP_MAP_TOFROM;
   13653 	  break;
   13654 	case GOVD_MAP_FORCE:
   13655 	  kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
   13656 	  break;
   13657 	case GOVD_MAP_TO_ONLY:
   13658 	  kind = GOMP_MAP_TO;
   13659 	  break;
   13660 	case GOVD_MAP_FROM_ONLY:
   13661 	  kind = GOMP_MAP_FROM;
   13662 	  break;
   13663 	case GOVD_MAP_ALLOC_ONLY:
   13664 	  kind = GOMP_MAP_ALLOC;
   13665 	  break;
   13666 	case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
   13667 	  kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
   13668 	  break;
   13669 	case GOVD_MAP_FORCE_PRESENT:
   13670 	  kind = GOMP_MAP_FORCE_PRESENT;
   13671 	  break;
   13672 	case GOVD_MAP_FORCE_PRESENT | GOVD_MAP_ALLOC_ONLY:
   13673 	  kind = GOMP_MAP_FORCE_PRESENT;
   13674 	  break;
   13675 	default:
   13676 	  gcc_unreachable ();
   13677 	}
   13678       OMP_CLAUSE_SET_MAP_KIND (clause, kind);
   13679       /* Setting of the implicit flag for the runtime is currently disabled for
   13680 	 OpenACC.  */
   13681       if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
   13682 	OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
   13683       if (DECL_SIZE (decl)
   13684 	  && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
   13685 	{
   13686 	  tree decl2 = DECL_VALUE_EXPR (decl);
   13687 	  gcc_assert (INDIRECT_REF_P (decl2));
   13688 	  decl2 = TREE_OPERAND (decl2, 0);
   13689 	  gcc_assert (DECL_P (decl2));
   13690 	  tree mem = build_simple_mem_ref (decl2);
   13691 	  OMP_CLAUSE_DECL (clause) = mem;
   13692 	  OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
   13693 	  if (gimplify_omp_ctxp->outer_context)
   13694 	    {
   13695 	      struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
   13696 	      omp_notice_variable (ctx, decl2, true);
   13697 	      omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
   13698 	    }
   13699 	  tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
   13700 				      OMP_CLAUSE_MAP);
   13701 	  OMP_CLAUSE_DECL (nc) = decl;
   13702 	  OMP_CLAUSE_SIZE (nc) = size_zero_node;
   13703 	  if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
   13704 	    OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
   13705 	  else
   13706 	    OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
   13707 	  OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
   13708 	  OMP_CLAUSE_CHAIN (clause) = nc;
   13709 	}
   13710       else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
   13711 	       && omp_privatize_by_reference (decl))
   13712 	{
   13713 	  OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
   13714 	  OMP_CLAUSE_SIZE (clause)
   13715 	    = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
   13716 	  struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   13717 	  gimplify_omp_ctxp = ctx->outer_context;
   13718 	  gimplify_expr (&OMP_CLAUSE_SIZE (clause),
   13719 			 pre_p, NULL, is_gimple_val, fb_rvalue);
   13720 	  gimplify_omp_ctxp = ctx;
   13721 	  tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
   13722 				      OMP_CLAUSE_MAP);
   13723 	  OMP_CLAUSE_DECL (nc) = decl;
   13724 	  OMP_CLAUSE_SIZE (nc) = size_zero_node;
   13725 	  OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
   13726 	  OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
   13727 	  OMP_CLAUSE_CHAIN (clause) = nc;
   13728 	}
   13729       else
   13730 	OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
   13731     }
   13732   if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
   13733     {
   13734       tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
   13735       OMP_CLAUSE_DECL (nc) = decl;
   13736       OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
   13737       OMP_CLAUSE_CHAIN (nc) = chain;
   13738       OMP_CLAUSE_CHAIN (clause) = nc;
   13739       struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   13740       gimplify_omp_ctxp = ctx->outer_context;
   13741       lang_hooks.decls.omp_finish_clause (nc, pre_p,
   13742 					  (ctx->region_type & ORT_ACC) != 0);
   13743       gimplify_omp_ctxp = ctx;
   13744     }
   13745   *list_p = clause;
   13746   struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   13747   gimplify_omp_ctxp = ctx->outer_context;
   13748   /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
   13749      in simd.  Those are only added for the local vars inside of simd body
   13750      and they don't need to be e.g. default constructible.  */
   13751   if (code != OMP_CLAUSE_PRIVATE || ctx->region_type != ORT_SIMD)
   13752     lang_hooks.decls.omp_finish_clause (clause, pre_p,
   13753 					(ctx->region_type & ORT_ACC) != 0);
   13754   if (gimplify_omp_ctxp)
   13755     for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
   13756       if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
   13757 	  && DECL_P (OMP_CLAUSE_SIZE (clause)))
   13758 	omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
   13759 			     true);
   13760   gimplify_omp_ctxp = ctx;
   13761   return 0;
   13762 }
   13763 
   13764 static void
   13765 gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
   13766 			     enum tree_code code)
   13767 {
   13768   struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   13769   tree *orig_list_p = list_p;
   13770   tree c, decl;
   13771   bool has_inscan_reductions = false;
   13772 
   13773   if (body)
   13774     {
   13775       struct gimplify_omp_ctx *octx;
   13776       for (octx = ctx; octx; octx = octx->outer_context)
   13777 	if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
   13778 	  break;
   13779       if (octx)
   13780 	{
   13781 	  struct walk_stmt_info wi;
   13782 	  memset (&wi, 0, sizeof (wi));
   13783 	  walk_gimple_seq (body, omp_find_stores_stmt,
   13784 			   omp_find_stores_op, &wi);
   13785 	}
   13786     }
   13787 
   13788   if (ctx->add_safelen1)
   13789     {
   13790       /* If there are VLAs in the body of simd loop, prevent
   13791 	 vectorization.  */
   13792       gcc_assert (ctx->region_type == ORT_SIMD);
   13793       c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
   13794       OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
   13795       OMP_CLAUSE_CHAIN (c) = *list_p;
   13796       *list_p = c;
   13797       list_p = &OMP_CLAUSE_CHAIN (c);
   13798     }
   13799 
   13800   if (ctx->region_type == ORT_WORKSHARE
   13801       && ctx->outer_context
   13802       && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
   13803     {
   13804       for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
   13805 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   13806 	    && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   13807 	  {
   13808 	    decl = OMP_CLAUSE_DECL (c);
   13809 	    splay_tree_node n
   13810 	      = splay_tree_lookup (ctx->outer_context->variables,
   13811 				   (splay_tree_key) decl);
   13812 	    gcc_checking_assert (!splay_tree_lookup (ctx->variables,
   13813 						     (splay_tree_key) decl));
   13814 	    omp_add_variable (ctx, decl, n->value);
   13815 	    tree c2 = copy_node (c);
   13816 	    OMP_CLAUSE_CHAIN (c2) = *list_p;
   13817 	    *list_p = c2;
   13818 	    if ((n->value & GOVD_FIRSTPRIVATE) == 0)
   13819 	      continue;
   13820 	    c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   13821 				   OMP_CLAUSE_FIRSTPRIVATE);
   13822 	    OMP_CLAUSE_DECL (c2) = decl;
   13823 	    OMP_CLAUSE_CHAIN (c2) = *list_p;
   13824 	    *list_p = c2;
   13825 	  }
   13826     }
   13827 
   13828   if (code == OMP_TARGET
   13829       || code == OMP_TARGET_DATA
   13830       || code == OMP_TARGET_ENTER_DATA
   13831       || code == OMP_TARGET_EXIT_DATA)
   13832     {
   13833       vec<omp_mapping_group> *groups;
   13834       groups = omp_gather_mapping_groups (list_p);
   13835       hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap = NULL;
   13836 
   13837       if (groups)
   13838 	{
   13839 	  grpmap = omp_index_mapping_groups (groups);
   13840 
   13841 	  omp_resolve_clause_dependencies (code, groups, grpmap);
   13842 	  omp_build_struct_sibling_lists (code, ctx->region_type, groups,
   13843 					  &grpmap, list_p);
   13844 
   13845 	  omp_mapping_group *outlist = NULL;
   13846 
   13847 	  delete grpmap;
   13848 	  delete groups;
   13849 
   13850 	  /* Rebuild now we have struct sibling lists.  */
   13851 	  groups = omp_gather_mapping_groups (list_p);
   13852 	  grpmap = omp_index_mapping_groups (groups);
   13853 
   13854 	  bool enter_exit = (code == OMP_TARGET_ENTER_DATA
   13855 			     || code == OMP_TARGET_EXIT_DATA);
   13856 
   13857 	  outlist = omp_tsort_mapping_groups (groups, grpmap, enter_exit);
   13858 	  outlist = omp_segregate_mapping_groups (outlist);
   13859 	  list_p = omp_reorder_mapping_groups (groups, outlist, list_p);
   13860 
   13861 	  delete grpmap;
   13862 	  delete groups;
   13863 	}
   13864     }
   13865   else if (ctx->region_type & ORT_ACC)
   13866     {
   13867       vec<omp_mapping_group> *groups;
   13868       groups = omp_gather_mapping_groups (list_p);
   13869       if (groups)
   13870 	{
   13871 	  hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap;
   13872 	  grpmap = omp_index_mapping_groups (groups);
   13873 
   13874 	  oacc_resolve_clause_dependencies (groups, grpmap);
   13875 	  omp_build_struct_sibling_lists (code, ctx->region_type, groups,
   13876 					  &grpmap, list_p);
   13877 
   13878 	  delete groups;
   13879 	  delete grpmap;
   13880 	}
   13881     }
   13882 
   13883   tree attach_list = NULL_TREE;
   13884   tree *attach_tail = &attach_list;
   13885 
   13886   tree *grp_start_p = NULL, grp_end = NULL_TREE;
   13887 
   13888   while ((c = *list_p) != NULL)
   13889     {
   13890       splay_tree_node n;
   13891       bool remove = false;
   13892       bool move_attach = false;
   13893 
   13894       if (grp_end && c == OMP_CLAUSE_CHAIN (grp_end))
   13895 	grp_end = NULL_TREE;
   13896 
   13897       switch (OMP_CLAUSE_CODE (c))
   13898 	{
   13899 	case OMP_CLAUSE_FIRSTPRIVATE:
   13900 	  if ((ctx->region_type & ORT_TARGET)
   13901 	      && (ctx->region_type & ORT_ACC) == 0
   13902 	      && TYPE_ATOMIC (strip_array_types
   13903 					(TREE_TYPE (OMP_CLAUSE_DECL (c)))))
   13904 	    {
   13905 	      error_at (OMP_CLAUSE_LOCATION (c),
   13906 			"%<_Atomic%> %qD in %<firstprivate%> clause on "
   13907 			"%<target%> construct", OMP_CLAUSE_DECL (c));
   13908 	      remove = true;
   13909 	      break;
   13910 	    }
   13911 	  if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
   13912 	    {
   13913 	      decl = OMP_CLAUSE_DECL (c);
   13914 	      n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   13915 	      if ((n->value & GOVD_MAP) != 0)
   13916 		{
   13917 		  remove = true;
   13918 		  break;
   13919 		}
   13920 	      OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) = 0;
   13921 	      OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) = 0;
   13922 	    }
   13923 	  /* FALLTHRU */
   13924 	case OMP_CLAUSE_PRIVATE:
   13925 	case OMP_CLAUSE_SHARED:
   13926 	case OMP_CLAUSE_LINEAR:
   13927 	  decl = OMP_CLAUSE_DECL (c);
   13928 	  n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   13929 	  remove = !(n->value & GOVD_SEEN);
   13930 	  if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
   13931 	      && code == OMP_PARALLEL
   13932 	      && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
   13933 	    remove = true;
   13934 	  if (! remove)
   13935 	    {
   13936 	      bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
   13937 	      if ((n->value & GOVD_DEBUG_PRIVATE)
   13938 		  || lang_hooks.decls.omp_private_debug_clause (decl, shared))
   13939 		{
   13940 		  gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
   13941 			      || ((n->value & GOVD_DATA_SHARE_CLASS)
   13942 				  == GOVD_SHARED));
   13943 		  OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
   13944 		  OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
   13945 		}
   13946               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
   13947 		  && ctx->has_depend
   13948 		  && DECL_P (decl))
   13949 		n->value |= GOVD_WRITTEN;
   13950 	      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
   13951 		  && (n->value & GOVD_WRITTEN) == 0
   13952 		  && DECL_P (decl)
   13953 		  && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   13954 		OMP_CLAUSE_SHARED_READONLY (c) = 1;
   13955 	      else if (DECL_P (decl)
   13956 		       && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
   13957 			    && (n->value & GOVD_WRITTEN) != 0)
   13958 			   || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   13959 			       && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
   13960 		       && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   13961 		omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
   13962 	    }
   13963 	  else
   13964 	    n->value &= ~GOVD_EXPLICIT;
   13965 	  break;
   13966 
   13967 	case OMP_CLAUSE_LASTPRIVATE:
   13968 	  /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
   13969 	     accurately reflect the presence of a FIRSTPRIVATE clause.  */
   13970 	  decl = OMP_CLAUSE_DECL (c);
   13971 	  n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   13972 	  OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
   13973 	    = (n->value & GOVD_FIRSTPRIVATE) != 0;
   13974 	  if (code == OMP_DISTRIBUTE
   13975 	      && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
   13976 	    {
   13977 	      remove = true;
   13978 	      error_at (OMP_CLAUSE_LOCATION (c),
   13979 			"same variable used in %<firstprivate%> and "
   13980 			"%<lastprivate%> clauses on %<distribute%> "
   13981 			"construct");
   13982 	    }
   13983 	  if (!remove
   13984 	      && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   13985 	      && DECL_P (decl)
   13986 	      && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   13987 	    omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
   13988 	  if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
   13989 	    remove = true;
   13990 	  break;
   13991 
   13992 	case OMP_CLAUSE_ALIGNED:
   13993 	  decl = OMP_CLAUSE_DECL (c);
   13994 	  if (!is_global_var (decl))
   13995 	    {
   13996 	      n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   13997 	      remove = n == NULL || !(n->value & GOVD_SEEN);
   13998 	      if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
   13999 		{
   14000 		  struct gimplify_omp_ctx *octx;
   14001 		  if (n != NULL
   14002 		      && (n->value & (GOVD_DATA_SHARE_CLASS
   14003 				      & ~GOVD_FIRSTPRIVATE)))
   14004 		    remove = true;
   14005 		  else
   14006 		    for (octx = ctx->outer_context; octx;
   14007 			 octx = octx->outer_context)
   14008 		      {
   14009 			n = splay_tree_lookup (octx->variables,
   14010 					       (splay_tree_key) decl);
   14011 			if (n == NULL)
   14012 			  continue;
   14013 			if (n->value & GOVD_LOCAL)
   14014 			  break;
   14015 			/* We have to avoid assigning a shared variable
   14016 			   to itself when trying to add
   14017 			   __builtin_assume_aligned.  */
   14018 			if (n->value & GOVD_SHARED)
   14019 			  {
   14020 			    remove = true;
   14021 			    break;
   14022 			  }
   14023 		      }
   14024 		}
   14025 	    }
   14026 	  else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
   14027 	    {
   14028 	      n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   14029 	      if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
   14030 		remove = true;
   14031 	    }
   14032 	  break;
   14033 
   14034 	case OMP_CLAUSE_HAS_DEVICE_ADDR:
   14035 	  decl = OMP_CLAUSE_DECL (c);
   14036 	  while (INDIRECT_REF_P (decl)
   14037 		 || TREE_CODE (decl) == ARRAY_REF)
   14038 	    decl = TREE_OPERAND (decl, 0);
   14039 	  n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   14040 	  remove = n == NULL || !(n->value & GOVD_SEEN);
   14041 	  break;
   14042 
   14043 	case OMP_CLAUSE_IS_DEVICE_PTR:
   14044 	case OMP_CLAUSE_NONTEMPORAL:
   14045 	  decl = OMP_CLAUSE_DECL (c);
   14046 	  n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   14047 	  remove = n == NULL || !(n->value & GOVD_SEEN);
   14048 	  break;
   14049 
   14050 	case OMP_CLAUSE_MAP:
   14051 	  decl = OMP_CLAUSE_DECL (c);
   14052 	  if (!grp_end)
   14053 	    {
   14054 	      grp_start_p = list_p;
   14055 	      grp_end = *omp_group_last (grp_start_p);
   14056 	    }
   14057 	  switch (OMP_CLAUSE_MAP_KIND (c))
   14058 	    {
   14059 	    case GOMP_MAP_PRESENT_ALLOC:
   14060 	    case GOMP_MAP_PRESENT_TO:
   14061 	    case GOMP_MAP_PRESENT_FROM:
   14062 	    case GOMP_MAP_PRESENT_TOFROM:
   14063 	      OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_PRESENT);
   14064 	      break;
   14065 	    default:
   14066 	      break;
   14067 	    }
   14068 	  switch (code)
   14069 	    {
   14070 	    case OACC_DATA:
   14071 	      if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
   14072 		break;
   14073 	      /* Fallthrough.  */
   14074 	    case OACC_HOST_DATA:
   14075 	    case OACC_ENTER_DATA:
   14076 	    case OACC_EXIT_DATA:
   14077 	    case OMP_TARGET_DATA:
   14078 	    case OMP_TARGET_ENTER_DATA:
   14079 	    case OMP_TARGET_EXIT_DATA:
   14080 	      if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   14081 		  || (OMP_CLAUSE_MAP_KIND (c)
   14082 		      == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   14083 		/* For target {,enter ,exit }data only the array slice is
   14084 		   mapped, but not the pointer to it.  */
   14085 		remove = true;
   14086 	      if (code == OMP_TARGET_EXIT_DATA
   14087 		  && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
   14088 		      || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER))
   14089 		remove = true;
   14090 	      break;
   14091 	    case OMP_TARGET:
   14092 	      break;
   14093 	    default:
   14094 	      break;
   14095 	    }
   14096 	  if (remove)
   14097 	    break;
   14098 	  if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
   14099 	    {
   14100 	      /* Sanity check: attach/detach map kinds use the size as a bias,
   14101 		 and it's never right to use the decl size for such
   14102 		 mappings.  */
   14103 	      gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
   14104 			  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
   14105 			  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DETACH
   14106 			  && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
   14107 			  && (OMP_CLAUSE_MAP_KIND (c)
   14108 			      != GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION));
   14109 	      OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
   14110 				    : TYPE_SIZE_UNIT (TREE_TYPE (decl));
   14111 	    }
   14112 	  gimplify_omp_ctxp = ctx->outer_context;
   14113 	  if (gimplify_expr (&OMP_CLAUSE_SIZE (c), pre_p, NULL,
   14114 				  is_gimple_val, fb_rvalue) == GS_ERROR)
   14115 	    {
   14116 	      gimplify_omp_ctxp = ctx;
   14117 	      remove = true;
   14118 	      break;
   14119 	    }
   14120 	  else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   14121 		    || (OMP_CLAUSE_MAP_KIND (c)
   14122 			== GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   14123 		    || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   14124 		   && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
   14125 	    {
   14126 	      OMP_CLAUSE_SIZE (c)
   14127 		= get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
   14128 					   false);
   14129 	      if ((ctx->region_type & ORT_TARGET) != 0)
   14130 		omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
   14131 				  GOVD_FIRSTPRIVATE | GOVD_SEEN);
   14132 	    }
   14133 	  gimplify_omp_ctxp = ctx;
   14134 	  /* Data clauses associated with reductions must be
   14135 	     compatible with present_or_copy.  Warn and adjust the clause
   14136 	     if that is not the case.  */
   14137 	  if (ctx->region_type == ORT_ACC_PARALLEL
   14138 	      || ctx->region_type == ORT_ACC_SERIAL)
   14139 	    {
   14140 	      tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
   14141 	      n = NULL;
   14142 
   14143 	      if (DECL_P (t))
   14144 		n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
   14145 
   14146 	      if (n && (n->value & GOVD_REDUCTION))
   14147 		{
   14148 		  enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
   14149 
   14150 		  OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
   14151 		  if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
   14152 		      && kind != GOMP_MAP_FORCE_PRESENT
   14153 		      && kind != GOMP_MAP_POINTER)
   14154 		    {
   14155 		      warning_at (OMP_CLAUSE_LOCATION (c), 0,
   14156 				  "incompatible data clause with reduction "
   14157 				  "on %qE; promoting to %<present_or_copy%>",
   14158 				  DECL_NAME (t));
   14159 		      OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
   14160 		    }
   14161 		}
   14162 	    }
   14163 	  if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
   14164 	       || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT_UNORD)
   14165 	      && (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA))
   14166 	    {
   14167 	      remove = true;
   14168 	      break;
   14169 	    }
   14170 	  /* If we have a DECL_VALUE_EXPR (e.g. this is a class member and/or
   14171 	     a variable captured in a lambda closure), look through that now
   14172 	     before the DECL_P check below.  (A code other than COMPONENT_REF,
   14173 	     i.e. INDIRECT_REF, will be a VLA/variable-length array
   14174 	     section.  A global var may be a variable in a common block.  We
   14175 	     don't want to do this here for either of those.)  */
   14176 	  if ((ctx->region_type & ORT_ACC) == 0
   14177 	      && DECL_P (decl)
   14178 	      && !is_global_var (decl)
   14179 	      && DECL_HAS_VALUE_EXPR_P (decl)
   14180 	      && TREE_CODE (DECL_VALUE_EXPR (decl)) == COMPONENT_REF)
   14181 	    decl = OMP_CLAUSE_DECL (c) = DECL_VALUE_EXPR (decl);
   14182 	  if (TREE_CODE (decl) == TARGET_EXPR)
   14183 	    {
   14184 	      if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
   14185 				 is_gimple_lvalue, fb_lvalue) == GS_ERROR)
   14186 		remove = true;
   14187 	    }
   14188 	  else if (!DECL_P (decl))
   14189 	    {
   14190 	      if ((ctx->region_type & ORT_TARGET) != 0
   14191 		  && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
   14192 		{
   14193 		  if (INDIRECT_REF_P (decl)
   14194 		      && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
   14195 		      && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
   14196 			  == REFERENCE_TYPE))
   14197 		    decl = TREE_OPERAND (decl, 0);
   14198 		  if (TREE_CODE (decl) == COMPONENT_REF)
   14199 		    {
   14200 		      while (TREE_CODE (decl) == COMPONENT_REF)
   14201 			decl = TREE_OPERAND (decl, 0);
   14202 		      if (DECL_P (decl))
   14203 			{
   14204 			  n = splay_tree_lookup (ctx->variables,
   14205 						 (splay_tree_key) decl);
   14206 			  if (!(n->value & GOVD_SEEN))
   14207 			    remove = true;
   14208 			}
   14209 		    }
   14210 		}
   14211 
   14212 	      tree d = decl, *pd;
   14213 	      if (TREE_CODE (d) == ARRAY_REF)
   14214 		{
   14215 		  while (TREE_CODE (d) == ARRAY_REF)
   14216 		    d = TREE_OPERAND (d, 0);
   14217 		  if (TREE_CODE (d) == COMPONENT_REF
   14218 		      && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
   14219 		    decl = d;
   14220 		}
   14221 	      pd = &OMP_CLAUSE_DECL (c);
   14222 	      if (d == decl
   14223 		  && TREE_CODE (decl) == INDIRECT_REF
   14224 		  && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
   14225 		  && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
   14226 		      == REFERENCE_TYPE)
   14227 		  && (OMP_CLAUSE_MAP_KIND (c)
   14228 		      != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
   14229 		{
   14230 		  pd = &TREE_OPERAND (decl, 0);
   14231 		  decl = TREE_OPERAND (decl, 0);
   14232 		}
   14233 
   14234 	      if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   14235 		switch (code)
   14236 		  {
   14237 		  case OACC_ENTER_DATA:
   14238 		  case OACC_EXIT_DATA:
   14239 		    if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
   14240 			== ARRAY_TYPE)
   14241 		      remove = true;
   14242 		    else if (code == OACC_ENTER_DATA)
   14243 		      goto change_to_attach;
   14244 		    /* Fallthrough.  */
   14245 		  case OMP_TARGET_EXIT_DATA:
   14246 		    OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DETACH);
   14247 		    break;
   14248 		  case OACC_UPDATE:
   14249 		    /* An "attach/detach" operation on an update directive
   14250 		       should behave as a GOMP_MAP_ALWAYS_POINTER.  Note that
   14251 		       both GOMP_MAP_ATTACH_DETACH and GOMP_MAP_ALWAYS_POINTER
   14252 		       kinds depend on the previous mapping (for non-TARGET
   14253 		       regions).  */
   14254 		    OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
   14255 		    break;
   14256 		  default:
   14257 		  change_to_attach:
   14258 		    OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ATTACH);
   14259 		    if ((ctx->region_type & ORT_TARGET) != 0)
   14260 		      move_attach = true;
   14261 		  }
   14262 	      else if ((ctx->region_type & ORT_TARGET) != 0
   14263 		       && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   14264 			   || (OMP_CLAUSE_MAP_KIND (c)
   14265 			       == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)))
   14266 		move_attach = true;
   14267 
   14268 	      /* If we have e.g. map(struct: *var), don't gimplify the
   14269 		 argument since omp-low.cc wants to see the decl itself.  */
   14270 	      if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
   14271 		break;
   14272 
   14273 	      /* We've already partly gimplified this in
   14274 		 gimplify_scan_omp_clauses.  Don't do any more.  */
   14275 	      if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
   14276 		break;
   14277 
   14278 	      gimplify_omp_ctxp = ctx->outer_context;
   14279 	      if (gimplify_expr (pd, pre_p, NULL, is_gimple_lvalue,
   14280 				 fb_lvalue) == GS_ERROR)
   14281 		remove = true;
   14282 	      gimplify_omp_ctxp = ctx;
   14283 	      break;
   14284 	    }
   14285 
   14286 	 if ((code == OMP_TARGET
   14287 	      || code == OMP_TARGET_DATA
   14288 	      || code == OMP_TARGET_ENTER_DATA
   14289 	      || code == OMP_TARGET_EXIT_DATA)
   14290 	     && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   14291 	   {
   14292 	     bool firstprivatize = false;
   14293 
   14294 	     for (struct gimplify_omp_ctx *octx = ctx->outer_context; octx;
   14295 		  octx = octx->outer_context)
   14296 	       {
   14297 		 splay_tree_node n
   14298 		   = splay_tree_lookup (octx->variables,
   14299 					(splay_tree_key) OMP_CLAUSE_DECL (c));
   14300 		 /* If this is contained in an outer OpenMP region as a
   14301 		    firstprivate value, remove the attach/detach.  */
   14302 		 if (n && (n->value & GOVD_FIRSTPRIVATE))
   14303 		   {
   14304 		     firstprivatize = true;
   14305 		     break;
   14306 		   }
   14307 	       }
   14308 
   14309 	     enum gomp_map_kind map_kind;
   14310 	     if (firstprivatize)
   14311 	       map_kind = GOMP_MAP_FIRSTPRIVATE_POINTER;
   14312 	     else if (code == OMP_TARGET_EXIT_DATA)
   14313 	       map_kind = GOMP_MAP_DETACH;
   14314 	     else
   14315 	       map_kind = GOMP_MAP_ATTACH;
   14316 	     OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
   14317 	   }
   14318 	 else if ((ctx->region_type & ORT_ACC) != 0
   14319 		  && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   14320 	   {
   14321 	     enum gomp_map_kind map_kind = (code == OACC_EXIT_DATA
   14322 					    ? GOMP_MAP_DETACH
   14323 					    : GOMP_MAP_ATTACH);
   14324 	     OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
   14325 	   }
   14326 
   14327 	  n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   14328 	  if ((ctx->region_type & ORT_TARGET) != 0
   14329 	      && !(n->value & GOVD_SEEN)
   14330 	      && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
   14331 	      && (!is_global_var (decl)
   14332 		  || !lookup_attribute ("omp declare target link",
   14333 					DECL_ATTRIBUTES (decl))))
   14334 	    {
   14335 	      remove = true;
   14336 	      /* For struct element mapping, if struct is never referenced
   14337 		 in target block and none of the mapping has always modifier,
   14338 		 remove all the struct element mappings, which immediately
   14339 		 follow the GOMP_MAP_STRUCT map clause.  */
   14340 	      if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
   14341 		  || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT_UNORD)
   14342 		{
   14343 		  HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
   14344 		  while (cnt--)
   14345 		    OMP_CLAUSE_CHAIN (c)
   14346 		      = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
   14347 		}
   14348 	    }
   14349 	  else if (DECL_SIZE (decl)
   14350 		   && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
   14351 		   && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
   14352 		   && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
   14353 		   && (OMP_CLAUSE_MAP_KIND (c)
   14354 		       != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   14355 	    {
   14356 	      /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
   14357 		 for these, TREE_CODE (DECL_SIZE (decl)) will always be
   14358 		 INTEGER_CST.  */
   14359 	      gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
   14360 
   14361 	      tree decl2 = DECL_VALUE_EXPR (decl);
   14362 	      gcc_assert (INDIRECT_REF_P (decl2));
   14363 	      decl2 = TREE_OPERAND (decl2, 0);
   14364 	      gcc_assert (DECL_P (decl2));
   14365 	      tree mem = build_simple_mem_ref (decl2);
   14366 	      OMP_CLAUSE_DECL (c) = mem;
   14367 	      OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
   14368 	      if (ctx->outer_context)
   14369 		{
   14370 		  omp_notice_variable (ctx->outer_context, decl2, true);
   14371 		  omp_notice_variable (ctx->outer_context,
   14372 				       OMP_CLAUSE_SIZE (c), true);
   14373 		}
   14374 	      if (((ctx->region_type & ORT_TARGET) != 0
   14375 		   || !ctx->target_firstprivatize_array_bases)
   14376 		  && ((n->value & GOVD_SEEN) == 0
   14377 		      || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
   14378 		{
   14379 		  tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   14380 					      OMP_CLAUSE_MAP);
   14381 		  OMP_CLAUSE_DECL (nc) = decl;
   14382 		  OMP_CLAUSE_SIZE (nc) = size_zero_node;
   14383 		  if (ctx->target_firstprivatize_array_bases)
   14384 		    OMP_CLAUSE_SET_MAP_KIND (nc,
   14385 					     GOMP_MAP_FIRSTPRIVATE_POINTER);
   14386 		  else
   14387 		    OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
   14388 		  OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
   14389 		  OMP_CLAUSE_CHAIN (c) = nc;
   14390 		  c = nc;
   14391 		}
   14392 	    }
   14393 	  else
   14394 	    {
   14395 	      if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
   14396 		OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
   14397 	      gcc_assert ((n->value & GOVD_SEEN) == 0
   14398 			  || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
   14399 			      == 0));
   14400 	    }
   14401 
   14402 	  /* If we have a target region, we can push all the attaches to the
   14403 	     end of the list (we may have standalone "attach" operations
   14404 	     synthesized for GOMP_MAP_STRUCT nodes that must be processed after
   14405 	     the attachment point AND the pointed-to block have been mapped).
   14406 	     If we have something else, e.g. "enter data", we need to keep
   14407 	     "attach" nodes together with the previous node they attach to so
   14408 	     that separate "exit data" operations work properly (see
   14409 	     libgomp/target.c).  */
   14410 	  if ((ctx->region_type & ORT_TARGET) != 0
   14411 	      && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   14412 		  || (OMP_CLAUSE_MAP_KIND (c)
   14413 		      == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)))
   14414 	    move_attach = true;
   14415 
   14416 	  break;
   14417 
   14418 	case OMP_CLAUSE_TO:
   14419 	case OMP_CLAUSE_FROM:
   14420 	case OMP_CLAUSE__CACHE_:
   14421 	  decl = OMP_CLAUSE_DECL (c);
   14422 	  if (!DECL_P (decl))
   14423 	    break;
   14424 	  if (DECL_SIZE (decl)
   14425 	      && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
   14426 	    {
   14427 	      tree decl2 = DECL_VALUE_EXPR (decl);
   14428 	      gcc_assert (INDIRECT_REF_P (decl2));
   14429 	      decl2 = TREE_OPERAND (decl2, 0);
   14430 	      gcc_assert (DECL_P (decl2));
   14431 	      tree mem = build_simple_mem_ref (decl2);
   14432 	      OMP_CLAUSE_DECL (c) = mem;
   14433 	      OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
   14434 	      if (ctx->outer_context)
   14435 		{
   14436 		  omp_notice_variable (ctx->outer_context, decl2, true);
   14437 		  omp_notice_variable (ctx->outer_context,
   14438 				       OMP_CLAUSE_SIZE (c), true);
   14439 		}
   14440 	    }
   14441 	  else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
   14442 	    OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
   14443 	  break;
   14444 
   14445 	case OMP_CLAUSE_REDUCTION:
   14446 	  if (OMP_CLAUSE_REDUCTION_INSCAN (c))
   14447 	    {
   14448 	      decl = OMP_CLAUSE_DECL (c);
   14449 	      n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   14450 	      if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
   14451 		{
   14452 		  remove = true;
   14453 		  error_at (OMP_CLAUSE_LOCATION (c),
   14454 			    "%qD specified in %<inscan%> %<reduction%> clause "
   14455 			    "but not in %<scan%> directive clause", decl);
   14456 		  break;
   14457 		}
   14458 	      has_inscan_reductions = true;
   14459 	    }
   14460 	  /* FALLTHRU */
   14461 	case OMP_CLAUSE_IN_REDUCTION:
   14462 	case OMP_CLAUSE_TASK_REDUCTION:
   14463 	  decl = OMP_CLAUSE_DECL (c);
   14464 	  /* OpenACC reductions need a present_or_copy data clause.
   14465 	     Add one if necessary.  Emit error when the reduction is private.  */
   14466 	  if (ctx->region_type == ORT_ACC_PARALLEL
   14467 	      || ctx->region_type == ORT_ACC_SERIAL)
   14468 	    {
   14469 	      n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   14470 	      if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
   14471 		{
   14472 		  remove = true;
   14473 		  error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
   14474 			    "reduction on %qE", DECL_NAME (decl));
   14475 		}
   14476 	      else if ((n->value & GOVD_MAP) == 0)
   14477 		{
   14478 		  tree next = OMP_CLAUSE_CHAIN (c);
   14479 		  tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
   14480 		  OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
   14481 		  OMP_CLAUSE_DECL (nc) = decl;
   14482 		  OMP_CLAUSE_CHAIN (c) = nc;
   14483 		  lang_hooks.decls.omp_finish_clause (nc, pre_p,
   14484 						      (ctx->region_type
   14485 						       & ORT_ACC) != 0);
   14486 		  while (1)
   14487 		    {
   14488 		      OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
   14489 		      if (OMP_CLAUSE_CHAIN (nc) == NULL)
   14490 			break;
   14491 		      nc = OMP_CLAUSE_CHAIN (nc);
   14492 		    }
   14493 		  OMP_CLAUSE_CHAIN (nc) = next;
   14494 		  n->value |= GOVD_MAP;
   14495 		}
   14496 	    }
   14497 	  if (DECL_P (decl)
   14498 	      && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   14499 	    omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
   14500 	  break;
   14501 
   14502 	case OMP_CLAUSE_ALLOCATE:
   14503 	  decl = OMP_CLAUSE_DECL (c);
   14504 	  n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   14505 	  if (n != NULL && !(n->value & GOVD_SEEN))
   14506 	    {
   14507 	      if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR))
   14508 		  != 0
   14509 		  && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0)
   14510 		remove = true;
   14511 	    }
   14512 	  if (!remove
   14513 	      && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
   14514 	      && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST
   14515 	      && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0
   14516 		  || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK
   14517 		  || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS))
   14518 	    {
   14519 	      tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
   14520 	      n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator);
   14521 	      if (n == NULL)
   14522 		{
   14523 		  enum omp_clause_default_kind default_kind
   14524 		    = ctx->default_kind;
   14525 		  ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
   14526 		  omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
   14527 				       true);
   14528 		  ctx->default_kind = default_kind;
   14529 		}
   14530 	      else
   14531 		omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
   14532 				     true);
   14533 	    }
   14534 	  break;
   14535 
   14536 	case OMP_CLAUSE_COPYIN:
   14537 	case OMP_CLAUSE_COPYPRIVATE:
   14538 	case OMP_CLAUSE_IF:
   14539 	case OMP_CLAUSE_SELF:
   14540 	case OMP_CLAUSE_NUM_THREADS:
   14541 	case OMP_CLAUSE_NUM_TEAMS:
   14542 	case OMP_CLAUSE_THREAD_LIMIT:
   14543 	case OMP_CLAUSE_DIST_SCHEDULE:
   14544 	case OMP_CLAUSE_DEVICE:
   14545 	case OMP_CLAUSE_SCHEDULE:
   14546 	case OMP_CLAUSE_NOWAIT:
   14547 	case OMP_CLAUSE_ORDERED:
   14548 	case OMP_CLAUSE_DEFAULT:
   14549 	case OMP_CLAUSE_UNTIED:
   14550 	case OMP_CLAUSE_COLLAPSE:
   14551 	case OMP_CLAUSE_FINAL:
   14552 	case OMP_CLAUSE_MERGEABLE:
   14553 	case OMP_CLAUSE_PROC_BIND:
   14554 	case OMP_CLAUSE_SAFELEN:
   14555 	case OMP_CLAUSE_SIMDLEN:
   14556 	case OMP_CLAUSE_DEPEND:
   14557 	case OMP_CLAUSE_DOACROSS:
   14558 	case OMP_CLAUSE_PRIORITY:
   14559 	case OMP_CLAUSE_GRAINSIZE:
   14560 	case OMP_CLAUSE_NUM_TASKS:
   14561 	case OMP_CLAUSE_NOGROUP:
   14562 	case OMP_CLAUSE_THREADS:
   14563 	case OMP_CLAUSE_SIMD:
   14564 	case OMP_CLAUSE_FILTER:
   14565 	case OMP_CLAUSE_HINT:
   14566 	case OMP_CLAUSE_DEFAULTMAP:
   14567 	case OMP_CLAUSE_ORDER:
   14568 	case OMP_CLAUSE_BIND:
   14569 	case OMP_CLAUSE_DETACH:
   14570 	case OMP_CLAUSE_USE_DEVICE_PTR:
   14571 	case OMP_CLAUSE_USE_DEVICE_ADDR:
   14572 	case OMP_CLAUSE_ASYNC:
   14573 	case OMP_CLAUSE_WAIT:
   14574 	case OMP_CLAUSE_INDEPENDENT:
   14575 	case OMP_CLAUSE_NUM_GANGS:
   14576 	case OMP_CLAUSE_NUM_WORKERS:
   14577 	case OMP_CLAUSE_VECTOR_LENGTH:
   14578 	case OMP_CLAUSE_GANG:
   14579 	case OMP_CLAUSE_WORKER:
   14580 	case OMP_CLAUSE_VECTOR:
   14581 	case OMP_CLAUSE_AUTO:
   14582 	case OMP_CLAUSE_SEQ:
   14583 	case OMP_CLAUSE_TILE:
   14584 	case OMP_CLAUSE_IF_PRESENT:
   14585 	case OMP_CLAUSE_FINALIZE:
   14586 	case OMP_CLAUSE_INCLUSIVE:
   14587 	case OMP_CLAUSE_EXCLUSIVE:
   14588 	  break;
   14589 
   14590 	case OMP_CLAUSE_NOHOST:
   14591 	default:
   14592 	  gcc_unreachable ();
   14593 	}
   14594 
   14595       if (remove)
   14596 	*list_p = OMP_CLAUSE_CHAIN (c);
   14597       else if (move_attach)
   14598 	{
   14599 	  /* Remove attach node from here, separate out into its own list.  */
   14600 	  *attach_tail = c;
   14601 	  *list_p = OMP_CLAUSE_CHAIN (c);
   14602 	  OMP_CLAUSE_CHAIN (c) = NULL_TREE;
   14603 	  attach_tail = &OMP_CLAUSE_CHAIN (c);
   14604 	}
   14605       else
   14606 	list_p = &OMP_CLAUSE_CHAIN (c);
   14607     }
   14608 
   14609   /* Splice attach nodes at the end of the list.  */
   14610   if (attach_list)
   14611     {
   14612       *list_p = attach_list;
   14613       list_p = attach_tail;
   14614     }
   14615 
   14616   /* Add in any implicit data sharing.  */
   14617   struct gimplify_adjust_omp_clauses_data data;
   14618   if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
   14619     {
   14620       /* OpenMP.  Implicit clauses are added at the start of the clause list,
   14621 	 but after any non-map clauses.  */
   14622       tree *implicit_add_list_p = orig_list_p;
   14623       while (*implicit_add_list_p
   14624 	     && OMP_CLAUSE_CODE (*implicit_add_list_p) != OMP_CLAUSE_MAP)
   14625 	implicit_add_list_p = &OMP_CLAUSE_CHAIN (*implicit_add_list_p);
   14626       data.list_p = implicit_add_list_p;
   14627     }
   14628   else
   14629     /* OpenACC.  */
   14630     data.list_p = list_p;
   14631   data.pre_p = pre_p;
   14632   splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
   14633 
   14634   if (has_inscan_reductions)
   14635     for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
   14636       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   14637 	  && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
   14638 	{
   14639 	  error_at (OMP_CLAUSE_LOCATION (c),
   14640 		    "%<inscan%> %<reduction%> clause used together with "
   14641 		    "%<linear%> clause for a variable other than loop "
   14642 		    "iterator");
   14643 	  break;
   14644 	}
   14645 
   14646   gimplify_omp_ctxp = ctx->outer_context;
   14647   delete_omp_context (ctx);
   14648 }
   14649 
   14650 /* Return 0 if CONSTRUCTS selectors don't match the OpenMP context,
   14651    -1 if unknown yet (simd is involved, won't be known until vectorization)
   14652    and 1 if they do.  If SCORES is non-NULL, it should point to an array
   14653    of at least 2*NCONSTRUCTS+2 ints, and will be filled with the positions
   14654    of the CONSTRUCTS (position -1 if it will never match) followed by
   14655    number of constructs in the OpenMP context construct trait.  If the
   14656    score depends on whether it will be in a declare simd clone or not,
   14657    the function returns 2 and there will be two sets of the scores, the first
   14658    one for the case that it is not in a declare simd clone, the other
   14659    that it is in a declare simd clone.  */
   14660 
   14661 int
   14662 omp_construct_selector_matches (enum tree_code *constructs, int nconstructs,
   14663 				int *scores)
   14664 {
   14665   int matched = 0, cnt = 0;
   14666   bool simd_seen = false;
   14667   bool target_seen = false;
   14668   int declare_simd_cnt = -1;
   14669   auto_vec<enum tree_code, 16> codes;
   14670   for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
   14671     {
   14672       if (((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
   14673 	  || ((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
   14674 	      == ORT_TARGET && ctx->code == OMP_TARGET)
   14675 	  || ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
   14676 	  || (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
   14677 	  || (ctx->region_type == ORT_SIMD
   14678 	      && ctx->code == OMP_SIMD
   14679 	      && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND)))
   14680 	{
   14681 	  ++cnt;
   14682 	  if (scores)
   14683 	    codes.safe_push (ctx->code);
   14684 	  else if (matched < nconstructs && ctx->code == constructs[matched])
   14685 	    {
   14686 	      if (ctx->code == OMP_SIMD)
   14687 		{
   14688 		  if (matched)
   14689 		    return 0;
   14690 		  simd_seen = true;
   14691 		}
   14692 	      ++matched;
   14693 	    }
   14694 	  if (ctx->code == OMP_TARGET)
   14695 	    {
   14696 	      if (scores == NULL)
   14697 		return matched < nconstructs ? 0 : simd_seen ? -1 : 1;
   14698 	      target_seen = true;
   14699 	      break;
   14700 	    }
   14701 	}
   14702       else if (ctx->region_type == ORT_WORKSHARE
   14703 	       && ctx->code == OMP_LOOP
   14704 	       && ctx->outer_context
   14705 	       && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
   14706 	       && ctx->outer_context->outer_context
   14707 	       && ctx->outer_context->outer_context->code == OMP_LOOP
   14708 	       && ctx->outer_context->outer_context->distribute)
   14709 	ctx = ctx->outer_context->outer_context;
   14710       ctx = ctx->outer_context;
   14711     }
   14712   if (!target_seen
   14713       && lookup_attribute ("omp declare simd",
   14714 			   DECL_ATTRIBUTES (current_function_decl)))
   14715     {
   14716       /* Declare simd is a maybe case, it is supposed to be added only to the
   14717 	 omp-simd-clone.cc added clones and not to the base function.  */
   14718       declare_simd_cnt = cnt++;
   14719       if (scores)
   14720 	codes.safe_push (OMP_SIMD);
   14721       else if (cnt == 0
   14722 	       && constructs[0] == OMP_SIMD)
   14723 	{
   14724 	  gcc_assert (matched == 0);
   14725 	  simd_seen = true;
   14726 	  if (++matched == nconstructs)
   14727 	    return -1;
   14728 	}
   14729     }
   14730   if (tree attr = lookup_attribute ("omp declare variant variant",
   14731 				    DECL_ATTRIBUTES (current_function_decl)))
   14732     {
   14733       tree selectors = TREE_VALUE (attr);
   14734       int variant_nconstructs = list_length (selectors);
   14735       enum tree_code *variant_constructs = NULL;
   14736       if (!target_seen && variant_nconstructs)
   14737 	{
   14738 	  variant_constructs
   14739 	    = (enum tree_code *) alloca (variant_nconstructs
   14740 					 * sizeof (enum tree_code));
   14741 	  omp_construct_traits_to_codes (selectors, variant_nconstructs,
   14742 					 variant_constructs);
   14743 	}
   14744       for (int i = 0; i < variant_nconstructs; i++)
   14745 	{
   14746 	  ++cnt;
   14747 	  if (scores)
   14748 	    codes.safe_push (variant_constructs[i]);
   14749 	  else if (matched < nconstructs
   14750 		   && variant_constructs[i] == constructs[matched])
   14751 	    {
   14752 	      if (variant_constructs[i] == OMP_SIMD)
   14753 		{
   14754 		  if (matched)
   14755 		    return 0;
   14756 		  simd_seen = true;
   14757 		}
   14758 	      ++matched;
   14759 	    }
   14760 	}
   14761     }
   14762   if (!target_seen
   14763       && lookup_attribute ("omp declare target block",
   14764 			   DECL_ATTRIBUTES (current_function_decl)))
   14765     {
   14766       if (scores)
   14767 	codes.safe_push (OMP_TARGET);
   14768       else if (matched < nconstructs && constructs[matched] == OMP_TARGET)
   14769 	++matched;
   14770     }
   14771   if (scores)
   14772     {
   14773       for (int pass = 0; pass < (declare_simd_cnt == -1 ? 1 : 2); pass++)
   14774 	{
   14775 	  int j = codes.length () - 1;
   14776 	  for (int i = nconstructs - 1; i >= 0; i--)
   14777 	    {
   14778 	      while (j >= 0
   14779 		     && (pass != 0 || declare_simd_cnt != j)
   14780 		     && constructs[i] != codes[j])
   14781 		--j;
   14782 	      if (pass == 0 && declare_simd_cnt != -1 && j > declare_simd_cnt)
   14783 		*scores++ = j - 1;
   14784 	      else
   14785 		*scores++ = j;
   14786 	    }
   14787 	  *scores++ = ((pass == 0 && declare_simd_cnt != -1)
   14788 		       ? codes.length () - 1 : codes.length ());
   14789 	}
   14790       return declare_simd_cnt == -1 ? 1 : 2;
   14791     }
   14792   if (matched == nconstructs)
   14793     return simd_seen ? -1 : 1;
   14794   return 0;
   14795 }
   14796 
   14797 /* Gimplify OACC_CACHE.  */
   14798 
   14799 static void
   14800 gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
   14801 {
   14802   tree expr = *expr_p;
   14803 
   14804   gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
   14805 			     OACC_CACHE);
   14806   gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
   14807 			       OACC_CACHE);
   14808 
   14809   /* TODO: Do something sensible with this information.  */
   14810 
   14811   *expr_p = NULL_TREE;
   14812 }
   14813 
   14814 /* Helper function of gimplify_oacc_declare.  The helper's purpose is to,
   14815    if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
   14816    kind.  The entry kind will replace the one in CLAUSE, while the exit
   14817    kind will be used in a new omp_clause and returned to the caller.  */
   14818 
   14819 static tree
   14820 gimplify_oacc_declare_1 (tree clause)
   14821 {
   14822   HOST_WIDE_INT kind, new_op;
   14823   bool ret = false;
   14824   tree c = NULL;
   14825 
   14826   kind = OMP_CLAUSE_MAP_KIND (clause);
   14827 
   14828   switch (kind)
   14829     {
   14830       case GOMP_MAP_ALLOC:
   14831 	new_op = GOMP_MAP_RELEASE;
   14832 	ret = true;
   14833 	break;
   14834 
   14835       case GOMP_MAP_FROM:
   14836 	OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
   14837 	new_op = GOMP_MAP_FROM;
   14838 	ret = true;
   14839 	break;
   14840 
   14841       case GOMP_MAP_TOFROM:
   14842 	OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
   14843 	new_op = GOMP_MAP_FROM;
   14844 	ret = true;
   14845 	break;
   14846 
   14847       case GOMP_MAP_DEVICE_RESIDENT:
   14848       case GOMP_MAP_FORCE_DEVICEPTR:
   14849       case GOMP_MAP_FORCE_PRESENT:
   14850       case GOMP_MAP_LINK:
   14851       case GOMP_MAP_POINTER:
   14852       case GOMP_MAP_TO:
   14853 	break;
   14854 
   14855       default:
   14856 	gcc_unreachable ();
   14857 	break;
   14858     }
   14859 
   14860   if (ret)
   14861     {
   14862       c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
   14863       OMP_CLAUSE_SET_MAP_KIND (c, new_op);
   14864       OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
   14865     }
   14866 
   14867   return c;
   14868 }
   14869 
   14870 /* Gimplify OACC_DECLARE.  */
   14871 
   14872 static void
   14873 gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
   14874 {
   14875   tree expr = *expr_p;
   14876   gomp_target *stmt;
   14877   tree clauses, t, decl;
   14878 
   14879   clauses = OACC_DECLARE_CLAUSES (expr);
   14880 
   14881   gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
   14882   gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
   14883 
   14884   for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
   14885     {
   14886       decl = OMP_CLAUSE_DECL (t);
   14887 
   14888       if (TREE_CODE (decl) == MEM_REF)
   14889 	decl = TREE_OPERAND (decl, 0);
   14890 
   14891       if (VAR_P (decl) && !is_oacc_declared (decl))
   14892 	{
   14893 	  tree attr = get_identifier ("oacc declare target");
   14894 	  DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
   14895 					      DECL_ATTRIBUTES (decl));
   14896 	}
   14897 
   14898       if (VAR_P (decl)
   14899 	  && !is_global_var (decl)
   14900 	  && DECL_CONTEXT (decl) == current_function_decl)
   14901 	{
   14902 	  tree c = gimplify_oacc_declare_1 (t);
   14903 	  if (c)
   14904 	    {
   14905 	      if (oacc_declare_returns == NULL)
   14906 		oacc_declare_returns = new hash_map<tree, tree>;
   14907 
   14908 	      oacc_declare_returns->put (decl, c);
   14909 	    }
   14910 	}
   14911 
   14912       if (gimplify_omp_ctxp)
   14913 	omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
   14914     }
   14915 
   14916   stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
   14917 				  clauses);
   14918 
   14919   gimplify_seq_add_stmt (pre_p, stmt);
   14920 
   14921   *expr_p = NULL_TREE;
   14922 }
   14923 
   14924 /* Gimplify the contents of an OMP_PARALLEL statement.  This involves
   14925    gimplification of the body, as well as scanning the body for used
   14926    variables.  We need to do this scan now, because variable-sized
   14927    decls will be decomposed during gimplification.  */
   14928 
   14929 static void
   14930 gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
   14931 {
   14932   tree expr = *expr_p;
   14933   gimple *g;
   14934   gimple_seq body = NULL;
   14935 
   14936   gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
   14937 			     OMP_PARALLEL_COMBINED (expr)
   14938 			     ? ORT_COMBINED_PARALLEL
   14939 			     : ORT_PARALLEL, OMP_PARALLEL);
   14940 
   14941   push_gimplify_context ();
   14942 
   14943   g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
   14944   if (gimple_code (g) == GIMPLE_BIND)
   14945     pop_gimplify_context (g);
   14946   else
   14947     pop_gimplify_context (NULL);
   14948 
   14949   gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
   14950 			       OMP_PARALLEL);
   14951 
   14952   g = gimple_build_omp_parallel (body,
   14953 				 OMP_PARALLEL_CLAUSES (expr),
   14954 				 NULL_TREE, NULL_TREE);
   14955   if (OMP_PARALLEL_COMBINED (expr))
   14956     gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
   14957   gimplify_seq_add_stmt (pre_p, g);
   14958   *expr_p = NULL_TREE;
   14959 }
   14960 
   14961 /* Gimplify the contents of an OMP_TASK statement.  This involves
   14962    gimplification of the body, as well as scanning the body for used
   14963    variables.  We need to do this scan now, because variable-sized
   14964    decls will be decomposed during gimplification.  */
   14965 
   14966 static void
   14967 gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
   14968 {
   14969   tree expr = *expr_p;
   14970   gimple *g;
   14971   gimple_seq body = NULL;
   14972   bool nowait = false;
   14973   bool has_depend = false;
   14974 
   14975   if (OMP_TASK_BODY (expr) == NULL_TREE)
   14976     {
   14977       for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   14978 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
   14979 	  {
   14980 	    has_depend = true;
   14981 	    if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
   14982 	      {
   14983 		error_at (OMP_CLAUSE_LOCATION (c),
   14984 			  "%<mutexinoutset%> kind in %<depend%> clause on a "
   14985 			  "%<taskwait%> construct");
   14986 		break;
   14987 	      }
   14988 	  }
   14989 	else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOWAIT)
   14990 	  nowait = true;
   14991       if (nowait && !has_depend)
   14992 	{
   14993 	  error_at (EXPR_LOCATION (expr),
   14994 		    "%<taskwait%> construct with %<nowait%> clause but no "
   14995 		    "%<depend%> clauses");
   14996 	  *expr_p = NULL_TREE;
   14997 	  return;
   14998 	}
   14999     }
   15000 
   15001   gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
   15002 			     omp_find_clause (OMP_TASK_CLAUSES (expr),
   15003 					      OMP_CLAUSE_UNTIED)
   15004 			     ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
   15005 
   15006   if (OMP_TASK_BODY (expr))
   15007     {
   15008       push_gimplify_context ();
   15009 
   15010       g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
   15011       if (gimple_code (g) == GIMPLE_BIND)
   15012 	pop_gimplify_context (g);
   15013       else
   15014 	pop_gimplify_context (NULL);
   15015     }
   15016 
   15017   gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
   15018 			       OMP_TASK);
   15019 
   15020   g = gimple_build_omp_task (body,
   15021 			     OMP_TASK_CLAUSES (expr),
   15022 			     NULL_TREE, NULL_TREE,
   15023 			     NULL_TREE, NULL_TREE, NULL_TREE);
   15024   if (OMP_TASK_BODY (expr) == NULL_TREE)
   15025     gimple_omp_task_set_taskwait_p (g, true);
   15026   gimplify_seq_add_stmt (pre_p, g);
   15027   *expr_p = NULL_TREE;
   15028 }
   15029 
   15030 /* Helper function for gimplify_omp_for.  If *TP is not a gimple constant,
   15031    force it into a temporary initialized in PRE_P and add firstprivate clause
   15032    to ORIG_FOR_STMT.  */
   15033 
   15034 static void
   15035 gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
   15036 			    tree orig_for_stmt)
   15037 {
   15038   if (*tp == NULL || is_gimple_constant (*tp))
   15039     return;
   15040 
   15041   *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
   15042   /* Reference to pointer conversion is considered useless,
   15043      but is significant for firstprivate clause.  Force it
   15044      here.  */
   15045   if (type
   15046       && TREE_CODE (type) == POINTER_TYPE
   15047       && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
   15048     {
   15049       tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
   15050       tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
   15051       gimplify_and_add (m, pre_p);
   15052       *tp = v;
   15053     }
   15054 
   15055   tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
   15056   OMP_CLAUSE_DECL (c) = *tp;
   15057   OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
   15058   OMP_FOR_CLAUSES (orig_for_stmt) = c;
   15059 }
   15060 
   15061 /* Helper function of gimplify_omp_for, find OMP_ORDERED with
   15062    null OMP_ORDERED_BODY inside of OMP_FOR's body.  */
   15063 
   15064 static tree
   15065 find_standalone_omp_ordered (tree *tp, int *walk_subtrees, void *)
   15066 {
   15067   switch (TREE_CODE (*tp))
   15068     {
   15069     case OMP_ORDERED:
   15070       if (OMP_ORDERED_BODY (*tp) == NULL_TREE)
   15071 	return *tp;
   15072       break;
   15073     case OMP_SIMD:
   15074     case OMP_PARALLEL:
   15075     case OMP_TARGET:
   15076       *walk_subtrees = 0;
   15077       break;
   15078     default:
   15079       break;
   15080     }
   15081   return NULL_TREE;
   15082 }
   15083 
   15084 /* Gimplify the gross structure of an OMP_FOR statement.  */
   15085 
   15086 static enum gimplify_status
   15087 gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
   15088 {
   15089   tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
   15090   enum gimplify_status ret = GS_ALL_DONE;
   15091   enum gimplify_status tret;
   15092   gomp_for *gfor;
   15093   gimple_seq for_body, for_pre_body;
   15094   int i;
   15095   bitmap has_decl_expr = NULL;
   15096   enum omp_region_type ort = ORT_WORKSHARE;
   15097   bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
   15098 
   15099   orig_for_stmt = for_stmt = *expr_p;
   15100 
   15101   bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
   15102 		 != NULL_TREE);
   15103   if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
   15104     {
   15105       tree *data[4] = { NULL, NULL, NULL, NULL };
   15106       gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
   15107       inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
   15108 				  find_combined_omp_for, data, NULL);
   15109       if (inner_for_stmt == NULL_TREE)
   15110 	{
   15111 	  gcc_assert (seen_error ());
   15112 	  *expr_p = NULL_TREE;
   15113 	  return GS_ERROR;
   15114 	}
   15115       if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
   15116 	{
   15117 	  append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
   15118 					  &OMP_FOR_PRE_BODY (for_stmt));
   15119 	  OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
   15120 	}
   15121       if (OMP_FOR_PRE_BODY (inner_for_stmt))
   15122 	{
   15123 	  append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
   15124 					  &OMP_FOR_PRE_BODY (for_stmt));
   15125 	  OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
   15126 	}
   15127 
   15128       if (data[0])
   15129 	{
   15130 	  /* We have some statements or variable declarations in between
   15131 	     the composite construct directives.  Move them around the
   15132 	     inner_for_stmt.  */
   15133 	  data[0] = expr_p;
   15134 	  for (i = 0; i < 3; i++)
   15135 	    if (data[i])
   15136 	      {
   15137 		tree t = *data[i];
   15138 		if (i < 2 && data[i + 1] == &OMP_BODY (t))
   15139 		  data[i + 1] = data[i];
   15140 		*data[i] = OMP_BODY (t);
   15141 		tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
   15142 				    NULL_TREE, make_node (BLOCK));
   15143 		OMP_BODY (t) = body;
   15144 		append_to_statement_list_force (inner_for_stmt,
   15145 						&BIND_EXPR_BODY (body));
   15146 		*data[3] = t;
   15147 		data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
   15148 		gcc_assert (*data[3] == inner_for_stmt);
   15149 	      }
   15150 	  return GS_OK;
   15151 	}
   15152 
   15153       for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
   15154 	if (!loop_p
   15155 	    && OMP_FOR_ORIG_DECLS (inner_for_stmt)
   15156 	    && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
   15157 					i)) == TREE_LIST
   15158 	    && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
   15159 					   i)))
   15160 	  {
   15161 	    tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
   15162 	    /* Class iterators aren't allowed on OMP_SIMD, so the only
   15163 	       case we need to solve is distribute parallel for.  They are
   15164 	       allowed on the loop construct, but that is already handled
   15165 	       in gimplify_omp_loop.  */
   15166 	    gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
   15167 			&& TREE_CODE (for_stmt) == OMP_DISTRIBUTE
   15168 			&& data[1]);
   15169 	    tree orig_decl = TREE_PURPOSE (orig);
   15170 	    tree last = TREE_VALUE (orig);
   15171 	    tree *pc;
   15172 	    for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
   15173 		 *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
   15174 	      if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
   15175 		   || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
   15176 		  && OMP_CLAUSE_DECL (*pc) == orig_decl)
   15177 		break;
   15178 	    if (*pc == NULL_TREE)
   15179 	      {
   15180 		tree *spc;
   15181 		for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
   15182 		     *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
   15183 		  if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
   15184 		      && OMP_CLAUSE_DECL (*spc) == orig_decl)
   15185 		    break;
   15186 		if (*spc)
   15187 		  {
   15188 		    tree c = *spc;
   15189 		    *spc = OMP_CLAUSE_CHAIN (c);
   15190 		    OMP_CLAUSE_CHAIN (c) = NULL_TREE;
   15191 		    *pc = c;
   15192 		  }
   15193 	      }
   15194 	    if (*pc == NULL_TREE)
   15195 	      ;
   15196 	    else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
   15197 	      {
   15198 		/* private clause will appear only on inner_for_stmt.
   15199 		   Change it into firstprivate, and add private clause
   15200 		   on for_stmt.  */
   15201 		tree c = copy_node (*pc);
   15202 		OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
   15203 		OMP_FOR_CLAUSES (for_stmt) = c;
   15204 		OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
   15205 		lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
   15206 	      }
   15207 	    else
   15208 	      {
   15209 		/* lastprivate clause will appear on both inner_for_stmt
   15210 		   and for_stmt.  Add firstprivate clause to
   15211 		   inner_for_stmt.  */
   15212 		tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
   15213 					   OMP_CLAUSE_FIRSTPRIVATE);
   15214 		OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
   15215 		OMP_CLAUSE_CHAIN (c) = *pc;
   15216 		*pc = c;
   15217 		lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
   15218 	      }
   15219 	    tree c = build_omp_clause (UNKNOWN_LOCATION,
   15220 				       OMP_CLAUSE_FIRSTPRIVATE);
   15221 	    OMP_CLAUSE_DECL (c) = last;
   15222 	    OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
   15223 	    OMP_PARALLEL_CLAUSES (*data[1]) = c;
   15224 	    c = build_omp_clause (UNKNOWN_LOCATION,
   15225 				  *pc ? OMP_CLAUSE_SHARED
   15226 				      : OMP_CLAUSE_FIRSTPRIVATE);
   15227 	    OMP_CLAUSE_DECL (c) = orig_decl;
   15228 	    OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
   15229 	    OMP_PARALLEL_CLAUSES (*data[1]) = c;
   15230 	  }
   15231       /* Similarly, take care of C++ range for temporaries, those should
   15232 	 be firstprivate on OMP_PARALLEL if any.  */
   15233       if (data[1])
   15234 	for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
   15235 	  if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
   15236 	      && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
   15237 					  i)) == TREE_LIST
   15238 	      && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
   15239 					   i)))
   15240 	    {
   15241 	      tree orig
   15242 		= TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
   15243 	      tree v = TREE_CHAIN (orig);
   15244 	      tree c = build_omp_clause (UNKNOWN_LOCATION,
   15245 					 OMP_CLAUSE_FIRSTPRIVATE);
   15246 	      /* First add firstprivate clause for the __for_end artificial
   15247 		 decl.  */
   15248 	      OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
   15249 	      if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
   15250 		  == REFERENCE_TYPE)
   15251 		OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
   15252 	      OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
   15253 	      OMP_PARALLEL_CLAUSES (*data[1]) = c;
   15254 	      if (TREE_VEC_ELT (v, 0))
   15255 		{
   15256 		  /* And now the same for __for_range artificial decl if it
   15257 		     exists.  */
   15258 		  c = build_omp_clause (UNKNOWN_LOCATION,
   15259 					OMP_CLAUSE_FIRSTPRIVATE);
   15260 		  OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
   15261 		  if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
   15262 		      == REFERENCE_TYPE)
   15263 		    OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
   15264 		  OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
   15265 		  OMP_PARALLEL_CLAUSES (*data[1]) = c;
   15266 		}
   15267 	    }
   15268     }
   15269 
   15270   switch (TREE_CODE (for_stmt))
   15271     {
   15272     case OMP_FOR:
   15273       if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
   15274 	{
   15275 	  if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   15276 			       OMP_CLAUSE_SCHEDULE))
   15277 	    error_at (EXPR_LOCATION (for_stmt),
   15278 		      "%qs clause may not appear on non-rectangular %qs",
   15279 		      "schedule", lang_GNU_Fortran () ? "do" : "for");
   15280 	  if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
   15281 	    error_at (EXPR_LOCATION (for_stmt),
   15282 		      "%qs clause may not appear on non-rectangular %qs",
   15283 		      "ordered", lang_GNU_Fortran () ? "do" : "for");
   15284 	}
   15285       break;
   15286     case OMP_DISTRIBUTE:
   15287       if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
   15288 	  && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   15289 			      OMP_CLAUSE_DIST_SCHEDULE))
   15290 	error_at (EXPR_LOCATION (for_stmt),
   15291 		  "%qs clause may not appear on non-rectangular %qs",
   15292 		  "dist_schedule", "distribute");
   15293       break;
   15294     case OACC_LOOP:
   15295       ort = ORT_ACC;
   15296       break;
   15297     case OMP_TASKLOOP:
   15298       if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
   15299 	{
   15300 	  if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   15301 			       OMP_CLAUSE_GRAINSIZE))
   15302 	    error_at (EXPR_LOCATION (for_stmt),
   15303 		      "%qs clause may not appear on non-rectangular %qs",
   15304 		      "grainsize", "taskloop");
   15305 	  if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   15306 			       OMP_CLAUSE_NUM_TASKS))
   15307 	    error_at (EXPR_LOCATION (for_stmt),
   15308 		      "%qs clause may not appear on non-rectangular %qs",
   15309 		      "num_tasks", "taskloop");
   15310 	}
   15311       if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
   15312 	ort = ORT_UNTIED_TASKLOOP;
   15313       else
   15314 	ort = ORT_TASKLOOP;
   15315       break;
   15316     case OMP_SIMD:
   15317       ort = ORT_SIMD;
   15318       break;
   15319     default:
   15320       gcc_unreachable ();
   15321     }
   15322 
   15323   /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
   15324      clause for the IV.  */
   15325   if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
   15326     {
   15327       t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
   15328       gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   15329       decl = TREE_OPERAND (t, 0);
   15330       for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
   15331 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   15332 	    && OMP_CLAUSE_DECL (c) == decl)
   15333 	  {
   15334 	    OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
   15335 	    break;
   15336 	  }
   15337     }
   15338 
   15339   if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
   15340     gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
   15341 			       loop_p && TREE_CODE (for_stmt) != OMP_SIMD
   15342 			       ? OMP_LOOP : TREE_CODE (for_stmt));
   15343 
   15344   if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
   15345     gimplify_omp_ctxp->distribute = true;
   15346 
   15347   /* Handle OMP_FOR_INIT.  */
   15348   for_pre_body = NULL;
   15349   if ((ort == ORT_SIMD
   15350        || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
   15351       && OMP_FOR_PRE_BODY (for_stmt))
   15352     {
   15353       has_decl_expr = BITMAP_ALLOC (NULL);
   15354       if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
   15355 	  && VAR_P (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt))))
   15356 	{
   15357 	  t = OMP_FOR_PRE_BODY (for_stmt);
   15358 	  bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
   15359 	}
   15360       else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
   15361 	{
   15362 	  tree_stmt_iterator si;
   15363 	  for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
   15364 	       tsi_next (&si))
   15365 	    {
   15366 	      t = tsi_stmt (si);
   15367 	      if (TREE_CODE (t) == DECL_EXPR
   15368 		  && VAR_P (DECL_EXPR_DECL (t)))
   15369 		bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
   15370 	    }
   15371 	}
   15372     }
   15373   if (OMP_FOR_PRE_BODY (for_stmt))
   15374     {
   15375       if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
   15376 	gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
   15377       else
   15378 	{
   15379 	  struct gimplify_omp_ctx ctx;
   15380 	  memset (&ctx, 0, sizeof (ctx));
   15381 	  ctx.region_type = ORT_NONE;
   15382 	  gimplify_omp_ctxp = &ctx;
   15383 	  gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
   15384 	  gimplify_omp_ctxp = NULL;
   15385 	}
   15386     }
   15387   OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
   15388 
   15389   if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
   15390     for_stmt = inner_for_stmt;
   15391 
   15392   /* For taskloop, need to gimplify the start, end and step before the
   15393      taskloop, outside of the taskloop omp context.  */
   15394   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
   15395     {
   15396       for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   15397 	{
   15398 	  t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   15399 	  gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
   15400 				   ? pre_p : &for_pre_body);
   15401 	      tree type = TREE_TYPE (TREE_OPERAND (t, 0));
   15402 	  if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   15403 	    {
   15404 	      tree v = TREE_OPERAND (t, 1);
   15405 	      gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
   15406 					  for_pre_p, orig_for_stmt);
   15407 	      gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
   15408 					  for_pre_p, orig_for_stmt);
   15409 	    }
   15410 	  else
   15411 	    gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
   15412 					orig_for_stmt);
   15413 
   15414 	  /* Handle OMP_FOR_COND.  */
   15415 	  t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
   15416 	  if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   15417 	    {
   15418 	      tree v = TREE_OPERAND (t, 1);
   15419 	      gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
   15420 					  for_pre_p, orig_for_stmt);
   15421 	      gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
   15422 					  for_pre_p, orig_for_stmt);
   15423 	    }
   15424 	  else
   15425 	    gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
   15426 					orig_for_stmt);
   15427 
   15428 	  /* Handle OMP_FOR_INCR.  */
   15429 	  t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   15430 	  if (TREE_CODE (t) == MODIFY_EXPR)
   15431 	    {
   15432 	      decl = TREE_OPERAND (t, 0);
   15433 	      t = TREE_OPERAND (t, 1);
   15434 	      tree *tp = &TREE_OPERAND (t, 1);
   15435 	      if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
   15436 		tp = &TREE_OPERAND (t, 0);
   15437 
   15438 	      gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
   15439 					  orig_for_stmt);
   15440 	    }
   15441 	}
   15442 
   15443       gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
   15444 				 OMP_TASKLOOP);
   15445     }
   15446 
   15447   if (orig_for_stmt != for_stmt)
   15448     gimplify_omp_ctxp->combined_loop = true;
   15449 
   15450   for_body = NULL;
   15451   gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
   15452 	      == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
   15453   gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
   15454 	      == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
   15455 
   15456   tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
   15457   bool is_doacross = false;
   15458   if (c && walk_tree_without_duplicates (&OMP_FOR_BODY (for_stmt),
   15459 					 find_standalone_omp_ordered, NULL))
   15460     {
   15461       OMP_CLAUSE_ORDERED_DOACROSS (c) = 1;
   15462       is_doacross = true;
   15463       int len = TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt));
   15464       gimplify_omp_ctxp->loop_iter_var.create (len * 2);
   15465       for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
   15466 	if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
   15467 	  {
   15468 	    error_at (OMP_CLAUSE_LOCATION (*pc),
   15469 		      "%<linear%> clause may not be specified together "
   15470 		      "with %<ordered%> clause if stand-alone %<ordered%> "
   15471 		      "construct is nested in it");
   15472 	    *pc = OMP_CLAUSE_CHAIN (*pc);
   15473 	  }
   15474 	else
   15475 	  pc = &OMP_CLAUSE_CHAIN (*pc);
   15476     }
   15477   int collapse = 1, tile = 0;
   15478   c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
   15479   if (c)
   15480     collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
   15481   c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
   15482   if (c)
   15483     tile = list_length (OMP_CLAUSE_TILE_LIST (c));
   15484   c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
   15485   hash_set<tree> *allocate_uids = NULL;
   15486   if (c)
   15487     {
   15488       allocate_uids = new hash_set<tree>;
   15489       for (; c; c = OMP_CLAUSE_CHAIN (c))
   15490 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
   15491 	  allocate_uids->add (OMP_CLAUSE_DECL (c));
   15492     }
   15493   for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   15494     {
   15495       t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   15496       gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   15497       decl = TREE_OPERAND (t, 0);
   15498       gcc_assert (DECL_P (decl));
   15499       gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
   15500 		  || POINTER_TYPE_P (TREE_TYPE (decl)));
   15501       if (is_doacross)
   15502 	{
   15503 	  if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
   15504 	    {
   15505 	      tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   15506 	      if (TREE_CODE (orig_decl) == TREE_LIST)
   15507 		{
   15508 		  orig_decl = TREE_PURPOSE (orig_decl);
   15509 		  if (!orig_decl)
   15510 		    orig_decl = decl;
   15511 		}
   15512 	      gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
   15513 	    }
   15514 	  else
   15515 	    gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
   15516 	  gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
   15517 	}
   15518 
   15519       if (for_stmt == orig_for_stmt)
   15520 	{
   15521 	  tree orig_decl = decl;
   15522 	  if (OMP_FOR_ORIG_DECLS (for_stmt))
   15523 	    {
   15524 	      tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   15525 	      if (TREE_CODE (orig_decl) == TREE_LIST)
   15526 		{
   15527 		  orig_decl = TREE_PURPOSE (orig_decl);
   15528 		  if (!orig_decl)
   15529 		    orig_decl = decl;
   15530 		}
   15531 	    }
   15532 	  if (is_global_var (orig_decl) && DECL_THREAD_LOCAL_P (orig_decl))
   15533 	    error_at (EXPR_LOCATION (for_stmt),
   15534 		      "threadprivate iteration variable %qD", orig_decl);
   15535 	}
   15536 
   15537       /* Make sure the iteration variable is private.  */
   15538       tree c = NULL_TREE;
   15539       tree c2 = NULL_TREE;
   15540       if (orig_for_stmt != for_stmt)
   15541 	{
   15542 	  /* Preserve this information until we gimplify the inner simd.  */
   15543 	  if (has_decl_expr
   15544 	      && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
   15545 	    TREE_PRIVATE (t) = 1;
   15546 	}
   15547       else if (ort == ORT_SIMD)
   15548 	{
   15549 	  splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
   15550 						 (splay_tree_key) decl);
   15551 	  omp_is_private (gimplify_omp_ctxp, decl,
   15552 			  1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
   15553 			       != 1));
   15554 	  if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
   15555 	    {
   15556 	      omp_notice_variable (gimplify_omp_ctxp, decl, true);
   15557 	      if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
   15558 		for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   15559 						OMP_CLAUSE_LASTPRIVATE);
   15560 		     c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
   15561 					       OMP_CLAUSE_LASTPRIVATE))
   15562 		  if (OMP_CLAUSE_DECL (c3) == decl)
   15563 		    {
   15564 		      warning_at (OMP_CLAUSE_LOCATION (c3), OPT_Wopenmp,
   15565 				  "conditional %<lastprivate%> on loop "
   15566 				  "iterator %qD ignored", decl);
   15567 		      OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
   15568 		      n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
   15569 		    }
   15570 	    }
   15571 	  else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
   15572 	    {
   15573 	      c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
   15574 	      OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
   15575 	      unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
   15576 	      if ((has_decl_expr
   15577 		   && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
   15578 		  || TREE_PRIVATE (t))
   15579 		{
   15580 		  OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
   15581 		  flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
   15582 		}
   15583 	      struct gimplify_omp_ctx *outer
   15584 		= gimplify_omp_ctxp->outer_context;
   15585 	      if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   15586 		{
   15587 		  if (outer->region_type == ORT_WORKSHARE
   15588 		      && outer->combined_loop)
   15589 		    {
   15590 		      n = splay_tree_lookup (outer->variables,
   15591 					     (splay_tree_key)decl);
   15592 		      if (n != NULL && (n->value & GOVD_LOCAL) != 0)
   15593 			{
   15594 			  OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
   15595 			  flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
   15596 			}
   15597 		      else
   15598 			{
   15599 			  struct gimplify_omp_ctx *octx = outer->outer_context;
   15600 			  if (octx
   15601 			      && octx->region_type == ORT_COMBINED_PARALLEL
   15602 			      && octx->outer_context
   15603 			      && (octx->outer_context->region_type
   15604 				  == ORT_WORKSHARE)
   15605 			      && octx->outer_context->combined_loop)
   15606 			    {
   15607 			      octx = octx->outer_context;
   15608 			      n = splay_tree_lookup (octx->variables,
   15609 						     (splay_tree_key)decl);
   15610 			      if (n != NULL && (n->value & GOVD_LOCAL) != 0)
   15611 				{
   15612 				  OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
   15613 				  flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
   15614 				}
   15615 			    }
   15616 			}
   15617 		    }
   15618 		}
   15619 
   15620 	      OMP_CLAUSE_DECL (c) = decl;
   15621 	      OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
   15622 	      OMP_FOR_CLAUSES (for_stmt) = c;
   15623 	      omp_add_variable (gimplify_omp_ctxp, decl, flags);
   15624 	      if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   15625 		omp_lastprivate_for_combined_outer_constructs (outer, decl,
   15626 							       true);
   15627 	    }
   15628 	  else
   15629 	    {
   15630 	      bool lastprivate
   15631 		= (!has_decl_expr
   15632 		   || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
   15633 	      if (TREE_PRIVATE (t))
   15634 		lastprivate = false;
   15635 	      if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
   15636 		{
   15637 		  tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   15638 		  if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
   15639 		    lastprivate = false;
   15640 		}
   15641 
   15642 	      struct gimplify_omp_ctx *outer
   15643 		= gimplify_omp_ctxp->outer_context;
   15644 	      if (outer && lastprivate)
   15645 		omp_lastprivate_for_combined_outer_constructs (outer, decl,
   15646 							       true);
   15647 
   15648 	      c = build_omp_clause (input_location,
   15649 				    lastprivate ? OMP_CLAUSE_LASTPRIVATE
   15650 						: OMP_CLAUSE_PRIVATE);
   15651 	      OMP_CLAUSE_DECL (c) = decl;
   15652 	      OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
   15653 	      OMP_FOR_CLAUSES (for_stmt) = c;
   15654 	      omp_add_variable (gimplify_omp_ctxp, decl,
   15655 				(lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
   15656 				| GOVD_EXPLICIT | GOVD_SEEN);
   15657 	      c = NULL_TREE;
   15658 	    }
   15659 	}
   15660       else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
   15661 	{
   15662 	  omp_notice_variable (gimplify_omp_ctxp, decl, true);
   15663 	  splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
   15664 						 (splay_tree_key) decl);
   15665 	  if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
   15666 	    for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   15667 					    OMP_CLAUSE_LASTPRIVATE);
   15668 		 c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
   15669 					   OMP_CLAUSE_LASTPRIVATE))
   15670 	      if (OMP_CLAUSE_DECL (c3) == decl)
   15671 		{
   15672 		  warning_at (OMP_CLAUSE_LOCATION (c3), OPT_Wopenmp,
   15673 			      "conditional %<lastprivate%> on loop "
   15674 			      "iterator %qD ignored", decl);
   15675 		  OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
   15676 		  n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
   15677 		}
   15678 	}
   15679       else
   15680 	omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
   15681 
   15682       /* If DECL is not a gimple register, create a temporary variable to act
   15683 	 as an iteration counter.  This is valid, since DECL cannot be
   15684 	 modified in the body of the loop.  Similarly for any iteration vars
   15685 	 in simd with collapse > 1 where the iterator vars must be
   15686 	 lastprivate.  And similarly for vars mentioned in allocate clauses.  */
   15687       if (orig_for_stmt != for_stmt)
   15688 	var = decl;
   15689       else if (!is_gimple_reg (decl)
   15690 	       || (ort == ORT_SIMD
   15691 		   && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
   15692 	       || (allocate_uids && allocate_uids->contains (decl)))
   15693 	{
   15694 	  struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   15695 	  /* Make sure omp_add_variable is not called on it prematurely.
   15696 	     We call it ourselves a few lines later.  */
   15697 	  gimplify_omp_ctxp = NULL;
   15698 	  var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
   15699 	  gimplify_omp_ctxp = ctx;
   15700 	  TREE_OPERAND (t, 0) = var;
   15701 
   15702 	  gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
   15703 
   15704 	  if (ort == ORT_SIMD
   15705 	      && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
   15706 	    {
   15707 	      c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
   15708 	      OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
   15709 	      OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
   15710 	      OMP_CLAUSE_DECL (c2) = var;
   15711 	      OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
   15712 	      OMP_FOR_CLAUSES (for_stmt) = c2;
   15713 	      omp_add_variable (gimplify_omp_ctxp, var,
   15714 				GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
   15715 	      if (c == NULL_TREE)
   15716 		{
   15717 		  c = c2;
   15718 		  c2 = NULL_TREE;
   15719 		}
   15720 	    }
   15721 	  else
   15722 	    omp_add_variable (gimplify_omp_ctxp, var,
   15723 			      GOVD_PRIVATE | GOVD_SEEN);
   15724 	}
   15725       else
   15726 	var = decl;
   15727 
   15728       gimplify_omp_ctxp->in_for_exprs = true;
   15729       if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   15730 	{
   15731 	  tree lb = TREE_OPERAND (t, 1);
   15732 	  tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
   15733 				is_gimple_val, fb_rvalue, false);
   15734 	  ret = MIN (ret, tret);
   15735 	  tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
   15736 				is_gimple_val, fb_rvalue, false);
   15737 	}
   15738       else
   15739 	tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
   15740 			      is_gimple_val, fb_rvalue, false);
   15741       gimplify_omp_ctxp->in_for_exprs = false;
   15742       ret = MIN (ret, tret);
   15743       if (ret == GS_ERROR)
   15744 	return ret;
   15745 
   15746       /* Handle OMP_FOR_COND.  */
   15747       t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
   15748       gcc_assert (COMPARISON_CLASS_P (t));
   15749       gcc_assert (TREE_OPERAND (t, 0) == decl);
   15750 
   15751       gimplify_omp_ctxp->in_for_exprs = true;
   15752       if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   15753 	{
   15754 	  tree ub = TREE_OPERAND (t, 1);
   15755 	  tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
   15756 				is_gimple_val, fb_rvalue, false);
   15757 	  ret = MIN (ret, tret);
   15758 	  tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
   15759 				is_gimple_val, fb_rvalue, false);
   15760 	}
   15761       else
   15762 	tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
   15763 			      is_gimple_val, fb_rvalue, false);
   15764       gimplify_omp_ctxp->in_for_exprs = false;
   15765       ret = MIN (ret, tret);
   15766 
   15767       /* Handle OMP_FOR_INCR.  */
   15768       t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   15769       switch (TREE_CODE (t))
   15770 	{
   15771 	case PREINCREMENT_EXPR:
   15772 	case POSTINCREMENT_EXPR:
   15773 	  {
   15774 	    tree decl = TREE_OPERAND (t, 0);
   15775 	    /* c_omp_for_incr_canonicalize_ptr() should have been
   15776 	       called to massage things appropriately.  */
   15777 	    gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
   15778 
   15779 	    if (orig_for_stmt != for_stmt)
   15780 	      break;
   15781 	    t = build_int_cst (TREE_TYPE (decl), 1);
   15782 	    if (c)
   15783 	      OMP_CLAUSE_LINEAR_STEP (c) = t;
   15784 	    t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
   15785 	    t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
   15786 	    TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
   15787 	    break;
   15788 	  }
   15789 
   15790 	case PREDECREMENT_EXPR:
   15791 	case POSTDECREMENT_EXPR:
   15792 	  /* c_omp_for_incr_canonicalize_ptr() should have been
   15793 	     called to massage things appropriately.  */
   15794 	  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
   15795 	  if (orig_for_stmt != for_stmt)
   15796 	    break;
   15797 	  t = build_int_cst (TREE_TYPE (decl), -1);
   15798 	  if (c)
   15799 	    OMP_CLAUSE_LINEAR_STEP (c) = t;
   15800 	  t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
   15801 	  t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
   15802 	  TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
   15803 	  break;
   15804 
   15805 	case MODIFY_EXPR:
   15806 	  gcc_assert (TREE_OPERAND (t, 0) == decl);
   15807 	  TREE_OPERAND (t, 0) = var;
   15808 
   15809 	  t = TREE_OPERAND (t, 1);
   15810 	  switch (TREE_CODE (t))
   15811 	    {
   15812 	    case PLUS_EXPR:
   15813 	      if (TREE_OPERAND (t, 1) == decl)
   15814 		{
   15815 		  TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
   15816 		  TREE_OPERAND (t, 0) = var;
   15817 		  break;
   15818 		}
   15819 
   15820 	      /* Fallthru.  */
   15821 	    case MINUS_EXPR:
   15822 	    case POINTER_PLUS_EXPR:
   15823 	      gcc_assert (TREE_OPERAND (t, 0) == decl);
   15824 	      TREE_OPERAND (t, 0) = var;
   15825 	      break;
   15826 	    default:
   15827 	      gcc_unreachable ();
   15828 	    }
   15829 
   15830 	  gimplify_omp_ctxp->in_for_exprs = true;
   15831 	  tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
   15832 				is_gimple_val, fb_rvalue, false);
   15833 	  ret = MIN (ret, tret);
   15834 	  if (c)
   15835 	    {
   15836 	      tree step = TREE_OPERAND (t, 1);
   15837 	      tree stept = TREE_TYPE (decl);
   15838 	      if (POINTER_TYPE_P (stept))
   15839 		stept = sizetype;
   15840 	      step = fold_convert (stept, step);
   15841 	      if (TREE_CODE (t) == MINUS_EXPR)
   15842 		step = fold_build1 (NEGATE_EXPR, stept, step);
   15843 	      OMP_CLAUSE_LINEAR_STEP (c) = step;
   15844 	      if (step != TREE_OPERAND (t, 1))
   15845 		{
   15846 		  tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
   15847 					&for_pre_body, NULL,
   15848 					is_gimple_val, fb_rvalue, false);
   15849 		  ret = MIN (ret, tret);
   15850 		}
   15851 	    }
   15852 	  gimplify_omp_ctxp->in_for_exprs = false;
   15853 	  break;
   15854 
   15855 	default:
   15856 	  gcc_unreachable ();
   15857 	}
   15858 
   15859       if (c2)
   15860 	{
   15861 	  gcc_assert (c);
   15862 	  OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
   15863 	}
   15864 
   15865       if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
   15866 	{
   15867 	  for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
   15868 	    if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   15869 		  && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
   15870 		 || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   15871 		     && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
   15872 		     && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
   15873 		&& OMP_CLAUSE_DECL (c) == decl)
   15874 	      {
   15875 		if (is_doacross && (collapse == 1 || i >= collapse))
   15876 		  t = var;
   15877 		else
   15878 		  {
   15879 		    t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   15880 		    gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   15881 		    gcc_assert (TREE_OPERAND (t, 0) == var);
   15882 		    t = TREE_OPERAND (t, 1);
   15883 		    gcc_assert (TREE_CODE (t) == PLUS_EXPR
   15884 				|| TREE_CODE (t) == MINUS_EXPR
   15885 				|| TREE_CODE (t) == POINTER_PLUS_EXPR);
   15886 		    gcc_assert (TREE_OPERAND (t, 0) == var);
   15887 		    t = build2 (TREE_CODE (t), TREE_TYPE (decl),
   15888 				is_doacross ? var : decl,
   15889 				TREE_OPERAND (t, 1));
   15890 		  }
   15891 		gimple_seq *seq;
   15892 		if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
   15893 		  seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
   15894 		else
   15895 		  seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
   15896 		push_gimplify_context ();
   15897 		gimplify_assign (decl, t, seq);
   15898 		gimple *bind = NULL;
   15899 		if (gimplify_ctxp->temps)
   15900 		  {
   15901 		    bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
   15902 		    *seq = NULL;
   15903 		    gimplify_seq_add_stmt (seq, bind);
   15904 		  }
   15905 		pop_gimplify_context (bind);
   15906 	      }
   15907 	}
   15908       if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
   15909 	for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
   15910 	  {
   15911 	    t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
   15912 	    gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   15913 	    if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
   15914 		&& TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
   15915 	      TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
   15916 	    t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
   15917 	    gcc_assert (COMPARISON_CLASS_P (t));
   15918 	    if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
   15919 		&& TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
   15920 	      TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
   15921 	  }
   15922     }
   15923 
   15924   BITMAP_FREE (has_decl_expr);
   15925   delete allocate_uids;
   15926 
   15927   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
   15928       || (loop_p && orig_for_stmt == for_stmt))
   15929     {
   15930       push_gimplify_context ();
   15931       if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
   15932 	{
   15933 	  OMP_FOR_BODY (orig_for_stmt)
   15934 	    = build3 (BIND_EXPR, void_type_node, NULL,
   15935 		      OMP_FOR_BODY (orig_for_stmt), NULL);
   15936 	  TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
   15937 	}
   15938     }
   15939 
   15940   gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
   15941 					 &for_body);
   15942 
   15943   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
   15944       || (loop_p && orig_for_stmt == for_stmt))
   15945     {
   15946       if (gimple_code (g) == GIMPLE_BIND)
   15947 	pop_gimplify_context (g);
   15948       else
   15949 	pop_gimplify_context (NULL);
   15950     }
   15951 
   15952   if (orig_for_stmt != for_stmt)
   15953     for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   15954       {
   15955 	t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   15956 	decl = TREE_OPERAND (t, 0);
   15957 	struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   15958 	if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
   15959 	  gimplify_omp_ctxp = ctx->outer_context;
   15960 	var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
   15961 	gimplify_omp_ctxp = ctx;
   15962 	omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
   15963 	TREE_OPERAND (t, 0) = var;
   15964 	t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   15965 	TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
   15966 	TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
   15967 	if (OMP_FOR_NON_RECTANGULAR (for_stmt))
   15968 	  for (int j = i + 1;
   15969 	       j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
   15970 	    {
   15971 	      t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
   15972 	      gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   15973 	      if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
   15974 		  && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
   15975 		{
   15976 		  TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
   15977 		  TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
   15978 		}
   15979 	      t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
   15980 	      gcc_assert (COMPARISON_CLASS_P (t));
   15981 	      if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
   15982 		  && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
   15983 		{
   15984 		  TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
   15985 		  TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
   15986 		}
   15987 	  }
   15988       }
   15989 
   15990   gimplify_adjust_omp_clauses (pre_p, for_body,
   15991 			       &OMP_FOR_CLAUSES (orig_for_stmt),
   15992 			       TREE_CODE (orig_for_stmt));
   15993 
   15994   int kind;
   15995   switch (TREE_CODE (orig_for_stmt))
   15996     {
   15997     case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
   15998     case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
   15999     case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
   16000     case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
   16001     case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
   16002     default:
   16003       gcc_unreachable ();
   16004     }
   16005   if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
   16006     {
   16007       gimplify_seq_add_seq (pre_p, for_pre_body);
   16008       for_pre_body = NULL;
   16009     }
   16010   gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
   16011 			       TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
   16012 			       for_pre_body);
   16013   if (orig_for_stmt != for_stmt)
   16014     gimple_omp_for_set_combined_p (gfor, true);
   16015   if (gimplify_omp_ctxp
   16016       && (gimplify_omp_ctxp->combined_loop
   16017 	  || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
   16018 	      && gimplify_omp_ctxp->outer_context
   16019 	      && gimplify_omp_ctxp->outer_context->combined_loop)))
   16020     {
   16021       gimple_omp_for_set_combined_into_p (gfor, true);
   16022       if (gimplify_omp_ctxp->combined_loop)
   16023 	gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
   16024       else
   16025 	gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
   16026     }
   16027 
   16028   for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   16029     {
   16030       t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   16031       gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
   16032       gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
   16033       t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
   16034       gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
   16035       gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
   16036       t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   16037       gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
   16038     }
   16039 
   16040   /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
   16041      constructs with GIMPLE_OMP_TASK sandwiched in between them.
   16042      The outer taskloop stands for computing the number of iterations,
   16043      counts for collapsed loops and holding taskloop specific clauses.
   16044      The task construct stands for the effect of data sharing on the
   16045      explicit task it creates and the inner taskloop stands for expansion
   16046      of the static loop inside of the explicit task construct.  */
   16047   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
   16048     {
   16049       tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
   16050       tree task_clauses = NULL_TREE;
   16051       tree c = *gfor_clauses_ptr;
   16052       tree *gtask_clauses_ptr = &task_clauses;
   16053       tree outer_for_clauses = NULL_TREE;
   16054       tree *gforo_clauses_ptr = &outer_for_clauses;
   16055       bitmap lastprivate_uids = NULL;
   16056       if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
   16057 	{
   16058 	  c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
   16059 	  if (c)
   16060 	    {
   16061 	      lastprivate_uids = BITMAP_ALLOC (NULL);
   16062 	      for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
   16063 					     OMP_CLAUSE_LASTPRIVATE))
   16064 		bitmap_set_bit (lastprivate_uids,
   16065 				DECL_UID (OMP_CLAUSE_DECL (c)));
   16066 	    }
   16067 	  c = *gfor_clauses_ptr;
   16068 	}
   16069       for (; c; c = OMP_CLAUSE_CHAIN (c))
   16070 	switch (OMP_CLAUSE_CODE (c))
   16071 	  {
   16072 	  /* These clauses are allowed on task, move them there.  */
   16073 	  case OMP_CLAUSE_SHARED:
   16074 	  case OMP_CLAUSE_FIRSTPRIVATE:
   16075 	  case OMP_CLAUSE_DEFAULT:
   16076 	  case OMP_CLAUSE_IF:
   16077 	  case OMP_CLAUSE_UNTIED:
   16078 	  case OMP_CLAUSE_FINAL:
   16079 	  case OMP_CLAUSE_MERGEABLE:
   16080 	  case OMP_CLAUSE_PRIORITY:
   16081 	  case OMP_CLAUSE_REDUCTION:
   16082 	  case OMP_CLAUSE_IN_REDUCTION:
   16083 	    *gtask_clauses_ptr = c;
   16084 	    gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   16085 	    break;
   16086 	  case OMP_CLAUSE_PRIVATE:
   16087 	    if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
   16088 	      {
   16089 		/* We want private on outer for and firstprivate
   16090 		   on task.  */
   16091 		*gtask_clauses_ptr
   16092 		  = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   16093 				      OMP_CLAUSE_FIRSTPRIVATE);
   16094 		OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
   16095 		lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
   16096 						    openacc);
   16097 		gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   16098 		*gforo_clauses_ptr = c;
   16099 		gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   16100 	      }
   16101 	    else
   16102 	      {
   16103 		*gtask_clauses_ptr = c;
   16104 		gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   16105 	      }
   16106 	    break;
   16107 	  /* These clauses go into outer taskloop clauses.  */
   16108 	  case OMP_CLAUSE_GRAINSIZE:
   16109 	  case OMP_CLAUSE_NUM_TASKS:
   16110 	  case OMP_CLAUSE_NOGROUP:
   16111 	    *gforo_clauses_ptr = c;
   16112 	    gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   16113 	    break;
   16114 	  /* Collapse clause we duplicate on both taskloops.  */
   16115 	  case OMP_CLAUSE_COLLAPSE:
   16116 	    *gfor_clauses_ptr = c;
   16117 	    gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   16118 	    *gforo_clauses_ptr = copy_node (c);
   16119 	    gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
   16120 	    break;
   16121 	  /* For lastprivate, keep the clause on inner taskloop, and add
   16122 	     a shared clause on task.  If the same decl is also firstprivate,
   16123 	     add also firstprivate clause on the inner taskloop.  */
   16124 	  case OMP_CLAUSE_LASTPRIVATE:
   16125 	    if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
   16126 	      {
   16127 		/* For taskloop C++ lastprivate IVs, we want:
   16128 		   1) private on outer taskloop
   16129 		   2) firstprivate and shared on task
   16130 		   3) lastprivate on inner taskloop  */
   16131 		*gtask_clauses_ptr
   16132 		  = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   16133 				      OMP_CLAUSE_FIRSTPRIVATE);
   16134 		OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
   16135 		lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
   16136 						    openacc);
   16137 		gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   16138 		OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
   16139 		*gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   16140 						       OMP_CLAUSE_PRIVATE);
   16141 		OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
   16142 		OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
   16143 		TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
   16144 		gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
   16145 	      }
   16146 	    *gfor_clauses_ptr = c;
   16147 	    gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   16148 	    *gtask_clauses_ptr
   16149 	      = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
   16150 	    OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
   16151 	    if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
   16152 	      OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
   16153 	    gtask_clauses_ptr
   16154 	      = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   16155 	    break;
   16156 	  /* Allocate clause we duplicate on task and inner taskloop
   16157 	     if the decl is lastprivate, otherwise just put on task.  */
   16158 	  case OMP_CLAUSE_ALLOCATE:
   16159 	    if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
   16160 		&& DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
   16161 	      {
   16162 		/* Additionally, put firstprivate clause on task
   16163 		   for the allocator if it is not constant.  */
   16164 		*gtask_clauses_ptr
   16165 		  = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   16166 				      OMP_CLAUSE_FIRSTPRIVATE);
   16167 		OMP_CLAUSE_DECL (*gtask_clauses_ptr)
   16168 		  = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
   16169 		gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   16170 	      }
   16171 	    if (lastprivate_uids
   16172 		&& bitmap_bit_p (lastprivate_uids,
   16173 				 DECL_UID (OMP_CLAUSE_DECL (c))))
   16174 	      {
   16175 		*gfor_clauses_ptr = c;
   16176 		gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   16177 		*gtask_clauses_ptr = copy_node (c);
   16178 		gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   16179 	      }
   16180 	    else
   16181 	      {
   16182 		*gtask_clauses_ptr = c;
   16183 		gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   16184 	      }
   16185 	    break;
   16186 	  default:
   16187 	    gcc_unreachable ();
   16188 	  }
   16189       *gfor_clauses_ptr = NULL_TREE;
   16190       *gtask_clauses_ptr = NULL_TREE;
   16191       *gforo_clauses_ptr = NULL_TREE;
   16192       BITMAP_FREE (lastprivate_uids);
   16193       gimple_set_location (gfor, input_location);
   16194       g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
   16195       g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
   16196 				 NULL_TREE, NULL_TREE, NULL_TREE);
   16197       gimple_set_location (g, input_location);
   16198       gimple_omp_task_set_taskloop_p (g, true);
   16199       g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
   16200       gomp_for *gforo
   16201 	= gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
   16202 				gimple_omp_for_collapse (gfor),
   16203 				gimple_omp_for_pre_body (gfor));
   16204       gimple_omp_for_set_pre_body (gfor, NULL);
   16205       gimple_omp_for_set_combined_p (gforo, true);
   16206       gimple_omp_for_set_combined_into_p (gfor, true);
   16207       for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
   16208 	{
   16209 	  tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
   16210 	  tree v = create_tmp_var (type);
   16211 	  gimple_omp_for_set_index (gforo, i, v);
   16212 	  t = unshare_expr (gimple_omp_for_initial (gfor, i));
   16213 	  gimple_omp_for_set_initial (gforo, i, t);
   16214 	  gimple_omp_for_set_cond (gforo, i,
   16215 				   gimple_omp_for_cond (gfor, i));
   16216 	  t = unshare_expr (gimple_omp_for_final (gfor, i));
   16217 	  gimple_omp_for_set_final (gforo, i, t);
   16218 	  t = unshare_expr (gimple_omp_for_incr (gfor, i));
   16219 	  gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
   16220 	  TREE_OPERAND (t, 0) = v;
   16221 	  gimple_omp_for_set_incr (gforo, i, t);
   16222 	  t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
   16223 	  OMP_CLAUSE_DECL (t) = v;
   16224 	  OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
   16225 	  gimple_omp_for_set_clauses (gforo, t);
   16226 	  if (OMP_FOR_NON_RECTANGULAR (for_stmt))
   16227 	    {
   16228 	      tree *p1 = NULL, *p2 = NULL;
   16229 	      t = gimple_omp_for_initial (gforo, i);
   16230 	      if (TREE_CODE (t) == TREE_VEC)
   16231 		p1 = &TREE_VEC_ELT (t, 0);
   16232 	      t = gimple_omp_for_final (gforo, i);
   16233 	      if (TREE_CODE (t) == TREE_VEC)
   16234 		{
   16235 		  if (p1)
   16236 		    p2 = &TREE_VEC_ELT (t, 0);
   16237 		  else
   16238 		    p1 = &TREE_VEC_ELT (t, 0);
   16239 		}
   16240 	      if (p1)
   16241 		{
   16242 		  int j;
   16243 		  for (j = 0; j < i; j++)
   16244 		    if (*p1 == gimple_omp_for_index (gfor, j))
   16245 		      {
   16246 			*p1 = gimple_omp_for_index (gforo, j);
   16247 			if (p2)
   16248 			  *p2 = *p1;
   16249 			break;
   16250 		      }
   16251 		  gcc_assert (j < i);
   16252 		}
   16253 	    }
   16254 	}
   16255       gimplify_seq_add_stmt (pre_p, gforo);
   16256     }
   16257   else
   16258     gimplify_seq_add_stmt (pre_p, gfor);
   16259 
   16260   if (TREE_CODE (orig_for_stmt) == OMP_FOR)
   16261     {
   16262       struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   16263       unsigned lastprivate_conditional = 0;
   16264       while (ctx
   16265 	     && (ctx->region_type == ORT_TARGET_DATA
   16266 		 || ctx->region_type == ORT_TASKGROUP))
   16267 	ctx = ctx->outer_context;
   16268       if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
   16269 	for (tree c = gimple_omp_for_clauses (gfor);
   16270 	     c; c = OMP_CLAUSE_CHAIN (c))
   16271 	  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   16272 	      && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   16273 	    ++lastprivate_conditional;
   16274       if (lastprivate_conditional)
   16275 	{
   16276 	  struct omp_for_data fd;
   16277 	  omp_extract_for_data (gfor, &fd, NULL);
   16278 	  tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
   16279 					      lastprivate_conditional);
   16280 	  tree var = create_tmp_var_raw (type);
   16281 	  tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
   16282 	  OMP_CLAUSE_DECL (c) = var;
   16283 	  OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
   16284 	  gimple_omp_for_set_clauses (gfor, c);
   16285 	  omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
   16286 	}
   16287     }
   16288   else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
   16289     {
   16290       unsigned lastprivate_conditional = 0;
   16291       for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
   16292 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   16293 	    && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   16294 	  ++lastprivate_conditional;
   16295       if (lastprivate_conditional)
   16296 	{
   16297 	  struct omp_for_data fd;
   16298 	  omp_extract_for_data (gfor, &fd, NULL);
   16299 	  tree type = unsigned_type_for (fd.iter_type);
   16300 	  while (lastprivate_conditional--)
   16301 	    {
   16302 	      tree c = build_omp_clause (UNKNOWN_LOCATION,
   16303 					 OMP_CLAUSE__CONDTEMP_);
   16304 	      OMP_CLAUSE_DECL (c) = create_tmp_var (type);
   16305 	      OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
   16306 	      gimple_omp_for_set_clauses (gfor, c);
   16307 	    }
   16308 	}
   16309     }
   16310 
   16311   if (ret != GS_ALL_DONE)
   16312     return GS_ERROR;
   16313   *expr_p = NULL_TREE;
   16314   return GS_ALL_DONE;
   16315 }
   16316 
   16317 /* Helper for gimplify_omp_loop, called through walk_tree.  */
   16318 
   16319 static tree
   16320 note_no_context_vars (tree *tp, int *, void *data)
   16321 {
   16322   if (VAR_P (*tp)
   16323       && DECL_CONTEXT (*tp) == NULL_TREE
   16324       && !is_global_var (*tp))
   16325     {
   16326       vec<tree> *d = (vec<tree> *) data;
   16327       d->safe_push (*tp);
   16328       DECL_CONTEXT (*tp) = current_function_decl;
   16329     }
   16330   return NULL_TREE;
   16331 }
   16332 
   16333 /* Gimplify the gross structure of an OMP_LOOP statement.  */
   16334 
   16335 static enum gimplify_status
   16336 gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
   16337 {
   16338   tree for_stmt = *expr_p;
   16339   tree clauses = OMP_FOR_CLAUSES (for_stmt);
   16340   struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
   16341   enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
   16342   int i;
   16343 
   16344   /* If order is not present, the behavior is as if order(concurrent)
   16345      appeared.  */
   16346   tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
   16347   if (order == NULL_TREE)
   16348     {
   16349       order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
   16350       OMP_CLAUSE_CHAIN (order) = clauses;
   16351       OMP_FOR_CLAUSES (for_stmt) = clauses = order;
   16352     }
   16353 
   16354   tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
   16355   if (bind == NULL_TREE)
   16356     {
   16357       if (!flag_openmp) /* flag_openmp_simd */
   16358 	;
   16359       else if (octx && (octx->region_type & ORT_TEAMS) != 0)
   16360 	kind = OMP_CLAUSE_BIND_TEAMS;
   16361       else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
   16362 	kind = OMP_CLAUSE_BIND_PARALLEL;
   16363       else
   16364 	{
   16365 	  for (; octx; octx = octx->outer_context)
   16366 	    {
   16367 	      if ((octx->region_type & ORT_ACC) != 0
   16368 		  || octx->region_type == ORT_NONE
   16369 		  || octx->region_type == ORT_IMPLICIT_TARGET)
   16370 		continue;
   16371 	      break;
   16372 	    }
   16373 	  if (octx == NULL && !in_omp_construct)
   16374 	    error_at (EXPR_LOCATION (for_stmt),
   16375 		      "%<bind%> clause not specified on a %<loop%> "
   16376 		      "construct not nested inside another OpenMP construct");
   16377 	}
   16378       bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
   16379       OMP_CLAUSE_CHAIN (bind) = clauses;
   16380       OMP_CLAUSE_BIND_KIND (bind) = kind;
   16381       OMP_FOR_CLAUSES (for_stmt) = bind;
   16382     }
   16383   else
   16384     switch (OMP_CLAUSE_BIND_KIND (bind))
   16385       {
   16386       case OMP_CLAUSE_BIND_THREAD:
   16387 	break;
   16388       case OMP_CLAUSE_BIND_PARALLEL:
   16389 	if (!flag_openmp) /* flag_openmp_simd */
   16390 	  {
   16391 	    OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
   16392 	    break;
   16393 	  }
   16394 	for (; octx; octx = octx->outer_context)
   16395 	  if (octx->region_type == ORT_SIMD
   16396 	      && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
   16397 	    {
   16398 	      error_at (EXPR_LOCATION (for_stmt),
   16399 			"%<bind(parallel)%> on a %<loop%> construct nested "
   16400 			"inside %<simd%> construct");
   16401 	      OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
   16402 	      break;
   16403 	    }
   16404 	kind = OMP_CLAUSE_BIND_PARALLEL;
   16405 	break;
   16406       case OMP_CLAUSE_BIND_TEAMS:
   16407 	if (!flag_openmp) /* flag_openmp_simd */
   16408 	  {
   16409 	    OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
   16410 	    break;
   16411 	  }
   16412 	if ((octx
   16413 	     && octx->region_type != ORT_IMPLICIT_TARGET
   16414 	     && octx->region_type != ORT_NONE
   16415 	     && (octx->region_type & ORT_TEAMS) == 0)
   16416 	    || in_omp_construct)
   16417 	  {
   16418 	    error_at (EXPR_LOCATION (for_stmt),
   16419 		      "%<bind(teams)%> on a %<loop%> region not strictly "
   16420 		      "nested inside of a %<teams%> region");
   16421 	    OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
   16422 	    break;
   16423 	  }
   16424 	kind = OMP_CLAUSE_BIND_TEAMS;
   16425 	break;
   16426       default:
   16427 	gcc_unreachable ();
   16428       }
   16429 
   16430   for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
   16431     switch (OMP_CLAUSE_CODE (*pc))
   16432       {
   16433       case OMP_CLAUSE_REDUCTION:
   16434 	if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
   16435 	  {
   16436 	    error_at (OMP_CLAUSE_LOCATION (*pc),
   16437 		      "%<inscan%> %<reduction%> clause on "
   16438 		      "%qs construct", "loop");
   16439 	    OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
   16440 	  }
   16441 	if (OMP_CLAUSE_REDUCTION_TASK (*pc))
   16442 	  {
   16443 	    error_at (OMP_CLAUSE_LOCATION (*pc),
   16444 		      "invalid %<task%> reduction modifier on construct "
   16445 		      "other than %<parallel%>, %qs or %<sections%>",
   16446 		      lang_GNU_Fortran () ? "do" : "for");
   16447 	    OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
   16448 	  }
   16449 	pc = &OMP_CLAUSE_CHAIN (*pc);
   16450 	break;
   16451       case OMP_CLAUSE_LASTPRIVATE:
   16452 	for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   16453 	  {
   16454 	    tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   16455 	    gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   16456 	    if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
   16457 	      break;
   16458 	    if (OMP_FOR_ORIG_DECLS (for_stmt)
   16459 		&& TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
   16460 					    i)) == TREE_LIST
   16461 		&& TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
   16462 					       i)))
   16463 	      {
   16464 		tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   16465 		if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
   16466 		  break;
   16467 	      }
   16468 	  }
   16469 	if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
   16470 	  {
   16471 	    error_at (OMP_CLAUSE_LOCATION (*pc),
   16472 		      "%<lastprivate%> clause on a %<loop%> construct refers "
   16473 		      "to a variable %qD which is not the loop iterator",
   16474 		      OMP_CLAUSE_DECL (*pc));
   16475 	    *pc = OMP_CLAUSE_CHAIN (*pc);
   16476 	    break;
   16477 	  }
   16478 	pc = &OMP_CLAUSE_CHAIN (*pc);
   16479 	break;
   16480       default:
   16481 	pc = &OMP_CLAUSE_CHAIN (*pc);
   16482 	break;
   16483     }
   16484 
   16485   TREE_SET_CODE (for_stmt, OMP_SIMD);
   16486 
   16487   int last;
   16488   switch (kind)
   16489     {
   16490     case OMP_CLAUSE_BIND_THREAD: last = 0; break;
   16491     case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
   16492     case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
   16493     }
   16494   for (int pass = 1; pass <= last; pass++)
   16495     {
   16496       if (pass == 2)
   16497 	{
   16498 	  tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
   16499 			      make_node (BLOCK));
   16500 	  append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
   16501 	  *expr_p = make_node (OMP_PARALLEL);
   16502 	  TREE_TYPE (*expr_p) = void_type_node;
   16503 	  OMP_PARALLEL_BODY (*expr_p) = bind;
   16504 	  OMP_PARALLEL_COMBINED (*expr_p) = 1;
   16505 	  SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
   16506 	  tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
   16507 	  for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   16508 	    if (OMP_FOR_ORIG_DECLS (for_stmt)
   16509 		&& (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
   16510 		    == TREE_LIST))
   16511 	      {
   16512 		tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   16513 		if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
   16514 		  {
   16515 		    *pc = build_omp_clause (UNKNOWN_LOCATION,
   16516 					    OMP_CLAUSE_FIRSTPRIVATE);
   16517 		    OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
   16518 		    pc = &OMP_CLAUSE_CHAIN (*pc);
   16519 		  }
   16520 	      }
   16521 	}
   16522       tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
   16523       tree *pc = &OMP_FOR_CLAUSES (t);
   16524       TREE_TYPE (t) = void_type_node;
   16525       OMP_FOR_BODY (t) = *expr_p;
   16526       SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
   16527       for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
   16528 	switch (OMP_CLAUSE_CODE (c))
   16529 	  {
   16530 	  case OMP_CLAUSE_BIND:
   16531 	  case OMP_CLAUSE_ORDER:
   16532 	  case OMP_CLAUSE_COLLAPSE:
   16533 	    *pc = copy_node (c);
   16534 	    pc = &OMP_CLAUSE_CHAIN (*pc);
   16535 	    break;
   16536 	  case OMP_CLAUSE_PRIVATE:
   16537 	  case OMP_CLAUSE_FIRSTPRIVATE:
   16538 	    /* Only needed on innermost.  */
   16539 	    break;
   16540 	  case OMP_CLAUSE_LASTPRIVATE:
   16541 	    if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
   16542 	      {
   16543 		*pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   16544 					OMP_CLAUSE_FIRSTPRIVATE);
   16545 		OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
   16546 		lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
   16547 		pc = &OMP_CLAUSE_CHAIN (*pc);
   16548 	      }
   16549 	    *pc = copy_node (c);
   16550 	    OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
   16551 	    TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
   16552 	    if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
   16553 	      {
   16554 		if (pass != last)
   16555 		  OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
   16556 		else
   16557 		  lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
   16558 		OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
   16559 	      }
   16560 	    pc = &OMP_CLAUSE_CHAIN (*pc);
   16561 	    break;
   16562 	  case OMP_CLAUSE_REDUCTION:
   16563 	    *pc = copy_node (c);
   16564 	    OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
   16565 	    TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
   16566 	    if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
   16567 	      {
   16568 		auto_vec<tree> no_context_vars;
   16569 		int walk_subtrees = 0;
   16570 		note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
   16571 				      &walk_subtrees, &no_context_vars);
   16572 		if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c))
   16573 		  note_no_context_vars (&p, &walk_subtrees, &no_context_vars);
   16574 		walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c),
   16575 					      note_no_context_vars,
   16576 					      &no_context_vars);
   16577 		walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c),
   16578 					      note_no_context_vars,
   16579 					      &no_context_vars);
   16580 
   16581 		OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
   16582 		  = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
   16583 		if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
   16584 		  OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
   16585 		    = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
   16586 
   16587 		hash_map<tree, tree> decl_map;
   16588 		decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c));
   16589 		decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
   16590 			      OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc));
   16591 		if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
   16592 		  decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
   16593 				OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc));
   16594 
   16595 		copy_body_data id;
   16596 		memset (&id, 0, sizeof (id));
   16597 		id.src_fn = current_function_decl;
   16598 		id.dst_fn = current_function_decl;
   16599 		id.src_cfun = cfun;
   16600 		id.decl_map = &decl_map;
   16601 		id.copy_decl = copy_decl_no_change;
   16602 		id.transform_call_graph_edges = CB_CGE_DUPLICATE;
   16603 		id.transform_new_cfg = true;
   16604 		id.transform_return_to_modify = false;
   16605 		id.eh_lp_nr = 0;
   16606 		walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r,
   16607 			   &id, NULL);
   16608 		walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r,
   16609 			   &id, NULL);
   16610 
   16611 		for (tree d : no_context_vars)
   16612 		  {
   16613 		    DECL_CONTEXT (d) = NULL_TREE;
   16614 		    DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE;
   16615 		  }
   16616 	      }
   16617 	    else
   16618 	      {
   16619 		OMP_CLAUSE_REDUCTION_INIT (*pc)
   16620 		  = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
   16621 		OMP_CLAUSE_REDUCTION_MERGE (*pc)
   16622 		  = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
   16623 	      }
   16624 	    pc = &OMP_CLAUSE_CHAIN (*pc);
   16625 	    break;
   16626 	  default:
   16627 	    gcc_unreachable ();
   16628 	  }
   16629       *pc = NULL_TREE;
   16630       *expr_p = t;
   16631     }
   16632   return gimplify_expr (expr_p, pre_p, NULL, is_gimple_stmt, fb_none);
   16633 }
   16634 
   16635 
   16636 /* Helper function of optimize_target_teams, find OMP_TEAMS inside
   16637    of OMP_TARGET's body.  */
   16638 
   16639 static tree
   16640 find_omp_teams (tree *tp, int *walk_subtrees, void *)
   16641 {
   16642   *walk_subtrees = 0;
   16643   switch (TREE_CODE (*tp))
   16644     {
   16645     case OMP_TEAMS:
   16646       return *tp;
   16647     case BIND_EXPR:
   16648     case STATEMENT_LIST:
   16649       *walk_subtrees = 1;
   16650       break;
   16651     default:
   16652       break;
   16653     }
   16654   return NULL_TREE;
   16655 }
   16656 
   16657 /* Helper function of optimize_target_teams, determine if the expression
   16658    can be computed safely before the target construct on the host.  */
   16659 
   16660 static tree
   16661 computable_teams_clause (tree *tp, int *walk_subtrees, void *)
   16662 {
   16663   splay_tree_node n;
   16664 
   16665   if (TYPE_P (*tp))
   16666     {
   16667       *walk_subtrees = 0;
   16668       return NULL_TREE;
   16669     }
   16670   switch (TREE_CODE (*tp))
   16671     {
   16672     case VAR_DECL:
   16673     case PARM_DECL:
   16674     case RESULT_DECL:
   16675       *walk_subtrees = 0;
   16676       if (error_operand_p (*tp)
   16677 	  || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
   16678 	  || DECL_HAS_VALUE_EXPR_P (*tp)
   16679 	  || DECL_THREAD_LOCAL_P (*tp)
   16680 	  || TREE_SIDE_EFFECTS (*tp)
   16681 	  || TREE_THIS_VOLATILE (*tp))
   16682 	return *tp;
   16683       if (is_global_var (*tp)
   16684 	  && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
   16685 	      || lookup_attribute ("omp declare target link",
   16686 				   DECL_ATTRIBUTES (*tp))))
   16687 	return *tp;
   16688       if (VAR_P (*tp)
   16689 	  && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
   16690 	  && !is_global_var (*tp)
   16691 	  && decl_function_context (*tp) == current_function_decl)
   16692 	return *tp;
   16693       n = splay_tree_lookup (gimplify_omp_ctxp->variables,
   16694 			     (splay_tree_key) *tp);
   16695       if (n == NULL)
   16696 	{
   16697 	  if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
   16698 	    return NULL_TREE;
   16699 	  return *tp;
   16700 	}
   16701       else if (n->value & GOVD_LOCAL)
   16702 	return *tp;
   16703       else if (n->value & GOVD_FIRSTPRIVATE)
   16704 	return NULL_TREE;
   16705       else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
   16706 	       == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
   16707 	return NULL_TREE;
   16708       return *tp;
   16709     case INTEGER_CST:
   16710       if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
   16711 	return *tp;
   16712       return NULL_TREE;
   16713     case TARGET_EXPR:
   16714       if (TARGET_EXPR_INITIAL (*tp)
   16715 	  || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
   16716 	return *tp;
   16717       return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
   16718 				      walk_subtrees, NULL);
   16719     /* Allow some reasonable subset of integral arithmetics.  */
   16720     case PLUS_EXPR:
   16721     case MINUS_EXPR:
   16722     case MULT_EXPR:
   16723     case TRUNC_DIV_EXPR:
   16724     case CEIL_DIV_EXPR:
   16725     case FLOOR_DIV_EXPR:
   16726     case ROUND_DIV_EXPR:
   16727     case TRUNC_MOD_EXPR:
   16728     case CEIL_MOD_EXPR:
   16729     case FLOOR_MOD_EXPR:
   16730     case ROUND_MOD_EXPR:
   16731     case RDIV_EXPR:
   16732     case EXACT_DIV_EXPR:
   16733     case MIN_EXPR:
   16734     case MAX_EXPR:
   16735     case LSHIFT_EXPR:
   16736     case RSHIFT_EXPR:
   16737     case BIT_IOR_EXPR:
   16738     case BIT_XOR_EXPR:
   16739     case BIT_AND_EXPR:
   16740     case NEGATE_EXPR:
   16741     case ABS_EXPR:
   16742     case BIT_NOT_EXPR:
   16743     case NON_LVALUE_EXPR:
   16744     CASE_CONVERT:
   16745       if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
   16746 	return *tp;
   16747       return NULL_TREE;
   16748     /* And disallow anything else, except for comparisons.  */
   16749     default:
   16750       if (COMPARISON_CLASS_P (*tp))
   16751 	return NULL_TREE;
   16752       return *tp;
   16753     }
   16754 }
   16755 
   16756 /* Try to determine if the num_teams and/or thread_limit expressions
   16757    can have their values determined already before entering the
   16758    target construct.
   16759    INTEGER_CSTs trivially are,
   16760    integral decls that are firstprivate (explicitly or implicitly)
   16761    or explicitly map(always, to:) or map(always, tofrom:) on the target
   16762    region too, and expressions involving simple arithmetics on those
   16763    too, function calls are not ok, dereferencing something neither etc.
   16764    Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
   16765    EXPR based on what we find:
   16766    0 stands for clause not specified at all, use implementation default
   16767    -1 stands for value that can't be determined easily before entering
   16768       the target construct.
   16769    -2 means that no explicit teams construct was specified
   16770    If teams construct is not present at all, use 1 for num_teams
   16771    and 0 for thread_limit (only one team is involved, and the thread
   16772    limit is implementation defined.  */
   16773 
   16774 static void
   16775 optimize_target_teams (tree target, gimple_seq *pre_p)
   16776 {
   16777   tree body = OMP_BODY (target);
   16778   tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
   16779   tree num_teams_lower = NULL_TREE;
   16780   tree num_teams_upper = integer_zero_node;
   16781   tree thread_limit = integer_zero_node;
   16782   location_t num_teams_loc = EXPR_LOCATION (target);
   16783   location_t thread_limit_loc = EXPR_LOCATION (target);
   16784   tree c, *p, expr;
   16785   struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
   16786 
   16787   if (teams == NULL_TREE)
   16788     num_teams_upper = build_int_cst (integer_type_node, -2);
   16789   else
   16790     for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
   16791       {
   16792 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
   16793 	  {
   16794 	    p = &num_teams_upper;
   16795 	    num_teams_loc = OMP_CLAUSE_LOCATION (c);
   16796 	    if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))
   16797 	      {
   16798 		expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
   16799 		if (TREE_CODE (expr) == INTEGER_CST)
   16800 		  num_teams_lower = expr;
   16801 		else if (walk_tree (&expr, computable_teams_clause,
   16802 				    NULL, NULL))
   16803 		  num_teams_lower = integer_minus_one_node;
   16804 		else
   16805 		  {
   16806 		    num_teams_lower = expr;
   16807 		    gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
   16808 		    if (gimplify_expr (&num_teams_lower, pre_p, NULL,
   16809 				       is_gimple_val, fb_rvalue, false)
   16810 			== GS_ERROR)
   16811 		      {
   16812 			gimplify_omp_ctxp = target_ctx;
   16813 			num_teams_lower = integer_minus_one_node;
   16814 		      }
   16815 		    else
   16816 		      {
   16817 			gimplify_omp_ctxp = target_ctx;
   16818 			if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
   16819 			  OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
   16820 			    = num_teams_lower;
   16821 		      }
   16822 		  }
   16823 	      }
   16824 	  }
   16825 	else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
   16826 	  {
   16827 	    p = &thread_limit;
   16828 	    thread_limit_loc = OMP_CLAUSE_LOCATION (c);
   16829 	  }
   16830 	else
   16831 	  continue;
   16832 	expr = OMP_CLAUSE_OPERAND (c, 0);
   16833 	if (TREE_CODE (expr) == INTEGER_CST)
   16834 	  {
   16835 	    *p = expr;
   16836 	    continue;
   16837 	  }
   16838 	if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
   16839 	  {
   16840 	    *p = integer_minus_one_node;
   16841 	    continue;
   16842 	  }
   16843 	*p = expr;
   16844 	gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
   16845 	if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
   16846 	    == GS_ERROR)
   16847 	  {
   16848 	    gimplify_omp_ctxp = target_ctx;
   16849 	    *p = integer_minus_one_node;
   16850 	    continue;
   16851 	  }
   16852 	gimplify_omp_ctxp = target_ctx;
   16853 	if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
   16854 	  OMP_CLAUSE_OPERAND (c, 0) = *p;
   16855       }
   16856   if (!omp_find_clause (OMP_TARGET_CLAUSES (target), OMP_CLAUSE_THREAD_LIMIT))
   16857     {
   16858       c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
   16859       OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
   16860       OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
   16861       OMP_TARGET_CLAUSES (target) = c;
   16862     }
   16863   c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
   16864   OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper;
   16865   OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower;
   16866   OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
   16867   OMP_TARGET_CLAUSES (target) = c;
   16868 }
   16869 
   16870 /* Gimplify the gross structure of several OMP constructs.  */
   16871 
   16872 static void
   16873 gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
   16874 {
   16875   tree expr = *expr_p;
   16876   gimple *stmt;
   16877   gimple_seq body = NULL;
   16878   enum omp_region_type ort;
   16879 
   16880   switch (TREE_CODE (expr))
   16881     {
   16882     case OMP_SECTIONS:
   16883     case OMP_SINGLE:
   16884       ort = ORT_WORKSHARE;
   16885       break;
   16886     case OMP_SCOPE:
   16887       ort = ORT_TASKGROUP;
   16888       break;
   16889     case OMP_TARGET:
   16890       ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
   16891       break;
   16892     case OACC_KERNELS:
   16893       ort = ORT_ACC_KERNELS;
   16894       break;
   16895     case OACC_PARALLEL:
   16896       ort = ORT_ACC_PARALLEL;
   16897       break;
   16898     case OACC_SERIAL:
   16899       ort = ORT_ACC_SERIAL;
   16900       break;
   16901     case OACC_DATA:
   16902       ort = ORT_ACC_DATA;
   16903       break;
   16904     case OMP_TARGET_DATA:
   16905       ort = ORT_TARGET_DATA;
   16906       break;
   16907     case OMP_TEAMS:
   16908       ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
   16909       if (gimplify_omp_ctxp == NULL
   16910 	  || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
   16911 	ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
   16912       break;
   16913     case OACC_HOST_DATA:
   16914       ort = ORT_ACC_HOST_DATA;
   16915       break;
   16916     default:
   16917       gcc_unreachable ();
   16918     }
   16919 
   16920   bool save_in_omp_construct = in_omp_construct;
   16921   if ((ort & ORT_ACC) == 0)
   16922     in_omp_construct = false;
   16923   gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
   16924 			     TREE_CODE (expr));
   16925   if (TREE_CODE (expr) == OMP_TARGET)
   16926     optimize_target_teams (expr, pre_p);
   16927   if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
   16928       || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
   16929     {
   16930       push_gimplify_context ();
   16931       gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
   16932       if (gimple_code (g) == GIMPLE_BIND)
   16933 	pop_gimplify_context (g);
   16934       else
   16935 	pop_gimplify_context (NULL);
   16936       if ((ort & ORT_TARGET_DATA) != 0)
   16937 	{
   16938 	  enum built_in_function end_ix;
   16939 	  switch (TREE_CODE (expr))
   16940 	    {
   16941 	    case OACC_DATA:
   16942 	    case OACC_HOST_DATA:
   16943 	      end_ix = BUILT_IN_GOACC_DATA_END;
   16944 	      break;
   16945 	    case OMP_TARGET_DATA:
   16946 	      end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
   16947 	      break;
   16948 	    default:
   16949 	      gcc_unreachable ();
   16950 	    }
   16951 	  tree fn = builtin_decl_explicit (end_ix);
   16952 	  g = gimple_build_call (fn, 0);
   16953 	  gimple_seq cleanup = NULL;
   16954 	  gimple_seq_add_stmt (&cleanup, g);
   16955 	  g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
   16956 	  body = NULL;
   16957 	  gimple_seq_add_stmt (&body, g);
   16958 	}
   16959     }
   16960   else
   16961     gimplify_and_add (OMP_BODY (expr), &body);
   16962   gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
   16963 			       TREE_CODE (expr));
   16964   in_omp_construct = save_in_omp_construct;
   16965 
   16966   switch (TREE_CODE (expr))
   16967     {
   16968     case OACC_DATA:
   16969       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
   16970 				      OMP_CLAUSES (expr));
   16971       break;
   16972     case OACC_HOST_DATA:
   16973       if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
   16974 	{
   16975 	  for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   16976 	    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
   16977 	      OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
   16978 	}
   16979 
   16980       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
   16981 				      OMP_CLAUSES (expr));
   16982       break;
   16983     case OACC_KERNELS:
   16984       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
   16985 				      OMP_CLAUSES (expr));
   16986       break;
   16987     case OACC_PARALLEL:
   16988       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
   16989 				      OMP_CLAUSES (expr));
   16990       break;
   16991     case OACC_SERIAL:
   16992       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
   16993 				      OMP_CLAUSES (expr));
   16994       break;
   16995     case OMP_SECTIONS:
   16996       stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
   16997       break;
   16998     case OMP_SINGLE:
   16999       stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
   17000       break;
   17001     case OMP_SCOPE:
   17002       stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr));
   17003       break;
   17004     case OMP_TARGET:
   17005       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
   17006 				      OMP_CLAUSES (expr));
   17007       break;
   17008     case OMP_TARGET_DATA:
   17009       /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
   17010 	 to be evaluated before the use_device_{ptr,addr} clauses if they
   17011 	 refer to the same variables.  */
   17012       {
   17013 	tree use_device_clauses;
   17014 	tree *pc, *uc = &use_device_clauses;
   17015 	for (pc = &OMP_CLAUSES (expr); *pc; )
   17016 	  if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
   17017 	      || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
   17018 	    {
   17019 	      *uc = *pc;
   17020 	      *pc = OMP_CLAUSE_CHAIN (*pc);
   17021 	      uc = &OMP_CLAUSE_CHAIN (*uc);
   17022 	    }
   17023 	  else
   17024 	    pc = &OMP_CLAUSE_CHAIN (*pc);
   17025 	*uc = NULL_TREE;
   17026 	*pc = use_device_clauses;
   17027 	stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
   17028 					OMP_CLAUSES (expr));
   17029       }
   17030       break;
   17031     case OMP_TEAMS:
   17032       stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
   17033       if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
   17034 	gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
   17035       break;
   17036     default:
   17037       gcc_unreachable ();
   17038     }
   17039 
   17040   gimplify_seq_add_stmt (pre_p, stmt);
   17041   *expr_p = NULL_TREE;
   17042 }
   17043 
   17044 /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
   17045    target update constructs.  */
   17046 
   17047 static void
   17048 gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
   17049 {
   17050   tree expr = *expr_p;
   17051   int kind;
   17052   gomp_target *stmt;
   17053   enum omp_region_type ort = ORT_WORKSHARE;
   17054 
   17055   switch (TREE_CODE (expr))
   17056     {
   17057     case OACC_ENTER_DATA:
   17058       kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA;
   17059       ort = ORT_ACC;
   17060       break;
   17061     case OACC_EXIT_DATA:
   17062       kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA;
   17063       ort = ORT_ACC;
   17064       break;
   17065     case OACC_UPDATE:
   17066       kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
   17067       ort = ORT_ACC;
   17068       break;
   17069     case OMP_TARGET_UPDATE:
   17070       kind = GF_OMP_TARGET_KIND_UPDATE;
   17071       break;
   17072     case OMP_TARGET_ENTER_DATA:
   17073       kind = GF_OMP_TARGET_KIND_ENTER_DATA;
   17074       break;
   17075     case OMP_TARGET_EXIT_DATA:
   17076       kind = GF_OMP_TARGET_KIND_EXIT_DATA;
   17077       break;
   17078     default:
   17079       gcc_unreachable ();
   17080     }
   17081   gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
   17082 			     ort, TREE_CODE (expr));
   17083   gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
   17084 			       TREE_CODE (expr));
   17085   if (TREE_CODE (expr) == OACC_UPDATE
   17086       && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
   17087 			  OMP_CLAUSE_IF_PRESENT))
   17088     {
   17089       /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
   17090 	 clause.  */
   17091       for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   17092 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
   17093 	  switch (OMP_CLAUSE_MAP_KIND (c))
   17094 	    {
   17095 	    case GOMP_MAP_FORCE_TO:
   17096 	      OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
   17097 	      break;
   17098 	    case GOMP_MAP_FORCE_FROM:
   17099 	      OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
   17100 	      break;
   17101 	    default:
   17102 	      break;
   17103 	    }
   17104     }
   17105   else if (TREE_CODE (expr) == OACC_EXIT_DATA
   17106 	   && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
   17107 			       OMP_CLAUSE_FINALIZE))
   17108     {
   17109       /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
   17110 	 semantics.  */
   17111       bool have_clause = false;
   17112       for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   17113 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
   17114 	  switch (OMP_CLAUSE_MAP_KIND (c))
   17115 	    {
   17116 	    case GOMP_MAP_FROM:
   17117 	      OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
   17118 	      have_clause = true;
   17119 	      break;
   17120 	    case GOMP_MAP_RELEASE:
   17121 	      OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
   17122 	      have_clause = true;
   17123 	      break;
   17124 	    case GOMP_MAP_TO_PSET:
   17125 	      /* Fortran arrays with descriptors must map that descriptor when
   17126 		 doing standalone "attach" operations (in OpenACC).  In that
   17127 		 case GOMP_MAP_TO_PSET appears by itself with no preceding
   17128 		 clause (see trans-openmp.cc:gfc_trans_omp_clauses).  */
   17129 	      break;
   17130 	    case GOMP_MAP_POINTER:
   17131 	      /* TODO PR92929: we may see these here, but they'll always follow
   17132 		 one of the clauses above, and will be handled by libgomp as
   17133 		 one group, so no handling required here.  */
   17134 	      gcc_assert (have_clause);
   17135 	      break;
   17136 	    case GOMP_MAP_DETACH:
   17137 	      OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
   17138 	      have_clause = false;
   17139 	      break;
   17140 	    case GOMP_MAP_STRUCT:
   17141 	    case GOMP_MAP_STRUCT_UNORD:
   17142 	      have_clause = false;
   17143 	      break;
   17144 	    default:
   17145 	      gcc_unreachable ();
   17146 	    }
   17147     }
   17148   stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr));
   17149 
   17150   gimplify_seq_add_stmt (pre_p, stmt);
   17151   *expr_p = NULL_TREE;
   17152 }
   17153 
   17154 /* A subroutine of gimplify_omp_atomic.  The front end is supposed to have
   17155    stabilized the lhs of the atomic operation as *ADDR.  Return true if
   17156    EXPR is this stabilized form.  */
   17157 
   17158 static bool
   17159 goa_lhs_expr_p (tree expr, tree addr)
   17160 {
   17161   /* Also include casts to other type variants.  The C front end is fond
   17162      of adding these for e.g. volatile variables.  This is like
   17163      STRIP_TYPE_NOPS but includes the main variant lookup.  */
   17164   STRIP_USELESS_TYPE_CONVERSION (expr);
   17165 
   17166   if (INDIRECT_REF_P (expr))
   17167     {
   17168       expr = TREE_OPERAND (expr, 0);
   17169       while (expr != addr
   17170 	     && (CONVERT_EXPR_P (expr)
   17171 		 || TREE_CODE (expr) == NON_LVALUE_EXPR)
   17172 	     && TREE_CODE (expr) == TREE_CODE (addr)
   17173 	     && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
   17174 	{
   17175 	  expr = TREE_OPERAND (expr, 0);
   17176 	  addr = TREE_OPERAND (addr, 0);
   17177 	}
   17178       if (expr == addr)
   17179 	return true;
   17180       return (TREE_CODE (addr) == ADDR_EXPR
   17181 	      && TREE_CODE (expr) == ADDR_EXPR
   17182 	      && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
   17183     }
   17184   if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
   17185     return true;
   17186   return false;
   17187 }
   17188 
   17189 /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR.  If an
   17190    expression does not involve the lhs, evaluate it into a temporary.
   17191    Return 1 if the lhs appeared as a subexpression, 0 if it did not,
   17192    or -1 if an error was encountered.  */
   17193 
   17194 static int
   17195 goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
   17196 		    tree lhs_var, tree &target_expr, bool rhs, int depth)
   17197 {
   17198   tree expr = *expr_p;
   17199   int saw_lhs = 0;
   17200 
   17201   if (goa_lhs_expr_p (expr, lhs_addr))
   17202     {
   17203       if (pre_p)
   17204 	*expr_p = lhs_var;
   17205       return 1;
   17206     }
   17207   if (is_gimple_val (expr))
   17208     return 0;
   17209 
   17210   /* Maximum depth of lhs in expression is for the
   17211      __builtin_clear_padding (...), __builtin_clear_padding (...),
   17212      __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs;  */
   17213   if (++depth > 7)
   17214     goto finish;
   17215 
   17216   switch (TREE_CODE_CLASS (TREE_CODE (expr)))
   17217     {
   17218     case tcc_binary:
   17219     case tcc_comparison:
   17220       saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
   17221 				     lhs_var, target_expr, true, depth);
   17222       /* FALLTHRU */
   17223     case tcc_unary:
   17224       saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
   17225 				     lhs_var, target_expr, true, depth);
   17226       break;
   17227     case tcc_expression:
   17228       switch (TREE_CODE (expr))
   17229 	{
   17230 	case TRUTH_ANDIF_EXPR:
   17231 	case TRUTH_ORIF_EXPR:
   17232 	case TRUTH_AND_EXPR:
   17233 	case TRUTH_OR_EXPR:
   17234 	case TRUTH_XOR_EXPR:
   17235 	case BIT_INSERT_EXPR:
   17236 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
   17237 					 lhs_addr, lhs_var, target_expr, true,
   17238 					 depth);
   17239 	  /* FALLTHRU */
   17240 	case TRUTH_NOT_EXPR:
   17241 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   17242 					 lhs_addr, lhs_var, target_expr, true,
   17243 					 depth);
   17244 	  break;
   17245 	case MODIFY_EXPR:
   17246 	  if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
   17247 					    target_expr, true, depth))
   17248 	    break;
   17249 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
   17250 					 lhs_addr, lhs_var, target_expr, true,
   17251 					 depth);
   17252 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   17253 					 lhs_addr, lhs_var, target_expr, false,
   17254 					 depth);
   17255 	  break;
   17256 	  /* FALLTHRU */
   17257 	case ADDR_EXPR:
   17258 	  if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
   17259 					    target_expr, true, depth))
   17260 	    break;
   17261 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   17262 					 lhs_addr, lhs_var, target_expr, false,
   17263 					 depth);
   17264 	  break;
   17265 	case COMPOUND_EXPR:
   17266 	  /* Break out any preevaluations from cp_build_modify_expr.  */
   17267 	  for (; TREE_CODE (expr) == COMPOUND_EXPR;
   17268 	       expr = TREE_OPERAND (expr, 1))
   17269 	    {
   17270 	      /* Special-case __builtin_clear_padding call before
   17271 		 __builtin_memcmp.  */
   17272 	      if (TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR)
   17273 		{
   17274 		  tree fndecl = get_callee_fndecl (TREE_OPERAND (expr, 0));
   17275 		  if (fndecl
   17276 		      && fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
   17277 		      && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
   17278 		      && (!pre_p
   17279 			  || goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL,
   17280 						 lhs_addr, lhs_var,
   17281 						 target_expr, true, depth)))
   17282 		    {
   17283 		      if (pre_p)
   17284 			*expr_p = expr;
   17285 		      saw_lhs = goa_stabilize_expr (&TREE_OPERAND (expr, 0),
   17286 						    pre_p, lhs_addr, lhs_var,
   17287 						    target_expr, true, depth);
   17288 		      saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1),
   17289 						     pre_p, lhs_addr, lhs_var,
   17290 						     target_expr, rhs, depth);
   17291 		      return saw_lhs;
   17292 		    }
   17293 		}
   17294 
   17295 	      if (pre_p)
   17296 		gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
   17297 	    }
   17298 	  if (!pre_p)
   17299 	    return goa_stabilize_expr (&expr, pre_p, lhs_addr, lhs_var,
   17300 				       target_expr, rhs, depth);
   17301 	  *expr_p = expr;
   17302 	  return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var,
   17303 				     target_expr, rhs, depth);
   17304 	case COND_EXPR:
   17305 	  if (!goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, lhs_addr,
   17306 				   lhs_var, target_expr, true, depth))
   17307 	    break;
   17308 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   17309 					 lhs_addr, lhs_var, target_expr, true,
   17310 					 depth);
   17311 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
   17312 					 lhs_addr, lhs_var, target_expr, true,
   17313 					 depth);
   17314 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 2), pre_p,
   17315 					 lhs_addr, lhs_var, target_expr, true,
   17316 					 depth);
   17317 	  break;
   17318 	case TARGET_EXPR:
   17319 	  if (TARGET_EXPR_INITIAL (expr))
   17320 	    {
   17321 	      if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr,
   17322 						lhs_var, target_expr, true,
   17323 						depth))
   17324 		break;
   17325 	      if (expr == target_expr)
   17326 		saw_lhs = 1;
   17327 	      else
   17328 		{
   17329 		  saw_lhs = goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr),
   17330 						pre_p, lhs_addr, lhs_var,
   17331 						target_expr, true, depth);
   17332 		  if (saw_lhs && target_expr == NULL_TREE && pre_p)
   17333 		    target_expr = expr;
   17334 		}
   17335 	    }
   17336 	  break;
   17337 	default:
   17338 	  break;
   17339 	}
   17340       break;
   17341     case tcc_reference:
   17342       if (TREE_CODE (expr) == BIT_FIELD_REF
   17343 	  || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
   17344 	saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   17345 				       lhs_addr, lhs_var, target_expr, true,
   17346 				       depth);
   17347       break;
   17348     case tcc_vl_exp:
   17349       if (TREE_CODE (expr) == CALL_EXPR)
   17350 	{
   17351 	  if (tree fndecl = get_callee_fndecl (expr))
   17352 	    if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING,
   17353 					   BUILT_IN_MEMCMP))
   17354 	      {
   17355 		int nargs = call_expr_nargs (expr);
   17356 		for (int i = 0; i < nargs; i++)
   17357 		  saw_lhs |= goa_stabilize_expr (&CALL_EXPR_ARG (expr, i),
   17358 						 pre_p, lhs_addr, lhs_var,
   17359 						 target_expr, true, depth);
   17360 	      }
   17361 	}
   17362       break;
   17363     default:
   17364       break;
   17365     }
   17366 
   17367  finish:
   17368   if (saw_lhs == 0 && pre_p)
   17369     {
   17370       enum gimplify_status gs;
   17371       if (TREE_CODE (expr) == CALL_EXPR && VOID_TYPE_P (TREE_TYPE (expr)))
   17372 	{
   17373 	  gimplify_stmt (&expr, pre_p);
   17374 	  return saw_lhs;
   17375 	}
   17376       else if (rhs)
   17377 	gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
   17378       else
   17379 	gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_lvalue, fb_lvalue);
   17380       if (gs != GS_ALL_DONE)
   17381 	saw_lhs = -1;
   17382     }
   17383 
   17384   return saw_lhs;
   17385 }
   17386 
   17387 /* Gimplify an OMP_ATOMIC statement.  */
   17388 
   17389 static enum gimplify_status
   17390 gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
   17391 {
   17392   tree addr = TREE_OPERAND (*expr_p, 0);
   17393   tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
   17394 	     ? NULL : TREE_OPERAND (*expr_p, 1);
   17395   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
   17396   tree tmp_load;
   17397   gomp_atomic_load *loadstmt;
   17398   gomp_atomic_store *storestmt;
   17399   tree target_expr = NULL_TREE;
   17400 
   17401   tmp_load = create_tmp_reg (type);
   17402   if (rhs
   17403       && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load, target_expr,
   17404 			     true, 0) < 0)
   17405     return GS_ERROR;
   17406 
   17407   if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
   17408       != GS_ALL_DONE)
   17409     return GS_ERROR;
   17410 
   17411   loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
   17412 					   OMP_ATOMIC_MEMORY_ORDER (*expr_p));
   17413   gimplify_seq_add_stmt (pre_p, loadstmt);
   17414   if (rhs)
   17415     {
   17416       /* BIT_INSERT_EXPR is not valid for non-integral bitfield
   17417 	 representatives.  Use BIT_FIELD_REF on the lhs instead.  */
   17418       tree rhsarg = rhs;
   17419       if (TREE_CODE (rhs) == COND_EXPR)
   17420 	rhsarg = TREE_OPERAND (rhs, 1);
   17421       if (TREE_CODE (rhsarg) == BIT_INSERT_EXPR
   17422 	  && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
   17423 	{
   17424 	  tree bitpos = TREE_OPERAND (rhsarg, 2);
   17425 	  tree op1 = TREE_OPERAND (rhsarg, 1);
   17426 	  tree bitsize;
   17427 	  tree tmp_store = tmp_load;
   17428 	  if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
   17429 	    tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
   17430 	  if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
   17431 	    bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
   17432 	  else
   17433 	    bitsize = TYPE_SIZE (TREE_TYPE (op1));
   17434 	  gcc_assert (TREE_OPERAND (rhsarg, 0) == tmp_load);
   17435 	  tree t = build2_loc (EXPR_LOCATION (rhsarg),
   17436 			       MODIFY_EXPR, void_type_node,
   17437 			       build3_loc (EXPR_LOCATION (rhsarg),
   17438 					   BIT_FIELD_REF, TREE_TYPE (op1),
   17439 					   tmp_store, bitsize, bitpos), op1);
   17440 	  if (TREE_CODE (rhs) == COND_EXPR)
   17441 	    t = build3_loc (EXPR_LOCATION (rhs), COND_EXPR, void_type_node,
   17442 			    TREE_OPERAND (rhs, 0), t, void_node);
   17443 	  gimplify_and_add (t, pre_p);
   17444 	  rhs = tmp_store;
   17445 	}
   17446       bool save_allow_rhs_cond_expr = gimplify_ctxp->allow_rhs_cond_expr;
   17447       if (TREE_CODE (rhs) == COND_EXPR)
   17448 	gimplify_ctxp->allow_rhs_cond_expr = true;
   17449       enum gimplify_status gs = gimplify_expr (&rhs, pre_p, NULL,
   17450 					       is_gimple_val, fb_rvalue);
   17451       gimplify_ctxp->allow_rhs_cond_expr = save_allow_rhs_cond_expr;
   17452       if (gs != GS_ALL_DONE)
   17453 	return GS_ERROR;
   17454     }
   17455 
   17456   if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
   17457     rhs = tmp_load;
   17458   storestmt
   17459     = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
   17460   if (TREE_CODE (*expr_p) != OMP_ATOMIC_READ && OMP_ATOMIC_WEAK (*expr_p))
   17461     {
   17462       gimple_omp_atomic_set_weak (loadstmt);
   17463       gimple_omp_atomic_set_weak (storestmt);
   17464     }
   17465   gimplify_seq_add_stmt (pre_p, storestmt);
   17466   switch (TREE_CODE (*expr_p))
   17467     {
   17468     case OMP_ATOMIC_READ:
   17469     case OMP_ATOMIC_CAPTURE_OLD:
   17470       *expr_p = tmp_load;
   17471       gimple_omp_atomic_set_need_value (loadstmt);
   17472       break;
   17473     case OMP_ATOMIC_CAPTURE_NEW:
   17474       *expr_p = rhs;
   17475       gimple_omp_atomic_set_need_value (storestmt);
   17476       break;
   17477     default:
   17478       *expr_p = NULL;
   17479       break;
   17480     }
   17481 
   17482   return GS_ALL_DONE;
   17483 }
   17484 
   17485 /* Gimplify a TRANSACTION_EXPR.  This involves gimplification of the
   17486    body, and adding some EH bits.  */
   17487 
   17488 static enum gimplify_status
   17489 gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
   17490 {
   17491   tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
   17492   gimple *body_stmt;
   17493   gtransaction *trans_stmt;
   17494   gimple_seq body = NULL;
   17495   int subcode = 0;
   17496 
   17497   /* Wrap the transaction body in a BIND_EXPR so we have a context
   17498      where to put decls for OMP.  */
   17499   if (TREE_CODE (tbody) != BIND_EXPR)
   17500     {
   17501       tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
   17502       TREE_SIDE_EFFECTS (bind) = 1;
   17503       SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
   17504       TRANSACTION_EXPR_BODY (expr) = bind;
   17505     }
   17506 
   17507   push_gimplify_context ();
   17508   temp = voidify_wrapper_expr (*expr_p, NULL);
   17509 
   17510   body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
   17511   pop_gimplify_context (body_stmt);
   17512 
   17513   trans_stmt = gimple_build_transaction (body);
   17514   if (TRANSACTION_EXPR_OUTER (expr))
   17515     subcode = GTMA_IS_OUTER;
   17516   else if (TRANSACTION_EXPR_RELAXED (expr))
   17517     subcode = GTMA_IS_RELAXED;
   17518   gimple_transaction_set_subcode (trans_stmt, subcode);
   17519 
   17520   gimplify_seq_add_stmt (pre_p, trans_stmt);
   17521 
   17522   if (temp)
   17523     {
   17524       *expr_p = temp;
   17525       return GS_OK;
   17526     }
   17527 
   17528   *expr_p = NULL_TREE;
   17529   return GS_ALL_DONE;
   17530 }
   17531 
   17532 /* Gimplify an OMP_ORDERED construct.  EXPR is the tree version.  BODY
   17533    is the OMP_BODY of the original EXPR (which has already been
   17534    gimplified so it's not present in the EXPR).
   17535 
   17536    Return the gimplified GIMPLE_OMP_ORDERED tuple.  */
   17537 
   17538 static gimple *
   17539 gimplify_omp_ordered (tree expr, gimple_seq body)
   17540 {
   17541   tree c, decls;
   17542   int failures = 0;
   17543   unsigned int i;
   17544   tree source_c = NULL_TREE;
   17545   tree sink_c = NULL_TREE;
   17546 
   17547   if (gimplify_omp_ctxp)
   17548     {
   17549       for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   17550 	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
   17551 	    && gimplify_omp_ctxp->loop_iter_var.is_empty ())
   17552 	  {
   17553 	    error_at (OMP_CLAUSE_LOCATION (c),
   17554 		      "%<ordered%> construct with %qs clause must be "
   17555 		      "closely nested inside a loop with %<ordered%> clause",
   17556 		      OMP_CLAUSE_DOACROSS_DEPEND (c) ? "depend" : "doacross");
   17557 	    failures++;
   17558 	  }
   17559 	else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
   17560 		 && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
   17561 	  {
   17562 	    bool fail = false;
   17563 	    sink_c = c;
   17564 	    if (OMP_CLAUSE_DECL (c) == NULL_TREE)
   17565 	      continue;  /* omp_cur_iteration - 1 */
   17566 	    for (decls = OMP_CLAUSE_DECL (c), i = 0;
   17567 		 decls && TREE_CODE (decls) == TREE_LIST;
   17568 		 decls = TREE_CHAIN (decls), ++i)
   17569 	      if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
   17570 		continue;
   17571 	      else if (TREE_VALUE (decls)
   17572 		       != gimplify_omp_ctxp->loop_iter_var[2 * i])
   17573 		{
   17574 		  error_at (OMP_CLAUSE_LOCATION (c),
   17575 			    "variable %qE is not an iteration "
   17576 			    "of outermost loop %d, expected %qE",
   17577 			    TREE_VALUE (decls), i + 1,
   17578 			    gimplify_omp_ctxp->loop_iter_var[2 * i]);
   17579 		  fail = true;
   17580 		  failures++;
   17581 		}
   17582 	      else
   17583 		TREE_VALUE (decls)
   17584 		  = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
   17585 	    if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
   17586 	      {
   17587 		error_at (OMP_CLAUSE_LOCATION (c),
   17588 			  "number of variables in %qs clause with "
   17589 			  "%<sink%> modifier does not match number of "
   17590 			  "iteration variables",
   17591 			  OMP_CLAUSE_DOACROSS_DEPEND (c)
   17592 			  ? "depend" : "doacross");
   17593 		failures++;
   17594 	      }
   17595 	  }
   17596 	else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
   17597 		 && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SOURCE)
   17598 	  {
   17599 	    if (source_c)
   17600 	      {
   17601 		error_at (OMP_CLAUSE_LOCATION (c),
   17602 			  "more than one %qs clause with %<source%> "
   17603 			  "modifier on an %<ordered%> construct",
   17604 			  OMP_CLAUSE_DOACROSS_DEPEND (source_c)
   17605 			  ? "depend" : "doacross");
   17606 		failures++;
   17607 	      }
   17608 	    else
   17609 	      source_c = c;
   17610 	  }
   17611     }
   17612   if (source_c && sink_c)
   17613     {
   17614       error_at (OMP_CLAUSE_LOCATION (source_c),
   17615 		"%qs clause with %<source%> modifier specified "
   17616 		"together with %qs clauses with %<sink%> modifier "
   17617 		"on the same construct",
   17618 		OMP_CLAUSE_DOACROSS_DEPEND (source_c) ? "depend" : "doacross",
   17619 		OMP_CLAUSE_DOACROSS_DEPEND (sink_c) ? "depend" : "doacross");
   17620       failures++;
   17621     }
   17622 
   17623   if (failures)
   17624     return gimple_build_nop ();
   17625   return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
   17626 }
   17627 
   17628 /* Convert the GENERIC expression tree *EXPR_P to GIMPLE.  If the
   17629    expression produces a value to be used as an operand inside a GIMPLE
   17630    statement, the value will be stored back in *EXPR_P.  This value will
   17631    be a tree of class tcc_declaration, tcc_constant, tcc_reference or
   17632    an SSA_NAME.  The corresponding sequence of GIMPLE statements is
   17633    emitted in PRE_P and POST_P.
   17634 
   17635    Additionally, this process may overwrite parts of the input
   17636    expression during gimplification.  Ideally, it should be
   17637    possible to do non-destructive gimplification.
   17638 
   17639    EXPR_P points to the GENERIC expression to convert to GIMPLE.  If
   17640       the expression needs to evaluate to a value to be used as
   17641       an operand in a GIMPLE statement, this value will be stored in
   17642       *EXPR_P on exit.  This happens when the caller specifies one
   17643       of fb_lvalue or fb_rvalue fallback flags.
   17644 
   17645    PRE_P will contain the sequence of GIMPLE statements corresponding
   17646        to the evaluation of EXPR and all the side-effects that must
   17647        be executed before the main expression.  On exit, the last
   17648        statement of PRE_P is the core statement being gimplified.  For
   17649        instance, when gimplifying 'if (++a)' the last statement in
   17650        PRE_P will be 'if (t.1)' where t.1 is the result of
   17651        pre-incrementing 'a'.
   17652 
   17653    POST_P will contain the sequence of GIMPLE statements corresponding
   17654        to the evaluation of all the side-effects that must be executed
   17655        after the main expression.  If this is NULL, the post
   17656        side-effects are stored at the end of PRE_P.
   17657 
   17658        The reason why the output is split in two is to handle post
   17659        side-effects explicitly.  In some cases, an expression may have
   17660        inner and outer post side-effects which need to be emitted in
   17661        an order different from the one given by the recursive
   17662        traversal.  For instance, for the expression (*p--)++ the post
   17663        side-effects of '--' must actually occur *after* the post
   17664        side-effects of '++'.  However, gimplification will first visit
   17665        the inner expression, so if a separate POST sequence was not
   17666        used, the resulting sequence would be:
   17667 
   17668        	    1	t.1 = *p
   17669        	    2	p = p - 1
   17670        	    3	t.2 = t.1 + 1
   17671        	    4	*p = t.2
   17672 
   17673        However, the post-decrement operation in line #2 must not be
   17674        evaluated until after the store to *p at line #4, so the
   17675        correct sequence should be:
   17676 
   17677        	    1	t.1 = *p
   17678        	    2	t.2 = t.1 + 1
   17679        	    3	*p = t.2
   17680        	    4	p = p - 1
   17681 
   17682        So, by specifying a separate post queue, it is possible
   17683        to emit the post side-effects in the correct order.
   17684        If POST_P is NULL, an internal queue will be used.  Before
   17685        returning to the caller, the sequence POST_P is appended to
   17686        the main output sequence PRE_P.
   17687 
   17688    GIMPLE_TEST_F points to a function that takes a tree T and
   17689        returns nonzero if T is in the GIMPLE form requested by the
   17690        caller.  The GIMPLE predicates are in gimple.cc.
   17691 
   17692    FALLBACK tells the function what sort of a temporary we want if
   17693        gimplification cannot produce an expression that complies with
   17694        GIMPLE_TEST_F.
   17695 
   17696        fb_none means that no temporary should be generated
   17697        fb_rvalue means that an rvalue is OK to generate
   17698        fb_lvalue means that an lvalue is OK to generate
   17699        fb_either means that either is OK, but an lvalue is preferable.
   17700        fb_mayfail means that gimplification may fail (in which case
   17701        GS_ERROR will be returned)
   17702 
   17703    The return value is either GS_ERROR or GS_ALL_DONE, since this
   17704    function iterates until EXPR is completely gimplified or an error
   17705    occurs.  */
   17706 
   17707 enum gimplify_status
   17708 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   17709 	       bool (*gimple_test_f) (tree), fallback_t fallback)
   17710 {
   17711   tree tmp;
   17712   gimple_seq internal_pre = NULL;
   17713   gimple_seq internal_post = NULL;
   17714   tree save_expr;
   17715   bool is_statement;
   17716   location_t saved_location;
   17717   enum gimplify_status ret;
   17718   gimple_stmt_iterator pre_last_gsi, post_last_gsi;
   17719   tree label;
   17720 
   17721   save_expr = *expr_p;
   17722   if (save_expr == NULL_TREE)
   17723     return GS_ALL_DONE;
   17724 
   17725   /* If we are gimplifying a top-level statement, PRE_P must be valid.  */
   17726   is_statement = gimple_test_f == is_gimple_stmt;
   17727   if (is_statement)
   17728     gcc_assert (pre_p);
   17729 
   17730   /* Consistency checks.  */
   17731   if (gimple_test_f == is_gimple_reg)
   17732     gcc_assert (fallback & (fb_rvalue | fb_lvalue));
   17733   else if (gimple_test_f == is_gimple_val
   17734            || gimple_test_f == is_gimple_call_addr
   17735 	   || gimple_test_f == is_gimple_condexpr_for_cond
   17736            || gimple_test_f == is_gimple_mem_rhs
   17737            || gimple_test_f == is_gimple_mem_rhs_or_call
   17738            || gimple_test_f == is_gimple_reg_rhs
   17739            || gimple_test_f == is_gimple_reg_rhs_or_call
   17740            || gimple_test_f == is_gimple_asm_val
   17741 	   || gimple_test_f == is_gimple_mem_ref_addr)
   17742     gcc_assert (fallback & fb_rvalue);
   17743   else if (gimple_test_f == is_gimple_min_lval
   17744 	   || gimple_test_f == is_gimple_lvalue)
   17745     gcc_assert (fallback & fb_lvalue);
   17746   else if (gimple_test_f == is_gimple_addressable)
   17747     gcc_assert (fallback & fb_either);
   17748   else if (gimple_test_f == is_gimple_stmt)
   17749     gcc_assert (fallback == fb_none);
   17750   else
   17751     {
   17752       /* We should have recognized the GIMPLE_TEST_F predicate to
   17753 	 know what kind of fallback to use in case a temporary is
   17754 	 needed to hold the value or address of *EXPR_P.  */
   17755       gcc_unreachable ();
   17756     }
   17757 
   17758   /* We used to check the predicate here and return immediately if it
   17759      succeeds.  This is wrong; the design is for gimplification to be
   17760      idempotent, and for the predicates to only test for valid forms, not
   17761      whether they are fully simplified.  */
   17762   if (pre_p == NULL)
   17763     pre_p = &internal_pre;
   17764 
   17765   if (post_p == NULL)
   17766     post_p = &internal_post;
   17767 
   17768   /* Remember the last statements added to PRE_P and POST_P.  Every
   17769      new statement added by the gimplification helpers needs to be
   17770      annotated with location information.  To centralize the
   17771      responsibility, we remember the last statement that had been
   17772      added to both queues before gimplifying *EXPR_P.  If
   17773      gimplification produces new statements in PRE_P and POST_P, those
   17774      statements will be annotated with the same location information
   17775      as *EXPR_P.  */
   17776   pre_last_gsi = gsi_last (*pre_p);
   17777   post_last_gsi = gsi_last (*post_p);
   17778 
   17779   saved_location = input_location;
   17780   if (save_expr != error_mark_node
   17781       && EXPR_HAS_LOCATION (*expr_p))
   17782     input_location = EXPR_LOCATION (*expr_p);
   17783 
   17784   /* Loop over the specific gimplifiers until the toplevel node
   17785      remains the same.  */
   17786   do
   17787     {
   17788       /* Strip away as many useless type conversions as possible
   17789 	 at the toplevel.  */
   17790       STRIP_USELESS_TYPE_CONVERSION (*expr_p);
   17791 
   17792       /* Remember the expr.  */
   17793       save_expr = *expr_p;
   17794 
   17795       /* Die, die, die, my darling.  */
   17796       if (error_operand_p (save_expr))
   17797 	{
   17798 	  ret = GS_ERROR;
   17799 	  break;
   17800 	}
   17801 
   17802       /* Do any language-specific gimplification.  */
   17803       ret = ((enum gimplify_status)
   17804 	     lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
   17805       if (ret == GS_OK)
   17806 	{
   17807 	  if (*expr_p == NULL_TREE)
   17808 	    break;
   17809 	  if (*expr_p != save_expr)
   17810 	    continue;
   17811 	}
   17812       else if (ret != GS_UNHANDLED)
   17813 	break;
   17814 
   17815       /* Make sure that all the cases set 'ret' appropriately.  */
   17816       ret = GS_UNHANDLED;
   17817       switch (TREE_CODE (*expr_p))
   17818 	{
   17819 	  /* First deal with the special cases.  */
   17820 
   17821 	case POSTINCREMENT_EXPR:
   17822 	case POSTDECREMENT_EXPR:
   17823 	case PREINCREMENT_EXPR:
   17824 	case PREDECREMENT_EXPR:
   17825 	  ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
   17826 					fallback != fb_none,
   17827 					TREE_TYPE (*expr_p));
   17828 	  break;
   17829 
   17830 	case VIEW_CONVERT_EXPR:
   17831 	  if ((fallback & fb_rvalue)
   17832 	      && is_gimple_reg_type (TREE_TYPE (*expr_p))
   17833 	      && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
   17834 	    {
   17835 	      ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   17836 				   post_p, is_gimple_val, fb_rvalue);
   17837 	      recalculate_side_effects (*expr_p);
   17838 	      break;
   17839 	    }
   17840 	  /* Fallthru.  */
   17841 
   17842 	case ARRAY_REF:
   17843 	case ARRAY_RANGE_REF:
   17844 	case REALPART_EXPR:
   17845 	case IMAGPART_EXPR:
   17846 	case COMPONENT_REF:
   17847 	  ret = gimplify_compound_lval (expr_p, pre_p, post_p,
   17848 					fallback ? fallback : fb_rvalue);
   17849 	  break;
   17850 
   17851 	case COND_EXPR:
   17852 	  ret = gimplify_cond_expr (expr_p, pre_p, fallback);
   17853 
   17854 	  /* C99 code may assign to an array in a structure value of a
   17855 	     conditional expression, and this has undefined behavior
   17856 	     only on execution, so create a temporary if an lvalue is
   17857 	     required.  */
   17858 	  if (fallback == fb_lvalue)
   17859 	    {
   17860 	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
   17861 	      mark_addressable (*expr_p);
   17862 	      ret = GS_OK;
   17863 	    }
   17864 	  break;
   17865 
   17866 	case CALL_EXPR:
   17867 	  ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
   17868 
   17869 	  /* C99 code may assign to an array in a structure returned
   17870 	     from a function, and this has undefined behavior only on
   17871 	     execution, so create a temporary if an lvalue is
   17872 	     required.  */
   17873 	  if (fallback == fb_lvalue)
   17874 	    {
   17875 	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
   17876 	      mark_addressable (*expr_p);
   17877 	      ret = GS_OK;
   17878 	    }
   17879 	  break;
   17880 
   17881 	case TREE_LIST:
   17882 	  gcc_unreachable ();
   17883 
   17884 	case OMP_ARRAY_SECTION:
   17885 	  gcc_unreachable ();
   17886 
   17887 	case COMPOUND_EXPR:
   17888 	  ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
   17889 	  break;
   17890 
   17891 	case COMPOUND_LITERAL_EXPR:
   17892 	  ret = gimplify_compound_literal_expr (expr_p, pre_p,
   17893 						gimple_test_f, fallback);
   17894 	  break;
   17895 
   17896 	case MODIFY_EXPR:
   17897 	case INIT_EXPR:
   17898 	  ret = gimplify_modify_expr (expr_p, pre_p, post_p,
   17899 				      fallback != fb_none);
   17900 	  break;
   17901 
   17902 	case TRUTH_ANDIF_EXPR:
   17903 	case TRUTH_ORIF_EXPR:
   17904 	  {
   17905 	    /* Preserve the original type of the expression and the
   17906 	       source location of the outer expression.  */
   17907 	    tree org_type = TREE_TYPE (*expr_p);
   17908 	    *expr_p = gimple_boolify (*expr_p);
   17909 	    *expr_p = build3_loc (input_location, COND_EXPR,
   17910 				  org_type, *expr_p,
   17911 				  fold_convert_loc
   17912 				    (input_location,
   17913 				     org_type, boolean_true_node),
   17914 				  fold_convert_loc
   17915 				    (input_location,
   17916 				     org_type, boolean_false_node));
   17917 	    ret = GS_OK;
   17918 	    break;
   17919 	  }
   17920 
   17921 	case TRUTH_NOT_EXPR:
   17922 	  {
   17923 	    tree type = TREE_TYPE (*expr_p);
   17924 	    /* The parsers are careful to generate TRUTH_NOT_EXPR
   17925 	       only with operands that are always zero or one.
   17926 	       We do not fold here but handle the only interesting case
   17927 	       manually, as fold may re-introduce the TRUTH_NOT_EXPR.  */
   17928 	    *expr_p = gimple_boolify (*expr_p);
   17929 	    if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
   17930 	      *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
   17931 				    TREE_TYPE (*expr_p),
   17932 				    TREE_OPERAND (*expr_p, 0));
   17933 	    else
   17934 	      *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
   17935 				    TREE_TYPE (*expr_p),
   17936 				    TREE_OPERAND (*expr_p, 0),
   17937 				    build_int_cst (TREE_TYPE (*expr_p), 1));
   17938 	    if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
   17939 	      *expr_p = fold_convert_loc (input_location, type, *expr_p);
   17940 	    ret = GS_OK;
   17941 	    break;
   17942 	  }
   17943 
   17944 	case ADDR_EXPR:
   17945 	  ret = gimplify_addr_expr (expr_p, pre_p, post_p);
   17946 	  break;
   17947 
   17948 	case ANNOTATE_EXPR:
   17949 	  {
   17950 	    tree cond = TREE_OPERAND (*expr_p, 0);
   17951 	    tree kind = TREE_OPERAND (*expr_p, 1);
   17952 	    tree data = TREE_OPERAND (*expr_p, 2);
   17953 	    tree type = TREE_TYPE (cond);
   17954 	    if (!INTEGRAL_TYPE_P (type))
   17955 	      {
   17956 		*expr_p = cond;
   17957 		ret = GS_OK;
   17958 		break;
   17959 	      }
   17960 	    tree tmp = create_tmp_var (type);
   17961 	    gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
   17962 	    gcall *call
   17963 	      = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
   17964 	    gimple_call_set_lhs (call, tmp);
   17965 	    gimplify_seq_add_stmt (pre_p, call);
   17966 	    *expr_p = tmp;
   17967 	    ret = GS_ALL_DONE;
   17968 	    break;
   17969 	  }
   17970 
   17971 	case VA_ARG_EXPR:
   17972 	  ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
   17973 	  break;
   17974 
   17975 	CASE_CONVERT:
   17976 	  if (IS_EMPTY_STMT (*expr_p))
   17977 	    {
   17978 	      ret = GS_ALL_DONE;
   17979 	      break;
   17980 	    }
   17981 
   17982 	  if (VOID_TYPE_P (TREE_TYPE (*expr_p))
   17983 	      || fallback == fb_none)
   17984 	    {
   17985 	      /* Just strip a conversion to void (or in void context) and
   17986 		 try again.  */
   17987 	      *expr_p = TREE_OPERAND (*expr_p, 0);
   17988 	      ret = GS_OK;
   17989 	      break;
   17990 	    }
   17991 
   17992 	  ret = gimplify_conversion (expr_p);
   17993 	  if (ret == GS_ERROR)
   17994 	    break;
   17995 	  if (*expr_p != save_expr)
   17996 	    break;
   17997 	  /* FALLTHRU */
   17998 
   17999 	case FIX_TRUNC_EXPR:
   18000 	  /* unary_expr: ... | '(' cast ')' val | ...  */
   18001 	  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   18002 			       is_gimple_val, fb_rvalue);
   18003 	  recalculate_side_effects (*expr_p);
   18004 	  break;
   18005 
   18006 	case INDIRECT_REF:
   18007 	  {
   18008 	    bool volatilep = TREE_THIS_VOLATILE (*expr_p);
   18009 	    bool notrap = TREE_THIS_NOTRAP (*expr_p);
   18010 	    tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
   18011 
   18012 	    *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
   18013 	    if (*expr_p != save_expr)
   18014 	      {
   18015 		ret = GS_OK;
   18016 		break;
   18017 	      }
   18018 
   18019 	    ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   18020 				 is_gimple_reg, fb_rvalue);
   18021 	    if (ret == GS_ERROR)
   18022 	      break;
   18023 
   18024 	    recalculate_side_effects (*expr_p);
   18025 	    *expr_p = fold_build2_loc (input_location, MEM_REF,
   18026 				       TREE_TYPE (*expr_p),
   18027 				       TREE_OPERAND (*expr_p, 0),
   18028 				       build_int_cst (saved_ptr_type, 0));
   18029 	    TREE_THIS_VOLATILE (*expr_p) = volatilep;
   18030 	    TREE_THIS_NOTRAP (*expr_p) = notrap;
   18031 	    ret = GS_OK;
   18032 	    break;
   18033 	  }
   18034 
   18035 	/* We arrive here through the various re-gimplifcation paths.  */
   18036 	case MEM_REF:
   18037 	  /* First try re-folding the whole thing.  */
   18038 	  tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
   18039 			     TREE_OPERAND (*expr_p, 0),
   18040 			     TREE_OPERAND (*expr_p, 1));
   18041 	  if (tmp)
   18042 	    {
   18043 	      REF_REVERSE_STORAGE_ORDER (tmp)
   18044 	        = REF_REVERSE_STORAGE_ORDER (*expr_p);
   18045 	      *expr_p = tmp;
   18046 	      recalculate_side_effects (*expr_p);
   18047 	      ret = GS_OK;
   18048 	      break;
   18049 	    }
   18050 	  /* Avoid re-gimplifying the address operand if it is already
   18051 	     in suitable form.  Re-gimplifying would mark the address
   18052 	     operand addressable.  Always gimplify when not in SSA form
   18053 	     as we still may have to gimplify decls with value-exprs.  */
   18054 	  if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
   18055 	      || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
   18056 	    {
   18057 	      ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   18058 				   is_gimple_mem_ref_addr, fb_rvalue);
   18059 	      if (ret == GS_ERROR)
   18060 		break;
   18061 	    }
   18062 	  recalculate_side_effects (*expr_p);
   18063 	  ret = GS_ALL_DONE;
   18064 	  break;
   18065 
   18066 	/* Constants need not be gimplified.  */
   18067 	case INTEGER_CST:
   18068 	case REAL_CST:
   18069 	case FIXED_CST:
   18070 	case STRING_CST:
   18071 	case COMPLEX_CST:
   18072 	case VECTOR_CST:
   18073 	  /* Drop the overflow flag on constants, we do not want
   18074 	     that in the GIMPLE IL.  */
   18075 	  if (TREE_OVERFLOW_P (*expr_p))
   18076 	    *expr_p = drop_tree_overflow (*expr_p);
   18077 	  ret = GS_ALL_DONE;
   18078 	  break;
   18079 
   18080 	case CONST_DECL:
   18081 	  /* If we require an lvalue, such as for ADDR_EXPR, retain the
   18082 	     CONST_DECL node.  Otherwise the decl is replaceable by its
   18083 	     value.  */
   18084 	  /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either.  */
   18085 	  if (fallback & fb_lvalue)
   18086 	    ret = GS_ALL_DONE;
   18087 	  else
   18088 	    {
   18089 	      *expr_p = DECL_INITIAL (*expr_p);
   18090 	      ret = GS_OK;
   18091 	    }
   18092 	  break;
   18093 
   18094 	case DECL_EXPR:
   18095 	  ret = gimplify_decl_expr (expr_p, pre_p);
   18096 	  break;
   18097 
   18098 	case BIND_EXPR:
   18099 	  ret = gimplify_bind_expr (expr_p, pre_p);
   18100 	  break;
   18101 
   18102 	case LOOP_EXPR:
   18103 	  ret = gimplify_loop_expr (expr_p, pre_p);
   18104 	  break;
   18105 
   18106 	case SWITCH_EXPR:
   18107 	  ret = gimplify_switch_expr (expr_p, pre_p);
   18108 	  break;
   18109 
   18110 	case EXIT_EXPR:
   18111 	  ret = gimplify_exit_expr (expr_p);
   18112 	  break;
   18113 
   18114 	case GOTO_EXPR:
   18115 	  /* If the target is not LABEL, then it is a computed jump
   18116 	     and the target needs to be gimplified.  */
   18117 	  if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
   18118 	    {
   18119 	      ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
   18120 				   NULL, is_gimple_val, fb_rvalue);
   18121 	      if (ret == GS_ERROR)
   18122 		break;
   18123 	    }
   18124 	  gimplify_seq_add_stmt (pre_p,
   18125 			  gimple_build_goto (GOTO_DESTINATION (*expr_p)));
   18126 	  ret = GS_ALL_DONE;
   18127 	  break;
   18128 
   18129 	case PREDICT_EXPR:
   18130 	  gimplify_seq_add_stmt (pre_p,
   18131 			gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
   18132 					      PREDICT_EXPR_OUTCOME (*expr_p)));
   18133 	  ret = GS_ALL_DONE;
   18134 	  break;
   18135 
   18136 	case LABEL_EXPR:
   18137 	  ret = gimplify_label_expr (expr_p, pre_p);
   18138 	  label = LABEL_EXPR_LABEL (*expr_p);
   18139 	  gcc_assert (decl_function_context (label) == current_function_decl);
   18140 
   18141 	  /* If the label is used in a goto statement, or address of the label
   18142 	     is taken, we need to unpoison all variables that were seen so far.
   18143 	     Doing so would prevent us from reporting a false positives.  */
   18144 	  if (asan_poisoned_variables
   18145 	      && asan_used_labels != NULL
   18146 	      && asan_used_labels->contains (label)
   18147 	      && !gimplify_omp_ctxp)
   18148 	    asan_poison_variables (asan_poisoned_variables, false, pre_p);
   18149 	  break;
   18150 
   18151 	case CASE_LABEL_EXPR:
   18152 	  ret = gimplify_case_label_expr (expr_p, pre_p);
   18153 
   18154 	  if (gimplify_ctxp->live_switch_vars)
   18155 	    asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
   18156 				   pre_p);
   18157 	  break;
   18158 
   18159 	case RETURN_EXPR:
   18160 	  ret = gimplify_return_expr (*expr_p, pre_p);
   18161 	  break;
   18162 
   18163 	case CONSTRUCTOR:
   18164 	  /* Don't reduce this in place; let gimplify_init_constructor work its
   18165 	     magic.  Buf if we're just elaborating this for side effects, just
   18166 	     gimplify any element that has side-effects.  */
   18167 	  if (fallback == fb_none)
   18168 	    {
   18169 	      unsigned HOST_WIDE_INT ix;
   18170 	      tree val;
   18171 	      tree temp = NULL_TREE;
   18172 	      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
   18173 		if (TREE_SIDE_EFFECTS (val))
   18174 		  append_to_statement_list (val, &temp);
   18175 
   18176 	      *expr_p = temp;
   18177 	      ret = temp ? GS_OK : GS_ALL_DONE;
   18178 	    }
   18179 	  /* C99 code may assign to an array in a constructed
   18180 	     structure or union, and this has undefined behavior only
   18181 	     on execution, so create a temporary if an lvalue is
   18182 	     required.  */
   18183 	  else if (fallback == fb_lvalue)
   18184 	    {
   18185 	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
   18186 	      mark_addressable (*expr_p);
   18187 	      ret = GS_OK;
   18188 	    }
   18189 	  else
   18190 	    ret = GS_ALL_DONE;
   18191 	  break;
   18192 
   18193 	  /* The following are special cases that are not handled by the
   18194 	     original GIMPLE grammar.  */
   18195 
   18196 	  /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
   18197 	     eliminated.  */
   18198 	case SAVE_EXPR:
   18199 	  ret = gimplify_save_expr (expr_p, pre_p, post_p);
   18200 	  break;
   18201 
   18202 	case BIT_FIELD_REF:
   18203 	  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   18204 			       post_p, is_gimple_lvalue, fb_either);
   18205 	  recalculate_side_effects (*expr_p);
   18206 	  break;
   18207 
   18208 	case TARGET_MEM_REF:
   18209 	  {
   18210 	    enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
   18211 
   18212 	    if (TMR_BASE (*expr_p))
   18213 	      r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
   18214 				  post_p, is_gimple_mem_ref_addr, fb_either);
   18215 	    if (TMR_INDEX (*expr_p))
   18216 	      r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
   18217 				  post_p, is_gimple_val, fb_rvalue);
   18218 	    if (TMR_INDEX2 (*expr_p))
   18219 	      r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
   18220 				  post_p, is_gimple_val, fb_rvalue);
   18221 	    /* TMR_STEP and TMR_OFFSET are always integer constants.  */
   18222 	    ret = MIN (r0, r1);
   18223 	  }
   18224 	  break;
   18225 
   18226 	case NON_LVALUE_EXPR:
   18227 	  /* This should have been stripped above.  */
   18228 	  gcc_unreachable ();
   18229 
   18230 	case ASM_EXPR:
   18231 	  ret = gimplify_asm_expr (expr_p, pre_p, post_p);
   18232 	  break;
   18233 
   18234 	case TRY_FINALLY_EXPR:
   18235 	case TRY_CATCH_EXPR:
   18236 	  {
   18237 	    gimple_seq eval, cleanup;
   18238 	    gtry *try_;
   18239 
   18240 	    /* Calls to destructors are generated automatically in FINALLY/CATCH
   18241 	       block. They should have location as UNKNOWN_LOCATION. However,
   18242 	       gimplify_call_expr will reset these call stmts to input_location
   18243 	       if it finds stmt's location is unknown. To prevent resetting for
   18244 	       destructors, we set the input_location to unknown.
   18245 	       Note that this only affects the destructor calls in FINALLY/CATCH
   18246 	       block, and will automatically reset to its original value by the
   18247 	       end of gimplify_expr.  */
   18248 	    input_location = UNKNOWN_LOCATION;
   18249 	    eval = cleanup = NULL;
   18250 	    gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
   18251 	    bool save_in_handler_expr = gimplify_ctxp->in_handler_expr;
   18252 	    if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
   18253 		&& TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
   18254 	      {
   18255 		gimple_seq n = NULL, e = NULL;
   18256 		gimplify_ctxp->in_handler_expr = true;
   18257 		gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
   18258 						0), &n);
   18259 		gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
   18260 						1), &e);
   18261 		if (!gimple_seq_empty_p (n) || !gimple_seq_empty_p (e))
   18262 		  {
   18263 		    geh_else *stmt = gimple_build_eh_else (n, e);
   18264 		    gimple_seq_add_stmt (&cleanup, stmt);
   18265 		  }
   18266 	      }
   18267 	    else
   18268 	      {
   18269 		gimplify_ctxp->in_handler_expr = true;
   18270 		gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
   18271 	      }
   18272 	    gimplify_ctxp->in_handler_expr = save_in_handler_expr;
   18273 	    /* Don't create bogus GIMPLE_TRY with empty cleanup.  */
   18274 	    if (gimple_seq_empty_p (cleanup))
   18275 	      {
   18276 		gimple_seq_add_seq (pre_p, eval);
   18277 		ret = GS_ALL_DONE;
   18278 		break;
   18279 	      }
   18280 	    try_ = gimple_build_try (eval, cleanup,
   18281 				     TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
   18282 				     ? GIMPLE_TRY_FINALLY
   18283 				     : GIMPLE_TRY_CATCH);
   18284 	    if (EXPR_HAS_LOCATION (save_expr))
   18285 	      gimple_set_location (try_, EXPR_LOCATION (save_expr));
   18286 	    else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
   18287 	      gimple_set_location (try_, saved_location);
   18288 	    if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
   18289 	      gimple_try_set_catch_is_cleanup (try_,
   18290 					       TRY_CATCH_IS_CLEANUP (*expr_p));
   18291 	    gimplify_seq_add_stmt (pre_p, try_);
   18292 	    ret = GS_ALL_DONE;
   18293 	    break;
   18294 	  }
   18295 
   18296 	case CLEANUP_POINT_EXPR:
   18297 	  ret = gimplify_cleanup_point_expr (expr_p, pre_p);
   18298 	  break;
   18299 
   18300 	case TARGET_EXPR:
   18301 	  ret = gimplify_target_expr (expr_p, pre_p, post_p);
   18302 	  break;
   18303 
   18304 	case CATCH_EXPR:
   18305 	  {
   18306 	    gimple *c;
   18307 	    gimple_seq handler = NULL;
   18308 	    gimplify_and_add (CATCH_BODY (*expr_p), &handler);
   18309 	    c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
   18310 	    gimplify_seq_add_stmt (pre_p, c);
   18311 	    ret = GS_ALL_DONE;
   18312 	    break;
   18313 	  }
   18314 
   18315 	case EH_FILTER_EXPR:
   18316 	  {
   18317 	    gimple *ehf;
   18318 	    gimple_seq failure = NULL;
   18319 
   18320 	    gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
   18321 	    ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
   18322 	    copy_warning (ehf, *expr_p);
   18323 	    gimplify_seq_add_stmt (pre_p, ehf);
   18324 	    ret = GS_ALL_DONE;
   18325 	    break;
   18326 	  }
   18327 
   18328 	case OBJ_TYPE_REF:
   18329 	  {
   18330 	    enum gimplify_status r0, r1;
   18331 	    r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
   18332 				post_p, is_gimple_val, fb_rvalue);
   18333 	    r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
   18334 				post_p, is_gimple_val, fb_rvalue);
   18335 	    TREE_SIDE_EFFECTS (*expr_p) = 0;
   18336 	    ret = MIN (r0, r1);
   18337 	  }
   18338 	  break;
   18339 
   18340 	case LABEL_DECL:
   18341 	  /* We get here when taking the address of a label.  We mark
   18342 	     the label as "forced"; meaning it can never be removed and
   18343 	     it is a potential target for any computed goto.  */
   18344 	  FORCED_LABEL (*expr_p) = 1;
   18345 	  ret = GS_ALL_DONE;
   18346 	  break;
   18347 
   18348 	case STATEMENT_LIST:
   18349 	  ret = gimplify_statement_list (expr_p, pre_p);
   18350 	  break;
   18351 
   18352 	case WITH_SIZE_EXPR:
   18353 	  {
   18354 	    gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   18355 			   post_p == &internal_post ? NULL : post_p,
   18356 			   gimple_test_f, fallback);
   18357 	    gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
   18358 			   is_gimple_val, fb_rvalue);
   18359 	    ret = GS_ALL_DONE;
   18360 	  }
   18361 	  break;
   18362 
   18363 	case VAR_DECL:
   18364 	case PARM_DECL:
   18365 	  ret = gimplify_var_or_parm_decl (expr_p);
   18366 	  break;
   18367 
   18368 	case RESULT_DECL:
   18369 	  /* When within an OMP context, notice uses of variables.  */
   18370 	  if (gimplify_omp_ctxp)
   18371 	    omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
   18372 	  /* Handlers can refer to the function result; if that has been
   18373 	     moved, we need to track it.  */
   18374 	  if (gimplify_ctxp->in_handler_expr && gimplify_ctxp->return_temp)
   18375 	    *expr_p = gimplify_ctxp->return_temp;
   18376 	  ret = GS_ALL_DONE;
   18377 	  break;
   18378 
   18379 	case DEBUG_EXPR_DECL:
   18380 	  gcc_unreachable ();
   18381 
   18382 	case DEBUG_BEGIN_STMT:
   18383 	  gimplify_seq_add_stmt (pre_p,
   18384 				 gimple_build_debug_begin_stmt
   18385 				 (TREE_BLOCK (*expr_p),
   18386 				  EXPR_LOCATION (*expr_p)));
   18387 	  ret = GS_ALL_DONE;
   18388 	  *expr_p = NULL;
   18389 	  break;
   18390 
   18391 	case SSA_NAME:
   18392 	  /* Allow callbacks into the gimplifier during optimization.  */
   18393 	  ret = GS_ALL_DONE;
   18394 	  break;
   18395 
   18396 	case OMP_PARALLEL:
   18397 	  gimplify_omp_parallel (expr_p, pre_p);
   18398 	  ret = GS_ALL_DONE;
   18399 	  break;
   18400 
   18401 	case OMP_TASK:
   18402 	  gimplify_omp_task (expr_p, pre_p);
   18403 	  ret = GS_ALL_DONE;
   18404 	  break;
   18405 
   18406 	case OMP_SIMD:
   18407 	  {
   18408 	    /* Temporarily disable into_ssa, as scan_omp_simd
   18409 	       which calls copy_gimple_seq_and_replace_locals can't deal
   18410 	       with SSA_NAMEs defined outside of the body properly.  */
   18411 	    bool saved_into_ssa = gimplify_ctxp->into_ssa;
   18412 	    gimplify_ctxp->into_ssa = false;
   18413 	    ret = gimplify_omp_for (expr_p, pre_p);
   18414 	    gimplify_ctxp->into_ssa = saved_into_ssa;
   18415 	    break;
   18416 	  }
   18417 
   18418 	case OMP_FOR:
   18419 	case OMP_DISTRIBUTE:
   18420 	case OMP_TASKLOOP:
   18421 	case OACC_LOOP:
   18422 	  ret = gimplify_omp_for (expr_p, pre_p);
   18423 	  break;
   18424 
   18425 	case OMP_LOOP:
   18426 	  ret = gimplify_omp_loop (expr_p, pre_p);
   18427 	  break;
   18428 
   18429 	case OACC_CACHE:
   18430 	  gimplify_oacc_cache (expr_p, pre_p);
   18431 	  ret = GS_ALL_DONE;
   18432 	  break;
   18433 
   18434 	case OACC_DECLARE:
   18435 	  gimplify_oacc_declare (expr_p, pre_p);
   18436 	  ret = GS_ALL_DONE;
   18437 	  break;
   18438 
   18439 	case OACC_HOST_DATA:
   18440 	case OACC_DATA:
   18441 	case OACC_KERNELS:
   18442 	case OACC_PARALLEL:
   18443 	case OACC_SERIAL:
   18444 	case OMP_SCOPE:
   18445 	case OMP_SECTIONS:
   18446 	case OMP_SINGLE:
   18447 	case OMP_TARGET:
   18448 	case OMP_TARGET_DATA:
   18449 	case OMP_TEAMS:
   18450 	  gimplify_omp_workshare (expr_p, pre_p);
   18451 	  ret = GS_ALL_DONE;
   18452 	  break;
   18453 
   18454 	case OACC_ENTER_DATA:
   18455 	case OACC_EXIT_DATA:
   18456 	case OACC_UPDATE:
   18457 	case OMP_TARGET_UPDATE:
   18458 	case OMP_TARGET_ENTER_DATA:
   18459 	case OMP_TARGET_EXIT_DATA:
   18460 	  gimplify_omp_target_update (expr_p, pre_p);
   18461 	  ret = GS_ALL_DONE;
   18462 	  break;
   18463 
   18464 	case OMP_SECTION:
   18465 	case OMP_STRUCTURED_BLOCK:
   18466 	case OMP_MASTER:
   18467 	case OMP_MASKED:
   18468 	case OMP_ORDERED:
   18469 	case OMP_CRITICAL:
   18470 	case OMP_SCAN:
   18471 	  {
   18472 	    gimple_seq body = NULL;
   18473 	    gimple *g;
   18474 	    bool saved_in_omp_construct = in_omp_construct;
   18475 
   18476 	    in_omp_construct = true;
   18477 	    gimplify_and_add (OMP_BODY (*expr_p), &body);
   18478 	    in_omp_construct = saved_in_omp_construct;
   18479 	    switch (TREE_CODE (*expr_p))
   18480 	      {
   18481 	      case OMP_SECTION:
   18482 	        g = gimple_build_omp_section (body);
   18483 	        break;
   18484 	      case OMP_STRUCTURED_BLOCK:
   18485 		g = gimple_build_omp_structured_block (body);
   18486 		break;
   18487 	      case OMP_MASTER:
   18488 		g = gimple_build_omp_master (body);
   18489 		break;
   18490 	      case OMP_ORDERED:
   18491 		g = gimplify_omp_ordered (*expr_p, body);
   18492 		if (OMP_BODY (*expr_p) == NULL_TREE
   18493 		    && gimple_code (g) == GIMPLE_OMP_ORDERED)
   18494 		  gimple_omp_ordered_standalone (g);
   18495 		break;
   18496 	      case OMP_MASKED:
   18497 		gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p),
   18498 					   pre_p, ORT_WORKSHARE, OMP_MASKED);
   18499 		gimplify_adjust_omp_clauses (pre_p, body,
   18500 					     &OMP_MASKED_CLAUSES (*expr_p),
   18501 					     OMP_MASKED);
   18502 		g = gimple_build_omp_masked (body,
   18503 					     OMP_MASKED_CLAUSES (*expr_p));
   18504 		break;
   18505 	      case OMP_CRITICAL:
   18506 		gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
   18507 					   pre_p, ORT_WORKSHARE, OMP_CRITICAL);
   18508 		gimplify_adjust_omp_clauses (pre_p, body,
   18509 					     &OMP_CRITICAL_CLAUSES (*expr_p),
   18510 					     OMP_CRITICAL);
   18511 		g = gimple_build_omp_critical (body,
   18512 		    			       OMP_CRITICAL_NAME (*expr_p),
   18513 		    			       OMP_CRITICAL_CLAUSES (*expr_p));
   18514 		break;
   18515 	      case OMP_SCAN:
   18516 		gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
   18517 					   pre_p, ORT_WORKSHARE, OMP_SCAN);
   18518 		gimplify_adjust_omp_clauses (pre_p, body,
   18519 					     &OMP_SCAN_CLAUSES (*expr_p),
   18520 					     OMP_SCAN);
   18521 		g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
   18522 		break;
   18523 	      default:
   18524 		gcc_unreachable ();
   18525 	      }
   18526 	    gimplify_seq_add_stmt (pre_p, g);
   18527 	    ret = GS_ALL_DONE;
   18528 	    break;
   18529 	  }
   18530 
   18531 	case OMP_TASKGROUP:
   18532 	  {
   18533 	    gimple_seq body = NULL;
   18534 
   18535 	    tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
   18536 	    bool saved_in_omp_construct = in_omp_construct;
   18537 	    gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
   18538 				       OMP_TASKGROUP);
   18539 	    gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
   18540 
   18541 	    in_omp_construct = true;
   18542 	    gimplify_and_add (OMP_BODY (*expr_p), &body);
   18543 	    in_omp_construct = saved_in_omp_construct;
   18544 	    gimple_seq cleanup = NULL;
   18545 	    tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
   18546 	    gimple *g = gimple_build_call (fn, 0);
   18547 	    gimple_seq_add_stmt (&cleanup, g);
   18548 	    g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
   18549 	    body = NULL;
   18550 	    gimple_seq_add_stmt (&body, g);
   18551 	    g = gimple_build_omp_taskgroup (body, *pclauses);
   18552 	    gimplify_seq_add_stmt (pre_p, g);
   18553 	    ret = GS_ALL_DONE;
   18554 	    break;
   18555 	  }
   18556 
   18557 	case OMP_ATOMIC:
   18558 	case OMP_ATOMIC_READ:
   18559 	case OMP_ATOMIC_CAPTURE_OLD:
   18560 	case OMP_ATOMIC_CAPTURE_NEW:
   18561 	  ret = gimplify_omp_atomic (expr_p, pre_p);
   18562 	  break;
   18563 
   18564 	case TRANSACTION_EXPR:
   18565 	  ret = gimplify_transaction (expr_p, pre_p);
   18566 	  break;
   18567 
   18568 	case TRUTH_AND_EXPR:
   18569 	case TRUTH_OR_EXPR:
   18570 	case TRUTH_XOR_EXPR:
   18571 	  {
   18572 	    tree orig_type = TREE_TYPE (*expr_p);
   18573 	    tree new_type, xop0, xop1;
   18574 	    *expr_p = gimple_boolify (*expr_p);
   18575 	    new_type = TREE_TYPE (*expr_p);
   18576 	    if (!useless_type_conversion_p (orig_type, new_type))
   18577 	      {
   18578 		*expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
   18579 		ret = GS_OK;
   18580 		break;
   18581 	      }
   18582 
   18583 	  /* Boolified binary truth expressions are semantically equivalent
   18584 	     to bitwise binary expressions.  Canonicalize them to the
   18585 	     bitwise variant.  */
   18586 	    switch (TREE_CODE (*expr_p))
   18587 	      {
   18588 	      case TRUTH_AND_EXPR:
   18589 		TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
   18590 		break;
   18591 	      case TRUTH_OR_EXPR:
   18592 		TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
   18593 		break;
   18594 	      case TRUTH_XOR_EXPR:
   18595 		TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
   18596 		break;
   18597 	      default:
   18598 		break;
   18599 	      }
   18600 	    /* Now make sure that operands have compatible type to
   18601 	       expression's new_type.  */
   18602 	    xop0 = TREE_OPERAND (*expr_p, 0);
   18603 	    xop1 = TREE_OPERAND (*expr_p, 1);
   18604 	    if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
   18605 	      TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
   18606 							    new_type,
   18607 	      						    xop0);
   18608 	    if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
   18609 	      TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
   18610 							    new_type,
   18611 	      						    xop1);
   18612 	    /* Continue classified as tcc_binary.  */
   18613 	    goto expr_2;
   18614 	  }
   18615 
   18616 	case VEC_COND_EXPR:
   18617 	  goto expr_3;
   18618 
   18619 	case VEC_PERM_EXPR:
   18620 	  /* Classified as tcc_expression.  */
   18621 	  goto expr_3;
   18622 
   18623 	case BIT_INSERT_EXPR:
   18624 	  /* Argument 3 is a constant.  */
   18625 	  goto expr_2;
   18626 
   18627 	case POINTER_PLUS_EXPR:
   18628 	  {
   18629 	    enum gimplify_status r0, r1;
   18630 	    r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   18631 				post_p, is_gimple_val, fb_rvalue);
   18632 	    r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
   18633 				post_p, is_gimple_val, fb_rvalue);
   18634 	    recalculate_side_effects (*expr_p);
   18635 	    ret = MIN (r0, r1);
   18636 	    break;
   18637 	  }
   18638 
   18639 	default:
   18640 	  switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
   18641 	    {
   18642 	    case tcc_comparison:
   18643 	      /* Handle comparison of objects of non scalar mode aggregates
   18644 	     	 with a call to memcmp.  It would be nice to only have to do
   18645 	     	 this for variable-sized objects, but then we'd have to allow
   18646 	     	 the same nest of reference nodes we allow for MODIFY_EXPR and
   18647 	     	 that's too complex.
   18648 
   18649 		 Compare scalar mode aggregates as scalar mode values.  Using
   18650 		 memcmp for them would be very inefficient at best, and is
   18651 		 plain wrong if bitfields are involved.  */
   18652 	      if (error_operand_p (TREE_OPERAND (*expr_p, 1)))
   18653 		ret = GS_ERROR;
   18654 	      else
   18655 		{
   18656 		  tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
   18657 
   18658 		  /* Vector comparisons need no boolification.  */
   18659 		  if (TREE_CODE (type) == VECTOR_TYPE)
   18660 		    goto expr_2;
   18661 		  else if (!AGGREGATE_TYPE_P (type))
   18662 		    {
   18663 		      tree org_type = TREE_TYPE (*expr_p);
   18664 		      *expr_p = gimple_boolify (*expr_p);
   18665 		      if (!useless_type_conversion_p (org_type,
   18666 						      TREE_TYPE (*expr_p)))
   18667 			{
   18668 			  *expr_p = fold_convert_loc (input_location,
   18669 						      org_type, *expr_p);
   18670 			  ret = GS_OK;
   18671 			}
   18672 		      else
   18673 			goto expr_2;
   18674 		    }
   18675 		  else if (TYPE_MODE (type) != BLKmode)
   18676 		    ret = gimplify_scalar_mode_aggregate_compare (expr_p);
   18677 		  else
   18678 		    ret = gimplify_variable_sized_compare (expr_p);
   18679 		}
   18680 	      break;
   18681 
   18682 	    /* If *EXPR_P does not need to be special-cased, handle it
   18683 	       according to its class.  */
   18684 	    case tcc_unary:
   18685 	      ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   18686 				   post_p, is_gimple_val, fb_rvalue);
   18687 	      break;
   18688 
   18689 	    case tcc_binary:
   18690 	    expr_2:
   18691 	      {
   18692 		enum gimplify_status r0, r1;
   18693 
   18694 		r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   18695 		                    post_p, is_gimple_val, fb_rvalue);
   18696 		r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
   18697 				    post_p, is_gimple_val, fb_rvalue);
   18698 
   18699 		ret = MIN (r0, r1);
   18700 		break;
   18701 	      }
   18702 
   18703 	    expr_3:
   18704 	      {
   18705 		enum gimplify_status r0, r1, r2;
   18706 
   18707 		r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   18708 		                    post_p, is_gimple_val, fb_rvalue);
   18709 		r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
   18710 				    post_p, is_gimple_val, fb_rvalue);
   18711 		r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
   18712 				    post_p, is_gimple_val, fb_rvalue);
   18713 
   18714 		ret = MIN (MIN (r0, r1), r2);
   18715 		break;
   18716 	      }
   18717 
   18718 	    case tcc_declaration:
   18719 	    case tcc_constant:
   18720 	      ret = GS_ALL_DONE;
   18721 	      goto dont_recalculate;
   18722 
   18723 	    default:
   18724 	      gcc_unreachable ();
   18725 	    }
   18726 
   18727 	  recalculate_side_effects (*expr_p);
   18728 
   18729 	dont_recalculate:
   18730 	  break;
   18731 	}
   18732 
   18733       gcc_assert (*expr_p || ret != GS_OK);
   18734     }
   18735   while (ret == GS_OK);
   18736 
   18737   /* If we encountered an error_mark somewhere nested inside, either
   18738      stub out the statement or propagate the error back out.  */
   18739   if (ret == GS_ERROR)
   18740     {
   18741       if (is_statement)
   18742 	*expr_p = NULL;
   18743       goto out;
   18744     }
   18745 
   18746   /* This was only valid as a return value from the langhook, which
   18747      we handled.  Make sure it doesn't escape from any other context.  */
   18748   gcc_assert (ret != GS_UNHANDLED);
   18749 
   18750   if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
   18751     {
   18752       /* We aren't looking for a value, and we don't have a valid
   18753 	 statement.  If it doesn't have side-effects, throw it away.
   18754 	 We can also get here with code such as "*&&L;", where L is
   18755 	 a LABEL_DECL that is marked as FORCED_LABEL.  */
   18756       if (TREE_CODE (*expr_p) == LABEL_DECL
   18757 	  || !TREE_SIDE_EFFECTS (*expr_p))
   18758 	*expr_p = NULL;
   18759       else if (!TREE_THIS_VOLATILE (*expr_p))
   18760 	{
   18761 	  /* This is probably a _REF that contains something nested that
   18762 	     has side effects.  Recurse through the operands to find it.  */
   18763 	  enum tree_code code = TREE_CODE (*expr_p);
   18764 
   18765 	  switch (code)
   18766 	    {
   18767 	    case COMPONENT_REF:
   18768 	    case REALPART_EXPR:
   18769 	    case IMAGPART_EXPR:
   18770 	    case VIEW_CONVERT_EXPR:
   18771 	      gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   18772 			     gimple_test_f, fallback);
   18773 	      break;
   18774 
   18775 	    case ARRAY_REF:
   18776 	    case ARRAY_RANGE_REF:
   18777 	      gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   18778 			     gimple_test_f, fallback);
   18779 	      gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
   18780 			     gimple_test_f, fallback);
   18781 	      break;
   18782 
   18783 	    default:
   18784 	       /* Anything else with side-effects must be converted to
   18785 		  a valid statement before we get here.  */
   18786 	      gcc_unreachable ();
   18787 	    }
   18788 
   18789 	  *expr_p = NULL;
   18790 	}
   18791       else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
   18792 	       && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode
   18793 	       && !is_empty_type (TREE_TYPE (*expr_p)))
   18794 	{
   18795 	  /* Historically, the compiler has treated a bare reference
   18796 	     to a non-BLKmode volatile lvalue as forcing a load.  */
   18797 	  tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
   18798 
   18799 	  /* Normally, we do not want to create a temporary for a
   18800 	     TREE_ADDRESSABLE type because such a type should not be
   18801 	     copied by bitwise-assignment.  However, we make an
   18802 	     exception here, as all we are doing here is ensuring that
   18803 	     we read the bytes that make up the type.  We use
   18804 	     create_tmp_var_raw because create_tmp_var will abort when
   18805 	     given a TREE_ADDRESSABLE type.  */
   18806 	  tree tmp = create_tmp_var_raw (type, "vol");
   18807 	  gimple_add_tmp_var (tmp);
   18808 	  gimplify_assign (tmp, *expr_p, pre_p);
   18809 	  *expr_p = NULL;
   18810 	}
   18811       else
   18812 	/* We can't do anything useful with a volatile reference to
   18813 	   an incomplete type, so just throw it away.  Likewise for
   18814 	   a BLKmode type, since any implicit inner load should
   18815 	   already have been turned into an explicit one by the
   18816 	   gimplification process.  */
   18817 	*expr_p = NULL;
   18818     }
   18819 
   18820   /* If we are gimplifying at the statement level, we're done.  Tack
   18821      everything together and return.  */
   18822   if (fallback == fb_none || is_statement)
   18823     {
   18824       /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
   18825          it out for GC to reclaim it.  */
   18826       *expr_p = NULL_TREE;
   18827 
   18828       if (!gimple_seq_empty_p (internal_pre)
   18829 	  || !gimple_seq_empty_p (internal_post))
   18830 	{
   18831 	  gimplify_seq_add_seq (&internal_pre, internal_post);
   18832 	  gimplify_seq_add_seq (pre_p, internal_pre);
   18833 	}
   18834 
   18835       /* The result of gimplifying *EXPR_P is going to be the last few
   18836 	 statements in *PRE_P and *POST_P.  Add location information
   18837 	 to all the statements that were added by the gimplification
   18838 	 helpers.  */
   18839       if (!gimple_seq_empty_p (*pre_p))
   18840 	annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
   18841 
   18842       if (!gimple_seq_empty_p (*post_p))
   18843 	annotate_all_with_location_after (*post_p, post_last_gsi,
   18844 					  input_location);
   18845 
   18846       goto out;
   18847     }
   18848 
   18849 #ifdef ENABLE_GIMPLE_CHECKING
   18850   if (*expr_p)
   18851     {
   18852       enum tree_code code = TREE_CODE (*expr_p);
   18853       /* These expressions should already be in gimple IR form.  */
   18854       gcc_assert (code != MODIFY_EXPR
   18855 		  && code != ASM_EXPR
   18856 		  && code != BIND_EXPR
   18857 		  && code != CATCH_EXPR
   18858 		  && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
   18859 		  && code != EH_FILTER_EXPR
   18860 		  && code != GOTO_EXPR
   18861 		  && code != LABEL_EXPR
   18862 		  && code != LOOP_EXPR
   18863 		  && code != SWITCH_EXPR
   18864 		  && code != TRY_FINALLY_EXPR
   18865 		  && code != EH_ELSE_EXPR
   18866 		  && code != OACC_PARALLEL
   18867 		  && code != OACC_KERNELS
   18868 		  && code != OACC_SERIAL
   18869 		  && code != OACC_DATA
   18870 		  && code != OACC_HOST_DATA
   18871 		  && code != OACC_DECLARE
   18872 		  && code != OACC_UPDATE
   18873 		  && code != OACC_ENTER_DATA
   18874 		  && code != OACC_EXIT_DATA
   18875 		  && code != OACC_CACHE
   18876 		  && code != OMP_CRITICAL
   18877 		  && code != OMP_FOR
   18878 		  && code != OACC_LOOP
   18879 		  && code != OMP_MASTER
   18880 		  && code != OMP_MASKED
   18881 		  && code != OMP_TASKGROUP
   18882 		  && code != OMP_ORDERED
   18883 		  && code != OMP_PARALLEL
   18884 		  && code != OMP_SCAN
   18885 		  && code != OMP_SECTIONS
   18886 		  && code != OMP_SECTION
   18887 		  && code != OMP_STRUCTURED_BLOCK
   18888 		  && code != OMP_SINGLE
   18889 		  && code != OMP_SCOPE);
   18890     }
   18891 #endif
   18892 
   18893   /* Otherwise we're gimplifying a subexpression, so the resulting
   18894      value is interesting.  If it's a valid operand that matches
   18895      GIMPLE_TEST_F, we're done. Unless we are handling some
   18896      post-effects internally; if that's the case, we need to copy into
   18897      a temporary before adding the post-effects to POST_P.  */
   18898   if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
   18899     goto out;
   18900 
   18901   /* Otherwise, we need to create a new temporary for the gimplified
   18902      expression.  */
   18903 
   18904   /* We can't return an lvalue if we have an internal postqueue.  The
   18905      object the lvalue refers to would (probably) be modified by the
   18906      postqueue; we need to copy the value out first, which means an
   18907      rvalue.  */
   18908   if ((fallback & fb_lvalue)
   18909       && gimple_seq_empty_p (internal_post)
   18910       && is_gimple_addressable (*expr_p))
   18911     {
   18912       /* An lvalue will do.  Take the address of the expression, store it
   18913 	 in a temporary, and replace the expression with an INDIRECT_REF of
   18914 	 that temporary.  */
   18915       tree ref_alias_type = reference_alias_ptr_type (*expr_p);
   18916       unsigned int ref_align = get_object_alignment (*expr_p);
   18917       tree ref_type = TREE_TYPE (*expr_p);
   18918       tmp = build_fold_addr_expr_loc (input_location, *expr_p);
   18919       gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
   18920       if (TYPE_ALIGN (ref_type) != ref_align)
   18921 	ref_type = build_aligned_type (ref_type, ref_align);
   18922       *expr_p = build2 (MEM_REF, ref_type,
   18923 			tmp, build_zero_cst (ref_alias_type));
   18924     }
   18925   else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
   18926     {
   18927       /* An rvalue will do.  Assign the gimplified expression into a
   18928 	 new temporary TMP and replace the original expression with
   18929 	 TMP.  First, make sure that the expression has a type so that
   18930 	 it can be assigned into a temporary.  */
   18931       gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
   18932       *expr_p = get_formal_tmp_var (*expr_p, pre_p);
   18933     }
   18934   else
   18935     {
   18936 #ifdef ENABLE_GIMPLE_CHECKING
   18937       if (!(fallback & fb_mayfail))
   18938 	{
   18939 	  fprintf (stderr, "gimplification failed:\n");
   18940 	  print_generic_expr (stderr, *expr_p);
   18941 	  debug_tree (*expr_p);
   18942 	  internal_error ("gimplification failed");
   18943 	}
   18944 #endif
   18945       gcc_assert (fallback & fb_mayfail);
   18946 
   18947       /* If this is an asm statement, and the user asked for the
   18948 	 impossible, don't die.  Fail and let gimplify_asm_expr
   18949 	 issue an error.  */
   18950       ret = GS_ERROR;
   18951       goto out;
   18952     }
   18953 
   18954   /* Make sure the temporary matches our predicate.  */
   18955   gcc_assert ((*gimple_test_f) (*expr_p));
   18956 
   18957   if (!gimple_seq_empty_p (internal_post))
   18958     {
   18959       annotate_all_with_location (internal_post, input_location);
   18960       gimplify_seq_add_seq (pre_p, internal_post);
   18961     }
   18962 
   18963  out:
   18964   input_location = saved_location;
   18965   return ret;
   18966 }
   18967 
   18968 /* Like gimplify_expr but make sure the gimplified result is not itself
   18969    a SSA name (but a decl if it were).  Temporaries required by
   18970    evaluating *EXPR_P may be still SSA names.  */
   18971 
   18972 static enum gimplify_status
   18973 gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   18974 	       bool (*gimple_test_f) (tree), fallback_t fallback,
   18975 	       bool allow_ssa)
   18976 {
   18977   enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
   18978 					    gimple_test_f, fallback);
   18979   if (! allow_ssa
   18980       && TREE_CODE (*expr_p) == SSA_NAME)
   18981     *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
   18982   return ret;
   18983 }
   18984 
   18985 /* Look through TYPE for variable-sized objects and gimplify each such
   18986    size that we find.  Add to LIST_P any statements generated.  */
   18987 
   18988 void
   18989 gimplify_type_sizes (tree type, gimple_seq *list_p)
   18990 {
   18991   if (type == NULL || type == error_mark_node)
   18992     return;
   18993 
   18994   const bool ignored_p
   18995     = TYPE_NAME (type)
   18996       && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
   18997       && DECL_IGNORED_P (TYPE_NAME (type));
   18998   tree t;
   18999 
   19000   /* We first do the main variant, then copy into any other variants.  */
   19001   type = TYPE_MAIN_VARIANT (type);
   19002 
   19003   /* Avoid infinite recursion.  */
   19004   if (TYPE_SIZES_GIMPLIFIED (type))
   19005     return;
   19006 
   19007   TYPE_SIZES_GIMPLIFIED (type) = 1;
   19008 
   19009   switch (TREE_CODE (type))
   19010     {
   19011     case INTEGER_TYPE:
   19012     case ENUMERAL_TYPE:
   19013     case BOOLEAN_TYPE:
   19014     case REAL_TYPE:
   19015     case FIXED_POINT_TYPE:
   19016       gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
   19017       gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
   19018 
   19019       for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
   19020 	{
   19021 	  TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
   19022 	  TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
   19023 	}
   19024       break;
   19025 
   19026     case ARRAY_TYPE:
   19027       /* These types may not have declarations, so handle them here.  */
   19028       gimplify_type_sizes (TREE_TYPE (type), list_p);
   19029       gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
   19030       /* Ensure VLA bounds aren't removed, for -O0 they should be variables
   19031 	 with assigned stack slots, for -O1+ -g they should be tracked
   19032 	 by VTA.  */
   19033       if (!ignored_p
   19034 	  && TYPE_DOMAIN (type)
   19035 	  && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
   19036 	{
   19037 	  t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
   19038 	  if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
   19039 	    DECL_IGNORED_P (t) = 0;
   19040 	  t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
   19041 	  if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
   19042 	    DECL_IGNORED_P (t) = 0;
   19043 	}
   19044       break;
   19045 
   19046     case RECORD_TYPE:
   19047     case UNION_TYPE:
   19048     case QUAL_UNION_TYPE:
   19049       for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
   19050 	if (TREE_CODE (field) == FIELD_DECL)
   19051 	  {
   19052 	    gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
   19053 	    /* Likewise, ensure variable offsets aren't removed.  */
   19054 	    if (!ignored_p
   19055 		&& (t = DECL_FIELD_OFFSET (field))
   19056 		&& VAR_P (t)
   19057 		&& DECL_ARTIFICIAL (t))
   19058 	      DECL_IGNORED_P (t) = 0;
   19059 	    gimplify_one_sizepos (&DECL_SIZE (field), list_p);
   19060 	    gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
   19061 	    gimplify_type_sizes (TREE_TYPE (field), list_p);
   19062 	  }
   19063       break;
   19064 
   19065     case POINTER_TYPE:
   19066     case REFERENCE_TYPE:
   19067 	/* We used to recurse on the pointed-to type here, which turned out to
   19068 	   be incorrect because its definition might refer to variables not
   19069 	   yet initialized at this point if a forward declaration is involved.
   19070 
   19071 	   It was actually useful for anonymous pointed-to types to ensure
   19072 	   that the sizes evaluation dominates every possible later use of the
   19073 	   values.  Restricting to such types here would be safe since there
   19074 	   is no possible forward declaration around, but would introduce an
   19075 	   undesirable middle-end semantic to anonymity.  We then defer to
   19076 	   front-ends the responsibility of ensuring that the sizes are
   19077 	   evaluated both early and late enough, e.g. by attaching artificial
   19078 	   type declarations to the tree.  */
   19079       break;
   19080 
   19081     default:
   19082       break;
   19083     }
   19084 
   19085   gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
   19086   gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
   19087 
   19088   for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
   19089     {
   19090       TYPE_SIZE (t) = TYPE_SIZE (type);
   19091       TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
   19092       TYPE_SIZES_GIMPLIFIED (t) = 1;
   19093     }
   19094 }
   19095 
   19096 /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
   19097    a size or position, has had all of its SAVE_EXPRs evaluated.
   19098    We add any required statements to *STMT_P.  */
   19099 
   19100 void
   19101 gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
   19102 {
   19103   tree expr = *expr_p;
   19104 
   19105   /* We don't do anything if the value isn't there, is constant, or contains
   19106      A PLACEHOLDER_EXPR.  We also don't want to do anything if it's already
   19107      a VAR_DECL.  If it's a VAR_DECL from another function, the gimplifier
   19108      will want to replace it with a new variable, but that will cause problems
   19109      if this type is from outside the function.  It's OK to have that here.  */
   19110   if (expr == NULL_TREE
   19111       || is_gimple_constant (expr)
   19112       || VAR_P (expr)
   19113       || CONTAINS_PLACEHOLDER_P (expr))
   19114     return;
   19115 
   19116   *expr_p = unshare_expr (expr);
   19117 
   19118   /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
   19119      if the def vanishes.  */
   19120   gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
   19121 
   19122   /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
   19123      FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
   19124      as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs.  */
   19125   if (is_gimple_constant (*expr_p))
   19126     *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
   19127 }
   19128 
   19129 /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
   19130    containing the sequence of corresponding GIMPLE statements.  If DO_PARMS
   19131    is true, also gimplify the parameters.  */
   19132 
   19133 gbind *
   19134 gimplify_body (tree fndecl, bool do_parms)
   19135 {
   19136   location_t saved_location = input_location;
   19137   gimple_seq parm_stmts, parm_cleanup = NULL, seq;
   19138   gimple *outer_stmt;
   19139   gbind *outer_bind;
   19140 
   19141   timevar_push (TV_TREE_GIMPLIFY);
   19142 
   19143   init_tree_ssa (cfun);
   19144 
   19145   /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
   19146      gimplification.  */
   19147   default_rtl_profile ();
   19148 
   19149   gcc_assert (gimplify_ctxp == NULL);
   19150   push_gimplify_context (true);
   19151 
   19152   if (flag_openacc || flag_openmp)
   19153     {
   19154       gcc_assert (gimplify_omp_ctxp == NULL);
   19155       if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
   19156 	gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
   19157     }
   19158 
   19159   /* Unshare most shared trees in the body and in that of any nested functions.
   19160      It would seem we don't have to do this for nested functions because
   19161      they are supposed to be output and then the outer function gimplified
   19162      first, but the g++ front end doesn't always do it that way.  */
   19163   unshare_body (fndecl);
   19164   unvisit_body (fndecl);
   19165 
   19166   /* Make sure input_location isn't set to something weird.  */
   19167   input_location = DECL_SOURCE_LOCATION (fndecl);
   19168 
   19169   /* Resolve callee-copies.  This has to be done before processing
   19170      the body so that DECL_VALUE_EXPR gets processed correctly.  */
   19171   parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
   19172 
   19173   /* Gimplify the function's body.  */
   19174   seq = NULL;
   19175   gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
   19176   outer_stmt = gimple_seq_first_nondebug_stmt (seq);
   19177   if (!outer_stmt)
   19178     {
   19179       outer_stmt = gimple_build_nop ();
   19180       gimplify_seq_add_stmt (&seq, outer_stmt);
   19181     }
   19182 
   19183   /* The body must contain exactly one statement, a GIMPLE_BIND.  If this is
   19184      not the case, wrap everything in a GIMPLE_BIND to make it so.  */
   19185   if (gimple_code (outer_stmt) == GIMPLE_BIND
   19186       && (gimple_seq_first_nondebug_stmt (seq)
   19187 	  == gimple_seq_last_nondebug_stmt (seq)))
   19188     {
   19189       outer_bind = as_a <gbind *> (outer_stmt);
   19190       if (gimple_seq_first_stmt (seq) != outer_stmt
   19191 	  || gimple_seq_last_stmt (seq) != outer_stmt)
   19192 	{
   19193 	  /* If there are debug stmts before or after outer_stmt, move them
   19194 	     inside of outer_bind body.  */
   19195 	  gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
   19196 	  gimple_seq second_seq = NULL;
   19197 	  if (gimple_seq_first_stmt (seq) != outer_stmt
   19198 	      && gimple_seq_last_stmt (seq) != outer_stmt)
   19199 	    {
   19200 	      second_seq = gsi_split_seq_after (gsi);
   19201 	      gsi_remove (&gsi, false);
   19202 	    }
   19203 	  else if (gimple_seq_first_stmt (seq) != outer_stmt)
   19204 	    gsi_remove (&gsi, false);
   19205 	  else
   19206 	    {
   19207 	      gsi_remove (&gsi, false);
   19208 	      second_seq = seq;
   19209 	      seq = NULL;
   19210 	    }
   19211 	  gimple_seq_add_seq_without_update (&seq,
   19212 					     gimple_bind_body (outer_bind));
   19213 	  gimple_seq_add_seq_without_update (&seq, second_seq);
   19214 	  gimple_bind_set_body (outer_bind, seq);
   19215 	}
   19216     }
   19217   else
   19218     outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
   19219 
   19220   DECL_SAVED_TREE (fndecl) = NULL_TREE;
   19221 
   19222   /* If we had callee-copies statements, insert them at the beginning
   19223      of the function and clear DECL_VALUE_EXPR_P on the parameters.  */
   19224   if (!gimple_seq_empty_p (parm_stmts))
   19225     {
   19226       tree parm;
   19227 
   19228       gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
   19229       if (parm_cleanup)
   19230 	{
   19231 	  gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
   19232 				      GIMPLE_TRY_FINALLY);
   19233 	  parm_stmts = NULL;
   19234 	  gimple_seq_add_stmt (&parm_stmts, g);
   19235 	}
   19236       gimple_bind_set_body (outer_bind, parm_stmts);
   19237 
   19238       for (parm = DECL_ARGUMENTS (current_function_decl);
   19239 	   parm; parm = DECL_CHAIN (parm))
   19240 	if (DECL_HAS_VALUE_EXPR_P (parm))
   19241 	  {
   19242 	    DECL_HAS_VALUE_EXPR_P (parm) = 0;
   19243 	    DECL_IGNORED_P (parm) = 0;
   19244 	  }
   19245     }
   19246 
   19247   if ((flag_openacc || flag_openmp || flag_openmp_simd)
   19248       && gimplify_omp_ctxp)
   19249     {
   19250       delete_omp_context (gimplify_omp_ctxp);
   19251       gimplify_omp_ctxp = NULL;
   19252     }
   19253 
   19254   pop_gimplify_context (outer_bind);
   19255   gcc_assert (gimplify_ctxp == NULL);
   19256 
   19257   if (flag_checking && !seen_error ())
   19258     verify_gimple_in_seq (gimple_bind_body (outer_bind));
   19259 
   19260   timevar_pop (TV_TREE_GIMPLIFY);
   19261   input_location = saved_location;
   19262 
   19263   return outer_bind;
   19264 }
   19265 
   19266 typedef char *char_p; /* For DEF_VEC_P.  */
   19267 
   19268 /* Return whether we should exclude FNDECL from instrumentation.  */
   19269 
   19270 static bool
   19271 flag_instrument_functions_exclude_p (tree fndecl)
   19272 {
   19273   vec<char_p> *v;
   19274 
   19275   v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
   19276   if (v && v->length () > 0)
   19277     {
   19278       const char *name;
   19279       int i;
   19280       char *s;
   19281 
   19282       name = lang_hooks.decl_printable_name (fndecl, 1);
   19283       FOR_EACH_VEC_ELT (*v, i, s)
   19284 	if (strstr (name, s) != NULL)
   19285 	  return true;
   19286     }
   19287 
   19288   v = (vec<char_p> *) flag_instrument_functions_exclude_files;
   19289   if (v && v->length () > 0)
   19290     {
   19291       const char *name;
   19292       int i;
   19293       char *s;
   19294 
   19295       name = DECL_SOURCE_FILE (fndecl);
   19296       FOR_EACH_VEC_ELT (*v, i, s)
   19297 	if (strstr (name, s) != NULL)
   19298 	  return true;
   19299     }
   19300 
   19301   return false;
   19302 }
   19303 
   19304 /* Build a call to the instrumentation function FNCODE and add it to SEQ.
   19305    If COND_VAR is not NULL, it is a boolean variable guarding the call to
   19306    the instrumentation function.  IF STMT is not NULL, it is a statement
   19307    to be executed just before the call to the instrumentation function.  */
   19308 
   19309 static void
   19310 build_instrumentation_call (gimple_seq *seq, enum built_in_function fncode,
   19311 			    tree cond_var, gimple *stmt)
   19312 {
   19313   /* The instrumentation hooks aren't going to call the instrumented
   19314      function and the address they receive is expected to be matchable
   19315      against symbol addresses.  Make sure we don't create a trampoline,
   19316      in case the current function is nested.  */
   19317   tree this_fn_addr = build_fold_addr_expr (current_function_decl);
   19318   TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
   19319 
   19320   tree label_true, label_false;
   19321   if (cond_var)
   19322     {
   19323       label_true = create_artificial_label (UNKNOWN_LOCATION);
   19324       label_false = create_artificial_label (UNKNOWN_LOCATION);
   19325       gcond *cond = gimple_build_cond (EQ_EXPR, cond_var, boolean_false_node,
   19326 				      label_true, label_false);
   19327       gimplify_seq_add_stmt (seq, cond);
   19328       gimplify_seq_add_stmt (seq, gimple_build_label (label_true));
   19329       gimplify_seq_add_stmt (seq, gimple_build_predict (PRED_COLD_LABEL,
   19330 							NOT_TAKEN));
   19331     }
   19332 
   19333   if (stmt)
   19334     gimplify_seq_add_stmt (seq, stmt);
   19335 
   19336   tree x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
   19337   gcall *call = gimple_build_call (x, 1, integer_zero_node);
   19338   tree tmp_var = create_tmp_var (ptr_type_node, "return_addr");
   19339   gimple_call_set_lhs (call, tmp_var);
   19340   gimplify_seq_add_stmt (seq, call);
   19341   x = builtin_decl_implicit (fncode);
   19342   call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
   19343   gimplify_seq_add_stmt (seq, call);
   19344 
   19345   if (cond_var)
   19346     gimplify_seq_add_stmt (seq, gimple_build_label (label_false));
   19347 }
   19348 
   19349 /* Entry point to the gimplification pass.  FNDECL is the FUNCTION_DECL
   19350    node for the function we want to gimplify.
   19351 
   19352    Return the sequence of GIMPLE statements corresponding to the body
   19353    of FNDECL.  */
   19354 
   19355 void
   19356 gimplify_function_tree (tree fndecl)
   19357 {
   19358   gimple_seq seq;
   19359   gbind *bind;
   19360 
   19361   gcc_assert (!gimple_body (fndecl));
   19362 
   19363   if (DECL_STRUCT_FUNCTION (fndecl))
   19364     push_cfun (DECL_STRUCT_FUNCTION (fndecl));
   19365   else
   19366     push_struct_function (fndecl);
   19367 
   19368   reset_cond_uid ();
   19369 
   19370   /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
   19371      if necessary.  */
   19372   cfun->curr_properties |= PROP_gimple_lva;
   19373 
   19374   if (asan_sanitize_use_after_scope ())
   19375     asan_poisoned_variables = new hash_set<tree> ();
   19376   bind = gimplify_body (fndecl, true);
   19377   if (asan_poisoned_variables)
   19378     {
   19379       delete asan_poisoned_variables;
   19380       asan_poisoned_variables = NULL;
   19381     }
   19382 
   19383   /* The tree body of the function is no longer needed, replace it
   19384      with the new GIMPLE body.  */
   19385   seq = NULL;
   19386   gimple_seq_add_stmt (&seq, bind);
   19387   gimple_set_body (fndecl, seq);
   19388 
   19389   /* If we're instrumenting function entry/exit, then prepend the call to
   19390      the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
   19391      catch the exit hook.  */
   19392   /* ??? Add some way to ignore exceptions for this TFE.  */
   19393   if (flag_instrument_function_entry_exit
   19394       && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
   19395       /* Do not instrument extern inline functions.  */
   19396       && !(DECL_DECLARED_INLINE_P (fndecl)
   19397 	   && DECL_EXTERNAL (fndecl)
   19398 	   && DECL_DISREGARD_INLINE_LIMITS (fndecl))
   19399       && !flag_instrument_functions_exclude_p (fndecl))
   19400     {
   19401       gimple_seq body = NULL, cleanup = NULL;
   19402       gassign *assign;
   19403       tree cond_var;
   19404 
   19405       /* If -finstrument-functions-once is specified, generate:
   19406 
   19407 	   static volatile bool C.0 = false;
   19408 	   bool tmp_called;
   19409 
   19410 	   tmp_called = C.0;
   19411 	   if (!tmp_called)
   19412 	     {
   19413 	       C.0 = true;
   19414 	       [call profiling enter function]
   19415 	     }
   19416 
   19417 	 without specific protection for data races.  */
   19418       if (flag_instrument_function_entry_exit > 1)
   19419 	{
   19420 	  tree first_var
   19421 	    = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
   19422 			  VAR_DECL,
   19423 			  create_tmp_var_name ("C"),
   19424 			  boolean_type_node);
   19425 	  DECL_ARTIFICIAL (first_var) = 1;
   19426 	  DECL_IGNORED_P (first_var) = 1;
   19427 	  TREE_STATIC (first_var) = 1;
   19428 	  TREE_THIS_VOLATILE (first_var) = 1;
   19429 	  TREE_USED (first_var) = 1;
   19430 	  DECL_INITIAL (first_var) = boolean_false_node;
   19431 	  varpool_node::add (first_var);
   19432 
   19433 	  cond_var = create_tmp_var (boolean_type_node, "tmp_called");
   19434 	  assign = gimple_build_assign (cond_var, first_var);
   19435 	  gimplify_seq_add_stmt (&body, assign);
   19436 
   19437 	  assign = gimple_build_assign (first_var, boolean_true_node);
   19438 	}
   19439 
   19440       else
   19441 	{
   19442 	  cond_var = NULL_TREE;
   19443 	  assign = NULL;
   19444 	}
   19445 
   19446       build_instrumentation_call (&body, BUILT_IN_PROFILE_FUNC_ENTER,
   19447 				  cond_var, assign);
   19448 
   19449       /* If -finstrument-functions-once is specified, generate:
   19450 
   19451 	   if (!tmp_called)
   19452 	     [call profiling exit function]
   19453 
   19454 	 without specific protection for data races.  */
   19455       build_instrumentation_call (&cleanup, BUILT_IN_PROFILE_FUNC_EXIT,
   19456 				  cond_var, NULL);
   19457 
   19458       gimple *tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
   19459       gimplify_seq_add_stmt (&body, tf);
   19460       gbind *new_bind = gimple_build_bind (NULL, body, NULL);
   19461 
   19462       /* Replace the current function body with the body
   19463          wrapped in the try/finally TF.  */
   19464       seq = NULL;
   19465       gimple_seq_add_stmt (&seq, new_bind);
   19466       gimple_set_body (fndecl, seq);
   19467       bind = new_bind;
   19468     }
   19469 
   19470   if (sanitize_flags_p (SANITIZE_THREAD)
   19471       && param_tsan_instrument_func_entry_exit)
   19472     {
   19473       gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
   19474       gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
   19475       gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
   19476       /* Replace the current function body with the body
   19477 	 wrapped in the try/finally TF.  */
   19478       seq = NULL;
   19479       gimple_seq_add_stmt (&seq, new_bind);
   19480       gimple_set_body (fndecl, seq);
   19481     }
   19482 
   19483   DECL_SAVED_TREE (fndecl) = NULL_TREE;
   19484   cfun->curr_properties |= PROP_gimple_any;
   19485 
   19486   pop_cfun ();
   19487 
   19488   dump_function (TDI_gimple, fndecl);
   19489 }
   19490 
   19491 /* Return a dummy expression of type TYPE in order to keep going after an
   19492    error.  */
   19493 
   19494 static tree
   19495 dummy_object (tree type)
   19496 {
   19497   tree t = build_int_cst (build_pointer_type (type), 0);
   19498   return build2 (MEM_REF, type, t, t);
   19499 }
   19500 
   19501 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
   19502    builtin function, but a very special sort of operator.  */
   19503 
   19504 enum gimplify_status
   19505 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
   19506 		      gimple_seq *post_p ATTRIBUTE_UNUSED)
   19507 {
   19508   tree promoted_type, have_va_type;
   19509   tree valist = TREE_OPERAND (*expr_p, 0);
   19510   tree type = TREE_TYPE (*expr_p);
   19511   tree t, tag, aptag;
   19512   location_t loc = EXPR_LOCATION (*expr_p);
   19513 
   19514   /* Verify that valist is of the proper type.  */
   19515   have_va_type = TREE_TYPE (valist);
   19516   if (have_va_type == error_mark_node)
   19517     return GS_ERROR;
   19518   have_va_type = targetm.canonical_va_list_type (have_va_type);
   19519   if (have_va_type == NULL_TREE
   19520       && POINTER_TYPE_P (TREE_TYPE (valist)))
   19521     /* Handle 'Case 1: Not an array type' from c-common.cc/build_va_arg.  */
   19522     have_va_type
   19523       = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
   19524   gcc_assert (have_va_type != NULL_TREE);
   19525 
   19526   /* Generate a diagnostic for requesting data of a type that cannot
   19527      be passed through `...' due to type promotion at the call site.  */
   19528   if ((promoted_type = lang_hooks.types.type_promotes_to (type))
   19529 	   != type)
   19530     {
   19531       static bool gave_help;
   19532       bool warned;
   19533       /* Use the expansion point to handle cases such as passing bool (defined
   19534 	 in a system header) through `...'.  */
   19535       location_t xloc
   19536 	= expansion_point_location_if_in_system_header (loc);
   19537 
   19538       /* Unfortunately, this is merely undefined, rather than a constraint
   19539 	 violation, so we cannot make this an error.  If this call is never
   19540 	 executed, the program is still strictly conforming.  */
   19541       auto_diagnostic_group d;
   19542       warned = warning_at (xloc, 0,
   19543 			   "%qT is promoted to %qT when passed through %<...%>",
   19544 			   type, promoted_type);
   19545       if (!gave_help && warned)
   19546 	{
   19547 	  gave_help = true;
   19548 	  inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
   19549 		  promoted_type, type);
   19550 	}
   19551 
   19552       /* We can, however, treat "undefined" any way we please.
   19553 	 Call abort to encourage the user to fix the program.  */
   19554       if (warned)
   19555 	inform (xloc, "if this code is reached, the program will abort");
   19556       /* Before the abort, allow the evaluation of the va_list
   19557 	 expression to exit or longjmp.  */
   19558       gimplify_and_add (valist, pre_p);
   19559       t = build_call_expr_loc (loc,
   19560 			       builtin_decl_implicit (BUILT_IN_TRAP), 0);
   19561       gimplify_and_add (t, pre_p);
   19562 
   19563       /* This is dead code, but go ahead and finish so that the
   19564 	 mode of the result comes out right.  */
   19565       *expr_p = dummy_object (type);
   19566       return GS_ALL_DONE;
   19567     }
   19568 
   19569   tag = build_int_cst (build_pointer_type (type), 0);
   19570   aptag = build_int_cst (TREE_TYPE (valist), 0);
   19571 
   19572   *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
   19573 					  valist, tag, aptag);
   19574 
   19575   /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
   19576      needs to be expanded.  */
   19577   cfun->curr_properties &= ~PROP_gimple_lva;
   19578 
   19579   return GS_OK;
   19580 }
   19581 
   19582 /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
   19583 
   19584    DST/SRC are the destination and source respectively.  You can pass
   19585    ungimplified trees in DST or SRC, in which case they will be
   19586    converted to a gimple operand if necessary.
   19587 
   19588    This function returns the newly created GIMPLE_ASSIGN tuple.  */
   19589 
   19590 gimple *
   19591 gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
   19592 {
   19593   tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
   19594   gimplify_and_add (t, seq_p);
   19595   ggc_free (t);
   19596   return gimple_seq_last_stmt (*seq_p);
   19597 }
   19598 
   19599 inline hashval_t
   19600 gimplify_hasher::hash (const elt_t *p)
   19601 {
   19602   tree t = p->val;
   19603   return iterative_hash_expr (t, 0);
   19604 }
   19605 
   19606 inline bool
   19607 gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
   19608 {
   19609   tree t1 = p1->val;
   19610   tree t2 = p2->val;
   19611   enum tree_code code = TREE_CODE (t1);
   19612 
   19613   if (TREE_CODE (t2) != code
   19614       || TREE_TYPE (t1) != TREE_TYPE (t2))
   19615     return false;
   19616 
   19617   if (!operand_equal_p (t1, t2, 0))
   19618     return false;
   19619 
   19620   /* Only allow them to compare equal if they also hash equal; otherwise
   19621      results are nondeterminate, and we fail bootstrap comparison.  */
   19622   gcc_checking_assert (hash (p1) == hash (p2));
   19623 
   19624   return true;
   19625 }
   19626