LCOV - code coverage report
Current view: top level - gcc - gimplify.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.5 % 10800 10207
Test Date: 2026-10-17 16:30:31 Functions: 97.9 % 242 237
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Tree lowering pass.  This pass converts the GENERIC functions-as-trees
       2              :    tree representation into the GIMPLE form.
       3              :    Copyright (C) 2002-2026 Free Software Foundation, Inc.
       4              :    Major work done by Sebastian Pop <s.pop@laposte.net>,
       5              :    Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
       6              : 
       7              : This file is part of GCC.
       8              : 
       9              : GCC is free software; you can redistribute it and/or modify it under
      10              : the terms of the GNU General Public License as published by the Free
      11              : Software Foundation; either version 3, or (at your option) any later
      12              : version.
      13              : 
      14              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      15              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      16              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      17              : for more details.
      18              : 
      19              : You should have received a copy of the GNU General Public License
      20              : along with GCC; see the file COPYING3.  If not see
      21              : <http://www.gnu.org/licenses/>.  */
      22              : 
      23              : #include "config.h"
      24              : #include "system.h"
      25              : #include "coretypes.h"
      26              : #include "backend.h"
      27              : #include "target.h"
      28              : #include "rtl.h"
      29              : #include "tree.h"
      30              : #include "memmodel.h"
      31              : #include "tm_p.h"
      32              : #include "gimple.h"
      33              : #include "gimple-predict.h"
      34              : #include "tree-pass.h"                /* FIXME: only for PROP_gimple_any */
      35              : #include "ssa.h"
      36              : #include "cgraph.h"
      37              : #include "tree-pretty-print.h"
      38              : #include "diagnostic-core.h"
      39              : #include "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              : #include "gcc-urlifier.h"
      74              : #include "insn-config.h"
      75              : #include "recog.h"
      76              : #include "output.h"
      77              : #include "gimplify_reg_info.h"
      78              : #include "tree-ssa-loop-niter.h" /* For simplify_replace_tree.  */
      79              : 
      80              : /* Identifier for a basic condition, mapping it to other basic conditions of
      81              :    its Boolean expression.  Basic conditions given the same uid (in the same
      82              :    function) are parts of the same ANDIF/ORIF expression.  Used for condition
      83              :    coverage.  */
      84              : static unsigned nextconduid = 1;
      85              : 
      86              : /* Annotated gconds so that basic conditions in the same expression map to
      87              :    the same uid.  This is used for condition coverage.  */
      88              : static hash_map <tree, unsigned> *cond_uids;
      89              : 
      90              : /* Get a fresh identifier for a new condition expression.  This is used for
      91              :    condition coverage.  */
      92              : static unsigned
      93      5907276 : next_cond_uid ()
      94              : {
      95      5907276 :   return nextconduid++;
      96              : }
      97              : 
      98              : /* Reset the condition uid to the value it should have when compiling a new
      99              :    function.  0 is already the default/untouched value, so start at non-zero.
     100              :    A valid and set id should always be > 0.  This is used for condition
     101              :    coverage.  */
     102              : static void
     103      3048501 : reset_cond_uid ()
     104              : {
     105      3048501 :   nextconduid = 1;
     106            0 : }
     107              : 
     108              : /* Associate the condition STMT with the discriminator UID.  STMTs that are
     109              :    broken down with ANDIF/ORIF from the same Boolean expression should be given
     110              :    the same UID; 'if (a && b && c) { if (d || e) ... } ...' should yield the
     111              :    { a: 1, b: 1, c: 1, d: 2, e: 2 } when gimplification is done.  This is used
     112              :    for condition coverage.  */
     113              : static void
     114      1230799 : tree_associate_condition_with_expr (tree stmt, unsigned uid)
     115              : {
     116      1230799 :   if (!condition_coverage_flag)
     117              :     return;
     118              : 
     119          542 :   if (!cond_uids)
     120           68 :     cond_uids = new hash_map <tree, unsigned> ();
     121              : 
     122          542 :   cond_uids->put (stmt, uid);
     123              : }
     124              : 
     125              : /* Hash set of poisoned variables in a bind expr.  */
     126              : static hash_set<tree> *asan_poisoned_variables = NULL;
     127              : 
     128              : /* Hash set of already-resolved calls to OpenMP "declare variant"
     129              :    functions.  A call can resolve to the original function and
     130              :    we don't want to repeat the resolution multiple times.  */
     131              : static hash_set<tree> *omp_resolved_variant_calls = NULL;
     132              : 
     133              : enum gimplify_omp_var_data
     134              : {
     135              :   GOVD_SEEN = 0x000001,
     136              :   GOVD_EXPLICIT = 0x000002,
     137              :   GOVD_SHARED = 0x000004,
     138              :   GOVD_PRIVATE = 0x000008,
     139              :   GOVD_FIRSTPRIVATE = 0x000010,
     140              :   GOVD_LASTPRIVATE = 0x000020,
     141              :   GOVD_REDUCTION = 0x000040,
     142              :   GOVD_LOCAL = 0x00080,
     143              :   GOVD_MAP = 0x000100,
     144              :   GOVD_DEBUG_PRIVATE = 0x000200,
     145              :   GOVD_PRIVATE_OUTER_REF = 0x000400,
     146              :   GOVD_LINEAR = 0x000800,
     147              :   GOVD_ALIGNED = 0x001000,
     148              : 
     149              :   /* Flag for GOVD_MAP: don't copy back.  */
     150              :   GOVD_MAP_TO_ONLY = 0x002000,
     151              : 
     152              :   /* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference.  */
     153              :   GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 0x004000,
     154              : 
     155              :   GOVD_MAP_0LEN_ARRAY = 0x008000,
     156              : 
     157              :   /* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping.  */
     158              :   GOVD_MAP_ALWAYS_TO = 0x010000,
     159              : 
     160              :   /* Flag for shared vars that are or might be stored to in the region.  */
     161              :   GOVD_WRITTEN = 0x020000,
     162              : 
     163              :   /* Flag for GOVD_MAP, if it is a forced mapping.  */
     164              :   GOVD_MAP_FORCE = 0x040000,
     165              : 
     166              :   /* Flag for GOVD_MAP: must be present already.  */
     167              :   GOVD_MAP_FORCE_PRESENT = 0x080000,
     168              : 
     169              :   /* Flag for GOVD_MAP: only allocate.  */
     170              :   GOVD_MAP_ALLOC_ONLY = 0x100000,
     171              : 
     172              :   /* Flag for GOVD_MAP: only copy back.  */
     173              :   GOVD_MAP_FROM_ONLY = 0x200000,
     174              : 
     175              :   GOVD_NONTEMPORAL = 0x400000,
     176              : 
     177              :   /* Flag for GOVD_LASTPRIVATE: conditional modifier.  */
     178              :   GOVD_LASTPRIVATE_CONDITIONAL = 0x800000,
     179              : 
     180              :   GOVD_CONDTEMP = 0x1000000,
     181              : 
     182              :   /* Flag for GOVD_REDUCTION: inscan seen in {in,ex}clusive clause.  */
     183              :   GOVD_REDUCTION_INSCAN = 0x2000000,
     184              : 
     185              :   /* Flag for GOVD_FIRSTPRIVATE: OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT.  */
     186              :   GOVD_FIRSTPRIVATE_IMPLICIT = 0x4000000,
     187              : 
     188              :   /* Flag to indicate this an allocator for the uses_allocators clause.  */
     189              :   GOVD_USES_ALLOCATORS_ALLOCATOR = 0x8000000,
     190              : 
     191              :   GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
     192              :                            | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
     193              :                            | GOVD_LOCAL)
     194              : };
     195              : 
     196              : 
     197              : enum omp_region_type
     198              : {
     199              :   ORT_WORKSHARE = 0x00,
     200              :   ORT_TASKGROUP = 0x01,
     201              :   ORT_DISPATCH  = 0x02,
     202              :   ORT_SIMD      = 0x04,
     203              : 
     204              :   ORT_PARALLEL  = 0x08,
     205              :   ORT_COMBINED_PARALLEL = ORT_PARALLEL | 1,
     206              : 
     207              :   ORT_TASK      = 0x10,
     208              :   ORT_UNTIED_TASK = ORT_TASK | 1,
     209              :   ORT_TASKLOOP  = ORT_TASK | 2,
     210              :   ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2,
     211              : 
     212              :   ORT_TEAMS     = 0x20,
     213              :   ORT_COMBINED_TEAMS = ORT_TEAMS | 1,
     214              :   ORT_HOST_TEAMS = ORT_TEAMS | 2,
     215              :   ORT_COMBINED_HOST_TEAMS = ORT_COMBINED_TEAMS | 2,
     216              : 
     217              :   /* Data region.  */
     218              :   ORT_TARGET_DATA = 0x40,
     219              : 
     220              :   /* Data region with offloading.  */
     221              :   ORT_TARGET    = 0x80,
     222              :   ORT_COMBINED_TARGET = ORT_TARGET | 1,
     223              :   ORT_IMPLICIT_TARGET = ORT_TARGET | 2,
     224              : 
     225              :   /* OpenACC variants.  */
     226              :   ORT_ACC       = 0x100,  /* A generic OpenACC region.  */
     227              :   ORT_ACC_DATA  = ORT_ACC | ORT_TARGET_DATA, /* Data construct.  */
     228              :   ORT_ACC_PARALLEL = ORT_ACC | ORT_TARGET,  /* Parallel construct */
     229              :   ORT_ACC_KERNELS  = ORT_ACC | ORT_TARGET | 2,  /* Kernels construct.  */
     230              :   ORT_ACC_SERIAL   = ORT_ACC | ORT_TARGET | 4,  /* Serial construct.  */
     231              :   ORT_ACC_HOST_DATA = ORT_ACC | ORT_TARGET_DATA | 2,  /* Host data.  */
     232              : 
     233              :   /* Dummy OpenMP region, used to disable expansion of
     234              :      DECL_VALUE_EXPRs in taskloop pre body.  */
     235              :   ORT_NONE      = 0x200
     236              : };
     237              : 
     238              : /* Gimplify hashtable helper.  */
     239              : 
     240              : struct gimplify_hasher : free_ptr_hash <elt_t>
     241              : {
     242              :   static inline hashval_t hash (const elt_t *);
     243              :   static inline bool equal (const elt_t *, const elt_t *);
     244              : };
     245              : 
     246              : struct gimplify_ctx
     247              : {
     248              :   struct gimplify_ctx *prev_context;
     249              : 
     250              :   vec<gbind *> bind_expr_stack;
     251              :   tree temps;
     252              :   gimple_seq conditional_cleanups;
     253              :   tree exit_label;
     254              :   tree return_temp;
     255              : 
     256              :   vec<tree> case_labels;
     257              :   hash_set<tree> *live_switch_vars;
     258              :   /* The formal temporary table.  Should this be persistent?  */
     259              :   hash_table<gimplify_hasher> *temp_htab;
     260              : 
     261              :   int conditions;
     262              :   unsigned into_ssa : 1;
     263              :   unsigned allow_rhs_cond_expr : 1;
     264              :   unsigned in_cleanup_point_expr : 1;
     265              :   unsigned keep_stack : 1;
     266              :   unsigned save_stack : 1;
     267              :   unsigned in_switch_expr : 1;
     268              :   unsigned in_handler_expr : 1;
     269              : };
     270              : 
     271              : enum gimplify_defaultmap_kind
     272              : {
     273              :   GDMK_SCALAR,
     274              :   GDMK_SCALAR_TARGET, /* w/ Fortran's target attr, implicit mapping, only.  */
     275              :   GDMK_AGGREGATE,
     276              :   GDMK_ALLOCATABLE,
     277              :   GDMK_POINTER
     278              : };
     279              : 
     280              : struct gimplify_omp_ctx
     281              : {
     282              :   struct gimplify_omp_ctx *outer_context;
     283              :   splay_tree variables;
     284              :   hash_map<omp_name_type<tree>, tree> *implicit_mappers;
     285              :   hash_set<tree> *privatized_types;
     286              :   tree clauses;
     287              :   /* Iteration variables in an OMP_FOR.  */
     288              :   vec<tree> loop_iter_var;
     289              :   location_t location;
     290              :   enum omp_clause_default_kind default_kind;
     291              :   enum omp_region_type region_type;
     292              :   enum tree_code code;
     293              :   bool combined_loop;
     294              :   bool distribute;
     295              :   bool target_firstprivatize_array_bases;
     296              :   bool add_safelen1;
     297              :   bool order_concurrent;
     298              :   bool has_depend;
     299              :   bool in_for_exprs;
     300              :   bool in_call_args;
     301              :   int defaultmap[5];
     302              : };
     303              : 
     304              : static struct gimplify_ctx *gimplify_ctxp;
     305              : static struct gimplify_omp_ctx *gimplify_omp_ctxp;
     306              : static bool in_omp_construct;
     307              : 
     308              : /* Forward declaration.  */
     309              : static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
     310              : static hash_map<tree, tree> *oacc_declare_returns;
     311              : static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
     312              :                                            bool (*) (tree), fallback_t, bool);
     313              : static void prepare_gimple_addressable (tree *, gimple_seq *);
     314              : 
     315              : /* Shorter alias name for the above function for use in gimplify.cc
     316              :    only.  */
     317              : 
     318              : static inline void
     319     95004446 : gimplify_seq_add_stmt (gimple_seq *seq_p, gimple *gs)
     320              : {
     321     95004446 :   gimple_seq_add_stmt_without_update (seq_p, gs);
     322              : }
     323              : 
     324              : /* Append sequence SRC to the end of sequence *DST_P.  If *DST_P is
     325              :    NULL, a new sequence is allocated.   This function is
     326              :    similar to gimple_seq_add_seq, but does not scan the operands.
     327              :    During gimplification, we need to manipulate statement sequences
     328              :    before the def/use vectors have been constructed.  */
     329              : 
     330              : static void
     331      9663626 : gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
     332              : {
     333      9663626 :   gimple_stmt_iterator si;
     334              : 
     335      9663626 :   if (src == NULL)
     336      4114743 :     return;
     337              : 
     338      5548883 :   si = gsi_last (*dst_p);
     339      5548883 :   gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
     340              : }
     341              : 
     342              : 
     343              : /* Pointer to a list of allocated gimplify_ctx structs to be used for pushing
     344              :    and popping gimplify contexts.  */
     345              : 
     346              : static struct gimplify_ctx *ctx_pool = NULL;
     347              : 
     348              : /* Return a gimplify context struct from the pool.  */
     349              : 
     350              : static inline struct gimplify_ctx *
     351      9219160 : ctx_alloc (void)
     352              : {
     353      9219160 :   struct gimplify_ctx * c = ctx_pool;
     354              : 
     355      9219160 :   if (c)
     356      8948516 :     ctx_pool = c->prev_context;
     357              :   else
     358       270644 :     c = XNEW (struct gimplify_ctx);
     359              : 
     360      9219160 :   memset (c, '\0', sizeof (*c));
     361      9219160 :   return c;
     362              : }
     363              : 
     364              : /* Put gimplify context C back into the pool.  */
     365              : 
     366              : static inline void
     367      9219156 : ctx_free (struct gimplify_ctx *c)
     368              : {
     369      9219156 :   c->prev_context = ctx_pool;
     370      9219156 :   ctx_pool = c;
     371              : }
     372              : 
     373              : /* Free allocated ctx stack memory.  */
     374              : 
     375              : void
     376       237831 : free_gimplify_stack (void)
     377              : {
     378       237831 :   struct gimplify_ctx *c;
     379              : 
     380       478284 :   while ((c = ctx_pool))
     381              :     {
     382       240453 :       ctx_pool = c->prev_context;
     383       240453 :       free (c);
     384              :     }
     385       237831 : }
     386              : 
     387              : 
     388              : /* Set up a context for the gimplifier.  */
     389              : 
     390              : void
     391      9219160 : push_gimplify_context (bool in_ssa, bool rhs_cond_ok)
     392              : {
     393      9219160 :   struct gimplify_ctx *c = ctx_alloc ();
     394              : 
     395      9219160 :   c->prev_context = gimplify_ctxp;
     396      9219160 :   gimplify_ctxp = c;
     397      9219160 :   gimplify_ctxp->into_ssa = in_ssa;
     398      9219160 :   gimplify_ctxp->allow_rhs_cond_expr = rhs_cond_ok;
     399      9219160 : }
     400              : 
     401              : /* Tear down a context for the gimplifier.  If BODY is non-null, then
     402              :    put the temporaries into the outer BIND_EXPR.  Otherwise, put them
     403              :    in the local_decls.
     404              : 
     405              :    BODY is not a sequence, but the first tuple in a sequence.  */
     406              : 
     407              : void
     408      9219156 : pop_gimplify_context (gimple *body)
     409              : {
     410      9219156 :   struct gimplify_ctx *c = gimplify_ctxp;
     411              : 
     412      9219156 :   gcc_assert (c
     413              :               && (!c->bind_expr_stack.exists ()
     414              :                   || c->bind_expr_stack.is_empty ()));
     415      9219156 :   c->bind_expr_stack.release ();
     416      9219156 :   gimplify_ctxp = c->prev_context;
     417              : 
     418      9219156 :   if (body)
     419      3173833 :     declare_vars (c->temps, body, false);
     420              :   else
     421      6045323 :     record_vars (c->temps);
     422              : 
     423      9219156 :   delete c->temp_htab;
     424      9219156 :   c->temp_htab = NULL;
     425      9219156 :   ctx_free (c);
     426      9219156 : }
     427              : 
     428              : /* Push a GIMPLE_BIND tuple onto the stack of bindings.  */
     429              : 
     430              : static void
     431      6094339 : gimple_push_bind_expr (gbind *bind_stmt)
     432              : {
     433      6094339 :   gimplify_ctxp->bind_expr_stack.reserve (8);
     434      6094339 :   gimplify_ctxp->bind_expr_stack.safe_push (bind_stmt);
     435      6094339 : }
     436              : 
     437              : /* Pop the first element off the stack of bindings.  */
     438              : 
     439              : static void
     440      6094339 : gimple_pop_bind_expr (void)
     441              : {
     442            0 :   gimplify_ctxp->bind_expr_stack.pop ();
     443            0 : }
     444              : 
     445              : /* Return the first element of the stack of bindings.  */
     446              : 
     447              : gbind *
     448            0 : gimple_current_bind_expr (void)
     449              : {
     450            0 :   return gimplify_ctxp->bind_expr_stack.last ();
     451              : }
     452              : 
     453              : /* Return the stack of bindings created during gimplification.  */
     454              : 
     455              : vec<gbind *>
     456          369 : gimple_bind_expr_stack (void)
     457              : {
     458          369 :   return gimplify_ctxp->bind_expr_stack;
     459              : }
     460              : 
     461              : /* Return true iff there is a COND_EXPR between us and the innermost
     462              :    CLEANUP_POINT_EXPR.  This info is used by gimple_push_cleanup.  */
     463              : 
     464              : static bool
     465      2995127 : gimple_conditional_context (void)
     466              : {
     467      2995127 :   return gimplify_ctxp->conditions > 0;
     468              : }
     469              : 
     470              : /* Note that we've entered a COND_EXPR.  */
     471              : 
     472              : static void
     473      5907723 : gimple_push_condition (void)
     474              : {
     475              : #ifdef ENABLE_GIMPLE_CHECKING
     476      5907723 :   if (gimplify_ctxp->conditions == 0)
     477      3886229 :     gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
     478              : #endif
     479      5907723 :   ++(gimplify_ctxp->conditions);
     480      5907723 : }
     481              : 
     482              : /* Note that we've left a COND_EXPR.  If we're back at unconditional scope
     483              :    now, add any conditional cleanups we've seen to the prequeue.  */
     484              : 
     485              : static void
     486      5907723 : gimple_pop_condition (gimple_seq *pre_p)
     487              : {
     488      5907723 :   int conds = --(gimplify_ctxp->conditions);
     489              : 
     490      5907723 :   gcc_assert (conds >= 0);
     491      5907723 :   if (conds == 0)
     492              :     {
     493      3886229 :       gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
     494      3886229 :       gimplify_ctxp->conditional_cleanups = NULL;
     495              :     }
     496      5907723 : }
     497              : 
     498              : /* A stable comparison routine for use with splay trees and DECLs.  */
     499              : 
     500              : static int
     501     18356602 : splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
     502              : {
     503     18356602 :   tree a = (tree) xa;
     504     18356602 :   tree b = (tree) xb;
     505              : 
     506     18356602 :   return DECL_UID (a) - DECL_UID (b);
     507              : }
     508              : 
     509              : /* Create a new omp construct that deals with variable remapping.  */
     510              : 
     511              : static struct gimplify_omp_ctx *
     512       141369 : new_omp_context (enum omp_region_type region_type)
     513              : {
     514       141369 :   struct gimplify_omp_ctx *c;
     515              : 
     516       141369 :   c = XCNEW (struct gimplify_omp_ctx);
     517       141369 :   c->outer_context = gimplify_omp_ctxp;
     518       141369 :   c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
     519       141369 :   c->implicit_mappers = new hash_map<omp_name_type<tree>, tree>;
     520       141369 :   c->privatized_types = new hash_set<tree>;
     521       141369 :   c->location = input_location;
     522       141369 :   c->region_type = region_type;
     523       141369 :   if ((region_type & ORT_TASK) == 0)
     524              :     c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
     525              :   else
     526         6304 :     c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
     527       141369 :   c->defaultmap[GDMK_SCALAR] = GOVD_MAP;
     528       141369 :   c->defaultmap[GDMK_SCALAR_TARGET] = GOVD_MAP;
     529       141369 :   c->defaultmap[GDMK_AGGREGATE] = GOVD_MAP;
     530       141369 :   c->defaultmap[GDMK_ALLOCATABLE] = GOVD_MAP;
     531       141369 :   c->defaultmap[GDMK_POINTER] = GOVD_MAP;
     532              : 
     533       141369 :   return c;
     534              : }
     535              : 
     536              : /* Destroy an omp construct that deals with variable remapping.  */
     537              : 
     538              : static void
     539       140810 : delete_omp_context (struct gimplify_omp_ctx *c)
     540              : {
     541       140810 :   splay_tree_delete (c->variables);
     542       281620 :   delete c->privatized_types;
     543       281620 :   delete c->implicit_mappers;
     544       140810 :   c->loop_iter_var.release ();
     545       140810 :   XDELETE (c);
     546       140810 : }
     547              : 
     548              : static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
     549              : static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
     550              : 
     551              : /* Both gimplify the statement T and append it to *SEQ_P.  This function
     552              :    behaves exactly as gimplify_stmt, but you don't have to pass T as a
     553              :    reference.  */
     554              : 
     555              : void
     556     39039817 : gimplify_and_add (tree t, gimple_seq *seq_p)
     557              : {
     558     39039817 :   gimplify_stmt (&t, seq_p);
     559     39039817 : }
     560              : 
     561              : /* Gimplify statement T into sequence *SEQ_P, and return the first
     562              :    tuple in the sequence of generated tuples for this statement.
     563              :    Return NULL if gimplifying T produced no tuples.  */
     564              : 
     565              : static gimple *
     566       106178 : gimplify_and_return_first (tree t, gimple_seq *seq_p)
     567              : {
     568       106178 :   gimple_stmt_iterator last = gsi_last (*seq_p);
     569              : 
     570       106178 :   gimplify_and_add (t, seq_p);
     571              : 
     572       106178 :   if (!gsi_end_p (last))
     573              :     {
     574         4881 :       gsi_next (&last);
     575         4881 :       return gsi_stmt (last);
     576              :     }
     577              :   else
     578       101297 :     return gimple_seq_first_stmt (*seq_p);
     579              : }
     580              : 
     581              : /* Returns true iff T is a valid RHS for an assignment to an un-renamed
     582              :    LHS, or for a call argument.  */
     583              : 
     584              : static bool
     585       238207 : is_gimple_mem_rhs (tree t)
     586              : {
     587              :   /* If we're dealing with a renamable type, either source or dest must be
     588              :      a renamed variable.  */
     589       238207 :   if (is_gimple_reg_type (TREE_TYPE (t)))
     590       234833 :     return is_gimple_val (t);
     591              :   else
     592         3374 :     return is_gimple_val (t) || is_gimple_lvalue (t);
     593              : }
     594              : 
     595              : /* Return true if T is a CALL_EXPR or an expression that can be
     596              :    assigned to a temporary.  Note that this predicate should only be
     597              :    used during gimplification.  See the rationale for this in
     598              :    gimplify_modify_expr.  */
     599              : 
     600              : static bool
     601    100039886 : is_gimple_reg_rhs_or_call (tree t)
     602              : {
     603     73466002 :   return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
     604    100039886 :           || TREE_CODE (t) == CALL_EXPR);
     605              : }
     606              : 
     607              : /* Return true if T is a valid memory RHS or a CALL_EXPR.  Note that
     608              :    this predicate should only be used during gimplification.  See the
     609              :    rationale for this in gimplify_modify_expr.  */
     610              : 
     611              : static bool
     612     14652402 : is_gimple_mem_rhs_or_call (tree t)
     613              : {
     614              :   /* If we're dealing with a renamable type, either source or dest must be
     615              :      a renamed variable.  */
     616     14652402 :   if (is_gimple_reg_type (TREE_TYPE (t)))
     617     11142316 :     return is_gimple_val (t);
     618              :   else
     619      3510086 :     return (is_gimple_val (t)
     620      1775517 :             || is_gimple_lvalue (t)
     621      1246494 :             || (TREE_CODE (t) == CONSTRUCTOR && CONSTRUCTOR_NELTS (t) == 0)
     622      4756188 :             || TREE_CODE (t) == CALL_EXPR);
     623              : }
     624              : 
     625              : /* Create a temporary with a name derived from VAL.  Subroutine of
     626              :    lookup_tmp_var; nobody else should call this function.  */
     627              : 
     628              : static inline tree
     629      2198533 : create_tmp_from_val (tree val)
     630              : {
     631              :   /* Drop all qualifiers and address-space information from the value type.  */
     632      2198533 :   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (val));
     633      2198533 :   tree var = create_tmp_var (type, get_name (val));
     634      2198533 :   return var;
     635              : }
     636              : 
     637              : /* Create a temporary to hold the value of VAL.  If IS_FORMAL, try to reuse
     638              :    an existing expression temporary.  If NOT_GIMPLE_REG, mark it as such.  */
     639              : 
     640              : static tree
     641      2437942 : lookup_tmp_var (tree val, bool is_formal, bool not_gimple_reg)
     642              : {
     643      2437942 :   tree ret;
     644              : 
     645              :   /* We cannot mark a formal temporary with DECL_NOT_GIMPLE_REG_P.  */
     646      2437942 :   gcc_assert (!is_formal || !not_gimple_reg);
     647              : 
     648              :   /* If not optimizing, never really reuse a temporary.  local-alloc
     649              :      won't allocate any variable that is used in more than one basic
     650              :      block, which means it will go into memory, causing much extra
     651              :      work in reload and final and poorer code generation, outweighing
     652              :      the extra memory allocation here.  */
     653      2437942 :   if (!optimize || !is_formal || TREE_SIDE_EFFECTS (val))
     654              :     {
     655      1108296 :       ret = create_tmp_from_val (val);
     656      1108296 :       DECL_NOT_GIMPLE_REG_P (ret) = not_gimple_reg;
     657              :     }
     658              :   else
     659              :     {
     660      1329646 :       elt_t elt, *elt_p;
     661      1329646 :       elt_t **slot;
     662              : 
     663      1329646 :       elt.val = val;
     664      1329646 :       if (!gimplify_ctxp->temp_htab)
     665       420578 :         gimplify_ctxp->temp_htab = new hash_table<gimplify_hasher> (1000);
     666      1329646 :       slot = gimplify_ctxp->temp_htab->find_slot (&elt, INSERT);
     667      1329646 :       if (*slot == NULL)
     668              :         {
     669      1090237 :           elt_p = XNEW (elt_t);
     670      1090237 :           elt_p->val = val;
     671      1090237 :           elt_p->temp = ret = create_tmp_from_val (val);
     672      1090237 :           *slot = elt_p;
     673              :         }
     674              :       else
     675              :         {
     676       239409 :           elt_p = *slot;
     677       239409 :           ret = elt_p->temp;
     678              :         }
     679              :     }
     680              : 
     681      2437942 :   return ret;
     682              : }
     683              : 
     684              : /* Helper for get_formal_tmp_var and get_initialized_tmp_var.  */
     685              : 
     686              : static tree
     687     27114493 : internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
     688              :                       bool is_formal, bool allow_ssa, bool not_gimple_reg)
     689              : {
     690     27114493 :   tree t, mod;
     691              : 
     692              :   /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
     693              :      can create an INIT_EXPR and convert it into a GIMPLE_CALL below.  */
     694     27114493 :   gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
     695              :                  fb_rvalue);
     696              : 
     697     27114493 :   if (allow_ssa
     698     26844247 :       && gimplify_ctxp->into_ssa
     699     52482604 :       && is_gimple_reg_type (TREE_TYPE (val)))
     700              :     {
     701     24676552 :       t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
     702     24676552 :       if (! gimple_in_ssa_p (cfun))
     703              :         {
     704     21291508 :           const char *name = get_name (val);
     705     21291508 :           if (name)
     706      6849024 :             SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
     707              :         }
     708              :     }
     709              :   else
     710      2437941 :     t = lookup_tmp_var (val, is_formal, not_gimple_reg);
     711              : 
     712     27114493 :   mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
     713              : 
     714     27114493 :   SET_EXPR_LOCATION (mod, EXPR_LOC_OR_LOC (val, input_location));
     715              : 
     716              :   /* gimplify_modify_expr might want to reduce this further.  */
     717     27114493 :   gimplify_and_add (mod, pre_p);
     718     27114493 :   ggc_free (mod);
     719              : 
     720              :   /* If we failed to gimplify VAL then we can end up with the temporary
     721              :      SSA name not having a definition.  In this case return a decl.  */
     722     27114493 :   if (TREE_CODE (t) == SSA_NAME && ! SSA_NAME_DEF_STMT (t))
     723            1 :     return lookup_tmp_var (val, is_formal, not_gimple_reg);
     724              : 
     725              :   return t;
     726              : }
     727              : 
     728              : /* Return a formal temporary variable initialized with VAL.  PRE_P is as
     729              :    in gimplify_expr.  Only use this function if:
     730              : 
     731              :    1) The value of the unfactored expression represented by VAL will not
     732              :       change between the initialization and use of the temporary, and
     733              :    2) The temporary will not be otherwise modified.
     734              : 
     735              :    For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
     736              :    and #2 means it is inappropriate for && temps.
     737              : 
     738              :    For other cases, use get_initialized_tmp_var instead.  */
     739              : 
     740              : tree
     741     26612546 : get_formal_tmp_var (tree val, gimple_seq *pre_p)
     742              : {
     743     26612546 :   return internal_get_tmp_var (val, pre_p, NULL, true, true, false);
     744              : }
     745              : 
     746              : /* Return a temporary variable initialized with VAL.  PRE_P and POST_P
     747              :    are as in gimplify_expr.  */
     748              : 
     749              : tree
     750       489814 : get_initialized_tmp_var (tree val, gimple_seq *pre_p,
     751              :                          gimple_seq *post_p /* = NULL */,
     752              :                          bool allow_ssa /* = true */)
     753              : {
     754       489814 :   return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa, false);
     755              : }
     756              : 
     757              : /* Declare all the variables in VARS in SCOPE.  If DEBUG_INFO is true,
     758              :    generate debug info for them; otherwise don't.  */
     759              : 
     760              : void
     761      3182098 : declare_vars (tree vars, gimple *gs, bool debug_info)
     762              : {
     763      3182098 :   tree last = vars;
     764      3182098 :   if (last)
     765              :     {
     766      2000914 :       tree temps, block;
     767              : 
     768      2000914 :       gbind *scope = as_a <gbind *> (gs);
     769              : 
     770      2000914 :       temps = nreverse (last);
     771              : 
     772      2000914 :       block = gimple_bind_block (scope);
     773      2000914 :       gcc_assert (!block || TREE_CODE (block) == BLOCK);
     774      2000914 :       if (!block || !debug_info)
     775              :         {
     776      1997064 :           DECL_CHAIN (last) = gimple_bind_vars (scope);
     777      1997064 :           gimple_bind_set_vars (scope, temps);
     778              :         }
     779              :       else
     780              :         {
     781              :           /* We need to attach the nodes both to the BIND_EXPR and to its
     782              :              associated BLOCK for debugging purposes.  The key point here
     783              :              is that the BLOCK_VARS of the BIND_EXPR_BLOCK of a BIND_EXPR
     784              :              is a subchain of the BIND_EXPR_VARS of the BIND_EXPR.  */
     785         3850 :           if (BLOCK_VARS (block))
     786         3657 :             BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
     787              :           else
     788              :             {
     789          193 :               gimple_bind_set_vars (scope,
     790              :                                     chainon (gimple_bind_vars (scope), temps));
     791          193 :               BLOCK_VARS (block) = temps;
     792              :             }
     793              :         }
     794              :     }
     795      3182098 : }
     796              : 
     797              : /* For VAR a VAR_DECL of variable size, try to find a constant upper bound
     798              :    for the size and adjust DECL_SIZE/DECL_SIZE_UNIT accordingly.  Abort if
     799              :    no such upper bound can be obtained.  */
     800              : 
     801              : static void
     802            0 : force_constant_size (tree var)
     803              : {
     804              :   /* The only attempt we make is by querying the maximum size of objects
     805              :      of the variable's type.  */
     806              : 
     807            0 :   HOST_WIDE_INT max_size;
     808              : 
     809            0 :   gcc_assert (VAR_P (var));
     810              : 
     811            0 :   max_size = max_int_size_in_bytes (TREE_TYPE (var));
     812              : 
     813            0 :   gcc_assert (max_size >= 0);
     814              : 
     815            0 :   DECL_SIZE_UNIT (var)
     816            0 :     = build_int_cst (TREE_TYPE (DECL_SIZE_UNIT (var)), max_size);
     817            0 :   DECL_SIZE (var)
     818            0 :     = build_int_cst (TREE_TYPE (DECL_SIZE (var)), max_size * BITS_PER_UNIT);
     819            0 : }
     820              : 
     821              : /* Push the temporary variable TMP into the current binding.  */
     822              : 
     823              : void
     824        29813 : gimple_add_tmp_var_fn (struct function *fn, tree tmp)
     825              : {
     826        29813 :   gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
     827              : 
     828              :   /* Later processing assumes that the object size is constant, which might
     829              :      not be true at this point.  Force the use of a constant upper bound in
     830              :      this case.  */
     831        29813 :   if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
     832            0 :     force_constant_size (tmp);
     833              : 
     834        29813 :   DECL_CONTEXT (tmp) = fn->decl;
     835        29813 :   DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
     836              : 
     837        29813 :   record_vars_into (tmp, fn->decl);
     838        29813 : }
     839              : 
     840              : /* Push the temporary variable TMP into the current binding.  */
     841              : 
     842              : void
     843     16835704 : gimple_add_tmp_var (tree tmp)
     844              : {
     845     16835704 :   gcc_assert (!DECL_CHAIN (tmp) && !DECL_SEEN_IN_BIND_EXPR_P (tmp));
     846              : 
     847              :   /* Later processing assumes that the object size is constant, which might
     848              :      not be true at this point.  Force the use of a constant upper bound in
     849              :      this case.  */
     850     16835704 :   if (!tree_fits_poly_uint64_p (DECL_SIZE_UNIT (tmp)))
     851            0 :     force_constant_size (tmp);
     852              : 
     853     16835704 :   DECL_CONTEXT (tmp) = current_function_decl;
     854     16835704 :   DECL_SEEN_IN_BIND_EXPR_P (tmp) = 1;
     855              : 
     856     16835704 :   if (gimplify_ctxp)
     857              :     {
     858      5857939 :       DECL_CHAIN (tmp) = gimplify_ctxp->temps;
     859      5857939 :       gimplify_ctxp->temps = tmp;
     860              : 
     861              :       /* Mark temporaries local within the nearest enclosing parallel.  */
     862      5857939 :       if (gimplify_omp_ctxp)
     863              :         {
     864              :           struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
     865       554529 :           int flag = GOVD_LOCAL | GOVD_SEEN;
     866              :           while (ctx
     867       554529 :                  && (ctx->region_type == ORT_WORKSHARE
     868              :                      || ctx->region_type == ORT_TASKGROUP
     869       406630 :                      || ctx->region_type == ORT_SIMD
     870       356214 :                      || ctx->region_type == ORT_ACC))
     871              :             {
     872       204967 :               if (ctx->region_type == ORT_SIMD
     873        50416 :                   && TREE_ADDRESSABLE (tmp)
     874           95 :                   && !TREE_STATIC (tmp))
     875              :                 {
     876           95 :                   if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
     877            0 :                     ctx->add_safelen1 = true;
     878           95 :                   else if (ctx->in_for_exprs)
     879              :                     flag = GOVD_PRIVATE;
     880              :                   else
     881              :                     flag = GOVD_PRIVATE | GOVD_SEEN;
     882              :                   break;
     883              :                 }
     884       204872 :               ctx = ctx->outer_context;
     885              :             }
     886       349562 :           if (ctx)
     887       322270 :             omp_add_variable (ctx, tmp, flag);
     888              :         }
     889              :     }
     890     10977765 :   else if (cfun)
     891     10977765 :     record_vars (tmp);
     892              :   else
     893              :     {
     894            0 :       gimple_seq body_seq;
     895              : 
     896              :       /* This case is for nested functions.  We need to expose the locals
     897              :          they create.  */
     898            0 :       body_seq = gimple_body (current_function_decl);
     899            0 :       declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
     900              :     }
     901     16835704 : }
     902              : 
     903              : /* Unshare all the trees in the body of FNDECL, as well as in the bodies of
     904              :    any nested functions.  */
     905              : 
     906              : static void
     907      3075893 : unshare_body (tree fndecl)
     908              : {
     909      3075893 :   struct cgraph_node *cgn = cgraph_node::get (fndecl);
     910              :   /* If the language requires deep unsharing, we need a pointer set to make
     911              :      sure we don't repeatedly unshare subtrees of unshareable nodes.  */
     912      3075893 :   hash_set<tree> *visited
     913      3075893 :     = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
     914              : 
     915      3075893 :   copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
     916      3075893 :   copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
     917      3075893 :   copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
     918              : 
     919      3080069 :   delete visited;
     920              : 
     921      3075893 :   if (cgn)
     922      6197168 :     for (cgn = first_nested_function (cgn); cgn;
     923        26888 :          cgn = next_nested_function (cgn))
     924        26888 :       unshare_body (cgn->decl);
     925      3075893 : }
     926              : 
     927              : /* Callback for walk_tree to unmark the visited trees rooted at *TP.
     928              :    Subtrees are walked until the first unvisited node is encountered.  */
     929              : 
     930              : static tree
     931    289189224 : unmark_visited_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
     932              : {
     933    289189224 :   tree t = *tp;
     934              : 
     935              :   /* If this node has been visited, unmark it and keep looking.  */
     936    289189224 :   if (TREE_VISITED (t))
     937    203453267 :     TREE_VISITED (t) = 0;
     938              : 
     939              :   /* Otherwise, don't look any deeper.  */
     940              :   else
     941     85735957 :     *walk_subtrees = 0;
     942              : 
     943    289189224 :   return NULL_TREE;
     944              : }
     945              : 
     946              : /* Unmark the visited trees rooted at *TP.  */
     947              : 
     948              : static inline void
     949      9227679 : unmark_visited (tree *tp)
     950              : {
     951      9227679 :   walk_tree (tp, unmark_visited_r, NULL, NULL);
     952      9227679 : }
     953              : 
     954              : /* Likewise, but mark all trees as not visited.  */
     955              : 
     956              : static void
     957      3075893 : unvisit_body (tree fndecl)
     958              : {
     959      3075893 :   struct cgraph_node *cgn = cgraph_node::get (fndecl);
     960              : 
     961      3075893 :   unmark_visited (&DECL_SAVED_TREE (fndecl));
     962      3075893 :   unmark_visited (&DECL_SIZE (DECL_RESULT (fndecl)));
     963      3075893 :   unmark_visited (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)));
     964              : 
     965      3075893 :   if (cgn)
     966      6170280 :     for (cgn = first_nested_function (cgn);
     967      3098584 :          cgn; cgn = next_nested_function (cgn))
     968        26888 :       unvisit_body (cgn->decl);
     969      3075893 : }
     970              : 
     971              : /* Return the EXPR_LOCATION of EXPR, if it (maybe recursively) has
     972              :    one, OR_ELSE otherwise.  The location of a STATEMENT_LISTs
     973              :    comprising at least one DEBUG_BEGIN_STMT followed by exactly one
     974              :    EXPR is the location of the EXPR.  */
     975              : 
     976              : static location_t
     977      1187112 : rexpr_location (tree expr, location_t or_else = UNKNOWN_LOCATION)
     978              : {
     979      1187112 :   if (!expr)
     980              :     return or_else;
     981              : 
     982      1187112 :   if (EXPR_HAS_LOCATION (expr))
     983       823031 :     return EXPR_LOCATION (expr);
     984              : 
     985       364081 :   if (TREE_CODE (expr) != STATEMENT_LIST)
     986              :     return or_else;
     987              : 
     988            0 :   tree_stmt_iterator i = tsi_start (expr);
     989              : 
     990            0 :   bool found = false;
     991            0 :   while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
     992              :     {
     993            0 :       found = true;
     994            0 :       tsi_next (&i);
     995              :     }
     996              : 
     997            0 :   if (!found || !tsi_one_before_end_p (i))
     998              :     return or_else;
     999              : 
    1000            0 :   return rexpr_location (tsi_stmt (i), or_else);
    1001              : }
    1002              : 
    1003              : /* Return TRUE iff EXPR (maybe recursively) has a location; see
    1004              :    rexpr_location for the potential recursion.  */
    1005              : 
    1006              : static inline bool
    1007       518529 : rexpr_has_location (tree expr)
    1008              : {
    1009       308243 :   return rexpr_location (expr) != UNKNOWN_LOCATION;
    1010              : }
    1011              : 
    1012              : 
    1013              : /* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
    1014              :    contain statements and have a value.  Assign its value to a temporary
    1015              :    and give it void_type_node.  Return the temporary, or NULL_TREE if
    1016              :    WRAPPER was already void.  */
    1017              : 
    1018              : tree
    1019     20936816 : voidify_wrapper_expr (tree wrapper, tree temp)
    1020              : {
    1021     20936816 :   tree type = TREE_TYPE (wrapper);
    1022     20936816 :   if (type && !VOID_TYPE_P (type))
    1023              :     {
    1024              :       tree *p;
    1025              : 
    1026              :       /* Set p to point to the body of the wrapper.  Loop until we find
    1027              :          something that isn't a wrapper.  */
    1028       814782 :       for (p = &wrapper; p && *p; )
    1029              :         {
    1030       814782 :           switch (TREE_CODE (*p))
    1031              :             {
    1032         3148 :             case BIND_EXPR:
    1033         3148 :               TREE_SIDE_EFFECTS (*p) = 1;
    1034         3148 :               TREE_TYPE (*p) = void_type_node;
    1035              :               /* For a BIND_EXPR, the body is operand 1.  */
    1036         3148 :               p = &BIND_EXPR_BODY (*p);
    1037         3148 :               break;
    1038              : 
    1039       377426 :             case CLEANUP_POINT_EXPR:
    1040       377426 :             case TRY_FINALLY_EXPR:
    1041       377426 :             case TRY_CATCH_EXPR:
    1042       377426 :               TREE_SIDE_EFFECTS (*p) = 1;
    1043       377426 :               TREE_TYPE (*p) = void_type_node;
    1044       377426 :               p = &TREE_OPERAND (*p, 0);
    1045       377426 :               break;
    1046              : 
    1047        17983 :             case STATEMENT_LIST:
    1048        17983 :               {
    1049        17983 :                 tree_stmt_iterator i = tsi_last (*p);
    1050        17983 :                 TREE_SIDE_EFFECTS (*p) = 1;
    1051        17983 :                 TREE_TYPE (*p) = void_type_node;
    1052        17983 :                 p = tsi_end_p (i) ? NULL : tsi_stmt_ptr (i);
    1053              :               }
    1054        17983 :               break;
    1055              : 
    1056              :             case COMPOUND_EXPR:
    1057              :               /* Advance to the last statement.  Set all container types to
    1058              :                  void.  */
    1059        65307 :               for (; TREE_CODE (*p) == COMPOUND_EXPR; p = &TREE_OPERAND (*p, 1))
    1060              :                 {
    1061        32661 :                   TREE_SIDE_EFFECTS (*p) = 1;
    1062        32661 :                   TREE_TYPE (*p) = void_type_node;
    1063              :                 }
    1064              :               break;
    1065              : 
    1066           76 :             case TRANSACTION_EXPR:
    1067           76 :               TREE_SIDE_EFFECTS (*p) = 1;
    1068           76 :               TREE_TYPE (*p) = void_type_node;
    1069           76 :               p = &TRANSACTION_EXPR_BODY (*p);
    1070           76 :               break;
    1071              : 
    1072       383503 :             default:
    1073              :               /* Assume that any tree upon which voidify_wrapper_expr is
    1074              :                  directly called is a wrapper, and that its body is op0.  */
    1075       383503 :               if (p == &wrapper)
    1076              :                 {
    1077           33 :                   TREE_SIDE_EFFECTS (*p) = 1;
    1078           33 :                   TREE_TYPE (*p) = void_type_node;
    1079           33 :                   p = &TREE_OPERAND (*p, 0);
    1080           33 :                   break;
    1081              :                 }
    1082       383470 :               goto out;
    1083              :             }
    1084              :         }
    1085              : 
    1086            0 :     out:
    1087       383470 :       if (p == NULL || IS_EMPTY_STMT (*p))
    1088              :         temp = NULL_TREE;
    1089       383470 :       else if (temp)
    1090              :         {
    1091              :           /* The wrapper is on the RHS of an assignment that we're pushing
    1092              :              down.  */
    1093         1994 :           gcc_assert (TREE_CODE (temp) == INIT_EXPR
    1094              :                       || TREE_CODE (temp) == MODIFY_EXPR);
    1095         1994 :           TREE_OPERAND (temp, 1) = *p;
    1096         1994 :           *p = temp;
    1097              :         }
    1098              :       else
    1099              :         {
    1100       381476 :           temp = create_tmp_var (type, "retval");
    1101       381476 :           *p = build2 (INIT_EXPR, type, temp, *p);
    1102              :         }
    1103              : 
    1104              :       return temp;
    1105              :     }
    1106              : 
    1107              :   return NULL_TREE;
    1108              : }
    1109              : 
    1110              : /* Prepare calls to builtins to SAVE and RESTORE the stack as well as
    1111              :    a temporary through which they communicate.  */
    1112              : 
    1113              : static void
    1114         7923 : build_stack_save_restore (gcall **save, gcall **restore)
    1115              : {
    1116         7923 :   tree tmp_var;
    1117              : 
    1118        15846 :   *save = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
    1119         7923 :   tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
    1120         7923 :   gimple_call_set_lhs (*save, tmp_var);
    1121              : 
    1122         7923 :   *restore
    1123         7923 :     = gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE),
    1124              :                          1, tmp_var);
    1125         7923 : }
    1126              : 
    1127              : /* Generate IFN_ASAN_MARK call that poisons shadow memory of the DECL
    1128              :    variable.  */
    1129              : 
    1130              : static tree
    1131          472 : build_asan_poison_call_expr (tree decl)
    1132              : {
    1133              :   /* Do not poison variables that have size equal to zero.  */
    1134          472 :   tree unit_size = DECL_SIZE_UNIT (decl);
    1135          472 :   if (zerop (unit_size))
    1136              :     return NULL_TREE;
    1137              : 
    1138          472 :   tree base = build_fold_addr_expr (decl);
    1139              : 
    1140          472 :   return build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_ASAN_MARK,
    1141              :                                        void_type_node, 3,
    1142              :                                        build_int_cst (integer_type_node,
    1143              :                                                       ASAN_MARK_POISON),
    1144              :                                        base, unit_size);
    1145              : }
    1146              : 
    1147              : /* Generate IFN_ASAN_MARK call that would poison or unpoison, depending
    1148              :    on POISON flag, shadow memory of a DECL variable.  The call will be
    1149              :    put on location identified by IT iterator, where BEFORE flag drives
    1150              :    position where the stmt will be put.  */
    1151              : 
    1152              : static void
    1153         5103 : asan_poison_variable (tree decl, bool poison, gimple_stmt_iterator *it,
    1154              :                       bool before)
    1155              : {
    1156         5103 :   tree unit_size = DECL_SIZE_UNIT (decl);
    1157         5103 :   tree base = build_fold_addr_expr (decl);
    1158              : 
    1159              :   /* Do not poison variables that have size equal to zero.  */
    1160         5103 :   if (zerop (unit_size))
    1161         5103 :     return;
    1162              : 
    1163              :   /* It's necessary to have all stack variables aligned to ASAN granularity
    1164              :      bytes.  */
    1165         5089 :   gcc_assert (!hwassist_sanitize_p () || hwassist_sanitize_stack_p ());
    1166         5089 :   unsigned shadow_granularity
    1167         5089 :     = (hwassist_sanitize_p ()
    1168         5089 :        ? HWASAN_TAG_GRANULE_SIZE : ASAN_SHADOW_GRANULARITY);
    1169         5089 :   if (DECL_ALIGN_UNIT (decl) <= shadow_granularity)
    1170         4887 :     SET_DECL_ALIGN (decl, BITS_PER_UNIT * shadow_granularity);
    1171              : 
    1172         5089 :   HOST_WIDE_INT flags = poison ? ASAN_MARK_POISON : ASAN_MARK_UNPOISON;
    1173              : 
    1174         5089 :   gimple *g
    1175         5089 :     = gimple_build_call_internal (IFN_ASAN_MARK, 3,
    1176         5089 :                                   build_int_cst (integer_type_node, flags),
    1177              :                                   base, unit_size);
    1178              : 
    1179         5089 :   if (before)
    1180         2660 :     gsi_insert_before (it, g, GSI_NEW_STMT);
    1181              :   else
    1182         2429 :     gsi_insert_after (it, g, GSI_NEW_STMT);
    1183              : }
    1184              : 
    1185              : /* Generate IFN_ASAN_MARK internal call that depending on POISON flag
    1186              :    either poisons or unpoisons a DECL.  Created statement is appended
    1187              :    to SEQ_P gimple sequence.  */
    1188              : 
    1189              : static void
    1190         4631 : asan_poison_variable (tree decl, bool poison, gimple_seq *seq_p)
    1191              : {
    1192         4631 :   gimple_stmt_iterator it = gsi_last (*seq_p);
    1193         4631 :   bool before = false;
    1194              : 
    1195         4631 :   if (gsi_end_p (it))
    1196         2451 :     before = true;
    1197              : 
    1198         4631 :   asan_poison_variable (decl, poison, &it, before);
    1199         4631 : }
    1200              : 
    1201              : /* Sort pair of VAR_DECLs A and B by DECL_UID.  */
    1202              : 
    1203              : static int
    1204          135 : sort_by_decl_uid (const void *a, const void *b)
    1205              : {
    1206          135 :   const tree *t1 = (const tree *)a;
    1207          135 :   const tree *t2 = (const tree *)b;
    1208              : 
    1209          135 :   int uid1 = DECL_UID (*t1);
    1210          135 :   int uid2 = DECL_UID (*t2);
    1211              : 
    1212          135 :   if (uid1 < uid2)
    1213              :     return -1;
    1214           53 :   else if (uid1 > uid2)
    1215              :     return 1;
    1216              :   else
    1217            0 :     return 0;
    1218              : }
    1219              : 
    1220              : /* Generate IFN_ASAN_MARK internal call for all VARIABLES
    1221              :    depending on POISON flag.  Created statement is appended
    1222              :    to SEQ_P gimple sequence.  */
    1223              : 
    1224              : static void
    1225      1046096 : asan_poison_variables (hash_set<tree> *variables, bool poison, gimple_seq *seq_p)
    1226              : {
    1227      1046096 :   unsigned c = variables->elements ();
    1228      1046096 :   if (c == 0)
    1229      1045822 :     return;
    1230              : 
    1231          274 :   auto_vec<tree> sorted_variables (c);
    1232              : 
    1233          274 :   for (hash_set<tree>::iterator it = variables->begin ();
    1234          569 :        it != variables->end (); ++it)
    1235          295 :     sorted_variables.safe_push (*it);
    1236              : 
    1237          274 :   sorted_variables.qsort (sort_by_decl_uid);
    1238              : 
    1239          274 :   unsigned i;
    1240          274 :   tree var;
    1241          843 :   FOR_EACH_VEC_ELT (sorted_variables, i, var)
    1242              :     {
    1243          295 :       asan_poison_variable (var, poison, seq_p);
    1244              : 
    1245              :       /* Add use_after_scope_memory attribute for the variable in order
    1246              :          to prevent re-written into SSA.  */
    1247          295 :       if (!lookup_attribute (ASAN_USE_AFTER_SCOPE_ATTRIBUTE,
    1248          295 :                              DECL_ATTRIBUTES (var)))
    1249           97 :         DECL_ATTRIBUTES (var)
    1250          194 :           = tree_cons (get_identifier (ASAN_USE_AFTER_SCOPE_ATTRIBUTE),
    1251              :                        integer_one_node,
    1252           97 :                        DECL_ATTRIBUTES (var));
    1253              :     }
    1254          274 : }
    1255              : 
    1256              : /* Gimplify a BIND_EXPR.  Just voidify and recurse.  */
    1257              : 
    1258              : static enum gimplify_status
    1259      6092087 : gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
    1260              : {
    1261      6092087 :   tree bind_expr = *expr_p;
    1262      6092087 :   bool old_keep_stack = gimplify_ctxp->keep_stack;
    1263      6092087 :   bool old_save_stack = gimplify_ctxp->save_stack;
    1264      6092087 :   tree t;
    1265      6092087 :   gbind *bind_stmt;
    1266      6092087 :   gimple_seq body, cleanup;
    1267      6092087 :   gcall *stack_save;
    1268      6092087 :   location_t start_locus = 0, end_locus = 0;
    1269      6092087 :   tree ret_clauses = NULL;
    1270              : 
    1271      6092087 :   tree temp = voidify_wrapper_expr (bind_expr, NULL);
    1272              : 
    1273              :   /* Mark variables seen in this bind expr.  */
    1274     13099237 :   for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
    1275              :     {
    1276      7007150 :       if (VAR_P (t))
    1277              :         {
    1278      6337413 :           struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
    1279      6337413 :           tree attr;
    1280              : 
    1281      6337413 :           if (flag_openmp
    1282       259563 :               && !is_global_var (t)
    1283       250624 :               && !TREE_STATIC (t)
    1284       250624 :               && DECL_CONTEXT (t) == current_function_decl
    1285       250624 :               && TREE_USED (t)
    1286      6586420 :               && (attr = lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t)))
    1287              :                  != NULL_TREE)
    1288              :             {
    1289           76 :               gcc_assert (!DECL_HAS_VALUE_EXPR_P (t));
    1290           76 :               tree alloc = TREE_PURPOSE (TREE_VALUE (attr));
    1291           76 :               tree align = TREE_VALUE (TREE_VALUE (attr));
    1292              :               /* Allocate directives that appear in a target region must specify
    1293              :                  an allocator clause unless a requires directive with the
    1294              :                  dynamic_allocators clause is present in the same compilation
    1295              :                  unit.  */
    1296           76 :               bool missing_dyn_alloc = false;
    1297           76 :               if ((omp_requires_mask & OMP_REQUIRES_DYNAMIC_ALLOCATORS) == 0)
    1298              :                 {
    1299              :                   /* This comes too early for omp_discover_declare_target...,
    1300              :                      but should at least catch the most common cases.  */
    1301           70 :                   missing_dyn_alloc
    1302           70 :                     = (alloc == NULL_TREE
    1303           70 :                        && cgraph_node::get (current_function_decl)->offloadable);
    1304           70 :                   for (struct gimplify_omp_ctx *ctx2 = ctx;
    1305           74 :                        ctx2 && !missing_dyn_alloc; ctx2 = ctx2->outer_context)
    1306           13 :                     if (ctx2->code == OMP_TARGET)
    1307              :                       {
    1308            9 :                         if (alloc == NULL_TREE)
    1309              :                           missing_dyn_alloc = true;
    1310            7 :                         else if (TREE_CODE (alloc) != INTEGER_CST)
    1311              :                           {
    1312            2 :                             tree alloc2 = alloc;
    1313            2 :                             if (TREE_CODE (alloc2) == MEM_REF
    1314            2 :                                 || TREE_CODE (alloc2) == INDIRECT_REF)
    1315            0 :                               alloc2 = TREE_OPERAND (alloc2, 0);
    1316            2 :                             tree c2;
    1317            2 :                             for (c2 = ctx2->clauses; c2;
    1318            0 :                                  c2 = OMP_CLAUSE_CHAIN (c2))
    1319            1 :                               if (OMP_CLAUSE_CODE (c2)
    1320              :                                   == OMP_CLAUSE_USES_ALLOCATORS)
    1321              :                                 {
    1322            1 :                                   tree t2
    1323            1 :                                     = OMP_CLAUSE_USES_ALLOCATORS_ALLOCATOR (c2);
    1324            1 :                                   if (operand_equal_p (alloc2, t2))
    1325              :                                     break;
    1326              :                                 }
    1327            2 :                             if (c2 == NULL_TREE)
    1328            1 :                               error_at (EXPR_LOC_OR_LOC (
    1329              :                                           alloc, DECL_SOURCE_LOCATION (t)),
    1330              :                                         "%qE in %<allocator%> clause inside a "
    1331              :                                         "target region must be specified in an "
    1332              :                                         "%<uses_allocators%> clause on the "
    1333              :                                         "%<target%> directive", alloc2);
    1334              :                           }
    1335              :                         break;
    1336              :                       }
    1337              :                 }
    1338           68 :               if (missing_dyn_alloc)
    1339            4 :                 error_at (DECL_SOURCE_LOCATION (t),
    1340              :                           "%<allocate%> directive for %qD inside a target "
    1341              :                           "region must specify an %<allocator%> clause", t);
    1342              :               /* Skip for omp_default_mem_alloc (= 1),
    1343              :                  unless align is present.  For C/C++, there should be always a
    1344              :                  statement list following if TREE_USED, except for, e.g., using
    1345              :                  this decl in a static_assert; in that case, only a single
    1346              :                  DECL_EXPR remains, which can be skipped here.  */
    1347           72 :               else if (!errorcount
    1348           55 :                        && (align != NULL_TREE
    1349           55 :                            || alloc == NULL_TREE
    1350           10 :                            || !integer_onep (alloc))
    1351          125 :                        && (lang_GNU_Fortran ()
    1352           25 :                            || (TREE_CODE (BIND_EXPR_BODY (bind_expr))
    1353              :                                != DECL_EXPR)))
    1354              :                 {
    1355              :                   /* Fortran might already use a pointer type internally;
    1356              :                      use that pointer except for type(C_ptr) and type(C_funptr);
    1357              :                      note that normal proc pointers are rejected.  */
    1358           53 :                   tree type = TREE_TYPE (t);
    1359           53 :                   tree tmp, v;
    1360           53 :                   if (lang_GNU_Fortran ()
    1361           28 :                       && POINTER_TYPE_P (type)
    1362            8 :                       && TREE_TYPE (type) != void_type_node
    1363           59 :                       && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
    1364              :                     {
    1365            6 :                       type = TREE_TYPE (type);
    1366            6 :                       v = t;
    1367              :                     }
    1368              :                   else
    1369              :                     {
    1370           47 :                       tmp = build_pointer_type (type);
    1371           47 :                       v = create_tmp_var (tmp, get_name (t));
    1372           47 :                       DECL_IGNORED_P (v) = 0;
    1373           47 :                       DECL_ATTRIBUTES (v)
    1374           47 :                         = tree_cons (get_identifier ("omp allocate var"),
    1375              :                                      build_tree_list (NULL_TREE, t),
    1376              :                                      remove_attribute ("omp allocate",
    1377           47 :                                                        DECL_ATTRIBUTES (t)));
    1378           47 :                       tmp = build_fold_indirect_ref (v);
    1379           47 :                       TREE_THIS_NOTRAP (tmp) = 1;
    1380           47 :                       SET_DECL_VALUE_EXPR (t, tmp);
    1381           47 :                       DECL_HAS_VALUE_EXPR_P (t) = 1;
    1382              :                     }
    1383           53 :                   tree sz = TYPE_SIZE_UNIT (type);
    1384              :                   /* The size to use in Fortran might not match TYPE_SIZE_UNIT;
    1385              :                      hence, for some decls, a size variable is saved in the
    1386              :                      attributes; use it, if available.  */
    1387           53 :                   if (TREE_CHAIN (TREE_VALUE (attr))
    1388           28 :                       && TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)))
    1389           59 :                       && TREE_PURPOSE (
    1390              :                            TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)))))
    1391              :                     {
    1392            6 :                       sz = TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)));
    1393            6 :                       sz = TREE_PURPOSE (sz);
    1394              :                     }
    1395           53 :                   if (alloc == NULL_TREE)
    1396           36 :                     alloc = build_zero_cst (ptr_type_node);
    1397           53 :                   if (align == NULL_TREE)
    1398           42 :                     align = build_int_cst (size_type_node, DECL_ALIGN_UNIT (t));
    1399              :                   else
    1400           11 :                     align = build_int_cst (size_type_node,
    1401           11 :                                            MAX (tree_to_uhwi (align),
    1402              :                                                 DECL_ALIGN_UNIT (t)));
    1403           53 :                   location_t loc = DECL_SOURCE_LOCATION (t);
    1404           53 :                   tmp = builtin_decl_explicit (BUILT_IN_GOMP_ALLOC);
    1405           53 :                   tmp = build_call_expr_loc (loc, tmp, 3, align, sz, alloc);
    1406           53 :                   tmp = fold_build2_loc (loc, MODIFY_EXPR, TREE_TYPE (v), v,
    1407           53 :                                          fold_convert (TREE_TYPE (v), tmp));
    1408           53 :                   gcc_assert (BIND_EXPR_BODY (bind_expr) != NULL_TREE);
    1409              :                   /* Ensure that either TREE_CHAIN (TREE_VALUE (attr) is set
    1410              :                      and GOMP_FREE added here or that DECL_HAS_VALUE_EXPR_P (t)
    1411              :                      is set, using in a condition much further below.  */
    1412           59 :                   gcc_assert (DECL_HAS_VALUE_EXPR_P (t)
    1413              :                               || TREE_CHAIN (TREE_VALUE (attr)));
    1414           53 :                   if (TREE_CHAIN (TREE_VALUE (attr)))
    1415              :                     {
    1416              :                       /* Fortran is special as it does not have properly nest
    1417              :                          declarations in blocks.  And as there is no
    1418              :                          initializer, there is also no expression to look for.
    1419              :                          Hence, the FE makes the statement list of the
    1420              :                          try-finally block available. We can put the GOMP_alloc
    1421              :                          at the top, unless an allocator or size expression
    1422              :                          requires to put it afterward; note that the size is
    1423              :                          always later in generated code; for strings, no
    1424              :                          size expr but still an expr might be available.
    1425              :                          As LTO does not handle a statement list, 'sl' has
    1426              :                          to be removed; done so by removing the attribute.  */
    1427           28 :                       DECL_ATTRIBUTES (t)
    1428           28 :                         = remove_attribute ("omp allocate",
    1429           28 :                                             DECL_ATTRIBUTES (t));
    1430           28 :                       tree sl = TREE_PURPOSE (TREE_CHAIN (TREE_VALUE (attr)));
    1431           28 :                       tree_stmt_iterator e = tsi_start (sl);
    1432           28 :                       tree needle = NULL_TREE;
    1433           28 :                       if (TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr))))
    1434              :                         {
    1435            6 :                           needle = TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr)));
    1436            6 :                           needle = (TREE_VALUE (needle) ? TREE_VALUE (needle)
    1437              :                                                         : sz);
    1438              :                         }
    1439           22 :                       else if (TREE_CHAIN (TREE_CHAIN (TREE_VALUE (attr))))
    1440              :                         needle = sz;
    1441           22 :                       else if (DECL_P (alloc) && DECL_ARTIFICIAL (alloc))
    1442              :                         needle = alloc;
    1443              : 
    1444           10 :                       if (needle != NULL_TREE)
    1445              :                         {
    1446           49 :                           while (!tsi_end_p (e))
    1447              :                             {
    1448           49 :                               if (*e == needle
    1449           49 :                                   || (TREE_CODE (*e) == MODIFY_EXPR
    1450           49 :                                       && TREE_OPERAND (*e, 0) == needle))
    1451              :                                 break;
    1452           39 :                               ++e;
    1453              :                             }
    1454           10 :                           gcc_assert (!tsi_end_p (e));
    1455              :                         }
    1456           28 :                       tsi_link_after (&e, tmp, TSI_SAME_STMT);
    1457              : 
    1458              :                       /* As the cleanup is in BIND_EXPR_BODY, GOMP_free is added
    1459              :                          here; for C/C++ it will be added in the 'cleanup'
    1460              :                          section after gimplification. But Fortran already has
    1461              :                          a try-finally block.  */
    1462           28 :                       sl = TREE_VALUE (TREE_CHAIN (TREE_VALUE (attr)));
    1463           28 :                       e = tsi_last (sl);
    1464           28 :                       tmp = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
    1465           28 :                       tmp = build_call_expr_loc (EXPR_LOCATION (*e), tmp, 2, v,
    1466              :                                                  build_zero_cst (ptr_type_node));
    1467           28 :                       tsi_link_after (&e, tmp, TSI_SAME_STMT);
    1468           28 :                       tmp = build_clobber (TREE_TYPE (v), CLOBBER_STORAGE_END);
    1469           28 :                       tmp = fold_build2_loc (loc, MODIFY_EXPR, TREE_TYPE (v), v,
    1470           28 :                                              fold_convert (TREE_TYPE (v), tmp));
    1471           28 :                       ++e;
    1472           28 :                       tsi_link_after (&e, tmp, TSI_SAME_STMT);
    1473              :                     }
    1474              :                   else
    1475              :                     {
    1476           25 :                       gcc_assert (TREE_CODE (BIND_EXPR_BODY (bind_expr))
    1477              :                                   == STATEMENT_LIST);
    1478           25 :                       tree_stmt_iterator e;
    1479           25 :                       e = tsi_start (BIND_EXPR_BODY (bind_expr));
    1480          113 :                       while (!tsi_end_p (e))
    1481              :                         {
    1482           88 :                           if ((TREE_CODE (*e) == DECL_EXPR
    1483           58 :                                && TREE_OPERAND (*e, 0) == t)
    1484          121 :                               || (TREE_CODE (*e) == CLEANUP_POINT_EXPR
    1485            0 :                                   && (TREE_CODE (TREE_OPERAND (*e, 0))
    1486              :                                       == DECL_EXPR)
    1487            0 :                                   && (TREE_OPERAND (TREE_OPERAND (*e, 0), 0)
    1488              :                                       == t)))
    1489              :                             break;
    1490           63 :                           ++e;
    1491              :                         }
    1492           25 :                       gcc_assert (!tsi_end_p (e));
    1493           25 :                       tsi_link_before (&e, tmp, TSI_SAME_STMT);
    1494              :                    }
    1495              :                 }
    1496              :             }
    1497              : 
    1498              :           /* Mark variable as local.  */
    1499      6337413 :           if (ctx && ctx->region_type != ORT_NONE && !DECL_EXTERNAL (t))
    1500              :             {
    1501       100890 :               if (! DECL_SEEN_IN_BIND_EXPR_P (t)
    1502       100890 :                   || splay_tree_lookup (ctx->variables,
    1503              :                                         (splay_tree_key) t) == NULL)
    1504              :                 {
    1505       100890 :                   int flag = GOVD_LOCAL;
    1506       100890 :                   if (ctx->region_type == ORT_SIMD
    1507         4376 :                       && TREE_ADDRESSABLE (t)
    1508           81 :                       && !TREE_STATIC (t))
    1509              :                     {
    1510           69 :                       if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST)
    1511            2 :                         ctx->add_safelen1 = true;
    1512              :                       else
    1513              :                         flag = GOVD_PRIVATE;
    1514              :                     }
    1515       100890 :                   omp_add_variable (ctx, t, flag | GOVD_SEEN);
    1516              :                 }
    1517              :               /* Static locals inside of target construct or offloaded
    1518              :                  routines need to be "omp declare target".  */
    1519       100890 :               if (TREE_STATIC (t))
    1520         1399 :                 for (; ctx; ctx = ctx->outer_context)
    1521         1214 :                   if ((ctx->region_type & ORT_TARGET) != 0)
    1522              :                     {
    1523          970 :                       if (!lookup_attribute ("omp declare target",
    1524          970 :                                              DECL_ATTRIBUTES (t)))
    1525              :                         {
    1526          958 :                           tree id = get_identifier ("omp declare target");
    1527          958 :                           DECL_ATTRIBUTES (t)
    1528          958 :                             = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
    1529          958 :                           varpool_node *node = varpool_node::get (t);
    1530          958 :                           if (node)
    1531              :                             {
    1532           33 :                               node->offloadable = 1;
    1533           33 :                               if (ENABLE_OFFLOADING && !DECL_EXTERNAL (t))
    1534              :                                 {
    1535              :                                   g->have_offload = true;
    1536              :                                   if (!in_lto_p)
    1537              :                                     vec_safe_push (offload_vars, t);
    1538              :                                 }
    1539              :                             }
    1540              :                         }
    1541              :                       break;
    1542              :                     }
    1543              :             }
    1544              : 
    1545      6337413 :           DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
    1546              : 
    1547      6337413 :           if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
    1548         1089 :             cfun->has_local_explicit_reg_vars = true;
    1549              :         }
    1550              :     }
    1551              : 
    1552     12184174 :   bind_stmt = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
    1553      6092087 :                                  BIND_EXPR_BLOCK (bind_expr));
    1554      6092087 :   gimple_push_bind_expr (bind_stmt);
    1555              : 
    1556      6092087 :   gimplify_ctxp->keep_stack = false;
    1557      6092087 :   gimplify_ctxp->save_stack = false;
    1558              : 
    1559              :   /* Gimplify the body into the GIMPLE_BIND tuple's body.  */
    1560      6092087 :   body = NULL;
    1561      6092087 :   gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
    1562      6092087 :   gimple_bind_set_body (bind_stmt, body);
    1563              : 
    1564              :   /* Source location wise, the cleanup code (stack_restore and clobbers)
    1565              :      belongs to the end of the block, so propagate what we have.  The
    1566              :      stack_save operation belongs to the beginning of block, which we can
    1567              :      infer from the bind_expr directly if the block has no explicit
    1568              :      assignment.  */
    1569      6092087 :   if (BIND_EXPR_BLOCK (bind_expr))
    1570              :     {
    1571      5960427 :       end_locus = BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (bind_expr));
    1572      5960427 :       start_locus = BLOCK_SOURCE_LOCATION (BIND_EXPR_BLOCK (bind_expr));
    1573              :     }
    1574      5960427 :   if (start_locus == 0)
    1575      6092087 :     start_locus = EXPR_LOCATION (bind_expr);
    1576              : 
    1577      6092087 :   cleanup = NULL;
    1578      6092087 :   stack_save = NULL;
    1579              : 
    1580              :   /* Add clobbers for all variables that go out of scope.  */
    1581     13099237 :   for (t = BIND_EXPR_VARS (bind_expr); t ; t = DECL_CHAIN (t))
    1582              :     {
    1583      7007150 :       if (VAR_P (t)
    1584      6337413 :           && !is_global_var (t)
    1585     13120555 :           && DECL_CONTEXT (t) == current_function_decl)
    1586              :         {
    1587      6113405 :           if (flag_openmp
    1588       250587 :               && DECL_HAS_VALUE_EXPR_P (t)
    1589         1086 :               && TREE_USED (t)
    1590      6114474 :               && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (t)))
    1591              :             {
    1592              :               /* For Fortran, TREE_CHAIN (TREE_VALUE (attr)) is set, which
    1593              :                  causes that the GOMP_free call is already added above;
    1594              :                  and "omp allocate" is removed from DECL_ATTRIBUTES.  */
    1595           25 :               tree v = TREE_OPERAND (DECL_VALUE_EXPR (t), 0);
    1596           25 :               tree tmp = builtin_decl_explicit (BUILT_IN_GOMP_FREE);
    1597           25 :               tmp = build_call_expr_loc (end_locus, tmp, 2, v,
    1598              :                                          build_zero_cst (ptr_type_node));
    1599           25 :               gimplify_and_add (tmp, &cleanup);
    1600           25 :               gimple *clobber_stmt;
    1601           25 :               tmp = build_clobber (TREE_TYPE (v), CLOBBER_STORAGE_END);
    1602           25 :               clobber_stmt = gimple_build_assign (v, tmp);
    1603           25 :               gimple_set_location (clobber_stmt, end_locus);
    1604           25 :               gimplify_seq_add_stmt (&cleanup, clobber_stmt);
    1605              :             }
    1606      6113405 :           if (!DECL_HARD_REGISTER (t)
    1607      6112316 :               && !TREE_THIS_VOLATILE (t)
    1608      6072519 :               && !DECL_HAS_VALUE_EXPR_P (t)
    1609              :               /* Only care for variables that have to be in memory.  Others
    1610              :                  will be rewritten into SSA names, hence moved to the
    1611              :                  top-level.  */
    1612      5944820 :               && !is_gimple_reg (t)
    1613      7401244 :               && flag_stack_reuse != SR_NONE)
    1614              :             {
    1615      1284046 :               tree clobber = build_clobber (TREE_TYPE (t), CLOBBER_STORAGE_END);
    1616      1284046 :               gimple *clobber_stmt;
    1617      1284046 :               clobber_stmt = gimple_build_assign (t, clobber);
    1618      1284046 :               gimple_set_location (clobber_stmt, end_locus);
    1619      1284046 :               gimplify_seq_add_stmt (&cleanup, clobber_stmt);
    1620              :             }
    1621              : 
    1622      6113405 :           if (flag_openacc && oacc_declare_returns != NULL)
    1623              :             {
    1624          207 :               tree key = t;
    1625          207 :               if (DECL_HAS_VALUE_EXPR_P (key))
    1626              :                 {
    1627            8 :                   key = DECL_VALUE_EXPR (key);
    1628            8 :                   if (INDIRECT_REF_P (key))
    1629            8 :                     key = TREE_OPERAND (key, 0);
    1630              :                 }
    1631          207 :               tree *c = oacc_declare_returns->get (key);
    1632          207 :               if (c != NULL)
    1633              :                 {
    1634          116 :                   if (ret_clauses)
    1635           64 :                     OMP_CLAUSE_CHAIN (*c) = ret_clauses;
    1636              : 
    1637          116 :                   ret_clauses = unshare_expr (*c);
    1638              : 
    1639          116 :                   oacc_declare_returns->remove (key);
    1640              : 
    1641          116 :                   if (oacc_declare_returns->is_empty ())
    1642              :                     {
    1643           40 :                       delete oacc_declare_returns;
    1644           40 :                       oacc_declare_returns = NULL;
    1645              :                     }
    1646              :                 }
    1647              :             }
    1648              :         }
    1649              : 
    1650      7007150 :       if (asan_poisoned_variables != NULL
    1651      7007150 :           && asan_poisoned_variables->contains (t))
    1652              :         {
    1653         2168 :           asan_poisoned_variables->remove (t);
    1654         2168 :           asan_poison_variable (t, true, &cleanup);
    1655              :         }
    1656              : 
    1657      7007150 :       if (gimplify_ctxp->live_switch_vars != NULL
    1658      7007150 :           && gimplify_ctxp->live_switch_vars->contains (t))
    1659           55 :         gimplify_ctxp->live_switch_vars->remove (t);
    1660              :     }
    1661              : 
    1662              :   /* If the code both contains VLAs and calls alloca, then we cannot reclaim
    1663              :      the stack space allocated to the VLAs.  */
    1664      6092087 :   if (gimplify_ctxp->save_stack && !gimplify_ctxp->keep_stack)
    1665              :     {
    1666         7923 :       gcall *stack_restore;
    1667              : 
    1668              :       /* Save stack on entry and restore it on exit.  Add a try_finally
    1669              :          block to achieve this.  */
    1670         7923 :       build_stack_save_restore (&stack_save, &stack_restore);
    1671              : 
    1672         7923 :       gimple_set_location (stack_save, start_locus);
    1673         7923 :       gimple_set_location (stack_restore, end_locus);
    1674              : 
    1675         7923 :       gimplify_seq_add_stmt (&cleanup, stack_restore);
    1676              :     }
    1677              : 
    1678      6092087 :   if (ret_clauses)
    1679              :     {
    1680           52 :       gomp_target *stmt;
    1681           52 :       gimple_stmt_iterator si = gsi_start (cleanup);
    1682              : 
    1683           52 :       stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
    1684              :                                       ret_clauses);
    1685           52 :       gsi_insert_seq_before_without_update (&si, stmt, GSI_NEW_STMT);
    1686              :     }
    1687              : 
    1688      6092087 :   if (cleanup)
    1689              :     {
    1690       793129 :       gtry *gs;
    1691       793129 :       gimple_seq new_body;
    1692              : 
    1693       793129 :       new_body = NULL;
    1694       793129 :       gs = gimple_build_try (gimple_bind_body (bind_stmt), cleanup,
    1695              :                              GIMPLE_TRY_FINALLY);
    1696              : 
    1697       793129 :       if (stack_save)
    1698         7923 :         gimplify_seq_add_stmt (&new_body, stack_save);
    1699       793129 :       gimplify_seq_add_stmt (&new_body, gs);
    1700       793129 :       gimple_bind_set_body (bind_stmt, new_body);
    1701              :     }
    1702              : 
    1703              :   /* keep_stack propagates all the way up to the outermost BIND_EXPR.  */
    1704      6092087 :   if (!gimplify_ctxp->keep_stack)
    1705      6076894 :     gimplify_ctxp->keep_stack = old_keep_stack;
    1706      6092087 :   gimplify_ctxp->save_stack = old_save_stack;
    1707              : 
    1708      6092087 :   gimple_pop_bind_expr ();
    1709              : 
    1710      6092087 :   gimplify_seq_add_stmt (pre_p, bind_stmt);
    1711              : 
    1712      6092087 :   if (temp)
    1713              :     {
    1714         1709 :       *expr_p = temp;
    1715         1709 :       return GS_OK;
    1716              :     }
    1717              : 
    1718              :   *expr_p = NULL_TREE;
    1719              :   return GS_ALL_DONE;
    1720              : }
    1721              : 
    1722              : /* Maybe add early return predict statement to PRE_P sequence.  */
    1723              : 
    1724              : static void
    1725      2320397 : maybe_add_early_return_predict_stmt (gimple_seq *pre_p)
    1726              : {
    1727              :   /* If we are not in a conditional context, add PREDICT statement.  */
    1728      2320397 :   if (gimple_conditional_context ())
    1729              :     {
    1730       450626 :       gimple *predict = gimple_build_predict (PRED_TREE_EARLY_RETURN,
    1731              :                                               NOT_TAKEN);
    1732       450626 :       gimplify_seq_add_stmt (pre_p, predict);
    1733              :     }
    1734      2320397 : }
    1735              : 
    1736              : /* Gimplify a RETURN_EXPR.  If the expression to be returned is not a
    1737              :    GIMPLE value, it is assigned to a new temporary and the statement is
    1738              :    re-written to return the temporary.
    1739              : 
    1740              :    PRE_P points to the sequence where side effects that must happen before
    1741              :    STMT should be stored.  */
    1742              : 
    1743              : static enum gimplify_status
    1744      2320406 : gimplify_return_expr (tree stmt, gimple_seq *pre_p)
    1745              : {
    1746      2320406 :   greturn *ret;
    1747      2320406 :   tree ret_expr = TREE_OPERAND (stmt, 0);
    1748      2320406 :   tree result_decl, result;
    1749              : 
    1750      2320406 :   if (ret_expr == error_mark_node)
    1751              :     return GS_ERROR;
    1752              : 
    1753      2320397 :   if (!ret_expr
    1754      2229053 :       || TREE_CODE (ret_expr) == RESULT_DECL)
    1755              :     {
    1756       107275 :       maybe_add_early_return_predict_stmt (pre_p);
    1757       107275 :       greturn *ret = gimple_build_return (ret_expr);
    1758       107275 :       copy_warning (ret, stmt);
    1759       107275 :       gimplify_seq_add_stmt (pre_p, ret);
    1760       107275 :       return GS_ALL_DONE;
    1761              :     }
    1762              : 
    1763      2213122 :   if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
    1764              :     result_decl = NULL_TREE;
    1765      2212799 :   else if (TREE_CODE (ret_expr) == COMPOUND_EXPR)
    1766              :     {
    1767              :       /* Used in C++ for handling EH cleanup of the return value if a local
    1768              :          cleanup throws.  Assume the front-end knows what it's doing.  */
    1769         5302 :       result_decl = DECL_RESULT (current_function_decl);
    1770              :       /* But crash if we end up trying to modify ret_expr below.  */
    1771         5302 :       ret_expr = NULL_TREE;
    1772              :     }
    1773              :   else
    1774              :     {
    1775      2207497 :       result_decl = TREE_OPERAND (ret_expr, 0);
    1776              : 
    1777              :       /* See through a return by reference.  */
    1778      2207497 :       if (INDIRECT_REF_P (result_decl))
    1779        43994 :         result_decl = TREE_OPERAND (result_decl, 0);
    1780              : 
    1781      2207497 :       gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
    1782              :                    || TREE_CODE (ret_expr) == INIT_EXPR)
    1783              :                   && TREE_CODE (result_decl) == RESULT_DECL);
    1784              :     }
    1785              : 
    1786              :   /* If aggregate_value_p is true, then we can return the bare RESULT_DECL.
    1787              :      Recall that aggregate_value_p is FALSE for any aggregate type that is
    1788              :      returned in registers.  If we're returning values in registers, then
    1789              :      we don't want to extend the lifetime of the RESULT_DECL, particularly
    1790              :      across another call.  In addition, for those aggregates for which
    1791              :      hard_function_value generates a PARALLEL, we'll die during normal
    1792              :      expansion of structure assignments; there's special code in expand_return
    1793              :      to handle this case that does not exist in expand_expr.  */
    1794         5302 :   if (!result_decl)
    1795              :     result = NULL_TREE;
    1796      2212799 :   else if (aggregate_value_p (result_decl, TREE_TYPE (current_function_decl)))
    1797              :     {
    1798       182804 :       if (!poly_int_tree_p (DECL_SIZE (result_decl)))
    1799              :         {
    1800           48 :           if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (result_decl)))
    1801            0 :             gimplify_type_sizes (TREE_TYPE (result_decl), pre_p);
    1802              :           /* Note that we don't use gimplify_vla_decl because the RESULT_DECL
    1803              :              should be effectively allocated by the caller, i.e. all calls to
    1804              :              this function must be subject to the Return Slot Optimization.  */
    1805           48 :           gimplify_one_sizepos (&DECL_SIZE (result_decl), pre_p);
    1806           48 :           gimplify_one_sizepos (&DECL_SIZE_UNIT (result_decl), pre_p);
    1807              :         }
    1808              :       result = result_decl;
    1809              :     }
    1810      2029995 :   else if (gimplify_ctxp->return_temp)
    1811              :     result = gimplify_ctxp->return_temp;
    1812              :   else
    1813              :     {
    1814      1528609 :       result = create_tmp_reg (TREE_TYPE (result_decl));
    1815              : 
    1816              :       /* ??? With complex control flow (usually involving abnormal edges),
    1817              :          we can wind up warning about an uninitialized value for this.  Due
    1818              :          to how this variable is constructed and initialized, this is never
    1819              :          true.  Give up and never warn.  */
    1820      1528609 :       suppress_warning (result, OPT_Wuninitialized);
    1821              : 
    1822      1528609 :       gimplify_ctxp->return_temp = result;
    1823              :     }
    1824              : 
    1825              :   /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
    1826              :      Then gimplify the whole thing.  */
    1827      2213122 :   if (result != result_decl)
    1828      2029995 :     TREE_OPERAND (ret_expr, 0) = result;
    1829              : 
    1830      2213122 :   gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
    1831              : 
    1832      2213122 :   maybe_add_early_return_predict_stmt (pre_p);
    1833      2213122 :   ret = gimple_build_return (result);
    1834      2213122 :   copy_warning (ret, stmt);
    1835      2213122 :   gimplify_seq_add_stmt (pre_p, ret);
    1836              : 
    1837      2213122 :   return GS_ALL_DONE;
    1838              : }
    1839              : 
    1840              : /* Gimplify a variable-length array DECL.  */
    1841              : 
    1842              : static void
    1843         9034 : gimplify_vla_decl (tree decl, gimple_seq *seq_p)
    1844              : {
    1845              :   /* This is a variable-sized decl.  Simplify its size and mark it
    1846              :      for deferred expansion.  */
    1847         9034 :   tree t, addr, ptr_type;
    1848              : 
    1849         9034 :   gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
    1850         9034 :   gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
    1851              : 
    1852              :   /* Don't mess with a DECL_VALUE_EXPR set by the front-end.  */
    1853         9034 :   if (DECL_HAS_VALUE_EXPR_P (decl))
    1854              :     return;
    1855              : 
    1856              :   /* All occurrences of this decl in final gimplified code will be
    1857              :      replaced by indirection.  Setting DECL_VALUE_EXPR does two
    1858              :      things: First, it lets the rest of the gimplifier know what
    1859              :      replacement to use.  Second, it lets the debug info know
    1860              :      where to find the value.  */
    1861         9029 :   ptr_type = build_pointer_type (TREE_TYPE (decl));
    1862         9029 :   addr = create_tmp_var (ptr_type, get_name (decl));
    1863         9029 :   DECL_IGNORED_P (addr) = 0;
    1864         9029 :   t = build_fold_indirect_ref (addr);
    1865         9029 :   TREE_THIS_NOTRAP (t) = 1;
    1866         9029 :   SET_DECL_VALUE_EXPR (decl, t);
    1867         9029 :   DECL_HAS_VALUE_EXPR_P (decl) = 1;
    1868              : 
    1869         9029 :   t = build_alloca_call_expr (DECL_SIZE_UNIT (decl), DECL_ALIGN (decl),
    1870         9029 :                               max_int_size_in_bytes (TREE_TYPE (decl)));
    1871              :   /* The call has been built for a variable-sized object.  */
    1872         9029 :   CALL_ALLOCA_FOR_VAR_P (t) = 1;
    1873         9029 :   t = fold_convert (ptr_type, t);
    1874         9029 :   t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
    1875              : 
    1876         9029 :   gimplify_and_add (t, seq_p);
    1877              : 
    1878              :   /* Record the dynamic allocation associated with DECL if requested.  */
    1879         9029 :   if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)
    1880            0 :     record_dynamic_alloc (decl);
    1881              : }
    1882              : 
    1883              : /* A helper function to be called via walk_tree.  Mark all labels under *TP
    1884              :    as being forced.  To be called for DECL_INITIAL of static variables.  */
    1885              : 
    1886              : static tree
    1887       863713 : force_labels_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
    1888              : {
    1889       863713 :   if (TYPE_P (*tp))
    1890            0 :     *walk_subtrees = 0;
    1891       863713 :   if (TREE_CODE (*tp) == LABEL_DECL)
    1892              :     {
    1893          986 :       FORCED_LABEL (*tp) = 1;
    1894          986 :       cfun->has_forced_label_in_static = 1;
    1895              :     }
    1896              : 
    1897       863713 :   return NULL_TREE;
    1898              : }
    1899              : 
    1900              : /* Generate an initialization to automatic variable DECL based on INIT_TYPE.
    1901              :    Build a call to internal const function DEFERRED_INIT:
    1902              :    1st argument: SIZE of the DECL;
    1903              :    2nd argument: INIT_TYPE;
    1904              :    3rd argument: NAME of the DECL;
    1905              : 
    1906              :    as LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, NAME of the DECL).  */
    1907              : 
    1908              : static void
    1909       158359 : gimple_add_init_for_auto_var (tree decl,
    1910              :                               enum auto_init_type init_type,
    1911              :                               gimple_seq *seq_p)
    1912              : {
    1913       158359 :   gcc_assert (auto_var_p (decl));
    1914       158359 :   gcc_assert (init_type > AUTO_INIT_UNINITIALIZED);
    1915              : 
    1916       158359 :   const location_t loc = DECL_SOURCE_LOCATION (decl);
    1917       158359 :   tree decl_size = TYPE_SIZE_UNIT (TREE_TYPE (decl));
    1918       158359 :   tree init_type_node = build_int_cst (integer_type_node, (int) init_type);
    1919       158359 :   tree decl_name;
    1920              : 
    1921       158359 :   if (DECL_NAME (decl))
    1922        90591 :     decl_name = build_string_literal (DECL_NAME (decl));
    1923              :   else
    1924              :     {
    1925        67768 :       char decl_name_anonymous[3 + (HOST_BITS_PER_INT + 2) / 3];
    1926        67768 :       sprintf (decl_name_anonymous, "D.%u", DECL_UID (decl));
    1927        67768 :       decl_name = build_string_literal (decl_name_anonymous);
    1928              :     }
    1929              : 
    1930       158359 :   tree call = build_call_expr_internal_loc (loc, IFN_DEFERRED_INIT,
    1931       158359 :                                             TREE_TYPE (decl), 3,
    1932              :                                             decl_size, init_type_node,
    1933              :                                             decl_name);
    1934              : 
    1935       158359 :   gimplify_assign (decl, call, seq_p);
    1936       158359 : }
    1937              : 
    1938              : /* Generate padding initialization for automatic variable DECL.
    1939              :    C guarantees that brace-init with fewer initializers than members
    1940              :    aggregate will initialize the rest of the aggregate as-if it were
    1941              :    static initialization.  In turn static initialization guarantees
    1942              :    that padding is initialized to zero. So, we always initialize paddings
    1943              :    to zeroes regardless INIT_TYPE.
    1944              :    To do the padding initialization, we insert a call to
    1945              :    __builtin_clear_padding (&decl, 0, for_auto_init = true).
    1946              :    Note, we add an additional dummy argument for __builtin_clear_padding,
    1947              :    'for_auto_init' to distinguish whether this call is for automatic
    1948              :    variable initialization or not.
    1949              :    */
    1950              : static void
    1951          116 : gimple_add_padding_init_for_auto_var (tree decl, bool is_vla,
    1952              :                                       gimple_seq *seq_p)
    1953              : {
    1954          116 :   tree addr_of_decl = NULL_TREE;
    1955          116 :   tree fn = builtin_decl_explicit (BUILT_IN_CLEAR_PADDING);
    1956              : 
    1957          116 :   if (is_vla)
    1958              :     {
    1959              :       /* The temporary address variable for this vla should be
    1960              :          created in gimplify_vla_decl.  */
    1961            0 :       gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
    1962            0 :       gcc_assert (INDIRECT_REF_P (DECL_VALUE_EXPR (decl)));
    1963            0 :       addr_of_decl = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
    1964              :     }
    1965              :   else
    1966              :     {
    1967          116 :       mark_addressable (decl);
    1968          116 :       addr_of_decl = build_fold_addr_expr (decl);
    1969              :     }
    1970              : 
    1971          116 :   gimple *call = gimple_build_call (fn, 2, addr_of_decl,
    1972          116 :                                     build_one_cst (TREE_TYPE (addr_of_decl)));
    1973          116 :   gimplify_seq_add_stmt (seq_p, call);
    1974          116 : }
    1975              : 
    1976              : /* Return true if the DECL need to be automatically initialized by the
    1977              :    compiler.  */
    1978              : static bool
    1979      4363821 : var_needs_auto_init_p (tree decl)
    1980              : {
    1981      4363821 :   if (auto_var_p (decl)
    1982      4264702 :       && (TREE_CODE (decl) != VAR_DECL || !DECL_HARD_REGISTER (decl))
    1983      4263994 :       && flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    1984       354648 :       && !lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl))
    1985       354640 :       && !lookup_attribute ("indeterminate", DECL_ATTRIBUTES (decl))
    1986       354631 :       && !OPAQUE_TYPE_P (TREE_TYPE (decl))
    1987      4718452 :       && !is_empty_type (TREE_TYPE (decl)))
    1988       327058 :     return true;
    1989              :   return false;
    1990              : }
    1991              : 
    1992              : /* Gimplify a DECL_EXPR node *STMT_P by making any necessary allocation
    1993              :    and initialization explicit.  */
    1994              : 
    1995              : static enum gimplify_status
    1996      6639478 : gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
    1997              : {
    1998      6639478 :   tree stmt = *stmt_p;
    1999      6639478 :   tree decl = DECL_EXPR_DECL (stmt);
    2000              : 
    2001      6639478 :   *stmt_p = NULL_TREE;
    2002              : 
    2003      6639478 :   if (TREE_TYPE (decl) == error_mark_node)
    2004              :     return GS_ERROR;
    2005              : 
    2006      6639391 :   if ((TREE_CODE (decl) == TYPE_DECL
    2007      6595559 :        || VAR_P (decl))
    2008     13231864 :       && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
    2009              :     {
    2010       717198 :       gimplify_type_sizes (TREE_TYPE (decl), seq_p);
    2011       717198 :       if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
    2012        23806 :         gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
    2013              :     }
    2014              : 
    2015              :   /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
    2016              :      in case its size expressions contain problematic nodes like CALL_EXPR.  */
    2017      6639391 :   if (TREE_CODE (decl) == TYPE_DECL
    2018        43832 :       && DECL_ORIGINAL_TYPE (decl)
    2019      6644712 :       && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
    2020              :     {
    2021            0 :       gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
    2022            0 :       if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
    2023            0 :         gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
    2024              :     }
    2025              : 
    2026      6639391 :   if (VAR_P (decl) && !DECL_EXTERNAL (decl))
    2027              :     {
    2028      6592473 :       tree init = DECL_INITIAL (decl);
    2029      6592473 :       bool is_vla = false;
    2030              :       /* Check whether a decl has FE created VALUE_EXPR here BEFORE
    2031              :          gimplify_vla_decl creates VALUE_EXPR for a vla decl.
    2032              :          If the decl has VALUE_EXPR that was created by FE (usually
    2033              :          C++FE), it's a proxy variable, and FE already initialized
    2034              :          the VALUE_EXPR of it, we should not initialize it anymore.  */
    2035      6592473 :       bool decl_had_value_expr_p = DECL_HAS_VALUE_EXPR_P (decl);
    2036              : 
    2037      6592473 :       poly_uint64 size;
    2038      6592473 :       if (!poly_int_tree_p (DECL_SIZE_UNIT (decl), &size)
    2039      6592473 :           || (!TREE_STATIC (decl)
    2040      6465320 :               && flag_stack_check == GENERIC_STACK_CHECK
    2041          234 :               && maybe_gt (size,
    2042              :                            (unsigned HOST_WIDE_INT) STACK_CHECK_MAX_VAR_SIZE)))
    2043              :         {
    2044         8907 :           gimplify_vla_decl (decl, seq_p);
    2045         8907 :           is_vla = true;
    2046              :         }
    2047              : 
    2048      6592473 :       if (asan_poisoned_variables
    2049         5247 :           && !is_vla
    2050         5061 :           && TREE_ADDRESSABLE (decl)
    2051         2463 :           && !TREE_STATIC (decl)
    2052         2253 :           && !DECL_HAS_VALUE_EXPR_P (decl)
    2053         2176 :           && DECL_ALIGN (decl) <= MAX_SUPPORTED_STACK_ALIGNMENT
    2054         2176 :           && dbg_cnt (asan_use_after_scope)
    2055         2176 :           && !gimplify_omp_ctxp
    2056              :           /* GNAT introduces temporaries to hold return values of calls in
    2057              :              initializers of variables defined in other units, so the
    2058              :              declaration of the variable is discarded completely.  We do not
    2059              :              want to issue poison calls for such dropped variables.  */
    2060      6594641 :           && (DECL_SEEN_IN_BIND_EXPR_P (decl)
    2061            0 :               || (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)))
    2062              :         {
    2063         2168 :           asan_poisoned_variables->add (decl);
    2064         2168 :           asan_poison_variable (decl, false, seq_p);
    2065         2168 :           if (!DECL_ARTIFICIAL (decl) && gimplify_ctxp->live_switch_vars)
    2066           55 :             gimplify_ctxp->live_switch_vars->add (decl);
    2067              :         }
    2068              : 
    2069              :       /* Some front ends do not explicitly declare all anonymous
    2070              :          artificial variables.  We compensate here by declaring the
    2071              :          variables, though it would be better if the front ends would
    2072              :          explicitly declare them.  */
    2073      6592473 :       if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
    2074      6592473 :           && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
    2075        17190 :         gimple_add_tmp_var (decl);
    2076              : 
    2077      6592473 :       if (init && init != error_mark_node)
    2078              :         {
    2079      3752319 :           if (!TREE_STATIC (decl))
    2080              :             {
    2081      3722312 :               DECL_INITIAL (decl) = NULL_TREE;
    2082      3722312 :               init = build2 (INIT_EXPR, void_type_node, decl, init);
    2083      3722312 :               gimplify_and_add (init, seq_p);
    2084      3722312 :               ggc_free (init);
    2085              :               /* Clear TREE_READONLY if we really have an initialization.  */
    2086      3722312 :               if (!DECL_INITIAL (decl)
    2087      3722312 :                   && !omp_privatize_by_reference (decl))
    2088      3699323 :                 TREE_READONLY (decl) = 0;
    2089              :             }
    2090              :           else
    2091              :             /* We must still examine initializers for static variables
    2092              :                as they may contain a label address.  */
    2093        30007 :             walk_tree (&init, force_labels_r, NULL, NULL);
    2094              :         }
    2095              :       /* When there is no explicit initializer, if the user requested,
    2096              :          We should insert an artificial initializer for this automatic
    2097              :          variable.  */
    2098      2840154 :       else if (var_needs_auto_init_p (decl)
    2099      2840154 :                && !decl_had_value_expr_p)
    2100              :         {
    2101        98751 :           gimple_add_init_for_auto_var (decl,
    2102              :                                         flag_auto_var_init,
    2103              :                                         seq_p);
    2104              :           /* The expanding of a call to the above .DEFERRED_INIT will apply
    2105              :              block initialization to the whole space covered by this variable.
    2106              :              As a result, all the paddings will be initialized to zeroes
    2107              :              for zero initialization and 0xFE byte-repeatable patterns for
    2108              :              pattern initialization.
    2109              :              In order to make the paddings as zeroes for pattern init, We
    2110              :              should add a call to __builtin_clear_padding to clear the
    2111              :              paddings to zero in compatible with CLANG.
    2112              :              We cannot insert this call if the variable is a gimple register
    2113              :              since __builtin_clear_padding will take the address of the
    2114              :              variable.  As a result, if a long double/_Complex long double
    2115              :              variable will spilled into stack later, its padding is 0XFE.  */
    2116        98751 :           if ((flag_auto_var_init & ~AUTO_INIT_CXX26) == AUTO_INIT_PATTERN
    2117          186 :               && !is_gimple_reg (decl)
    2118        98849 :               && clear_padding_type_may_have_padding_p (TREE_TYPE (decl)))
    2119           75 :             gimple_add_padding_init_for_auto_var (decl, is_vla, seq_p);
    2120              :         }
    2121              :     }
    2122              : 
    2123              :   return GS_ALL_DONE;
    2124              : }
    2125              : 
    2126              : /* Gimplify a LOOP_EXPR.  Normally this just involves gimplifying the body
    2127              :    and replacing the LOOP_EXPR with goto, but if the loop contains an
    2128              :    EXIT_EXPR, we need to append a label for it to jump to.  */
    2129              : 
    2130              : static enum gimplify_status
    2131       207479 : gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
    2132              : {
    2133       207479 :   tree saved_label = gimplify_ctxp->exit_label;
    2134       207479 :   tree start_label = create_artificial_label (UNKNOWN_LOCATION);
    2135              : 
    2136       207479 :   gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
    2137              : 
    2138       207479 :   gimplify_ctxp->exit_label = NULL_TREE;
    2139              : 
    2140       207479 :   gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
    2141              : 
    2142       207479 :   gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
    2143              : 
    2144       207479 :   if (gimplify_ctxp->exit_label)
    2145         6402 :     gimplify_seq_add_stmt (pre_p,
    2146         3201 :                            gimple_build_label (gimplify_ctxp->exit_label));
    2147              : 
    2148       207479 :   gimplify_ctxp->exit_label = saved_label;
    2149              : 
    2150       207479 :   *expr_p = NULL;
    2151       207479 :   return GS_ALL_DONE;
    2152              : }
    2153              : 
    2154              : /* Gimplify a statement list onto a sequence.  These may be created either
    2155              :    by an enlightened front-end, or by shortcut_cond_expr.  */
    2156              : 
    2157              : static enum gimplify_status
    2158      8719235 : gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
    2159              : {
    2160      8719235 :   tree temp = voidify_wrapper_expr (*expr_p, NULL);
    2161              : 
    2162      8719235 :   tree_stmt_iterator i = tsi_start (*expr_p);
    2163              : 
    2164     56125929 :   while (!tsi_end_p (i))
    2165              :     {
    2166     38687459 :       gimplify_stmt (tsi_stmt_ptr (i), pre_p);
    2167     38687459 :       tsi_delink (&i);
    2168              :     }
    2169              : 
    2170      8719235 :   if (temp)
    2171              :     {
    2172        14835 :       *expr_p = temp;
    2173        14835 :       return GS_OK;
    2174              :     }
    2175              : 
    2176              :   return GS_ALL_DONE;
    2177              : }
    2178              : 
    2179              : 
    2180              : /* Emit warning for the unreachable statement STMT if needed.
    2181              :    Return the gimple itself when the warning is emitted, otherwise
    2182              :    return NULL.  */
    2183              : static gimple *
    2184          181 : emit_warn_switch_unreachable (gimple *stmt)
    2185              : {
    2186          181 :   if (gimple_code (stmt) == GIMPLE_GOTO
    2187           50 :       && TREE_CODE (gimple_goto_dest (stmt)) == LABEL_DECL
    2188          231 :       && DECL_ARTIFICIAL (gimple_goto_dest (stmt)))
    2189              :   /* Don't warn for compiler-generated gotos.  These occur
    2190              :      in Duff's devices, for example.  */
    2191              :     return NULL;
    2192              :   else
    2193          131 :     warning_at (gimple_location (stmt), OPT_Wswitch_unreachable,
    2194              :                 "statement will never be executed");
    2195          131 :   return stmt;
    2196              : }
    2197              : 
    2198              : /* Callback for walk_gimple_seq.  */
    2199              : 
    2200              : static tree
    2201        50897 : warn_switch_unreachable_and_auto_init_r (gimple_stmt_iterator *gsi_p,
    2202              :                                          bool *handled_ops_p,
    2203              :                                          struct walk_stmt_info *wi)
    2204              : {
    2205        50897 :   gimple *stmt = gsi_stmt (*gsi_p);
    2206        50897 :   bool unreachable_issued = wi->info != NULL;
    2207              : 
    2208        50897 :   *handled_ops_p = true;
    2209        50897 :   switch (gimple_code (stmt))
    2210              :     {
    2211          446 :     case GIMPLE_TRY:
    2212              :       /* A compiler-generated cleanup or a user-written try block.
    2213              :          If it's empty, don't dive into it--that would result in
    2214              :          worse location info.  */
    2215          446 :       if (gimple_try_eval (stmt) == NULL)
    2216              :         {
    2217            3 :           if (warn_switch_unreachable && !unreachable_issued)
    2218            3 :             wi->info = emit_warn_switch_unreachable (stmt);
    2219              : 
    2220              :           /* Stop when auto var init warning is not on.  */
    2221            3 :           if (!warn_trivial_auto_var_init)
    2222            3 :             return integer_zero_node;
    2223              :         }
    2224              :       /* Fall through.  */
    2225         2679 :     case GIMPLE_BIND:
    2226         2679 :     case GIMPLE_CATCH:
    2227         2679 :     case GIMPLE_EH_FILTER:
    2228         2679 :     case GIMPLE_TRANSACTION:
    2229              :       /* Walk the sub-statements.  */
    2230         2679 :       *handled_ops_p = false;
    2231         2679 :       break;
    2232              : 
    2233              :     case GIMPLE_DEBUG:
    2234              :       /* Ignore these.  We may generate them before declarations that
    2235              :          are never executed.  If there's something to warn about,
    2236              :          there will be non-debug stmts too, and we'll catch those.  */
    2237              :       break;
    2238              : 
    2239           60 :     case GIMPLE_ASSIGN:
    2240              :       /* See comment below in the GIMPLE_CALL case.  */
    2241           60 :       if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2242           20 :           && gimple_assign_single_p (stmt)
    2243           79 :           && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
    2244              :         {
    2245            6 :           gimple *g = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
    2246            6 :           if (gimple_call_internal_p (g, IFN_DEFERRED_INIT))
    2247              :             break;
    2248              :         }
    2249           54 :       goto do_default;
    2250              : 
    2251        46753 :     case GIMPLE_LABEL:
    2252              :       /* Stop till the first Label.  */
    2253        46753 :       return integer_zero_node;
    2254           62 :     case GIMPLE_CALL:
    2255           62 :       if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
    2256              :         {
    2257            8 :           *handled_ops_p = false;
    2258            8 :           break;
    2259              :         }
    2260              :       /* Don't warn for compiler-generated initializations for
    2261              :          -ftrivial-auto-var-init for -Wswitch-unreachable.  Though
    2262              :          do warn for -Wtrivial-auto-var-init.
    2263              :          There are 3 cases:
    2264              :          case 1: a call to .DEFERRED_INIT;
    2265              :          case 2: a call to __builtin_clear_padding with the 2nd argument is
    2266              :                  present and non-zero;
    2267              :          case 3: a gimple assign store right after the call to .DEFERRED_INIT
    2268              :                  that has the LHS of .DEFERRED_INIT as the RHS as following:
    2269              :                   _1 = .DEFERRED_INIT (4, 2, &"i1"[0]);
    2270              :                   i1 = _1.
    2271              :          case 3 is handled above in the GIMPLE_ASSIGN case.  */
    2272           54 :       if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2273           54 :           && gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
    2274              :         {
    2275           33 :           if (warn_trivial_auto_var_init)
    2276              :             {
    2277              :               /* Get the variable name from the 3rd argument of call.  */
    2278           12 :               tree var_name = gimple_call_arg (stmt, 2);
    2279           12 :               var_name = TREE_OPERAND (TREE_OPERAND (var_name, 0), 0);
    2280           12 :               const char *var_name_str = TREE_STRING_POINTER (var_name);
    2281              : 
    2282           12 :               warning_at (gimple_location (stmt), OPT_Wtrivial_auto_var_init,
    2283              :                           "%qs cannot be initialized with "
    2284              :                           "%<-ftrivial-auto-var_init%>", var_name_str);
    2285              :             }
    2286              :           break;
    2287              :        }
    2288           21 :       if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2289            7 :           && gimple_call_builtin_p (stmt, BUILT_IN_CLEAR_PADDING)
    2290           24 :           && (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 1)))
    2291              :         break;
    2292              :       /* Fall through.  */
    2293          178 :     default:
    2294          178 :     do_default:
    2295              :       /* check the first "real" statement (not a decl/lexical scope/...), issue
    2296              :          warning if needed.  */
    2297          178 :       if (warn_switch_unreachable && !unreachable_issued)
    2298          178 :         wi->info = emit_warn_switch_unreachable (stmt);
    2299              :       /* Stop when auto var init warning is not on.  */
    2300          178 :       if (!warn_trivial_auto_var_init)
    2301          178 :         return integer_zero_node;
    2302              :       break;
    2303              :     }
    2304              :   return NULL_TREE;
    2305              : }
    2306              : 
    2307              : 
    2308              : /* Possibly warn about unreachable statements between switch's controlling
    2309              :    expression and the first case.  Also warn about -ftrivial-auto-var-init
    2310              :    cannot initialize the auto variable under such situation.
    2311              :    SEQ is the body of a switch expression.  */
    2312              : 
    2313              : static void
    2314        50872 : maybe_warn_switch_unreachable_and_auto_init (gimple_seq seq)
    2315              : {
    2316           60 :   if ((!warn_switch_unreachable && !warn_trivial_auto_var_init)
    2317              :       /* This warning doesn't play well with Fortran when optimizations
    2318              :          are on.  */
    2319        50812 :       || lang_GNU_Fortran ()
    2320        97980 :       || seq == NULL)
    2321         3935 :     return;
    2322              : 
    2323        46937 :   struct walk_stmt_info wi;
    2324              : 
    2325        46937 :   memset (&wi, 0, sizeof (wi));
    2326        46937 :   walk_gimple_seq (seq, warn_switch_unreachable_and_auto_init_r, NULL, &wi);
    2327              : }
    2328              : 
    2329              : 
    2330              : /* A label entry that pairs label and a location.  */
    2331              : struct label_entry
    2332              : {
    2333              :   tree label;
    2334              :   location_t loc;
    2335              : };
    2336              : 
    2337              : /* Find LABEL in vector of label entries VEC.  */
    2338              : 
    2339              : static struct label_entry *
    2340        12352 : find_label_entry (const auto_vec<struct label_entry> *vec, tree label)
    2341              : {
    2342        12352 :   unsigned int i;
    2343        12352 :   struct label_entry *l;
    2344              : 
    2345        23634 :   FOR_EACH_VEC_ELT (*vec, i, l)
    2346        20270 :     if (l->label == label)
    2347              :       return l;
    2348              :   return NULL;
    2349              : }
    2350              : 
    2351              : /* Return true if LABEL, a LABEL_DECL, represents a case label
    2352              :    in a vector of labels CASES.  */
    2353              : 
    2354              : static bool
    2355        16478 : case_label_p (const vec<tree> *cases, tree label)
    2356              : {
    2357        16478 :   unsigned int i;
    2358        16478 :   tree l;
    2359              : 
    2360       165417 :   FOR_EACH_VEC_ELT (*cases, i, l)
    2361       165083 :     if (CASE_LABEL (l) == label)
    2362              :       return true;
    2363              :   return false;
    2364              : }
    2365              : 
    2366              : /* Find the last nondebug statement in a scope STMT.  */
    2367              : 
    2368              : static gimple *
    2369         2257 : last_stmt_in_scope (gimple *stmt)
    2370              : {
    2371         4196 :   if (!stmt)
    2372              :     return NULL;
    2373              : 
    2374         6834 :   auto last_stmt_in_seq = [] (gimple_seq s) 
    2375              :     {
    2376         2649 :       gimple_seq_node n;
    2377         5289 :       for (n = gimple_seq_last (s);
    2378         2654 :            n && (is_gimple_debug (n)
    2379         2641 :                  || (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2380          109 :                      && gimple_call_internal_p (n, IFN_DEFERRED_INIT)));
    2381            5 :         n = n->prev)
    2382            7 :       if (n == s)
    2383              :         return (gimple *) NULL;
    2384              :       return (gimple *) n;
    2385              :     };
    2386              : 
    2387         4185 :   switch (gimple_code (stmt))
    2388              :     {
    2389         1391 :     case GIMPLE_BIND:
    2390         1391 :       {
    2391         1391 :         gbind *bind = as_a <gbind *> (stmt);
    2392         1391 :         stmt = last_stmt_in_seq (gimple_bind_body (bind));
    2393         1391 :         return last_stmt_in_scope (stmt);
    2394              :       }
    2395              : 
    2396          710 :     case GIMPLE_TRY:
    2397          710 :       {
    2398          710 :         gtry *try_stmt = as_a <gtry *> (stmt);
    2399          710 :         stmt = last_stmt_in_seq (gimple_try_eval (try_stmt));
    2400          710 :         gimple *last_eval = last_stmt_in_scope (stmt);
    2401          710 :         if (gimple_stmt_may_fallthru (last_eval)
    2402          567 :             && (last_eval == NULL
    2403          564 :                 || !gimple_call_internal_p (last_eval, IFN_FALLTHROUGH))
    2404         1270 :             && gimple_try_kind (try_stmt) == GIMPLE_TRY_FINALLY)
    2405              :           {
    2406          548 :             stmt = last_stmt_in_seq (gimple_try_cleanup (try_stmt));
    2407          548 :             return last_stmt_in_scope (stmt);
    2408              :           }
    2409              :         else
    2410              :           return last_eval;
    2411              :       }
    2412              : 
    2413            0 :     case GIMPLE_DEBUG:
    2414            0 :       gcc_unreachable ();
    2415              : 
    2416              :     default:
    2417              :       return stmt;
    2418              :     }
    2419              : }
    2420              : 
    2421              : /* Collect labels that may fall through into LABELS and return the statement
    2422              :    preceding another case label, or a user-defined label.  Store a location
    2423              :    useful to give warnings at *PREVLOC (usually the location of the returned
    2424              :    statement or of its surrounding scope).  */
    2425              : 
    2426              : static gimple *
    2427        21093 : collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
    2428              :                             auto_vec <struct label_entry> *labels,
    2429              :                             location_t *prevloc)
    2430              : {
    2431        21093 :   gimple *prev = NULL;
    2432              : 
    2433        21093 :   *prevloc = UNKNOWN_LOCATION;
    2434       102348 :   do
    2435              :     {
    2436       102348 :       if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND)
    2437              :         {
    2438              :           /* Recognize the special GIMPLE_BIND added by gimplify_switch_expr,
    2439              :              which starts on a GIMPLE_SWITCH and ends with a break label.
    2440              :              Handle that as a single statement that can fall through.  */
    2441         1452 :           gbind *bind = as_a <gbind *> (gsi_stmt (*gsi_p));
    2442         1452 :           gimple *first = gimple_seq_first_stmt (gimple_bind_body (bind));
    2443         1452 :           gimple *last = gimple_seq_last_stmt (gimple_bind_body (bind));
    2444         1446 :           if (last
    2445         1446 :               && gimple_code (first) == GIMPLE_SWITCH
    2446         1548 :               && gimple_code (last) == GIMPLE_LABEL)
    2447              :             {
    2448          102 :               tree label = gimple_label_label (as_a <glabel *> (last));
    2449          102 :               if (SWITCH_BREAK_LABEL_P (label))
    2450              :                 {
    2451          102 :                   prev = bind;
    2452          102 :                   gsi_next (gsi_p);
    2453          102 :                   continue;
    2454              :                 }
    2455              :             }
    2456              :         }
    2457       102246 :       if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
    2458       102246 :           || gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
    2459              :         {
    2460              :           /* Nested scope.  Only look at the last statement of
    2461              :              the innermost scope.  */
    2462         1547 :           location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
    2463         1547 :           gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
    2464         1547 :           if (last)
    2465              :             {
    2466         1539 :               prev = last;
    2467              :               /* It might be a label without a location.  Use the
    2468              :                  location of the scope then.  */
    2469         1539 :               if (!gimple_has_location (prev))
    2470          671 :                 *prevloc = bind_loc;
    2471              :             }
    2472         1547 :           gsi_next (gsi_p);
    2473         1547 :           continue;
    2474         1547 :         }
    2475              : 
    2476              :       /* Ifs are tricky.  */
    2477       100699 :       if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
    2478              :         {
    2479         7268 :           gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
    2480         7268 :           tree false_lab = gimple_cond_false_label (cond_stmt);
    2481         7268 :           location_t if_loc = gimple_location (cond_stmt);
    2482              : 
    2483              :           /* If we have e.g.
    2484              :                if (i > 1) goto <D.2259>; else goto D;
    2485              :              we can't do much with the else-branch.  */
    2486         7268 :           if (!DECL_ARTIFICIAL (false_lab))
    2487              :             break;
    2488              : 
    2489              :           /* Go on until the false label, then one step back.  */
    2490        55328 :           for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
    2491              :             {
    2492        55328 :               gimple *stmt = gsi_stmt (*gsi_p);
    2493        55328 :               if (gimple_code (stmt) == GIMPLE_LABEL
    2494        55328 :                   && gimple_label_label (as_a <glabel *> (stmt)) == false_lab)
    2495              :                 break;
    2496              :             }
    2497              : 
    2498              :           /* Not found?  Oops.  */
    2499         7268 :           if (gsi_end_p (*gsi_p))
    2500              :             break;
    2501              : 
    2502              :           /* A dead label can't fall through.  */
    2503         7268 :           if (!UNUSED_LABEL_P (false_lab))
    2504              :             {
    2505         7221 :               struct label_entry l = { false_lab, if_loc };
    2506         7221 :               labels->safe_push (l);
    2507              :             }
    2508              : 
    2509              :           /* Go to the last statement of the then branch.  */
    2510         7268 :           gsi_prev (gsi_p);
    2511              : 
    2512              :           /* if (i != 0) goto <D.1759>; else goto <D.1760>;
    2513              :              <D.1759>:
    2514              :              <stmt>;
    2515              :              goto <D.1761>;
    2516              :              <D.1760>:
    2517              :            */
    2518         7268 :           if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
    2519         7268 :               && !gimple_has_location (gsi_stmt (*gsi_p)))
    2520              :             {
    2521              :               /* Look at the statement before, it might be
    2522              :                  attribute fallthrough, in which case don't warn.  */
    2523         1626 :               gsi_prev (gsi_p);
    2524         1626 :               bool fallthru_before_dest
    2525         1626 :                 = gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_FALLTHROUGH);
    2526         1626 :               gsi_next (gsi_p);
    2527         1626 :               tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
    2528         1626 :               if (!fallthru_before_dest)
    2529              :                 {
    2530         1569 :                   struct label_entry l = { goto_dest, if_loc };
    2531         1569 :                   labels->safe_push (l);
    2532              :                 }
    2533              :             }
    2534              :           /* This case is about
    2535              :               if (1 != 0) goto <D.2022>; else goto <D.2023>;
    2536              :               <D.2022>:
    2537              :               n = n + 1; // #1
    2538              :               <D.2023>:  // #2
    2539              :               <D.1988>:  // #3
    2540              :              where #2 is UNUSED_LABEL_P and we want to warn about #1 falling
    2541              :              through to #3.  So set PREV to #1.  */
    2542         5642 :           else if (UNUSED_LABEL_P (false_lab))
    2543           47 :             prev = gsi_stmt (*gsi_p);
    2544              : 
    2545              :           /* And move back.  */
    2546         7268 :           gsi_next (gsi_p);
    2547              :         }
    2548              : 
    2549       100699 :       tree lab;
    2550              :       /* Remember the last statement.  Skip labels that are of no interest
    2551              :          to us.  */
    2552       100699 :       if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
    2553              :         {
    2554        12134 :           tree label = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
    2555        12134 :           if (find_label_entry (labels, label))
    2556         8790 :             prev = gsi_stmt (*gsi_p);
    2557              :         }
    2558        88565 :       else if (gimple_call_internal_p (gsi_stmt (*gsi_p), IFN_ASAN_MARK))
    2559              :         ;
    2560        88565 :       else if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2561        88565 :                && gimple_call_internal_p (gsi_stmt (*gsi_p),
    2562              :                                           IFN_DEFERRED_INIT))
    2563              :         ;
    2564        88559 :       else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_PREDICT)
    2565              :         ;
    2566        87331 :       else if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2567         2382 :                && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
    2568          348 :                && (lab = gimple_goto_dest (gsi_stmt (*gsi_p)))
    2569          348 :                && TREE_CODE (lab) == LABEL_DECL
    2570        87678 :                && VACUOUS_INIT_LABEL_P (lab))
    2571              :         ;
    2572        87331 :       else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
    2573        67015 :         prev = gsi_stmt (*gsi_p);
    2574       100699 :       gsi_next (gsi_p);
    2575              :     }
    2576       102348 :   while (!gsi_end_p (*gsi_p)
    2577              :          /* Stop if we find a case or a user-defined label.  */
    2578       200609 :          && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
    2579        21872 :              || !gimple_has_location (gsi_stmt (*gsi_p))));
    2580              : 
    2581        21093 :   if (prev && gimple_has_location (prev))
    2582        20640 :     *prevloc = gimple_location (prev);
    2583        21093 :   return prev;
    2584              : }
    2585              : 
    2586              : /* Return true if the switch fallthrough warning should occur.  LABEL is
    2587              :    the label statement that we're falling through to.  */
    2588              : 
    2589              : static bool
    2590        16999 : should_warn_for_implicit_fallthrough (gimple_stmt_iterator *gsi_p, tree label)
    2591              : {
    2592        16999 :   gimple_stmt_iterator gsi = *gsi_p;
    2593              : 
    2594              :   /* Don't warn if the label is marked with a "falls through" comment.  */
    2595        16999 :   if (FALLTHROUGH_LABEL_P (label))
    2596              :     return false;
    2597              : 
    2598              :   /* Don't warn for non-case labels followed by a statement:
    2599              :        case 0:
    2600              :          foo ();
    2601              :        label:
    2602              :          bar ();
    2603              :      as these are likely intentional.  */
    2604        16219 :   if (!case_label_p (&gimplify_ctxp->case_labels, label))
    2605              :     {
    2606              :       tree l;
    2607          334 :       while (!gsi_end_p (gsi)
    2608          334 :              && ((gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
    2609          259 :                   && (l
    2610          259 :                       = gimple_label_label (as_a <glabel *> (gsi_stmt (gsi))))
    2611          259 :                   && !case_label_p (&gimplify_ctxp->case_labels, l))
    2612          153 :                  || (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2613           31 :                      && gimple_call_internal_p (gsi_stmt (gsi),
    2614              :                                                 IFN_DEFERRED_INIT))))
    2615          173 :         gsi_next_nondebug (&gsi);
    2616          161 :       if (gsi_end_p (gsi) || gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
    2617              :         return false;
    2618              :     }
    2619              : 
    2620              :   /* Don't warn for terminated branches, i.e. when the subsequent case labels
    2621              :      immediately breaks.  */
    2622        16144 :   gsi = *gsi_p;
    2623              : 
    2624              :   /* Skip all immediately following labels.  */
    2625        35963 :   while (!gsi_end_p (gsi)
    2626        35963 :          && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
    2627        16293 :              || gimple_code (gsi_stmt (gsi)) == GIMPLE_PREDICT
    2628        16084 :              || (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2629          775 :                  && gimple_call_internal_p (gsi_stmt (gsi),
    2630              :                                             IFN_DEFERRED_INIT))))
    2631        19819 :     gsi_next_nondebug (&gsi);
    2632              : 
    2633              :   /* { ... something; default:; } */
    2634        16144 :   if (gsi_end_p (gsi)
    2635              :       /* { ... something; default: break; } or
    2636              :          { ... something; default: goto L; } */
    2637        16078 :       || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
    2638              :       /* { ... something; default: return; } */
    2639        31123 :       || gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
    2640         1192 :     return false;
    2641              : 
    2642              :   return true;
    2643              : }
    2644              : 
    2645              : /* Callback for walk_gimple_seq.  */
    2646              : 
    2647              : static tree
    2648        22101 : warn_implicit_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
    2649              :                              struct walk_stmt_info *)
    2650              : {
    2651        22101 :   gimple *stmt = gsi_stmt (*gsi_p);
    2652              : 
    2653        22101 :   *handled_ops_p = true;
    2654        22101 :   switch (gimple_code (stmt))
    2655              :     {
    2656          299 :     case GIMPLE_TRY:
    2657          299 :     case GIMPLE_BIND:
    2658          299 :     case GIMPLE_CATCH:
    2659          299 :     case GIMPLE_EH_FILTER:
    2660          299 :     case GIMPLE_TRANSACTION:
    2661              :       /* Walk the sub-statements.  */
    2662          299 :       *handled_ops_p = false;
    2663          299 :       break;
    2664              : 
    2665              :     /* Find a sequence of form:
    2666              : 
    2667              :        GIMPLE_LABEL
    2668              :        [...]
    2669              :        <may fallthru stmt>
    2670              :        GIMPLE_LABEL
    2671              : 
    2672              :        and possibly warn.  */
    2673              :     case GIMPLE_LABEL:
    2674              :       {
    2675              :         /* Found a label.  Skip all immediately following labels.  */
    2676        49612 :         while (!gsi_end_p (*gsi_p)
    2677        49612 :                && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
    2678        28285 :           gsi_next_nondebug (gsi_p);
    2679              : 
    2680              :         /* There might be no more statements.  */
    2681        21327 :         if (gsi_end_p (*gsi_p))
    2682         4321 :           return integer_zero_node;
    2683              : 
    2684              :         /* Vector of labels that fall through.  */
    2685        21093 :         auto_vec <struct label_entry> labels;
    2686        21093 :         location_t prevloc;
    2687        21093 :         gimple *prev = collect_fallthrough_labels (gsi_p, &labels, &prevloc);
    2688              : 
    2689              :         /* There might be no more statements.  */
    2690        21093 :         if (gsi_end_p (*gsi_p))
    2691         4087 :           return integer_zero_node;
    2692              : 
    2693        17006 :         gimple *next = gsi_stmt (*gsi_p);
    2694        17006 :         tree label;
    2695              :         /* If what follows is a label, then we may have a fallthrough.  */
    2696        17006 :         if (gimple_code (next) == GIMPLE_LABEL
    2697        17006 :             && gimple_has_location (next)
    2698        17006 :             && (label = gimple_label_label (as_a <glabel *> (next)))
    2699        34012 :             && prev != NULL)
    2700              :           {
    2701        16999 :             struct label_entry *l;
    2702        16999 :             bool warned_p = false;
    2703        16999 :             auto_diagnostic_group d;
    2704        16999 :             if (!should_warn_for_implicit_fallthrough (gsi_p, label))
    2705              :               /* Quiet.  */;
    2706        14952 :             else if (gimple_code (prev) == GIMPLE_LABEL
    2707          218 :                      && (label = gimple_label_label (as_a <glabel *> (prev)))
    2708        15170 :                      && (l = find_label_entry (&labels, label)))
    2709          198 :               warned_p = warning_at (l->loc, OPT_Wimplicit_fallthrough_,
    2710              :                                      "this statement may fall through");
    2711        14754 :             else if (!gimple_call_internal_p (prev, IFN_FALLTHROUGH)
    2712              :                      /* Try to be clever and don't warn when the statement
    2713              :                         can't actually fall through.  */
    2714        14174 :                      && gimple_stmt_may_fallthru (prev)
    2715        15055 :                      && prevloc != UNKNOWN_LOCATION)
    2716          301 :               warned_p = warning_at (prevloc,
    2717          301 :                                      OPT_Wimplicit_fallthrough_,
    2718              :                                      "this statement may fall through");
    2719          499 :             if (warned_p)
    2720          499 :               inform (gimple_location (next), "here");
    2721              : 
    2722              :             /* Mark this label as processed so as to prevent multiple
    2723              :                warnings in nested switches.  */
    2724        16999 :             FALLTHROUGH_LABEL_P (label) = true;
    2725              : 
    2726              :             /* So that next warn_implicit_fallthrough_r will start looking for
    2727              :                a new sequence starting with this label.  */
    2728        16999 :             gsi_prev (gsi_p);
    2729        16999 :           }
    2730         4087 :       }
    2731        17006 :       break;
    2732              :    default:
    2733              :       break;
    2734              :     }
    2735              :   return NULL_TREE;
    2736              : }
    2737              : 
    2738              : /* Warn when a switch case falls through.  */
    2739              : 
    2740              : static void
    2741        50872 : maybe_warn_implicit_fallthrough (gimple_seq seq)
    2742              : {
    2743        50872 :   if (!warn_implicit_fallthrough)
    2744        46692 :     return;
    2745              : 
    2746              :   /* This warning is meant for C/C++/ObjC/ObjC++ only.  */
    2747         4180 :   if (!(lang_GNU_C ()
    2748         1232 :         || lang_GNU_CXX ()
    2749            0 :         || lang_GNU_OBJC ()))
    2750              :     return;
    2751              : 
    2752         4180 :   struct walk_stmt_info wi;
    2753         4180 :   memset (&wi, 0, sizeof (wi));
    2754         4180 :   walk_gimple_seq (seq, warn_implicit_fallthrough_r, NULL, &wi);
    2755              : }
    2756              : 
    2757              : /* Callback for walk_gimple_seq.  */
    2758              : 
    2759              : static tree
    2760      3291845 : expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
    2761              :                       struct walk_stmt_info *wi)
    2762              : {
    2763      3291845 :   gimple *stmt = gsi_stmt (*gsi_p);
    2764              : 
    2765      3291845 :   *handled_ops_p = true;
    2766      3291845 :   switch (gimple_code (stmt))
    2767              :     {
    2768       148843 :     case GIMPLE_TRY:
    2769       148843 :     case GIMPLE_BIND:
    2770       148843 :     case GIMPLE_CATCH:
    2771       148843 :     case GIMPLE_EH_FILTER:
    2772       148843 :     case GIMPLE_TRANSACTION:
    2773              :       /* Walk the sub-statements.  */
    2774       148843 :       *handled_ops_p = false;
    2775       148843 :       break;
    2776       259783 :     case GIMPLE_CALL:
    2777       259783 :       static_cast<location_t *>(wi->info)[0] = UNKNOWN_LOCATION;
    2778       259783 :       if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH))
    2779              :         {
    2780         3962 :           location_t loc = gimple_location (stmt);
    2781         3962 :           gsi_remove (gsi_p, true);
    2782         3962 :           wi->removed_stmt = true;
    2783              : 
    2784              :           /* nothrow flag is added by genericize_c_loop to mark fallthrough
    2785              :              statement at the end of some loop's body.  Those should be
    2786              :              always diagnosed, either because they indeed don't precede
    2787              :              a case label or default label, or because the next statement
    2788              :              is not within the same iteration statement.  */
    2789         3962 :           if ((stmt->subcode & GF_CALL_NOTHROW) != 0)
    2790              :             {
    2791           12 :               pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
    2792              :                                "a case label or default label");
    2793           12 :               break;
    2794              :             }
    2795              : 
    2796         3950 :           if (gsi_end_p (*gsi_p))
    2797              :             {
    2798           32 :               static_cast<location_t *>(wi->info)[0] = BUILTINS_LOCATION;
    2799           32 :               static_cast<location_t *>(wi->info)[1] = loc;
    2800           32 :               break;
    2801              :             }
    2802              : 
    2803         3918 :           bool found = false;
    2804              : 
    2805         3918 :           gimple_stmt_iterator gsi2 = *gsi_p;
    2806         3918 :           stmt = gsi_stmt (gsi2);
    2807         3918 :           tree lab;
    2808         3918 :           if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2809         1704 :               && gimple_code (stmt) == GIMPLE_GOTO
    2810           20 :               && (lab = gimple_goto_dest (stmt))
    2811           20 :               && TREE_CODE (lab) == LABEL_DECL
    2812         3938 :               && VACUOUS_INIT_LABEL_P (lab))
    2813              :             {
    2814              :               /* Handle for C++ artificial -ftrivial-auto-var-init=
    2815              :                  sequences.  Those look like:
    2816              :                  goto lab1;
    2817              :                  lab2:;
    2818              :                  v1 = .DEFERRED_INIT (...);
    2819              :                  v2 = .DEFERRED_INIT (...);
    2820              :                  lab3:;
    2821              :                  v3 = .DEFERRED_INIT (...);
    2822              :                  lab1:;
    2823              :                  In this case, a case/default label can be either in between
    2824              :                  the GIMPLE_GOTO and the corresponding GIMPLE_LABEL, if jumps
    2825              :                  from the switch condition to the case/default label cross
    2826              :                  vacuous initialization of some variables, or after the
    2827              :                  corresponding GIMPLE_LABEL, if those jumps don't cross
    2828              :                  any such initialization but there is an adjacent named label
    2829              :                  which crosses such initialization.  So, for the purpose of
    2830              :                  this function, just ignore the goto but until reaching the
    2831              :                  corresponding GIMPLE_LABEL allow also .DEFERRED_INIT
    2832              :                  calls.  */
    2833            5 :               gsi_next (&gsi2);
    2834              :             }
    2835         3913 :           else if (gimple_code (stmt) == GIMPLE_GOTO
    2836         3913 :                    && !gimple_has_location (stmt))
    2837              :             {
    2838              :               /* Go on until the artificial label.  */
    2839           57 :               tree goto_dest = gimple_goto_dest (stmt);
    2840          414 :               for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
    2841              :                 {
    2842          357 :                   if (gimple_code (gsi_stmt (gsi2)) == GIMPLE_LABEL
    2843          357 :                       && gimple_label_label (as_a <glabel *> (gsi_stmt (gsi2)))
    2844              :                            == goto_dest)
    2845              :                     break;
    2846              :                 }
    2847              : 
    2848              :               /* Not found?  Stop.  */
    2849           57 :               if (gsi_end_p (gsi2))
    2850              :                 break;
    2851              : 
    2852              :               /* Look one past it.  */
    2853           57 :               gsi_next (&gsi2);
    2854              :             }
    2855              : 
    2856              :           /* We're looking for a case label or default label here.  */
    2857         4016 :           while (!gsi_end_p (gsi2))
    2858              :             {
    2859         4016 :               stmt = gsi_stmt (gsi2);
    2860         4016 :               if (gimple_code (stmt) == GIMPLE_LABEL)
    2861              :                 {
    2862         3973 :                   tree label = gimple_label_label (as_a <glabel *> (stmt));
    2863         3973 :                   if (gimple_has_location (stmt) && DECL_ARTIFICIAL (label))
    2864              :                     {
    2865              :                       found = true;
    2866              :                       break;
    2867              :                     }
    2868              :                 }
    2869           43 :               else if (gimple_call_internal_p (stmt, IFN_ASAN_MARK))
    2870              :                 ;
    2871           43 :               else if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    2872           43 :                        && gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
    2873              :                 ;
    2874           43 :               else if (!is_gimple_debug (stmt))
    2875              :                 /* Anything else is not expected.  */
    2876              :                 break;
    2877           98 :               gsi_next (&gsi2);
    2878              :             }
    2879         3918 :           if (!found)
    2880           23 :             pedwarn (loc, 0, "attribute %<fallthrough%> not preceding "
    2881              :                      "a case label or default label");
    2882              :         }
    2883              :       break;
    2884      2883219 :     default:
    2885      2883219 :       static_cast<location_t *>(wi->info)[0] = UNKNOWN_LOCATION;
    2886      2883219 :       break;
    2887              :     }
    2888      3291845 :   return NULL_TREE;
    2889              : }
    2890              : 
    2891              : /* Expand all FALLTHROUGH () calls in SEQ.  */
    2892              : 
    2893              : static void
    2894        49043 : expand_FALLTHROUGH (gimple_seq *seq_p)
    2895              : {
    2896        49043 :   auto_urlify_attributes sentinel;
    2897              : 
    2898        49043 :   struct walk_stmt_info wi;
    2899        49043 :   location_t loc[2];
    2900        49043 :   memset (&wi, 0, sizeof (wi));
    2901        49043 :   loc[0] = UNKNOWN_LOCATION;
    2902        49043 :   loc[1] = UNKNOWN_LOCATION;
    2903        49043 :   wi.info = (void *) &loc[0];
    2904        49043 :   walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi);
    2905        49043 :   if (loc[0] != UNKNOWN_LOCATION)
    2906              :     /* We've found [[fallthrough]]; at the end of a switch, which the C++
    2907              :        standard says is ill-formed; see [dcl.attr.fallthrough].  */
    2908            8 :     pedwarn (loc[1], 0, "attribute %<fallthrough%> not preceding "
    2909              :              "a case label or default label");
    2910        49043 : }
    2911              : 
    2912              : 
    2913              : /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
    2914              :    branch to.  */
    2915              : 
    2916              : static enum gimplify_status
    2917        50872 : gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
    2918              : {
    2919        50872 :   tree switch_expr = *expr_p;
    2920        50872 :   gimple_seq switch_body_seq = NULL;
    2921        50872 :   enum gimplify_status ret;
    2922        50872 :   tree index_type = TREE_TYPE (switch_expr);
    2923        50872 :   if (index_type == NULL_TREE)
    2924        11450 :     index_type = TREE_TYPE (SWITCH_COND (switch_expr));
    2925              : 
    2926        50872 :   ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
    2927              :                        fb_rvalue);
    2928        50872 :   if (ret == GS_ERROR || ret == GS_UNHANDLED)
    2929              :     return ret;
    2930              : 
    2931        50872 :   if (SWITCH_BODY (switch_expr))
    2932              :     {
    2933        50872 :       vec<tree> labels;
    2934        50872 :       vec<tree> saved_labels;
    2935        50872 :       hash_set<tree> *saved_live_switch_vars = NULL;
    2936        50872 :       tree default_case = NULL_TREE;
    2937        50872 :       gswitch *switch_stmt;
    2938              : 
    2939              :       /* Save old labels, get new ones from body, then restore the old
    2940              :          labels.  Save all the things from the switch body to append after.  */
    2941        50872 :       saved_labels = gimplify_ctxp->case_labels;
    2942        50872 :       gimplify_ctxp->case_labels.create (8);
    2943              : 
    2944              :       /* Do not create live_switch_vars if SWITCH_BODY is not a BIND_EXPR.  */
    2945        50872 :       saved_live_switch_vars = gimplify_ctxp->live_switch_vars;
    2946        50872 :       tree_code body_type = TREE_CODE (SWITCH_BODY (switch_expr));
    2947        50872 :       if (body_type == BIND_EXPR || body_type == STATEMENT_LIST)
    2948        50588 :         gimplify_ctxp->live_switch_vars = new hash_set<tree> (4);
    2949              :       else
    2950          284 :         gimplify_ctxp->live_switch_vars = NULL;
    2951              : 
    2952        50872 :       bool old_in_switch_expr = gimplify_ctxp->in_switch_expr;
    2953        50872 :       gimplify_ctxp->in_switch_expr = true;
    2954              : 
    2955        50872 :       gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
    2956              : 
    2957        50872 :       gimplify_ctxp->in_switch_expr = old_in_switch_expr;
    2958        50872 :       maybe_warn_switch_unreachable_and_auto_init (switch_body_seq);
    2959        50872 :       maybe_warn_implicit_fallthrough (switch_body_seq);
    2960              :       /* Only do this for the outermost GIMPLE_SWITCH.  */
    2961        50872 :       if (!gimplify_ctxp->in_switch_expr)
    2962        49043 :         expand_FALLTHROUGH (&switch_body_seq);
    2963              : 
    2964        50872 :       labels = gimplify_ctxp->case_labels;
    2965        50872 :       gimplify_ctxp->case_labels = saved_labels;
    2966              : 
    2967        50872 :       if (gimplify_ctxp->live_switch_vars)
    2968              :         {
    2969        50588 :           gcc_assert (gimplify_ctxp->live_switch_vars->is_empty ());
    2970        50588 :           delete gimplify_ctxp->live_switch_vars;
    2971              :         }
    2972        50872 :       gimplify_ctxp->live_switch_vars = saved_live_switch_vars;
    2973              : 
    2974        50872 :       preprocess_case_label_vec_for_gimple (labels, index_type,
    2975              :                                             &default_case);
    2976              : 
    2977        50872 :       bool add_bind = false;
    2978        50872 :       if (!default_case)
    2979              :         {
    2980        15033 :           glabel *new_default;
    2981              : 
    2982        15033 :           default_case
    2983        15033 :             = build_case_label (NULL_TREE, NULL_TREE,
    2984              :                                 create_artificial_label (UNKNOWN_LOCATION));
    2985        15033 :           if (old_in_switch_expr)
    2986              :             {
    2987         1083 :               SWITCH_BREAK_LABEL_P (CASE_LABEL (default_case)) = 1;
    2988         1083 :               add_bind = true;
    2989              :             }
    2990        15033 :           new_default = gimple_build_label (CASE_LABEL (default_case));
    2991        15033 :           gimplify_seq_add_stmt (&switch_body_seq, new_default);
    2992              :         }
    2993        35839 :       else if (old_in_switch_expr)
    2994              :         {
    2995          746 :           gimple *last = gimple_seq_last_stmt (switch_body_seq);
    2996          746 :           if (last && gimple_code (last) == GIMPLE_LABEL)
    2997              :             {
    2998          481 :               tree label = gimple_label_label (as_a <glabel *> (last));
    2999          481 :               if (SWITCH_BREAK_LABEL_P (label))
    3000        50872 :                 add_bind = true;
    3001              :             }
    3002              :         }
    3003              : 
    3004        50872 :       switch_stmt = gimple_build_switch (SWITCH_COND (switch_expr),
    3005              :                                          default_case, labels);
    3006        50872 :       gimple_set_location (switch_stmt, EXPR_LOCATION (switch_expr));
    3007              :       /* For the benefit of -Wimplicit-fallthrough, if switch_body_seq
    3008              :          ends with a GIMPLE_LABEL holding SWITCH_BREAK_LABEL_P LABEL_DECL,
    3009              :          wrap the GIMPLE_SWITCH up to that GIMPLE_LABEL into a GIMPLE_BIND,
    3010              :          so that we can easily find the start and end of the switch
    3011              :          statement.  */
    3012        50872 :       if (add_bind)
    3013              :         {
    3014         1563 :           gimple_seq bind_body = NULL;
    3015         1563 :           gimplify_seq_add_stmt (&bind_body, switch_stmt);
    3016         1563 :           gimple_seq_add_seq (&bind_body, switch_body_seq);
    3017         1563 :           gbind *bind = gimple_build_bind (NULL_TREE, bind_body, NULL_TREE);
    3018         1563 :           gimple_set_location (bind, EXPR_LOCATION (switch_expr));
    3019         1563 :           gimplify_seq_add_stmt (pre_p, bind);
    3020              :         }
    3021              :       else
    3022              :         {
    3023        49309 :           gimplify_seq_add_stmt (pre_p, switch_stmt);
    3024        49309 :           gimplify_seq_add_seq (pre_p, switch_body_seq);
    3025              :         }
    3026        50872 :       labels.release ();
    3027              :     }
    3028              :   else
    3029            0 :     gcc_unreachable ();
    3030              : 
    3031        50872 :   return GS_ALL_DONE;
    3032              : }
    3033              : 
    3034              : /* Gimplify the LABEL_EXPR pointed to by EXPR_P.  */
    3035              : 
    3036              : static enum gimplify_status
    3037      2617976 : gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
    3038              : {
    3039      2617976 :   gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
    3040              :               == current_function_decl);
    3041              : 
    3042      2617976 :   tree label = LABEL_EXPR_LABEL (*expr_p);
    3043      2617976 :   glabel *label_stmt = gimple_build_label (label);
    3044      2617976 :   gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
    3045      2617976 :   gimplify_seq_add_stmt (pre_p, label_stmt);
    3046              : 
    3047      2617976 :   if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
    3048           21 :     gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
    3049              :                                                       NOT_TAKEN));
    3050      2617955 :   else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
    3051           11 :     gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
    3052              :                                                       TAKEN));
    3053              : 
    3054      2617976 :   return GS_ALL_DONE;
    3055              : }
    3056              : 
    3057              : /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P.  */
    3058              : 
    3059              : static enum gimplify_status
    3060      1045379 : gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
    3061              : {
    3062      1045379 :   struct gimplify_ctx *ctxp;
    3063      1045379 :   glabel *label_stmt;
    3064              : 
    3065              :   /* Invalid programs can play Duff's Device type games with, for example,
    3066              :      #pragma omp parallel.  At least in the C front end, we don't
    3067              :      detect such invalid branches until after gimplification, in the
    3068              :      diagnose_omp_blocks pass.  */
    3069      1045389 :   for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
    3070      1045389 :     if (ctxp->case_labels.exists ())
    3071              :       break;
    3072              : 
    3073      1045379 :   tree label = CASE_LABEL (*expr_p);
    3074      1045379 :   label_stmt = gimple_build_label (label);
    3075      1045379 :   gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
    3076      1045379 :   ctxp->case_labels.safe_push (*expr_p);
    3077      1045379 :   gimplify_seq_add_stmt (pre_p, label_stmt);
    3078              : 
    3079      1045379 :   if (lookup_attribute ("cold", DECL_ATTRIBUTES (label)))
    3080           16 :     gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_COLD_LABEL,
    3081              :                                                       NOT_TAKEN));
    3082      1045363 :   else if (lookup_attribute ("hot", DECL_ATTRIBUTES (label)))
    3083           20 :     gimple_seq_add_stmt (pre_p, gimple_build_predict (PRED_HOT_LABEL,
    3084              :                                                       TAKEN));
    3085              : 
    3086      1045379 :   return GS_ALL_DONE;
    3087              : }
    3088              : 
    3089              : /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
    3090              :    if necessary.  */
    3091              : 
    3092              : tree
    3093      1807717 : build_and_jump (tree *label_p)
    3094              : {
    3095      1807717 :   if (label_p == NULL)
    3096              :     /* If there's nowhere to jump, just fall through.  */
    3097              :     return NULL_TREE;
    3098              : 
    3099      1225447 :   if (*label_p == NULL_TREE)
    3100              :     {
    3101       702348 :       tree label = create_artificial_label (UNKNOWN_LOCATION);
    3102       702348 :       *label_p = label;
    3103              :     }
    3104              : 
    3105      1225447 :   return build1 (GOTO_EXPR, void_type_node, *label_p);
    3106              : }
    3107              : 
    3108              : /* Gimplify an EXIT_EXPR by converting to a GOTO_EXPR inside a COND_EXPR.
    3109              :    This also involves building a label to jump to and communicating it to
    3110              :    gimplify_loop_expr through gimplify_ctxp->exit_label.  */
    3111              : 
    3112              : static enum gimplify_status
    3113         3207 : gimplify_exit_expr (tree *expr_p)
    3114              : {
    3115         3207 :   tree cond = TREE_OPERAND (*expr_p, 0);
    3116         3207 :   tree expr;
    3117              : 
    3118         3207 :   expr = build_and_jump (&gimplify_ctxp->exit_label);
    3119         3207 :   expr = build3 (COND_EXPR, void_type_node, cond, expr, NULL_TREE);
    3120         3207 :   *expr_p = expr;
    3121              : 
    3122         3207 :   return GS_OK;
    3123              : }
    3124              : 
    3125              : /* *EXPR_P is a COMPONENT_REF being used as an rvalue.  If its type is
    3126              :    different from its canonical type, wrap the whole thing inside a
    3127              :    NOP_EXPR and force the type of the COMPONENT_REF to be the canonical
    3128              :    type.
    3129              : 
    3130              :    The canonical type of a COMPONENT_REF is the type of the field being
    3131              :    referenced--unless the field is a bit-field which can be read directly
    3132              :    in a smaller mode, in which case the canonical type is the
    3133              :    sign-appropriate type corresponding to that mode.  */
    3134              : 
    3135              : static void
    3136     19108266 : canonicalize_component_ref (tree *expr_p)
    3137              : {
    3138     19108266 :   tree expr = *expr_p;
    3139     19108266 :   tree type;
    3140              : 
    3141     19108266 :   gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
    3142              : 
    3143     19108266 :   if (INTEGRAL_TYPE_P (TREE_TYPE (expr)))
    3144      7653063 :     type = TREE_TYPE (get_unwidened (expr, NULL_TREE));
    3145              :   else
    3146     11455203 :     type = TREE_TYPE (TREE_OPERAND (expr, 1));
    3147              : 
    3148              :   /* One could argue that all the stuff below is not necessary for
    3149              :      the non-bitfield case and declare it a FE error if type
    3150              :      adjustment would be needed.  */
    3151     19108266 :   if (TREE_TYPE (expr) != type)
    3152              :     {
    3153              : #ifdef ENABLE_TYPES_CHECKING
    3154       821060 :       tree old_type = TREE_TYPE (expr);
    3155              : #endif
    3156       821060 :       int type_quals;
    3157              : 
    3158              :       /* We need to preserve qualifiers and propagate them from
    3159              :          operand 0.  */
    3160       821060 :       type_quals = TYPE_QUALS (type)
    3161       821060 :         | TYPE_QUALS (TREE_TYPE (TREE_OPERAND (expr, 0)));
    3162       821060 :       if (TYPE_QUALS (type) != type_quals)
    3163       820803 :         type = build_qualified_type (TYPE_MAIN_VARIANT (type), type_quals);
    3164              : 
    3165              :       /* Set the type of the COMPONENT_REF to the underlying type.  */
    3166       821060 :       TREE_TYPE (expr) = type;
    3167              : 
    3168              : #ifdef ENABLE_TYPES_CHECKING
    3169              :       /* It is now a FE error, if the conversion from the canonical
    3170              :          type to the original expression type is not useless.  */
    3171       821060 :       gcc_assert (useless_type_conversion_p (old_type, type));
    3172              : #endif
    3173              :     }
    3174     19108266 : }
    3175              : 
    3176              : /* If a NOP conversion is changing a pointer to array of foo to a pointer
    3177              :    to foo, embed that change in the ADDR_EXPR by converting
    3178              :       T array[U];
    3179              :       (T *)&array
    3180              :    ==>
    3181              :       &array[L]
    3182              :    where L is the lower bound.  For simplicity, only do this for constant
    3183              :    lower bound.
    3184              :    The constraint is that the type of &array[L] is trivially convertible
    3185              :    to T *.  */
    3186              : 
    3187              : static void
    3188       565737 : canonicalize_addr_expr (tree *expr_p)
    3189              : {
    3190       565737 :   tree expr = *expr_p;
    3191       565737 :   tree addr_expr = TREE_OPERAND (expr, 0);
    3192       565737 :   tree datype, ddatype, pddatype;
    3193              : 
    3194              :   /* We simplify only conversions from an ADDR_EXPR to a pointer type.  */
    3195      1131128 :   if (!POINTER_TYPE_P (TREE_TYPE (expr))
    3196       565737 :       || TREE_CODE (addr_expr) != ADDR_EXPR)
    3197              :     return;
    3198              : 
    3199              :   /* The addr_expr type should be a pointer to an array.  */
    3200          346 :   datype = TREE_TYPE (TREE_TYPE (addr_expr));
    3201          346 :   if (TREE_CODE (datype) != ARRAY_TYPE)
    3202              :     return;
    3203              : 
    3204              :   /* The pointer to element type shall be trivially convertible to
    3205              :      the expression pointer type.  */
    3206           28 :   ddatype = TREE_TYPE (datype);
    3207           28 :   pddatype = build_pointer_type (ddatype);
    3208           28 :   if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)),
    3209              :                                   pddatype))
    3210              :     return;
    3211              : 
    3212              :   /* The lower bound and element sizes must be constant.  */
    3213            0 :   if (!TYPE_SIZE_UNIT (ddatype)
    3214            0 :       || TREE_CODE (TYPE_SIZE_UNIT (ddatype)) != INTEGER_CST
    3215            0 :       || !TYPE_DOMAIN (datype) || !TYPE_MIN_VALUE (TYPE_DOMAIN (datype))
    3216            0 :       || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (datype))) != INTEGER_CST)
    3217              :     return;
    3218              : 
    3219              :   /* All checks succeeded.  Build a new node to merge the cast.  */
    3220            0 :   *expr_p = build4 (ARRAY_REF, ddatype, TREE_OPERAND (addr_expr, 0),
    3221            0 :                     TYPE_MIN_VALUE (TYPE_DOMAIN (datype)),
    3222              :                     NULL_TREE, NULL_TREE);
    3223            0 :   *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p);
    3224              : 
    3225              :   /* We can have stripped a required restrict qualifier above.  */
    3226            0 :   if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
    3227            0 :     *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
    3228              : }
    3229              : 
    3230              : /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR.  Remove it and/or other conversions
    3231              :    underneath as appropriate.  */
    3232              : 
    3233              : static enum gimplify_status
    3234     13268342 : gimplify_conversion (tree *expr_p)
    3235              : {
    3236     13268342 :   location_t loc = EXPR_LOCATION (*expr_p);
    3237     13268342 :   gcc_assert (CONVERT_EXPR_P (*expr_p));
    3238              : 
    3239              :   /* Then strip away all but the outermost conversion.  */
    3240     13268342 :   STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
    3241              : 
    3242              :   /* And remove the outermost conversion if it's useless.  */
    3243     13268342 :   if (tree_ssa_useless_type_conversion (*expr_p))
    3244            0 :     *expr_p = TREE_OPERAND (*expr_p, 0);
    3245              : 
    3246              :   /* If we still have a conversion at the toplevel,
    3247              :      then canonicalize some constructs.  */
    3248     13268342 :   if (CONVERT_EXPR_P (*expr_p))
    3249              :     {
    3250     13268342 :       tree sub = TREE_OPERAND (*expr_p, 0);
    3251              : 
    3252              :       /* If a NOP conversion is changing the type of a COMPONENT_REF
    3253              :          expression, then canonicalize its type now in order to expose more
    3254              :          redundant conversions.  */
    3255     13268342 :       if (TREE_CODE (sub) == COMPONENT_REF)
    3256       277497 :         canonicalize_component_ref (&TREE_OPERAND (*expr_p, 0));
    3257              : 
    3258              :       /* If a NOP conversion is changing a pointer to array of foo
    3259              :          to a pointer to foo, embed that change in the ADDR_EXPR.  */
    3260     12990845 :       else if (TREE_CODE (sub) == ADDR_EXPR)
    3261       565737 :         canonicalize_addr_expr (expr_p);
    3262              :     }
    3263              : 
    3264              :   /* If we have a conversion to a non-register type force the
    3265              :      use of a VIEW_CONVERT_EXPR instead.  */
    3266     13268342 :   if (CONVERT_EXPR_P (*expr_p) && !is_gimple_reg_type (TREE_TYPE (*expr_p)))
    3267           90 :     *expr_p = fold_build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p),
    3268           90 :                                TREE_OPERAND (*expr_p, 0));
    3269              : 
    3270              :   /* Canonicalize CONVERT_EXPR to NOP_EXPR.  */
    3271     13268342 :   if (TREE_CODE (*expr_p) == CONVERT_EXPR)
    3272       233882 :     TREE_SET_CODE (*expr_p, NOP_EXPR);
    3273              : 
    3274     13268342 :   return GS_OK;
    3275              : }
    3276              : 
    3277              : /* Gimplify a VAR_DECL or PARM_DECL.  Return GS_OK if we expanded a
    3278              :    DECL_VALUE_EXPR, and it's worth re-examining things.  */
    3279              : 
    3280              : static enum gimplify_status
    3281    130635419 : gimplify_var_or_parm_decl (tree *expr_p)
    3282              : {
    3283    130635419 :   tree decl = *expr_p;
    3284              : 
    3285              :   /* ??? If this is a local variable, and it has not been seen in any
    3286              :      outer BIND_EXPR, then it's probably the result of a duplicate
    3287              :      declaration, for which we've already issued an error.  It would
    3288              :      be really nice if the front end wouldn't leak these at all.
    3289              :      Currently the only known culprit is C++ destructors, as seen
    3290              :      in g++.old-deja/g++.jason/binding.C.
    3291              :      Another possible culpit are size expressions for variably modified
    3292              :      types which are lost in the FE or not gimplified correctly.  */
    3293    130635419 :   if (VAR_P (decl)
    3294    101534234 :       && !DECL_SEEN_IN_BIND_EXPR_P (decl)
    3295     17312919 :       && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)
    3296    130695515 :       && decl_function_context (decl) == current_function_decl)
    3297              :     {
    3298           77 :       gcc_assert (seen_error ());
    3299              :       return GS_ERROR;
    3300              :     }
    3301              : 
    3302              :   /* When within an OMP context, notice uses of variables.  */
    3303    130635342 :   if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
    3304              :     return GS_ALL_DONE;
    3305              : 
    3306              :   /* If the decl is an alias for another expression, substitute it now.  */
    3307    130629522 :   if (DECL_HAS_VALUE_EXPR_P (decl))
    3308              :     {
    3309       462288 :       *expr_p = unshare_expr (DECL_VALUE_EXPR (decl));
    3310       462288 :       return GS_OK;
    3311              :     }
    3312              : 
    3313              :   return GS_ALL_DONE;
    3314              : }
    3315              : 
    3316              : /* Recalculate the value of the TREE_SIDE_EFFECTS flag for T.  */
    3317              : 
    3318              : static void
    3319    113589841 : recalculate_side_effects (tree t)
    3320              : {
    3321    113589841 :   enum tree_code code = TREE_CODE (t);
    3322    113589841 :   int len = TREE_OPERAND_LENGTH (t);
    3323    113589841 :   int i;
    3324              : 
    3325    113589841 :   switch (TREE_CODE_CLASS (code))
    3326              :     {
    3327       674165 :     case tcc_expression:
    3328       674165 :       switch (code)
    3329              :         {
    3330              :         case INIT_EXPR:
    3331              :         case MODIFY_EXPR:
    3332              :         case VA_ARG_EXPR:
    3333              :         case PREDECREMENT_EXPR:
    3334              :         case PREINCREMENT_EXPR:
    3335              :         case POSTDECREMENT_EXPR:
    3336              :         case POSTINCREMENT_EXPR:
    3337              :           /* All of these have side-effects, no matter what their
    3338              :              operands are.  */
    3339              :           return;
    3340              : 
    3341              :         default:
    3342              :           break;
    3343              :         }
    3344              :       /* Fall through.  */
    3345              : 
    3346    113589837 :     case tcc_comparison:  /* a comparison expression */
    3347    113589837 :     case tcc_unary:       /* a unary arithmetic expression */
    3348    113589837 :     case tcc_binary:      /* a binary arithmetic expression */
    3349    113589837 :     case tcc_reference:   /* a reference */
    3350    113589837 :     case tcc_vl_exp:        /* a function call */
    3351    113589837 :       TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
    3352    369976083 :       for (i = 0; i < len; ++i)
    3353              :         {
    3354    256386246 :           tree op = TREE_OPERAND (t, i);
    3355    256386246 :           if (op && TREE_SIDE_EFFECTS (op))
    3356      1305206 :             TREE_SIDE_EFFECTS (t) = 1;
    3357              :         }
    3358              :       break;
    3359              : 
    3360              :     case tcc_constant:
    3361              :       /* No side-effects.  */
    3362              :       return;
    3363              : 
    3364              :     case tcc_declaration:
    3365              :       /* These can have side-effects if TREE_THIS_VOLATILE,
    3366              :          but those should be set elsewhere, not in
    3367              :          recalculate_side_effects.  Can be triggered e.g. if
    3368              :          a comparison is folded into one of its operands.  */
    3369              :       return;
    3370              : 
    3371            2 :     default:
    3372            2 :       if (code == SSA_NAME)
    3373              :         /* No side-effects.  */
    3374              :         return;
    3375            0 :       gcc_unreachable ();
    3376              :    }
    3377              : }
    3378              : 
    3379              : /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
    3380              :    node *EXPR_P.
    3381              : 
    3382              :       compound_lval
    3383              :               : min_lval '[' val ']'
    3384              :               | min_lval '.' ID
    3385              :               | compound_lval '[' val ']'
    3386              :               | compound_lval '.' ID
    3387              : 
    3388              :    This is not part of the original SIMPLE definition, which separates
    3389              :    array and member references, but it seems reasonable to handle them
    3390              :    together.  Also, this way we don't run into problems with union
    3391              :    aliasing; gcc requires that for accesses through a union to alias, the
    3392              :    union reference must be explicit, which was not always the case when we
    3393              :    were splitting up array and member refs.
    3394              : 
    3395              :    PRE_P points to the sequence where side effects that must happen before
    3396              :      *EXPR_P should be stored.
    3397              : 
    3398              :    POST_P points to the sequence where side effects that must happen after
    3399              :      *EXPR_P should be stored.  */
    3400              : 
    3401              : static enum gimplify_status
    3402     30901455 : gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
    3403              :                         fallback_t fallback)
    3404              : {
    3405     30901455 :   tree *p;
    3406     30901455 :   enum gimplify_status ret = GS_ALL_DONE, tret;
    3407     30901455 :   int i;
    3408     30901455 :   location_t loc = EXPR_LOCATION (*expr_p);
    3409     30901455 :   tree expr = *expr_p;
    3410              : 
    3411              :   /* Create a stack of the subexpressions so later we can walk them in
    3412              :      order from inner to outer.  */
    3413     30901455 :   auto_vec<tree, 10> expr_stack;
    3414              : 
    3415              :   /* We can handle anything that get_inner_reference can deal with.  */
    3416     74550668 :   for (p = expr_p; ; p = &TREE_OPERAND (*p, 0))
    3417              :     {
    3418     43715330 :     restart:
    3419              :       /* Fold INDIRECT_REFs now to turn them into ARRAY_REFs.  */
    3420     74616785 :       if (TREE_CODE (*p) == INDIRECT_REF)
    3421      4101599 :         *p = fold_indirect_ref_loc (loc, *p);
    3422              : 
    3423     74616785 :       if (handled_component_p (*p))
    3424              :         ;
    3425              :       /* Expand DECL_VALUE_EXPR now.  In some cases that may expose
    3426              :          additional COMPONENT_REFs.  */
    3427     13705662 :       else if ((VAR_P (*p) || TREE_CODE (*p) == PARM_DECL)
    3428     32419201 :                && gimplify_var_or_parm_decl (p) == GS_OK)
    3429        66117 :         goto restart;
    3430              :       else
    3431              :         break;
    3432              : 
    3433     43649213 :       expr_stack.safe_push (*p);
    3434              :     }
    3435              : 
    3436     30901455 :   gcc_assert (expr_stack.length ());
    3437              : 
    3438              :   /* Now EXPR_STACK is a stack of pointers to all the refs we've
    3439              :      walked through and P points to the innermost expression.
    3440              : 
    3441              :      Java requires that we elaborated nodes in source order.  That
    3442              :      means we must gimplify the inner expression followed by each of
    3443              :      the indices, in order.  But we can't gimplify the inner
    3444              :      expression until we deal with any variable bounds, sizes, or
    3445              :      positions in order to deal with PLACEHOLDER_EXPRs.
    3446              : 
    3447              :      The base expression may contain a statement expression that
    3448              :      has declarations used in size expressions, so has to be
    3449              :      gimplified before gimplifying the size expressions.
    3450              : 
    3451              :      So we do this in three steps.  First we deal with variable
    3452              :      bounds, sizes, and positions, then we gimplify the base and
    3453              :      ensure it is memory if needed, then we deal with the annotations
    3454              :      for any variables in the components and any indices, from left
    3455              :      to right.  */
    3456              : 
    3457     30901455 :   bool need_non_reg = false;
    3458     74550665 :   for (i = expr_stack.length () - 1; i >= 0; i--)
    3459              :     {
    3460     43649213 :       tree t = expr_stack[i];
    3461              : 
    3462     43649213 :       if (error_operand_p (TREE_OPERAND (t, 0)))
    3463              :         return GS_ERROR;
    3464              : 
    3465     43649210 :       if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
    3466              :         {
    3467              :           /* Deal with the low bound and element type size and put them into
    3468              :              the ARRAY_REF.  If these values are set, they have already been
    3469              :              gimplified.  */
    3470      9090779 :           if (TREE_OPERAND (t, 2) == NULL_TREE)
    3471              :             {
    3472      9026473 :               tree low = unshare_expr (array_ref_low_bound (t));
    3473      9026473 :               if (!is_gimple_min_invariant (low))
    3474              :                 {
    3475            0 :                   TREE_OPERAND (t, 2) = low;
    3476              :                 }
    3477              :             }
    3478              : 
    3479      9090779 :           if (TREE_OPERAND (t, 3) == NULL_TREE)
    3480              :             {
    3481      9076724 :               tree elmt_size = array_ref_element_size (t);
    3482      9076724 :               if (!is_gimple_min_invariant (elmt_size))
    3483              :                 {
    3484         8781 :                   elmt_size = unshare_expr (elmt_size);
    3485         8781 :                   tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0)));
    3486         8781 :                   tree factor = size_int (TYPE_ALIGN_UNIT (elmt_type));
    3487              : 
    3488              :                   /* Divide the element size by the alignment of the element
    3489              :                      type (above).  */
    3490         8781 :                   elmt_size = size_binop_loc (loc, EXACT_DIV_EXPR,
    3491              :                                               elmt_size, factor);
    3492              : 
    3493         8781 :                   TREE_OPERAND (t, 3) = elmt_size;
    3494              :                 }
    3495              :             }
    3496              :           need_non_reg = true;
    3497              :         }
    3498     34558431 :       else if (TREE_CODE (t) == COMPONENT_REF)
    3499              :         {
    3500              :           /* Set the field offset into T and gimplify it.  */
    3501     33245142 :           if (TREE_OPERAND (t, 2) == NULL_TREE)
    3502              :             {
    3503     33244763 :               tree offset = component_ref_field_offset (t);
    3504     33244763 :               if (!is_gimple_min_invariant (offset))
    3505              :                 {
    3506          287 :                   offset = unshare_expr (offset);
    3507          287 :                   tree field = TREE_OPERAND (t, 1);
    3508          287 :                   tree factor
    3509          287 :                     = size_int (DECL_OFFSET_ALIGN (field) / BITS_PER_UNIT);
    3510              : 
    3511              :                   /* Divide the offset by its alignment.  */
    3512          287 :                   offset = size_binop_loc (loc, EXACT_DIV_EXPR,
    3513              :                                            offset, factor);
    3514              : 
    3515          287 :                   TREE_OPERAND (t, 2) = offset;
    3516              :                 }
    3517              :             }
    3518              :           need_non_reg = true;
    3519              :         }
    3520      1313289 :       else if (!is_gimple_reg_type (TREE_TYPE (t)))
    3521              :         /* When the result of an operation, in particular a VIEW_CONVERT_EXPR
    3522              :            is a non-register type then require the base object to be a
    3523              :            non-register as well.  */
    3524     42619989 :         need_non_reg = true;
    3525              :     }
    3526              : 
    3527              :   /* Step 2 is to gimplify the base expression.  Make sure lvalue is set
    3528              :      so as to match the min_lval predicate.  Failure to do so may result
    3529              :      in the creation of large aggregate temporaries.  */
    3530     30901452 :   tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
    3531              :                         fallback | fb_lvalue);
    3532     30901452 :   ret = MIN (ret, tret);
    3533     30901452 :   if (ret == GS_ERROR)
    3534              :     return GS_ERROR;
    3535              : 
    3536              :   /* Step 2a: if we have component references we do not support on
    3537              :      registers then make sure the base isn't a register.  Of course
    3538              :      we can only do so if an rvalue is OK.  */
    3539     30901452 :   if (need_non_reg && (fallback & fb_rvalue))
    3540     23042598 :     prepare_gimple_addressable (p, pre_p);
    3541              : 
    3542              : 
    3543              :   /* Step 3: gimplify size expressions and the indices and operands of
    3544              :      ARRAY_REF.  During this loop we also remove any useless conversions.
    3545              :      If we operate on a register also make sure to properly gimplify
    3546              :      to individual operations.  */
    3547              : 
    3548     30901452 :   bool reg_operations = is_gimple_reg (*p);
    3549    105452114 :   for (; expr_stack.length () > 0; )
    3550              :     {
    3551     43649210 :       tree t = expr_stack.pop ();
    3552              : 
    3553     43649210 :       if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
    3554              :         {
    3555      9090779 :           gcc_assert (!reg_operations);
    3556              : 
    3557              :           /* Gimplify the low bound and element type size. */
    3558      9090779 :           tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
    3559              :                                 is_gimple_reg, fb_rvalue);
    3560      9090779 :           ret = MIN (ret, tret);
    3561              : 
    3562      9090779 :           tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
    3563              :                                 is_gimple_reg, fb_rvalue);
    3564      9090779 :           ret = MIN (ret, tret);
    3565              : 
    3566              :           /* Gimplify the dimension.  */
    3567      9090779 :           tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
    3568              :                                 is_gimple_val, fb_rvalue);
    3569      9090779 :           ret = MIN (ret, tret);
    3570              :         }
    3571     34558431 :       else if (TREE_CODE (t) == COMPONENT_REF)
    3572              :         {
    3573     33245142 :           gcc_assert (!reg_operations);
    3574              : 
    3575     33245142 :           tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
    3576              :                                 is_gimple_reg, fb_rvalue);
    3577     33245142 :           ret = MIN (ret, tret);
    3578              :         }
    3579      1313289 :       else if (reg_operations)
    3580              :         {
    3581       910330 :           tret = gimplify_expr (&TREE_OPERAND (t, 0), pre_p, post_p,
    3582              :                                 is_gimple_val, fb_rvalue);
    3583      1313289 :           ret = MIN (ret, tret);
    3584              :         }
    3585              : 
    3586     43649210 :       STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
    3587              : 
    3588              :       /* The innermost expression P may have originally had
    3589              :          TREE_SIDE_EFFECTS set which would have caused all the outer
    3590              :          expressions in *EXPR_P leading to P to also have had
    3591              :          TREE_SIDE_EFFECTS set.  */
    3592     43649210 :       recalculate_side_effects (t);
    3593              :     }
    3594              : 
    3595              :   /* If the outermost expression is a COMPONENT_REF, canonicalize its type.  */
    3596     30901452 :   if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
    3597              :     {
    3598     18830769 :       canonicalize_component_ref (expr_p);
    3599              :     }
    3600              : 
    3601     30901452 :   expr_stack.release ();
    3602              : 
    3603     30901452 :   gcc_assert (*expr_p == expr || ret != GS_ALL_DONE);
    3604              : 
    3605              :   return ret;
    3606     30901455 : }
    3607              : 
    3608              : /*  Gimplify the self modifying expression pointed to by EXPR_P
    3609              :     (++, --, +=, -=).
    3610              : 
    3611              :     PRE_P points to the list where side effects that must happen before
    3612              :         *EXPR_P should be stored.
    3613              : 
    3614              :     POST_P points to the list where side effects that must happen after
    3615              :         *EXPR_P should be stored.
    3616              : 
    3617              :     WANT_VALUE is nonzero iff we want to use the value of this expression
    3618              :         in another expression.
    3619              : 
    3620              :     ARITH_TYPE is the type the computation should be performed in.  */
    3621              : 
    3622              : enum gimplify_status
    3623      1153529 : gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
    3624              :                         bool want_value, tree arith_type)
    3625              : {
    3626      1153529 :   enum tree_code code;
    3627      1153529 :   tree lhs, lvalue, rhs, t1;
    3628      1153529 :   gimple_seq post = NULL, *orig_post_p = post_p;
    3629      1153529 :   bool postfix;
    3630      1153529 :   enum tree_code arith_code;
    3631      1153529 :   enum gimplify_status ret;
    3632      1153529 :   location_t loc = EXPR_LOCATION (*expr_p);
    3633              : 
    3634      1153529 :   code = TREE_CODE (*expr_p);
    3635              : 
    3636      1153529 :   gcc_assert (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR
    3637              :               || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR);
    3638              : 
    3639              :   /* Prefix or postfix?  */
    3640      1153529 :   if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
    3641              :     /* Faster to treat as prefix if result is not used.  */
    3642              :     postfix = want_value;
    3643              :   else
    3644              :     postfix = false;
    3645              : 
    3646              :   /* For postfix, make sure the inner expression's post side effects
    3647              :      are executed after side effects from this expression.  */
    3648       410986 :   if (postfix)
    3649      1153529 :     post_p = &post;
    3650              : 
    3651              :   /* Add or subtract?  */
    3652      1153529 :   if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
    3653              :     arith_code = PLUS_EXPR;
    3654              :   else
    3655        46130 :     arith_code = MINUS_EXPR;
    3656              : 
    3657              :   /* Gimplify the LHS into a GIMPLE lvalue.  */
    3658      1153529 :   lvalue = TREE_OPERAND (*expr_p, 0);
    3659      1153529 :   ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
    3660      1153529 :   if (ret == GS_ERROR)
    3661              :     return ret;
    3662              : 
    3663              :   /* Extract the operands to the arithmetic operation.  */
    3664      1153526 :   lhs = lvalue;
    3665      1153526 :   rhs = TREE_OPERAND (*expr_p, 1);
    3666              : 
    3667              :   /* For postfix operator, we evaluate the LHS to an rvalue and then use
    3668              :      that as the result value and in the postqueue operation.  */
    3669      1153526 :   if (postfix)
    3670              :     {
    3671       189173 :       ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
    3672       189173 :       if (ret == GS_ERROR)
    3673              :         return ret;
    3674              : 
    3675       189173 :       lhs = get_initialized_tmp_var (lhs, pre_p);
    3676              :     }
    3677              : 
    3678              :   /* For POINTERs increment, use POINTER_PLUS_EXPR.  */
    3679      1153526 :   if (POINTER_TYPE_P (TREE_TYPE (lhs)))
    3680              :     {
    3681       238862 :       rhs = convert_to_ptrofftype_loc (loc, rhs);
    3682       238862 :       if (arith_code == MINUS_EXPR)
    3683        10281 :         rhs = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (rhs), rhs);
    3684       238862 :       t1 = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (*expr_p), lhs, rhs);
    3685              :     }
    3686              :   else
    3687       914664 :     t1 = fold_convert (TREE_TYPE (*expr_p),
    3688              :                        fold_build2 (arith_code, arith_type,
    3689              :                                     fold_convert (arith_type, lhs),
    3690              :                                     fold_convert (arith_type, rhs)));
    3691              : 
    3692      1153526 :   if (postfix)
    3693              :     {
    3694       189173 :       gimplify_assign (lvalue, t1, pre_p);
    3695       189173 :       gimplify_seq_add_seq (orig_post_p, post);
    3696       189173 :       *expr_p = lhs;
    3697       189173 :       return GS_ALL_DONE;
    3698              :     }
    3699              :   else
    3700              :     {
    3701       964353 :       *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
    3702       964353 :       return GS_OK;
    3703              :     }
    3704              : }
    3705              : 
    3706              : /* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR.  */
    3707              : 
    3708              : static void
    3709     83977124 : maybe_with_size_expr (tree *expr_p)
    3710              : {
    3711     83977124 :   tree expr = *expr_p;
    3712     83977124 :   tree type = TREE_TYPE (expr);
    3713     83977124 :   tree size;
    3714              : 
    3715              :   /* If we've already wrapped this or the type is error_mark_node, we can't do
    3716              :      anything.  */
    3717     83977124 :   if (TREE_CODE (expr) == WITH_SIZE_EXPR
    3718     83976999 :       || type == error_mark_node)
    3719              :     return;
    3720              : 
    3721              :   /* If the size isn't known or is a constant, we have nothing to do.  */
    3722     83976851 :   size = TYPE_SIZE_UNIT (type);
    3723     83976851 :   if (!size || poly_int_tree_p (size))
    3724              :     return;
    3725              : 
    3726              :   /* Otherwise, make a WITH_SIZE_EXPR.  */
    3727         1698 :   size = unshare_expr (size);
    3728         1698 :   size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, expr);
    3729         1698 :   *expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
    3730              : }
    3731              : 
    3732              : /* Helper for gimplify_call_expr.  Gimplify a single argument *ARG_P
    3733              :    Store any side-effects in PRE_P.  CALL_LOCATION is the location of
    3734              :    the CALL_EXPR.  If ALLOW_SSA is set the actual parameter may be
    3735              :    gimplified to an SSA name.  */
    3736              : 
    3737              : enum gimplify_status
    3738     35209664 : gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
    3739              :               bool allow_ssa)
    3740              : {
    3741     35209664 :   bool (*test) (tree);
    3742     35209664 :   fallback_t fb;
    3743              : 
    3744              :   /* In general, we allow lvalues for function arguments to avoid
    3745              :      extra overhead of copying large aggregates out of even larger
    3746              :      aggregates into temporaries only to copy the temporaries to
    3747              :      the argument list.  Make optimizers happy by pulling out to
    3748              :      temporaries those types that fit in registers.  */
    3749     35209664 :   if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
    3750              :     test = is_gimple_val, fb = fb_rvalue;
    3751              :   else
    3752              :     {
    3753      1615204 :       test = is_gimple_lvalue, fb = fb_either;
    3754              :       /* Also strip a TARGET_EXPR that would force an extra copy.  */
    3755      1615204 :       if (TREE_CODE (*arg_p) == TARGET_EXPR)
    3756              :         {
    3757       335668 :           tree init = TARGET_EXPR_INITIAL (*arg_p);
    3758       335668 :           if (init
    3759       335665 :               && !VOID_TYPE_P (TREE_TYPE (init))
    3760              :               /* Currently, due to c++/116015, it is not desirable to
    3761              :                  strip a TARGET_EXPR whose initializer is a {}.  The
    3762              :                  problem is that if we do elide it, we also have to
    3763              :                  replace all the occurrences of the slot temporary in the
    3764              :                  initializer with the temporary created for the argument.
    3765              :                  But we do not have that temporary yet so the replacement
    3766              :                  would be quite awkward and it might be needed to resort
    3767              :                  back to a PLACEHOLDER_EXPR.  Note that stripping the
    3768              :                  TARGET_EXPR wouldn't help anyway, as gimplify_expr would
    3769              :                  just allocate a temporary to store the CONSTRUCTOR into.
    3770              :                  (FIXME PR116375.)
    3771              : 
    3772              :                  See convert_for_arg_passing for the C++ code that marks
    3773              :                  the TARGET_EXPR as eliding or not.  */
    3774       629082 :               && TREE_CODE (init) != CONSTRUCTOR)
    3775       254574 :             *arg_p = init;
    3776              :         }
    3777              :     }
    3778              : 
    3779              :   /* If this is a variable sized type, we must remember the size.  */
    3780     35209664 :   maybe_with_size_expr (arg_p);
    3781              : 
    3782              :   /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c.  */
    3783              :   /* Make sure arguments have the same location as the function call
    3784              :      itself.  */
    3785     35209664 :   protected_set_expr_location (*arg_p, call_location);
    3786              : 
    3787              :   /* There is a sequence point before a function call.  Side effects in
    3788              :      the argument list must occur before the actual call. So, when
    3789              :      gimplifying arguments, force gimplify_expr to use an internal
    3790              :      post queue which is then appended to the end of PRE_P.  */
    3791     35209664 :   return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
    3792              : }
    3793              : 
    3794              : /* Don't fold inside offloading or taskreg regions: it can break code by
    3795              :    adding decl references that weren't in the source.  We'll do it during
    3796              :    omplower pass instead.  */
    3797              : 
    3798              : static bool
    3799     60623209 : maybe_fold_stmt (gimple_stmt_iterator *gsi)
    3800              : {
    3801     60623209 :   struct gimplify_omp_ctx *ctx;
    3802     61152161 :   for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context)
    3803      1201063 :     if ((ctx->region_type & (ORT_TARGET | ORT_PARALLEL | ORT_TASK)) != 0)
    3804              :       return false;
    3805       533971 :     else if ((ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
    3806              :       return false;
    3807              :   /* Delay folding of builtins until the IL is in consistent state
    3808              :      so the diagnostic machinery can do a better job.  */
    3809     59951098 :   if (gimple_call_builtin_p (gsi_stmt (*gsi)))
    3810              :     return false;
    3811     57541304 :   return fold_stmt (gsi);
    3812              : }
    3813              : 
    3814              : static tree
    3815              : expand_late_variant_directive (vec<struct omp_variant> all_candidates,
    3816              :                                tree construct_context);
    3817              : 
    3818              : 
    3819              : /* Helper function for calls to omp_dynamic_cond: find the current
    3820              :    enclosing block in the gimplification context.  */
    3821              : static tree
    3822          369 : find_supercontext (void)
    3823              : {
    3824          369 :   vec<gbind *>stack = gimple_bind_expr_stack ();
    3825          706 :   for (int i = stack.length () - 1; i >= 0; i++)
    3826              :     {
    3827          337 :       gbind *b = stack[i];
    3828          337 :       if (b->block)
    3829              :         return b->block;
    3830              :     }
    3831              :   return NULL_TREE;
    3832              : }
    3833              : 
    3834              : /* OpenMP: Handle the append_args and adjust_args clauses of
    3835              :    declare_variant for EXPR, which is a CALL_EXPR whose CALL_EXPR_FN
    3836              :    is the variant, within a dispatch construct with clauses DISPATCH_CLAUSES.
    3837              :    WANT_VALUE and POINTERIZE are as for expand_variant_call_expr.
    3838              : 
    3839              :    'append_args' causes interop objects are added after the last regular
    3840              :    (nonhidden, nonvariadic) arguments of the variant function.
    3841              :    'adjust_args' with need_device_{addr,ptr} converts the pointer target of
    3842              :    a pointer from a host to a device address. This uses either the default
    3843              :    device or the passed device number, which then sets the default device
    3844              :    address.  */
    3845              : static tree
    3846          471 : modify_call_for_omp_dispatch (tree expr, tree dispatch_clauses,
    3847              :                               bool want_value, bool pointerize)
    3848              : {
    3849          471 :   location_t loc = EXPR_LOCATION (expr);
    3850          471 :   tree fndecl = get_callee_fndecl (expr);
    3851              : 
    3852              :   /* Skip processing if we don't get the expected call form.  */
    3853          471 :   if (!fndecl)
    3854              :     return expr;
    3855              : 
    3856          471 :   tree init_code = NULL_TREE;
    3857          471 :   tree cleanup = NULL_TREE;
    3858          471 :   tree clobbers = NULL_TREE;
    3859          471 :   int nargs = call_expr_nargs (expr);
    3860          471 :   tree dispatch_device_num = NULL_TREE;
    3861          471 :   tree dispatch_interop = NULL_TREE;
    3862          471 :   tree dispatch_append_args = NULL_TREE;
    3863          471 :   int nfirst_args = 0;
    3864          471 :   tree dispatch_adjust_args_list
    3865          471 :     = lookup_attribute ("omp declare variant variant args",
    3866          471 :                         DECL_ATTRIBUTES (fndecl));
    3867              : 
    3868          471 :   if (dispatch_adjust_args_list)
    3869              :     {
    3870          389 :       dispatch_adjust_args_list = TREE_VALUE (dispatch_adjust_args_list);
    3871          389 :       dispatch_append_args = TREE_CHAIN (dispatch_adjust_args_list);
    3872          389 :       if (TREE_PURPOSE (dispatch_adjust_args_list) == NULL_TREE
    3873          389 :           && TREE_VALUE (dispatch_adjust_args_list) == NULL_TREE)
    3874              :         dispatch_adjust_args_list = NULL_TREE;
    3875              :     }
    3876          389 :   if (dispatch_append_args)
    3877              :     {
    3878          245 :       nfirst_args = tree_to_shwi (TREE_PURPOSE (dispatch_append_args));
    3879          245 :       dispatch_append_args = TREE_VALUE (dispatch_append_args);
    3880              :     }
    3881          471 :   dispatch_device_num = omp_find_clause (dispatch_clauses, OMP_CLAUSE_DEVICE);
    3882          471 :   if (dispatch_device_num)
    3883          287 :     dispatch_device_num = OMP_CLAUSE_DEVICE_ID (dispatch_device_num);
    3884          471 :   dispatch_interop = omp_find_clause (dispatch_clauses, OMP_CLAUSE_INTEROP);
    3885          471 :   int nappend = 0, ninterop = 0;
    3886         1351 :   for (tree t = dispatch_append_args; t; t = TREE_CHAIN (t))
    3887          409 :     nappend++;
    3888              : 
    3889              :   /* FIXME: error checking should be taken out of this function and
    3890              :      handled before any attempt at filtering or resolution happens.
    3891              :      Otherwise whether or not diagnostics appear is determined by
    3892              :      GCC internals, how good the front ends are at constant-folding,
    3893              :      the split between early/late resolution, etc instead of the code
    3894              :      as written by the user.  */
    3895          471 :   if (dispatch_interop)
    3896          861 :     for (tree t = dispatch_interop; t; t = TREE_CHAIN (t))
    3897          605 :       if (OMP_CLAUSE_CODE (t) == OMP_CLAUSE_INTEROP)
    3898          409 :         ninterop++;
    3899          471 :   if (dispatch_interop && !dispatch_device_num)
    3900              :     {
    3901            7 :       gcc_checking_assert (ninterop > 1);
    3902            7 :       error_at (OMP_CLAUSE_LOCATION (dispatch_interop),
    3903              :                 "the %<device%> clause must be present if the %<interop%> "
    3904              :                 "clause has more than one list item");
    3905              :     }
    3906          471 :   if (nappend < ninterop)
    3907              :     {
    3908           48 :       error_at (OMP_CLAUSE_LOCATION (dispatch_interop),
    3909              :                 "number of list items in %<interop%> clause (%d) "
    3910              :                 "exceeds the number of %<append_args%> items (%d) for "
    3911              :                 "%<declare variant%> candidate %qD", ninterop, nappend, fndecl);
    3912           88 :       inform (dispatch_append_args
    3913            8 :               ? EXPR_LOCATION (TREE_PURPOSE (dispatch_append_args))
    3914           40 :               : DECL_SOURCE_LOCATION (fndecl),
    3915              :               "%<declare variant%> candidate %qD declared here", fndecl);
    3916           48 :       ninterop = nappend;
    3917              :     }
    3918          471 :   if (dispatch_append_args)
    3919              :     {
    3920          245 :       tree *buffer = XALLOCAVEC (tree, nargs + nappend);
    3921          245 :       tree arg = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
    3922              :       /* Copy the first arguments; insert then the interop objects,
    3923              :          and then copy the rest (nargs - nfirst_args) args.  */
    3924          245 :       int i;
    3925          679 :       for (i = 0; i < nfirst_args; i++)
    3926              :         {
    3927          434 :           arg = TREE_CHAIN (arg);
    3928          434 :           buffer[i] = CALL_EXPR_ARG (expr, i);
    3929              :         }
    3930              :       int j = ninterop;
    3931          583 :       for (tree t = dispatch_interop; t && j > 0; t = TREE_CHAIN (t))
    3932          338 :         if (OMP_CLAUSE_CODE (t) == OMP_CLAUSE_INTEROP)
    3933          338 :           buffer[i + --j] = OMP_CLAUSE_DECL (t);
    3934          245 :       gcc_checking_assert (j == 0);
    3935              : 
    3936              :       /* Do we need to create additional interop objects?  */
    3937          245 :       if (ninterop < nappend)
    3938              :         {
    3939           56 :           if (dispatch_device_num == NULL_TREE)
    3940              :             /* Not remapping device number.  */
    3941           22 :             dispatch_device_num = build_int_cst (integer_type_node,
    3942              :                                                  GOMP_DEVICE_DEFAULT_OMP_61);
    3943           56 :           int nnew = nappend - ninterop;
    3944           56 :           tree nobjs = build_int_cst (integer_type_node, nnew);
    3945           56 :           tree a, t;
    3946              : 
    3947              :           /* Skip to the append_args clause for the first constructed
    3948              :              interop argument.  */
    3949           56 :           tree apparg = dispatch_append_args;
    3950           83 :           for (j = 0; j < ninterop; j++)
    3951           27 :             apparg = TREE_CHAIN (apparg);
    3952              : 
    3953              :           /* omp_interop_t *objs[n]; */
    3954           56 :           tree objtype = build_pointer_type (pointer_sized_int_node);
    3955           56 :           t = build_array_type_nelts (objtype, nnew);
    3956           56 :           tree objs = create_tmp_var (t, "interopobjs");
    3957              : 
    3958              :           /* int target_tgtsync[n]; */
    3959           56 :           t = build_array_type_nelts (integer_type_node, nnew);
    3960           56 :           tree target_tgtsync = create_tmp_var (t, "tgt_tgtsync");
    3961              : 
    3962              :           /* Scan first to determine if we need a prefer_type array.  */
    3963           56 :           tree prefer_type = NULL_TREE;
    3964           56 :           tree prefer_type_type = NULL_TREE;
    3965          141 :           for (j = ninterop, a = apparg; j < nappend; j++, a = TREE_CHAIN (a))
    3966           64 :             if (TREE_VALUE (a) != NULL_TREE)
    3967              :               {
    3968              :                 /* const char *prefer_type[n];  */
    3969           35 :                 t = build_qualified_type (char_type_node, TYPE_QUAL_CONST);
    3970           35 :                 prefer_type_type = build_pointer_type (t);
    3971           35 :                 t = build_array_type_nelts (prefer_type_type, nnew);
    3972           35 :                 prefer_type = create_tmp_var (t, "pref_type");
    3973           35 :                 break;
    3974              :               }
    3975              : 
    3976              :           /* Initialize the arrays, generating temp vars and clobbers for
    3977              :              the interop objects.  (The constructed array holding the
    3978              :              pointers to these objects shouldn't need clobbering as there's
    3979              :              no reason for GOMP_interop to modify its contents.)  */
    3980          127 :           for (j = ninterop, a = apparg; j < nappend; j++, a = TREE_CHAIN (a))
    3981              :             {
    3982              :               /* The allocated temporaries for the interop objects
    3983              :                  have type omp_interop_t, which is an integer type that
    3984              :                  can encode a pointer.  */
    3985           71 :               tree objvar = create_tmp_var (pointer_sized_int_node, "interop");
    3986           71 :               buffer[i + j] = objvar;
    3987           71 :               TREE_ADDRESSABLE (objvar) = 1;
    3988              :               /* Generate a clobber for the temporary for when we're done
    3989              :                  with it.  */
    3990           71 :               tree c = build_clobber (pointer_sized_int_node,
    3991              :                                       CLOBBER_OBJECT_END);
    3992           71 :               c = build2 (MODIFY_EXPR, pointer_sized_int_node, objvar, c);
    3993           71 :               if (clobbers)
    3994           15 :                 clobbers = build2 (COMPOUND_EXPR, TREE_TYPE (clobbers),
    3995              :                                    c, clobbers);
    3996              :               else
    3997              :                 clobbers = c;
    3998              : 
    3999              :               /* objs[offset] = &objvar;  */
    4000           71 :               tree offset = build_int_cst (integer_type_node, j - ninterop);
    4001           71 :               tree init = build4 (ARRAY_REF, objtype, objs, offset,
    4002              :                                   NULL_TREE, NULL_TREE);
    4003           71 :               init = build2 (MODIFY_EXPR, objtype, init,
    4004              :                              build_fold_addr_expr (objvar));
    4005           71 :               if (init_code)
    4006           15 :                 init_code = build2 (COMPOUND_EXPR, TREE_TYPE (init),
    4007              :                                     init_code, init);
    4008              :               else
    4009              :                 init_code = init;
    4010              : 
    4011              :               /* target_tgtsync[offset] = tgt;
    4012              :                  (Don't blame me, I didn't design the encoding of this
    4013              :                  info into the dispatch interop clause data structure,
    4014              :                  but the runtime wants a bit mask.)  */
    4015           71 :               tree tree_tgt = TREE_OPERAND (TREE_PURPOSE (a), 0);
    4016           71 :               int tgt = 0;
    4017           71 :               if (TREE_PURPOSE (tree_tgt) == boolean_true_node)
    4018           42 :                 tgt |= GOMP_INTEROP_TARGET;
    4019           71 :               if (TREE_VALUE (tree_tgt) == boolean_true_node)
    4020           36 :                 tgt |= GOMP_INTEROP_TARGETSYNC;
    4021           71 :               init = build4 (ARRAY_REF, integer_type_node,
    4022              :                              target_tgtsync, offset, NULL_TREE, NULL_TREE);
    4023           71 :               init = build2 (MODIFY_EXPR, integer_type_node, init,
    4024           71 :                              build_int_cst (integer_type_node, tgt));
    4025           71 :               init_code = build2 (COMPOUND_EXPR, TREE_TYPE (init),
    4026              :                                   init_code, init);
    4027              : 
    4028           71 :               if (prefer_type)
    4029              :                 {
    4030           45 :                   tree pref = TREE_VALUE (a);
    4031           45 :                   if (pref == NULL_TREE)
    4032            6 :                     pref = null_pointer_node;
    4033              :                   else
    4034           39 :                     pref = build_fold_addr_expr (pref);
    4035           45 :                   init = build4 (ARRAY_REF, prefer_type_type, prefer_type,
    4036              :                                  offset, NULL_TREE, NULL_TREE);
    4037           45 :                   init = build2 (MODIFY_EXPR, prefer_type_type, init,
    4038              :                                  pref);
    4039           45 :                   init_code = build2 (COMPOUND_EXPR, TREE_TYPE (init),
    4040              :                                       init_code, init);
    4041              :                 }
    4042              :             }
    4043              : 
    4044           56 :           objs = build_fold_addr_expr (objs);
    4045           56 :           target_tgtsync = build_fold_addr_expr (target_tgtsync);
    4046           56 :           prefer_type = prefer_type ? build_fold_addr_expr (prefer_type)
    4047              :                                     : null_pointer_node;
    4048           56 :           tree fn = builtin_decl_explicit (BUILT_IN_GOMP_INTEROP);
    4049           56 :           tree create
    4050           56 :             = build_call_expr_loc (loc, fn, 11, dispatch_device_num,
    4051              :                                    nobjs, objs, target_tgtsync, prefer_type,
    4052              :                                    integer_zero_node, null_pointer_node,
    4053              :                                    integer_zero_node, null_pointer_node,
    4054              :                                    integer_zero_node, null_pointer_node);
    4055           56 :           if (init_code)
    4056           56 :             init_code = build2 (COMPOUND_EXPR, TREE_TYPE (create),
    4057              :                                 init_code, create);
    4058              :           else
    4059              :             init_code = create;
    4060              : 
    4061           56 :           cleanup
    4062           56 :             = build_call_expr_loc (loc, fn, 11, dispatch_device_num,
    4063              :                                    integer_zero_node, null_pointer_node,
    4064              :                                    null_pointer_node, null_pointer_node,
    4065              :                                    integer_zero_node, null_pointer_node,
    4066              :                                    nobjs, objs,
    4067              :                                    integer_zero_node, null_pointer_node);
    4068           56 :           if (clobbers)
    4069           56 :             cleanup = build2 (COMPOUND_EXPR, TREE_TYPE (clobbers),
    4070              :                               cleanup, clobbers);
    4071              :         }
    4072              : 
    4073          654 :       for (j = 0; j < nappend; j++)
    4074              :         {
    4075              :           /* Fortran permits by-reference or by-value for the dummy arg
    4076              :              and by-value, by-reference, ptr by-reference as actual
    4077              :              argument. Handle this.  */
    4078          409 :           tree obj = buffer[i + j];  // interop object
    4079          409 :           tree a2 = TREE_VALUE (arg);  // parameter type
    4080          766 :           if (POINTER_TYPE_P (TREE_TYPE (obj))
    4081          436 :               && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (obj))))
    4082              :             {
    4083           32 :               tree t = TREE_TYPE (TREE_TYPE (obj));
    4084           32 :               gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (t)));
    4085           32 :               obj = fold_build1 (INDIRECT_REF, t, obj);
    4086              :             }
    4087          750 :           if (POINTER_TYPE_P (TREE_TYPE (obj))
    4088          420 :               && INTEGRAL_TYPE_P (a2))
    4089              :             {
    4090           43 :               tree t = TREE_TYPE (TREE_TYPE (obj));
    4091           43 :               gcc_checking_assert (INTEGRAL_TYPE_P (t));
    4092           43 :               obj = fold_build1 (INDIRECT_REF, t, obj);
    4093              :             }
    4094          497 :           else if (INTEGRAL_TYPE_P (TREE_TYPE (obj))
    4095          461 :                    && POINTER_TYPE_P (a2))
    4096              :             {
    4097           18 :               gcc_checking_assert (INTEGRAL_TYPE_P (TREE_TYPE (a2)));
    4098           18 :               obj = build_fold_addr_expr (obj);
    4099              :             }
    4100          348 :           else if (!INTEGRAL_TYPE_P (a2)
    4101          348 :                    || !INTEGRAL_TYPE_P (TREE_TYPE (obj)))
    4102              :             {
    4103           36 :               tree t = TREE_TYPE (obj);
    4104           36 :               gcc_checking_assert (POINTER_TYPE_P (t)
    4105              :                                    && POINTER_TYPE_P (a2)
    4106              :                                    && INTEGRAL_TYPE_P (TREE_TYPE (t))
    4107              :                                    && INTEGRAL_TYPE_P (TREE_TYPE (a2)));
    4108              :             }
    4109          409 :           buffer[i + j] = obj;
    4110          409 :           arg = TREE_CHAIN (arg);
    4111              :         }
    4112          245 :       i += nappend;
    4113          534 :       for (j = nfirst_args; j < nargs; j++)
    4114          289 :         buffer[i++] = CALL_EXPR_ARG (expr, j);
    4115          245 :       nargs += nappend;
    4116          245 :       tree call = expr;
    4117          490 :       expr = build_call_array_loc (EXPR_LOCATION (expr), TREE_TYPE (call),
    4118          245 :                                    CALL_EXPR_FN (call), nargs, buffer);
    4119              : 
    4120              :       /* Copy all CALL_EXPR flags.  */
    4121          245 :       CALL_EXPR_STATIC_CHAIN (expr) = CALL_EXPR_STATIC_CHAIN (call);
    4122          245 :       CALL_EXPR_TAILCALL (expr) = CALL_EXPR_TAILCALL (call);
    4123          245 :       CALL_EXPR_RETURN_SLOT_OPT (expr)
    4124          245 :         = CALL_EXPR_RETURN_SLOT_OPT (call);
    4125          245 :       CALL_FROM_THUNK_P (expr) = CALL_FROM_THUNK_P (call);
    4126          245 :       SET_EXPR_LOCATION (expr, EXPR_LOCATION (call));
    4127          245 :       CALL_EXPR_VA_ARG_PACK (expr) = CALL_EXPR_VA_ARG_PACK (call);
    4128              :     }
    4129              : 
    4130              :   /* Nothing to do for adjust_args?  */
    4131          471 :   if (!dispatch_adjust_args_list || !TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
    4132          260 :     goto add_cleanup;
    4133              : 
    4134              :   /* Handle adjust_args.  */
    4135          966 :   for (int i = 0; i < nargs; i++)
    4136              :     {
    4137          755 :       tree *arg_p = &CALL_EXPR_ARG (expr, i);
    4138              : 
    4139              :       /* Nothing to do if arg is constant null pointer.  */
    4140          755 :       if (integer_zerop (*arg_p))
    4141            6 :         continue;
    4142              : 
    4143              :       bool need_device_ptr = false;
    4144              :       bool need_device_addr = false;
    4145         2247 :       for (int need_addr = 0; need_addr <= 1; need_addr++)
    4146         2301 :         for (tree arg = (need_addr
    4147         1498 :                          ? TREE_VALUE (dispatch_adjust_args_list)
    4148         1498 :                          : TREE_PURPOSE (dispatch_adjust_args_list));
    4149         2301 :              arg != NULL; arg = TREE_CHAIN (arg))
    4150              :           {
    4151         1152 :             if (TREE_VALUE (arg)
    4152         1152 :                 && TREE_CODE (TREE_VALUE (arg)) == INTEGER_CST
    4153         2304 :                 && wi::eq_p (i, wi::to_wide (TREE_VALUE (arg))))
    4154              :               {
    4155          349 :                 if (need_addr)
    4156              :                   need_device_addr = true;
    4157              :                 else
    4158          349 :                   need_device_ptr = true;
    4159              :                 break;
    4160              :               }
    4161              :           }
    4162              : 
    4163          749 :       if (need_device_ptr || need_device_addr)
    4164              :         {
    4165          740 :           bool is_device_ptr = false;
    4166          740 :           bool has_device_addr = false;
    4167              : 
    4168          740 :           for (tree c = dispatch_clauses; c; c = TREE_CHAIN (c))
    4169              :             {
    4170          454 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR
    4171          454 :                   || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
    4172              :                 {
    4173          164 :                   tree decl1 = DECL_NAME (OMP_CLAUSE_DECL (c));
    4174          164 :                   tree decl2 = tree_strip_nop_conversions (*arg_p);
    4175          164 :                   if (TREE_CODE (decl2) == ADDR_EXPR)
    4176           19 :                     decl2 = TREE_OPERAND (decl2, 0);
    4177          164 :                   if (VAR_P (decl2) || TREE_CODE (decl2) == PARM_DECL)
    4178              :                     {
    4179          140 :                       decl2 = DECL_NAME (decl2);
    4180          140 :                       if (decl1 == decl2
    4181          203 :                           && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR)
    4182              :                         {
    4183           58 :                           if (need_device_addr)
    4184            0 :                             warning_at (OMP_CLAUSE_LOCATION (c),
    4185            0 :                                         OPT_Wopenmp,
    4186              :                                         "%<is_device_ptr%> for %qD does"
    4187              :                                         " not imply %<has_device_addr%> "
    4188              :                                         "required for %<need_device_addr%>",
    4189            0 :                                         OMP_CLAUSE_DECL (c));
    4190              :                           is_device_ptr = true;
    4191              :                           break;
    4192              :                         }
    4193           82 :                       else if (decl1 == decl2)
    4194              :                         {
    4195            5 :                           if (need_device_ptr)
    4196           10 :                             warning_at (OMP_CLAUSE_LOCATION (c),
    4197            5 :                                         OPT_Wopenmp,
    4198              :                                         "%<has_device_addr%> for %qD does"
    4199              :                                         " not imply %<is_device_ptr%> "
    4200              :                                         "required for %<need_device_ptr%>",
    4201            5 :                                         OMP_CLAUSE_DECL (c));
    4202              :                           has_device_addr = true;
    4203              :                           break;
    4204              :                         }
    4205              :                     }
    4206              :                 }
    4207              :             }
    4208              : 
    4209          349 :           if ((need_device_ptr && !is_device_ptr)
    4210           58 :               || (need_device_addr && !has_device_addr))
    4211              :             {
    4212          291 :               if (dispatch_device_num == NULL_TREE)
    4213              :                 {
    4214              :                   // device_num = omp_get_default_device ()
    4215          105 :                   tree fn
    4216          105 :                     = builtin_decl_explicit (BUILT_IN_OMP_GET_DEFAULT_DEVICE);
    4217          105 :                   tree call = build_call_expr (fn, 0);
    4218          105 :                   dispatch_device_num = create_tmp_var_raw (TREE_TYPE (call));
    4219          105 :                   tree init
    4220          105 :                     = build4 (TARGET_EXPR, TREE_TYPE (call),
    4221              :                               dispatch_device_num, call, NULL_TREE, NULL_TREE);
    4222          105 :                   if (init_code)
    4223            0 :                     init_code = build2 (COMPOUND_EXPR, TREE_TYPE (init),
    4224              :                                         init_code, init);
    4225              :                   else
    4226              :                     init_code = init;
    4227              :                 }
    4228              : 
    4229              :               // We want to emit the following statement:
    4230              :               //   mapped_arg = omp_get_mapped_ptr (arg,
    4231              :               //                device_num)
    4232              :               // but arg has to be the actual pointer, not a
    4233              :               // reference or a conversion expression.
    4234          291 :               tree actual_ptr
    4235          291 :                 = ((TREE_CODE (*arg_p) == ADDR_EXPR)
    4236          291 :                    ? TREE_OPERAND (*arg_p, 0)
    4237           38 :                    : *arg_p);
    4238          291 :               if (TREE_CODE (actual_ptr) == NOP_EXPR
    4239          291 :                   && (TREE_CODE (TREE_TYPE (TREE_OPERAND (actual_ptr, 0)))
    4240              :                       == REFERENCE_TYPE))
    4241              :                 {
    4242            6 :                   actual_ptr = TREE_OPERAND (actual_ptr, 0);
    4243            6 :                   actual_ptr = build1 (INDIRECT_REF,
    4244            6 :                                        TREE_TYPE (actual_ptr),
    4245              :                                        actual_ptr);
    4246              :                 }
    4247          291 :               tree fn = builtin_decl_explicit (BUILT_IN_OMP_GET_MAPPED_PTR);
    4248          291 :               tree mapped_arg = build_call_expr_loc (loc, fn, 2, actual_ptr,
    4249              :                                                      dispatch_device_num);
    4250              : 
    4251          291 :               if (TREE_CODE (*arg_p) == ADDR_EXPR
    4252          291 :                   || (TREE_CODE (TREE_TYPE (actual_ptr)) == REFERENCE_TYPE))
    4253           47 :                 mapped_arg = build_fold_addr_expr (mapped_arg);
    4254          244 :               else if (TREE_CODE (*arg_p) == NOP_EXPR)
    4255           35 :                 mapped_arg = build1 (NOP_EXPR, TREE_TYPE (*arg_p),
    4256              :                                      mapped_arg);
    4257          291 :               *arg_p = mapped_arg;
    4258              :             }
    4259              :         }
    4260              :     }
    4261              : 
    4262          471 :  add_cleanup:
    4263          471 :   if (cleanup)
    4264              :     {
    4265           56 :       tree result = NULL_TREE;
    4266           56 :       if (want_value && pointerize)
    4267              :         {
    4268            0 :           tree tmp = create_tmp_var (build_pointer_type (TREE_TYPE (expr)),
    4269              :                                      "cleanuptmp");
    4270            0 :           result = build_simple_mem_ref (tmp);
    4271            0 :           expr = build2 (INIT_EXPR, TREE_TYPE (tmp), tmp,
    4272              :                          build_fold_addr_expr (expr));
    4273              :         }
    4274           56 :       else if (want_value)
    4275              :         {
    4276           18 :           tree tmp = create_tmp_var (TREE_TYPE (expr), "cleanuptmp");
    4277           18 :           result = tmp;
    4278           18 :           expr = build2 (INIT_EXPR, TREE_TYPE (tmp), tmp, expr);
    4279              :         }
    4280           56 :       if (init_code)
    4281           56 :         expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init_code, expr);
    4282           56 :       expr = build2 (TRY_FINALLY_EXPR, void_type_node, expr, cleanup);
    4283              : 
    4284           56 :       if (result)
    4285           18 :         expr = build2 (COMPOUND_EXPR, TREE_TYPE (result), expr, result);
    4286              :     }
    4287          415 :   else if (init_code)
    4288          105 :     expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init_code, expr);
    4289              : 
    4290              :   return expr;
    4291              : }
    4292              : 
    4293              : /* Helper function for gimplify_call_expr: handle "declare variant"
    4294              :    resolution and expansion of the CALL_EXPR EXPR.  WANT_VALUE is true
    4295              :    if the result value of the call is needed; POINTERIZE is true if it
    4296              :    also needs to be pointerized.  If OMP_DISPATCH_P is true, apply
    4297              :    associated transformations using DISPATCH_CLAUSES.
    4298              :    This function may return either the original call or some other
    4299              :    expression such as a conditional to select one of multiple calls.
    4300              : 
    4301              :    FIXME: this function is written to be independent of gimplifier internals
    4302              :    so that it could be moved to omp-general.cc and invoked from the
    4303              :    front ends instead, per PR115076.  */
    4304              : 
    4305              : static tree
    4306         1355 : expand_variant_call_expr (tree expr, bool want_value, bool pointerize,
    4307              :                           bool omp_dispatch_p, tree dispatch_clauses)
    4308              : {
    4309              :   /* If we've already processed this call, stop now.  This can happen
    4310              :      if the variant call resolves to the original function, or to
    4311              :      a dynamic conditional that includes the default call to the original
    4312              :      function.  */
    4313         1355 :   gcc_assert (omp_resolved_variant_calls != NULL);
    4314         1355 :   if (omp_resolved_variant_calls->contains (expr))
    4315          131 :     return expr;
    4316              : 
    4317         1224 :   tree fndecl = get_callee_fndecl (expr);
    4318         1224 :   tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (expr));
    4319         1224 :   location_t loc = EXPR_LOCATION (expr);
    4320         1224 :   tree construct_context = omp_get_construct_context ();
    4321         1224 :   vec<struct omp_variant> all_candidates
    4322         1224 :     = omp_declare_variant_candidates (fndecl, construct_context);
    4323         1224 :   gcc_assert (!all_candidates.is_empty ());
    4324         1224 :   vec<struct omp_variant> candidates
    4325         1224 :     = omp_get_dynamic_candidates (all_candidates, construct_context);
    4326              : 
    4327              :   /* If the variant call could be resolved now, build a nest of COND_EXPRs
    4328              :      if there are dynamic candidates, and/or a new CALL_EXPR for each
    4329              :      candidate call.  */
    4330         1224 :   if (!candidates.is_empty ())
    4331              :     {
    4332         1212 :       int n = candidates.length ();
    4333         1212 :       tree tail = NULL_TREE;
    4334              : 
    4335         2462 :       for (int i = n - 1; i >= 0; i--)
    4336              :         {
    4337         1250 :           if (tail)
    4338           38 :             gcc_assert (candidates[i].dynamic_selector);
    4339              :           else
    4340         1212 :             gcc_assert (!candidates[i].dynamic_selector);
    4341         1250 :           if (candidates[i].alternative == fndecl)
    4342              :             {
    4343              :               /* We should only get the original function back as the
    4344              :                  default.  */
    4345          284 :               gcc_assert (!tail);
    4346          284 :               omp_resolved_variant_calls->add (expr);
    4347          284 :               tail = expr;
    4348              :             }
    4349              :           else
    4350              :             {
    4351              :               /* For the final static selector, we can re-use the old
    4352              :                  CALL_EXPR and just replace the function, unless it may
    4353              :                  need dispatch argument modification.  Otherwise,
    4354              :                  make a copy of it.  */
    4355          966 :               tree thiscall = (tail || omp_dispatch_p
    4356          966 :                                ? unshare_expr (expr) : expr);
    4357          966 :               CALL_EXPR_FN (thiscall) = build1 (ADDR_EXPR, fnptrtype,
    4358          966 :                                                 candidates[i].alternative);
    4359          966 :               if (omp_dispatch_p)
    4360          471 :                 thiscall = modify_call_for_omp_dispatch (thiscall,
    4361              :                                                          dispatch_clauses,
    4362              :                                                          want_value,
    4363              :                                                          pointerize);
    4364          966 :               if (!tail)
    4365              :                 tail = thiscall;
    4366              :               else
    4367           76 :                 tail = build3 (COND_EXPR, TREE_TYPE (expr),
    4368           38 :                                omp_dynamic_cond (candidates[i].selector,
    4369              :                                                  find_supercontext ()),
    4370              :                                thiscall, tail);
    4371              :             }
    4372              :         }
    4373              :       return tail;
    4374              :     }
    4375              : 
    4376              :   /* If we couldn't resolve the variant call now, expand it into a loop using
    4377              :      a switch and OMP_NEXT_VARIANT for dispatch.  The ompdevlow pass will
    4378              :      handle OMP_NEXT_VARIANT expansion.  */
    4379              :   else
    4380              :     {
    4381              :       /* If we need a usable return value, we need a temporary
    4382              :          and an assignment in each alternative.  This logic was borrowed
    4383              :          from gimplify_cond_expr.  */
    4384           12 :       tree type = TREE_TYPE (expr);
    4385           12 :       tree tmp = NULL_TREE, result = NULL_TREE;
    4386              : 
    4387           12 :       if (want_value)
    4388              :         {
    4389           12 :           if (pointerize)
    4390              :             {
    4391            0 :               type = build_pointer_type (type);
    4392            0 :               tmp = create_tmp_var (type, "iftmp");
    4393            0 :               result = build_simple_mem_ref_loc (loc, tmp);
    4394              :             }
    4395              :           else
    4396              :             {
    4397           12 :               tmp = create_tmp_var (type, "iftmp");
    4398           12 :               result = tmp;
    4399              :             }
    4400              :         }
    4401              : 
    4402              :       /* Preprocess the all_candidates array so that the alternative field of
    4403              :          each element holds the actual function call expression and possible
    4404              :          assignment, instead of just the decl for the variant function.  */
    4405           60 :       for (unsigned int i = 0; i < all_candidates.length (); i++)
    4406              :         {
    4407           48 :           tree decl = all_candidates[i].alternative;
    4408           48 :           tree thiscall;
    4409              : 
    4410              :           /* We need to turn the decl from the candidate into a function
    4411              :              call and possible assignment, and stuff that in
    4412              :              the directive seq of the gomp_variant.  */
    4413           48 :           if (decl == fndecl)
    4414              :             {
    4415           12 :               thiscall = expr;
    4416           12 :               omp_resolved_variant_calls->add (expr);
    4417              :             }
    4418              :           else
    4419              :             {
    4420           36 :               thiscall = unshare_expr (expr);
    4421           36 :               CALL_EXPR_FN (thiscall) = build1 (ADDR_EXPR, fnptrtype, decl);
    4422           36 :               if (omp_dispatch_p)
    4423            0 :                 thiscall = modify_call_for_omp_dispatch (thiscall,
    4424              :                                                          dispatch_clauses,
    4425              :                                                          want_value,
    4426              :                                                          pointerize);
    4427              :             }
    4428           48 :           if (pointerize)
    4429            0 :             thiscall = build_fold_addr_expr_loc (loc, thiscall);
    4430           48 :           if (want_value)
    4431           48 :             thiscall = build2 (INIT_EXPR, type, tmp, thiscall);
    4432           48 :           all_candidates[i].alternative = thiscall;
    4433              :         }
    4434              : 
    4435           12 :       cgraph_node::get (cfun->decl)->has_omp_variant_constructs = 1;
    4436           12 :       tree expansion = expand_late_variant_directive (all_candidates,
    4437              :                                                       construct_context);
    4438           12 :       if (result)
    4439           12 :         expansion = build2 (COMPOUND_EXPR, TREE_TYPE (result),
    4440              :                             expansion, result);
    4441              :       return expansion;
    4442              :     }
    4443              : }
    4444              : 
    4445              : /* Wrapper around expand_variant_call_expr to interface with gimplifier
    4446              :    state.  EXPR and OMP_DISPATCH_P are as for expand_variant_call_expr,
    4447              :    FALLBACK is used to compute the WANT_VALUE and POINTERIZE arguments.  */
    4448              : static tree
    4449         1355 : gimplify_variant_call_expr (tree expr, fallback_t fallback,
    4450              :                             bool omp_dispatch_p)
    4451              : {
    4452         1355 :   tree type = TREE_TYPE (expr);
    4453         1355 :   bool want_value = (fallback != fb_none && !VOID_TYPE_P (type));
    4454          673 :   bool pointerize = false;
    4455              :   /* If the result value must be an lvalue or the result type must
    4456              :      live in memory, then we have to pointerize it if we need a temporary.  */
    4457          673 :   if (want_value
    4458          673 :       && ((!(fallback & fb_rvalue) && (fallback & fb_lvalue))
    4459          673 :           || TREE_ADDRESSABLE (type)))
    4460            0 :     pointerize = true;
    4461              : 
    4462         1867 :   return expand_variant_call_expr (expr, want_value, pointerize,
    4463              :                                    omp_dispatch_p,
    4464              :                                    (omp_dispatch_p
    4465          512 :                                     ? gimplify_omp_ctxp->clauses
    4466         1355 :                                     : NULL_TREE));
    4467              : }
    4468              : 
    4469              : 
    4470              : /* Helper function for gimplify_call_expr, called via walk_tree.
    4471              :    Find used user labels.  */
    4472              : 
    4473              : static tree
    4474          766 : find_used_user_labels (tree *tp, int *, void *)
    4475              : {
    4476          766 :   if (TREE_CODE (*tp) == LABEL_EXPR
    4477           15 :       && !DECL_ARTIFICIAL (LABEL_EXPR_LABEL (*tp))
    4478           15 :       && DECL_NAME (LABEL_EXPR_LABEL (*tp))
    4479          781 :       && TREE_USED (LABEL_EXPR_LABEL (*tp)))
    4480           15 :     return *tp;
    4481              :   return NULL_TREE;
    4482              : }
    4483              : 
    4484              : 
    4485              : /* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
    4486              :    WANT_VALUE is true if the result of the call is desired.  */
    4487              : 
    4488              : static enum gimplify_status
    4489     17554339 : gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
    4490              : {
    4491     17554339 :   bool want_value = (fallback != fb_none);
    4492     17554339 :   tree fndecl, parms, p, fnptrtype;
    4493     17554339 :   enum gimplify_status ret;
    4494     17554339 :   int i, nargs;
    4495     17554339 :   gcall *call;
    4496     17554339 :   bool builtin_va_start_p = false, omp_dispatch_p = false;
    4497     17554339 :   location_t loc = EXPR_LOCATION (*expr_p);
    4498              : 
    4499     17554339 :   gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
    4500              : 
    4501              :   /* For reliable diagnostics during inlining, it is necessary that
    4502              :      every call_expr be annotated with file and line.  */
    4503     17554339 :   if (! EXPR_HAS_LOCATION (*expr_p))
    4504       526642 :     SET_EXPR_LOCATION (*expr_p, input_location);
    4505              : 
    4506              :   /* Gimplify internal functions created in the FEs.  */
    4507     17554339 :   if (CALL_EXPR_FN (*expr_p) == NULL_TREE)
    4508              :     {
    4509       605680 :       enum internal_fn ifn = CALL_EXPR_IFN (*expr_p);
    4510       605680 :       if (ifn == IFN_GOMP_DISPATCH)
    4511              :         {
    4512          884 :           gcc_assert (flag_openmp
    4513              :                       && gimplify_omp_ctxp
    4514              :                       && gimplify_omp_ctxp->code == OMP_DISPATCH);
    4515          884 :           *expr_p = CALL_EXPR_ARG (*expr_p, 0);
    4516          884 :           gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
    4517          884 :           if (! EXPR_HAS_LOCATION (*expr_p))
    4518           94 :             SET_EXPR_LOCATION (*expr_p, input_location);
    4519              :           omp_dispatch_p = true;
    4520              :         }
    4521              :       else
    4522              :         {
    4523       604796 :           if (want_value)
    4524              :             return GS_ALL_DONE;
    4525              : 
    4526        21173 :           nargs = call_expr_nargs (*expr_p);
    4527        21173 :           auto_vec<tree> vargs (nargs);
    4528              : 
    4529        21173 :           if (ifn == IFN_ASSUME)
    4530              :             {
    4531          533 :               if (simple_condition_p (CALL_EXPR_ARG (*expr_p, 0)))
    4532              :                 {
    4533              :                   /* If the [[assume (cond)]]; condition is simple
    4534              :                      enough and can be evaluated unconditionally
    4535              :                      without side-effects, expand it as
    4536              :                      if (!cond) __builtin_unreachable ();  */
    4537          311 :                   tree fndecl = builtin_decl_explicit (BUILT_IN_UNREACHABLE);
    4538          311 :                   *expr_p
    4539          622 :                     = build3 (COND_EXPR, void_type_node,
    4540          311 :                               CALL_EXPR_ARG (*expr_p, 0), void_node,
    4541          311 :                               build_call_expr_loc (EXPR_LOCATION (*expr_p),
    4542              :                                                    fndecl, 0));
    4543          311 :                   return GS_OK;
    4544              :                 }
    4545              :               /* If not optimizing, ignore the assumptions unless there
    4546              :                  are used user labels in it.  */
    4547          222 :               if ((!optimize
    4548           98 :                    && !walk_tree_without_duplicates (&CALL_EXPR_ARG (*expr_p,
    4549              :                                                                      0),
    4550              :                                                      find_used_user_labels,
    4551              :                                                      NULL))
    4552          237 :                   || seen_error ())
    4553              :                 {
    4554           94 :                   *expr_p = NULL_TREE;
    4555           94 :                   return GS_ALL_DONE;
    4556              :                 }
    4557              :               /* Temporarily, until gimple lowering, transform
    4558              :                  .ASSUME (cond);
    4559              :                  into:
    4560              :                  [[assume (guard)]]
    4561              :                  {
    4562              :                    guard = cond;
    4563              :                  }
    4564              :                  such that gimple lowering can outline the condition into
    4565              :                  a separate function easily.  */
    4566          128 :               tree guard = create_tmp_var (boolean_type_node);
    4567          128 :               *expr_p = build2 (MODIFY_EXPR, void_type_node, guard,
    4568          128 :                                 gimple_boolify (CALL_EXPR_ARG (*expr_p, 0)));
    4569          128 :               *expr_p = build3 (BIND_EXPR, void_type_node, NULL, *expr_p, NULL);
    4570          128 :               push_gimplify_context ();
    4571          128 :               gimple_seq body = NULL;
    4572          128 :               gimple *g = gimplify_and_return_first (*expr_p, &body);
    4573          128 :               pop_gimplify_context (g);
    4574          128 :               g = gimple_build_assume (guard, body);
    4575          128 :               gimple_set_location (g, loc);
    4576          128 :               gimplify_seq_add_stmt (pre_p, g);
    4577          128 :               *expr_p = NULL_TREE;
    4578          128 :               return GS_ALL_DONE;
    4579              :             }
    4580        20640 :           else if (ifn == IFN_UBSAN_BOUNDS
    4581        20640 :                    && nargs == 3
    4582        20640 :                    && integer_onep (CALL_EXPR_ARG (*expr_p, 0)))
    4583              :             {
    4584              :               /* If first argument is one, add TYPE_MAX_VALUE (TYPE_DOMAIN (t))
    4585              :                  to 3rd argument and change first argument to 0.  This is
    4586              :                  done by ubsan_instrument_bounds so that we can use the
    4587              :                  max value from gimplify_type_sizes here instead of original
    4588              :                  expression for VLAs.  */
    4589          406 :               tree type = TREE_TYPE (CALL_EXPR_ARG (*expr_p, 0));
    4590          406 :               CALL_EXPR_ARG (*expr_p, 0) = build_int_cst (type, 0);
    4591          406 :               gcc_assert (TREE_CODE (type) == POINTER_TYPE);
    4592          406 :               type = TREE_TYPE (type);
    4593          406 :               gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
    4594          406 :               tree maxv = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
    4595          406 :               gcc_assert (maxv);
    4596          406 :               tree arg3 = CALL_EXPR_ARG (*expr_p, 2);
    4597          406 :               CALL_EXPR_ARG (*expr_p, 2)
    4598          812 :                 = fold_build2 (PLUS_EXPR, TREE_TYPE (arg3), maxv, arg3);
    4599              :             }
    4600              : 
    4601        46429 :           for (i = 0; i < nargs; i++)
    4602              :             {
    4603        25789 :               gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
    4604        25789 :                             EXPR_LOCATION (*expr_p));
    4605        25789 :               vargs.quick_push (CALL_EXPR_ARG (*expr_p, i));
    4606              :             }
    4607              : 
    4608        20640 :           gcall *call = gimple_build_call_internal_vec (ifn, vargs);
    4609        20640 :           gimple_call_set_nothrow (call, TREE_NOTHROW (*expr_p));
    4610        20640 :           gimplify_seq_add_stmt (pre_p, call);
    4611        20640 :           return GS_ALL_DONE;
    4612        21173 :         }
    4613              :     }
    4614              : 
    4615              :   /* This may be a call to a builtin function.
    4616              : 
    4617              :      Builtin function calls may be transformed into different
    4618              :      (and more efficient) builtin function calls under certain
    4619              :      circumstances.  Unfortunately, gimplification can muck things
    4620              :      up enough that the builtin expanders are not aware that certain
    4621              :      transformations are still valid.
    4622              : 
    4623              :      So we attempt transformation/gimplification of the call before
    4624              :      we gimplify the CALL_EXPR.  At this time we do not manage to
    4625              :      transform all calls in the same manner as the expanders do, but
    4626              :      we do transform most of them.  */
    4627     16949543 :   fndecl = get_callee_fndecl (*expr_p);
    4628     16949543 :   if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
    4629      3986749 :     switch (DECL_FUNCTION_CODE (fndecl))
    4630              :       {
    4631        94654 :       CASE_BUILT_IN_ALLOCA:
    4632              :         /* If the call has been built for a variable-sized object, then we
    4633              :            want to restore the stack level when the enclosing BIND_EXPR is
    4634              :            exited to reclaim the allocated space; otherwise, we precisely
    4635              :            need to do the opposite and preserve the latest stack level.  */
    4636        94654 :         if (CALL_ALLOCA_FOR_VAR_P (*expr_p))
    4637         9029 :           gimplify_ctxp->save_stack = true;
    4638              :         else
    4639        85625 :           gimplify_ctxp->keep_stack = true;
    4640              :         break;
    4641              : 
    4642        20897 :       case BUILT_IN_VA_START:
    4643        20897 :         {
    4644        20897 :           builtin_va_start_p = true;
    4645        20897 :           if (call_expr_nargs (*expr_p) < 2)
    4646              :             {
    4647            1 :               error ("too few arguments to function %<va_start%>");
    4648            1 :               *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
    4649            1 :               return GS_OK;
    4650              :             }
    4651              : 
    4652        20896 :           if (fold_builtin_next_arg (*expr_p, true))
    4653              :             {
    4654            8 :               *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
    4655            8 :               return GS_OK;
    4656              :             }
    4657              :           break;
    4658              :         }
    4659              : 
    4660           30 :       case BUILT_IN_EH_RETURN:
    4661           30 :         cfun->calls_eh_return = true;
    4662           30 :         break;
    4663              : 
    4664         1036 :       case BUILT_IN_CLEAR_PADDING:
    4665         1036 :         if (call_expr_nargs (*expr_p) == 1)
    4666              :           {
    4667              :             /* Remember the original type of the argument in an internal
    4668              :                dummy second argument, as in GIMPLE pointer conversions are
    4669              :                useless.  Also mark this call as not for automatic
    4670              :                initialization in the internal dummy third argument.  */
    4671          518 :             p = CALL_EXPR_ARG (*expr_p, 0);
    4672          518 :             *expr_p
    4673          518 :               = build_call_expr_loc (EXPR_LOCATION (*expr_p), fndecl, 2, p,
    4674          518 :                                      build_zero_cst (TREE_TYPE (p)));
    4675          518 :             return GS_OK;
    4676              :           }
    4677              :         break;
    4678              : 
    4679              :       default:
    4680              :         ;
    4681              :       }
    4682     16949016 :   if (fndecl && fndecl_built_in_p (fndecl))
    4683              :     {
    4684      4226995 :       tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
    4685      4226995 :       if (new_tree && new_tree != *expr_p)
    4686              :         {
    4687              :           /* There was a transformation of this call which computes the
    4688              :              same value, but in a more efficient way.  Return and try
    4689              :              again.  */
    4690          773 :           *expr_p = new_tree;
    4691          773 :           return GS_OK;
    4692              :         }
    4693              :     }
    4694              : 
    4695              :   /* Remember the original function pointer type.  */
    4696     16948243 :   fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
    4697              : 
    4698              :   /* Handle "declare variant" resolution and arglist processing.  */
    4699     16948243 :   if (flag_openmp
    4700       391398 :       && fndecl
    4701       390717 :       && cfun
    4702       390717 :       && (cfun->curr_properties & PROP_gimple_any) == 0
    4703       251530 :       && !omp_has_novariants ()
    4704     17199661 :       && lookup_attribute ("omp declare variant base",
    4705       251418 :                            DECL_ATTRIBUTES (fndecl)))
    4706              :     {
    4707         1355 :       tree orig = *expr_p;
    4708         1355 :       *expr_p = gimplify_variant_call_expr (*expr_p, fallback,
    4709              :                                             omp_dispatch_p);
    4710              : 
    4711              :       /* This may resolve to the same call, or the call expr with just
    4712              :          the function replaced, in which case we should just continue to
    4713              :          gimplify it normally.  Otherwise, if we get something else back,
    4714              :          stop here and re-gimplify the whole replacement expr.  */
    4715         1355 :       if (*expr_p != orig)
    4716              :         return GS_OK;
    4717              :     }
    4718              : 
    4719              :   /* There is a sequence point before the call, so any side effects in
    4720              :      the calling expression must occur before the actual call.  Force
    4721              :      gimplify_expr to use an internal post queue.  */
    4722     16947754 :   ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
    4723              :                        is_gimple_call_addr, fb_rvalue);
    4724              : 
    4725     16947754 :   if (ret == GS_ERROR)
    4726              :     return GS_ERROR;
    4727              : 
    4728     16947752 :   nargs = call_expr_nargs (*expr_p);
    4729              : 
    4730              :   /* Get argument types for verification.  */
    4731     16947752 :   fndecl = get_callee_fndecl (*expr_p);
    4732     16947752 :   parms = NULL_TREE;
    4733     16947752 :   if (fndecl)
    4734     16723084 :     parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
    4735              :   else
    4736       224668 :     parms = TYPE_ARG_TYPES (TREE_TYPE (fnptrtype));
    4737              : 
    4738     33670836 :   if (fndecl && DECL_ARGUMENTS (fndecl))
    4739              :     p = DECL_ARGUMENTS (fndecl);
    4740      7408637 :   else if (parms)
    4741              :     p = parms;
    4742              :   else
    4743              :     p = NULL_TREE;
    4744     45108722 :   for (i = 0; i < nargs && p; i++, p = TREE_CHAIN (p))
    4745              :     ;
    4746              : 
    4747              :   /* If the last argument is __builtin_va_arg_pack () and it is not
    4748              :      passed as a named argument, decrease the number of CALL_EXPR
    4749              :      arguments and set instead the CALL_EXPR_VA_ARG_PACK flag.  */
    4750     16947752 :   if (!p
    4751     16947752 :       && i < nargs
    4752     16947752 :       && TREE_CODE (CALL_EXPR_ARG (*expr_p, nargs - 1)) == CALL_EXPR)
    4753              :     {
    4754         5960 :       tree last_arg = CALL_EXPR_ARG (*expr_p, nargs - 1);
    4755         5960 :       tree last_arg_fndecl = get_callee_fndecl (last_arg);
    4756              : 
    4757         5960 :       if (last_arg_fndecl
    4758         5960 :           && fndecl_built_in_p (last_arg_fndecl, BUILT_IN_VA_ARG_PACK))
    4759              :         {
    4760          132 :           tree call = *expr_p;
    4761              : 
    4762          132 :           --nargs;
    4763          264 :           *expr_p = build_call_array_loc (loc, TREE_TYPE (call),
    4764          132 :                                           CALL_EXPR_FN (call),
    4765          132 :                                           nargs, CALL_EXPR_ARGP (call));
    4766              : 
    4767              :           /* Copy all CALL_EXPR flags, location and block, except
    4768              :              CALL_EXPR_VA_ARG_PACK flag.  */
    4769          132 :           CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
    4770          132 :           CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
    4771          132 :           CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
    4772          132 :             = CALL_EXPR_RETURN_SLOT_OPT (call);
    4773          132 :           CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
    4774          132 :           SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
    4775              : 
    4776              :           /* Set CALL_EXPR_VA_ARG_PACK.  */
    4777          132 :           CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
    4778              :         }
    4779              :     }
    4780              : 
    4781              :   /* If the call returns twice then after building the CFG the call
    4782              :      argument computations will no longer dominate the call because
    4783              :      we add an abnormal incoming edge to the call.  So do not use SSA
    4784              :      vars there.  */
    4785     16947752 :   bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
    4786              : 
    4787              : 
    4788              :   /* Gimplify the function arguments.  */
    4789     16947752 :   if (nargs > 0)
    4790              :     {
    4791     14834300 :       for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
    4792     44468486 :            PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
    4793     29634186 :            PUSH_ARGS_REVERSED ? i-- : i++)
    4794              :         {
    4795     29634186 :           enum gimplify_status t;
    4796              : 
    4797              :           /* Avoid gimplifying the second argument to va_start, which needs to
    4798              :              be the plain PARM_DECL.  */
    4799     29634186 :           if ((i != 1) || !builtin_va_start_p)
    4800              :             {
    4801     29613298 :               tree *arg_p = &CALL_EXPR_ARG (*expr_p, i);
    4802              : 
    4803     29613298 :               if (gimplify_omp_ctxp && gimplify_omp_ctxp->code == OMP_DISPATCH)
    4804         6687 :                 gimplify_omp_ctxp->in_call_args = true;
    4805     29613298 :               t = gimplify_arg (arg_p, pre_p, EXPR_LOCATION (*expr_p),
    4806              :                                 !returns_twice);
    4807     29613298 :               if (gimplify_omp_ctxp && gimplify_omp_ctxp->code == OMP_DISPATCH)
    4808         6687 :                 gimplify_omp_ctxp->in_call_args = false;
    4809              : 
    4810     29613298 :               if (t == GS_ERROR)
    4811     29634186 :                 ret = GS_ERROR;
    4812              :             }
    4813              :         }
    4814              :     }
    4815              : 
    4816              :   /* Gimplify the static chain.  */
    4817     16947752 :   if (CALL_EXPR_STATIC_CHAIN (*expr_p))
    4818              :     {
    4819        28853 :       if (fndecl && !DECL_STATIC_CHAIN (fndecl))
    4820            3 :         CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL;
    4821              :       else
    4822              :         {
    4823        28174 :           enum gimplify_status t;
    4824        28174 :           t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
    4825        28174 :                             EXPR_LOCATION (*expr_p), ! returns_twice);
    4826        28174 :           if (t == GS_ERROR)
    4827     16947752 :             ret = GS_ERROR;
    4828              :         }
    4829              :     }
    4830              : 
    4831              :   /* Verify the function result.  */
    4832     16947752 :   if (want_value && fndecl
    4833     16947752 :       && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
    4834              :     {
    4835            0 :       error_at (loc, "using result of function returning %<void%>");
    4836            0 :       ret = GS_ERROR;
    4837              :     }
    4838              : 
    4839              :   /* Try this again in case gimplification exposed something.  */
    4840     16947752 :   if (ret != GS_ERROR)
    4841              :     {
    4842     16947602 :       tree new_tree = fold_call_expr (input_location, *expr_p, !want_value);
    4843              : 
    4844     16947602 :       if (new_tree && new_tree != *expr_p)
    4845              :         {
    4846              :           /* There was a transformation of this call which computes the
    4847              :              same value, but in a more efficient way.  Return and try
    4848              :              again.  */
    4849        11459 :           *expr_p = new_tree;
    4850        11459 :           return GS_OK;
    4851              :         }
    4852              :     }
    4853              :   else
    4854              :     {
    4855          150 :       *expr_p = error_mark_node;
    4856          150 :       return GS_ERROR;
    4857              :     }
    4858              : 
    4859              :   /* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
    4860              :      decl.  This allows us to eliminate redundant or useless
    4861              :      calls to "const" functions.  */
    4862     16936143 :   if (TREE_CODE (*expr_p) == CALL_EXPR)
    4863              :     {
    4864     16936143 :       int flags = call_expr_flags (*expr_p);
    4865     16936143 :       if (flags & (ECF_CONST | ECF_PURE)
    4866              :           /* An infinite loop is considered a side effect.  */
    4867      2459888 :           && !(flags & (ECF_LOOPING_CONST_OR_PURE)))
    4868      2049205 :         TREE_SIDE_EFFECTS (*expr_p) = 0;
    4869              :     }
    4870              : 
    4871              :   /* If the value is not needed by the caller, emit a new GIMPLE_CALL
    4872              :      and clear *EXPR_P.  Otherwise, leave *EXPR_P in its gimplified
    4873              :      form and delegate the creation of a GIMPLE_CALL to
    4874              :      gimplify_modify_expr.  This is always possible because when
    4875              :      WANT_VALUE is true, the caller wants the result of this call into
    4876              :      a temporary, which means that we will emit an INIT_EXPR in
    4877              :      internal_get_tmp_var which will then be handled by
    4878              :      gimplify_modify_expr.  */
    4879     16936143 :   if (!want_value)
    4880              :     {
    4881              :       /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
    4882              :          have to do is replicate it as a GIMPLE_CALL tuple.  */
    4883      6452016 :       gimple_stmt_iterator gsi;
    4884      6452016 :       call = gimple_build_call_from_tree (*expr_p, fnptrtype);
    4885      6452016 :       notice_special_calls (call);
    4886      6452016 :       gimplify_seq_add_stmt (pre_p, call);
    4887      6452016 :       gsi = gsi_last (*pre_p);
    4888      6452016 :       maybe_fold_stmt (&gsi);
    4889      6452016 :       *expr_p = NULL_TREE;
    4890              :     }
    4891              :   else
    4892              :     /* Remember the original function type.  */
    4893     10484127 :     CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
    4894     10484127 :                                      CALL_EXPR_FN (*expr_p));
    4895              : 
    4896              :   return ret;
    4897              : }
    4898              : 
    4899              : /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
    4900              :    rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
    4901              : 
    4902              :    TRUE_LABEL_P and FALSE_LABEL_P point to the labels to jump to if the
    4903              :    condition is true or false, respectively.  If null, we should generate
    4904              :    our own to skip over the evaluation of this specific expression.
    4905              : 
    4906              :    LOCUS is the source location of the COND_EXPR.
    4907              : 
    4908              :    The condition_uid is a discriminator tag for condition coverage used to map
    4909              :    conditions to its corresponding full Boolean function.
    4910              : 
    4911              :    This function is the tree equivalent of do_jump.
    4912              : 
    4913              :    shortcut_cond_r should only be called by shortcut_cond_expr.  */
    4914              : 
    4915              : static tree
    4916      1333094 : shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p,
    4917              :                  location_t locus, unsigned condition_uid)
    4918              : {
    4919      1333094 :   tree local_label = NULL_TREE;
    4920      1333094 :   tree t, expr = NULL;
    4921              : 
    4922              :   /* OK, it's not a simple case; we need to pull apart the COND_EXPR to
    4923              :      retain the shortcut semantics.  Just insert the gotos here;
    4924              :      shortcut_cond_expr will append the real blocks later.  */
    4925      1333094 :   if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
    4926              :     {
    4927       125615 :       location_t new_locus;
    4928              : 
    4929              :       /* Turn if (a && b) into
    4930              : 
    4931              :          if (a); else goto no;
    4932              :          if (b) goto yes; else goto no;
    4933              :          (no:) */
    4934              : 
    4935       125615 :       if (false_label_p == NULL)
    4936         3999 :         false_label_p = &local_label;
    4937              : 
    4938              :       /* Keep the original source location on the first 'if'.  */
    4939       125615 :       t = shortcut_cond_r (TREE_OPERAND (pred, 0), NULL, false_label_p, locus,
    4940              :                            condition_uid);
    4941       125615 :       append_to_statement_list (t, &expr);
    4942              : 
    4943              :       /* Set the source location of the && on the second 'if'.  */
    4944       125615 :       new_locus = rexpr_location (pred, locus);
    4945       125615 :       t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
    4946              :                            new_locus, condition_uid);
    4947       125615 :       append_to_statement_list (t, &expr);
    4948              :     }
    4949      1207479 :   else if (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
    4950              :     {
    4951       384942 :       location_t new_locus;
    4952              : 
    4953              :       /* Turn if (a || b) into
    4954              : 
    4955              :          if (a) goto yes;
    4956              :          if (b) goto yes; else goto no;
    4957              :          (yes:) */
    4958              : 
    4959       384942 :       if (true_label_p == NULL)
    4960       230716 :         true_label_p = &local_label;
    4961              : 
    4962              :       /* Keep the original source location on the first 'if'.  */
    4963       384942 :       t = shortcut_cond_r (TREE_OPERAND (pred, 0), true_label_p, NULL, locus,
    4964              :                            condition_uid);
    4965       384942 :       append_to_statement_list (t, &expr);
    4966              : 
    4967              :       /* Set the source location of the || on the second 'if'.  */
    4968       384942 :       new_locus = rexpr_location (pred, locus);
    4969       384942 :       t = shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p, false_label_p,
    4970              :                            new_locus, condition_uid);
    4971       384942 :       append_to_statement_list (t, &expr);
    4972              :     }
    4973       822537 :   else if (TREE_CODE (pred) == COND_EXPR
    4974          852 :            && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 1)))
    4975       823389 :            && !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (pred, 2))))
    4976              :     {
    4977          846 :       location_t new_locus;
    4978              : 
    4979              :       /* As long as we're messing with gotos, turn if (a ? b : c) into
    4980              :          if (a)
    4981              :            if (b) goto yes; else goto no;
    4982              :          else
    4983              :            if (c) goto yes; else goto no;
    4984              : 
    4985              :          Don't do this if one of the arms has void type, which can happen
    4986              :          in C++ when the arm is throw.  */
    4987              : 
    4988              :       /* Keep the original source location on the first 'if'.  Set the source
    4989              :          location of the ? on the second 'if'.  */
    4990          846 :       new_locus = rexpr_location (pred, locus);
    4991         1692 :       expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (pred, 0),
    4992          846 :                      shortcut_cond_r (TREE_OPERAND (pred, 1), true_label_p,
    4993              :                                       false_label_p, locus, condition_uid),
    4994          846 :                      shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
    4995              :                                       false_label_p, new_locus,
    4996              :                                       condition_uid));
    4997          846 :       tree_associate_condition_with_expr (expr, condition_uid);
    4998              :     }
    4999              :   else
    5000              :     {
    5001       821691 :       expr = build3 (COND_EXPR, void_type_node, pred,
    5002              :                      build_and_jump (true_label_p),
    5003              :                      build_and_jump (false_label_p));
    5004       821691 :       SET_EXPR_LOCATION (expr, locus);
    5005       821691 :       tree_associate_condition_with_expr (expr, condition_uid);
    5006              :     }
    5007              : 
    5008      1333094 :   if (local_label)
    5009              :     {
    5010       234715 :       t = build1 (LABEL_EXPR, void_type_node, local_label);
    5011       234715 :       append_to_statement_list (t, &expr);
    5012              :     }
    5013              : 
    5014      1333094 :   return expr;
    5015              : }
    5016              : 
    5017              : /* If EXPR is a GOTO_EXPR, return it.  If it is a STATEMENT_LIST, skip
    5018              :    any of its leading DEBUG_BEGIN_STMTS and recurse on the subsequent
    5019              :    statement, if it is the last one.  Otherwise, return NULL.  */
    5020              : 
    5021              : static tree
    5022     11725246 : find_goto (tree expr)
    5023              : {
    5024     12056315 :   if (!expr)
    5025              :     return NULL_TREE;
    5026              : 
    5027     10091939 :   if (TREE_CODE (expr) == GOTO_EXPR)
    5028              :     return expr;
    5029              : 
    5030      8054264 :   if (TREE_CODE (expr) != STATEMENT_LIST)
    5031              :     return NULL_TREE;
    5032              : 
    5033      1051456 :   tree_stmt_iterator i = tsi_start (expr);
    5034              : 
    5035      1414009 :   while (!tsi_end_p (i) && TREE_CODE (tsi_stmt (i)) == DEBUG_BEGIN_STMT)
    5036       362553 :     tsi_next (&i);
    5037              : 
    5038      1051456 :   if (!tsi_one_before_end_p (i))
    5039              :     return NULL_TREE;
    5040              : 
    5041       331069 :   return find_goto (tsi_stmt (i));
    5042              : }
    5043              : 
    5044              : /* Same as find_goto, except that it returns NULL if the destination
    5045              :    is not a LABEL_DECL.  */
    5046              : 
    5047              : static inline tree
    5048     11725246 : find_goto_label (tree expr)
    5049              : {
    5050     11725246 :   tree dest = find_goto (expr);
    5051     13762921 :   if (dest && TREE_CODE (GOTO_DESTINATION (dest)) == LABEL_DECL)
    5052      2037564 :     return dest;
    5053              :   return NULL_TREE;
    5054              : }
    5055              : 
    5056              : 
    5057              : /* Given a multi-term condition (ANDIF, ORIF), walk the predicate PRED and tag
    5058              :    every basic condition with CONDITION_UID.  Two basic conditions share the
    5059              :    CONDITION_UID discriminator when they belong to the same predicate, which is
    5060              :    used by the condition coverage.  Doing this as an explicit step makes for a
    5061              :    simpler implementation than weaving it into the splitting code as the
    5062              :    splitting code eventually calls the entry point gimplfiy_expr which makes
    5063              :    bookkeeping complicated.  */
    5064              : static void
    5065       576366 : tag_shortcut_cond (tree pred, unsigned condition_uid)
    5066              : {
    5067       615667 :   if (TREE_CODE (pred) == TRUTH_ANDIF_EXPR
    5068       615667 :       || TREE_CODE (pred) == TRUTH_ORIF_EXPR)
    5069              :     {
    5070       565194 :       tree fst = TREE_OPERAND (pred, 0);
    5071       565194 :       tree lst = TREE_OPERAND (pred, 1);
    5072              : 
    5073       565194 :       if (TREE_CODE (fst) == TRUTH_ANDIF_EXPR
    5074       565194 :           || TREE_CODE (fst) == TRUTH_ORIF_EXPR)
    5075       168793 :         tag_shortcut_cond (fst, condition_uid);
    5076       396401 :       else if (TREE_CODE (fst) == COND_EXPR)
    5077          244 :         tree_associate_condition_with_expr (fst, condition_uid);
    5078              : 
    5079       565194 :       if (TREE_CODE (lst) == TRUTH_ANDIF_EXPR
    5080       565194 :           || TREE_CODE (lst) == TRUTH_ORIF_EXPR)
    5081              :         tag_shortcut_cond (lst, condition_uid);
    5082       525893 :       else if (TREE_CODE (lst) == COND_EXPR)
    5083          445 :         tree_associate_condition_with_expr (lst, condition_uid);
    5084              :     }
    5085       576366 : }
    5086              : 
    5087              : /* Given a conditional expression EXPR with short-circuit boolean
    5088              :    predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
    5089              :    predicate apart into the equivalent sequence of conditionals.  CONDITION_UID
    5090              :    is a the tag/discriminator for this EXPR - all basic conditions in the
    5091              :    expression will be given the same CONDITION_UID.  */
    5092              : static tree
    5093       407573 : shortcut_cond_expr (tree expr, unsigned condition_uid)
    5094              : {
    5095       407573 :   tree pred = TREE_OPERAND (expr, 0);
    5096       407573 :   tree then_ = TREE_OPERAND (expr, 1);
    5097       407573 :   tree else_ = TREE_OPERAND (expr, 2);
    5098       407573 :   tree true_label, false_label, end_label, t;
    5099       407573 :   tree *true_label_p;
    5100       407573 :   tree *false_label_p;
    5101       407573 :   bool emit_end, emit_false, jump_over_else;
    5102       407573 :   bool then_se = then_ && TREE_SIDE_EFFECTS (then_);
    5103       407573 :   bool else_se = else_ && TREE_SIDE_EFFECTS (else_);
    5104              : 
    5105       407573 :   tag_shortcut_cond (pred, condition_uid);
    5106              : 
    5107              :   /* First do simple transformations.  */
    5108       407573 :   if (!else_se)
    5109              :     {
    5110              :       /* If there is no 'else', turn
    5111              :            if (a && b) then c
    5112              :          into
    5113              :            if (a) if (b) then c.  */
    5114       293137 :       while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
    5115              :         {
    5116              :           /* Keep the original source location on the first 'if'.  */
    5117        51388 :           location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
    5118        51388 :           TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
    5119              :           /* Set the source location of the && on the second 'if'.  */
    5120        51388 :           if (rexpr_has_location (pred))
    5121        50364 :             SET_EXPR_LOCATION (expr, rexpr_location (pred));
    5122        51388 :           then_ = shortcut_cond_expr (expr, condition_uid);
    5123        51388 :           then_se = then_ && TREE_SIDE_EFFECTS (then_);
    5124        51388 :           pred = TREE_OPERAND (pred, 0);
    5125        51388 :           expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
    5126        51388 :           SET_EXPR_LOCATION (expr, locus);
    5127              :         }
    5128              :     }
    5129              : 
    5130       407573 :   if (!then_se)
    5131              :     {
    5132              :       /* If there is no 'then', turn
    5133              :            if (a || b); else d
    5134              :          into
    5135              :            if (a); else if (b); else d.  */
    5136        25589 :       while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
    5137              :         {
    5138              :           /* Keep the original source location on the first 'if'.  */
    5139          797 :           location_t locus = EXPR_LOC_OR_LOC (expr, input_location);
    5140          797 :           TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
    5141              :           /* Set the source location of the || on the second 'if'.  */
    5142          797 :           if (rexpr_has_location (pred))
    5143          796 :             SET_EXPR_LOCATION (expr, rexpr_location (pred));
    5144          797 :           else_ = shortcut_cond_expr (expr, condition_uid);
    5145          797 :           else_se = else_ && TREE_SIDE_EFFECTS (else_);
    5146          797 :           pred = TREE_OPERAND (pred, 0);
    5147          797 :           expr = build3 (COND_EXPR, void_type_node, pred, NULL_TREE, else_);
    5148          797 :           SET_EXPR_LOCATION (expr, locus);
    5149              :         }
    5150              :     }
    5151              : 
    5152              :   /* The expr tree should also have the expression id set.  */
    5153       407573 :   tree_associate_condition_with_expr (expr, condition_uid);
    5154              : 
    5155              :   /* If we're done, great.  */
    5156       407573 :   if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
    5157       407573 :       && TREE_CODE (pred) != TRUTH_ORIF_EXPR)
    5158        97285 :     return expr;
    5159              : 
    5160              :   /* Otherwise we need to mess with gotos.  Change
    5161              :        if (a) c; else d;
    5162              :      to
    5163              :        if (a); else goto no;
    5164              :        c; goto end;
    5165              :        no: d; end:
    5166              :      and recursively gimplify the condition.  */
    5167              : 
    5168       310288 :   true_label = false_label = end_label = NULL_TREE;
    5169              : 
    5170              :   /* If our arms just jump somewhere, hijack those labels so we don't
    5171              :      generate jumps to jumps.  */
    5172              : 
    5173       310288 :   if (tree then_goto = find_goto_label (then_))
    5174              :     {
    5175         4630 :       true_label = GOTO_DESTINATION (then_goto);
    5176         4630 :       then_ = NULL;
    5177         4630 :       then_se = false;
    5178              :     }
    5179              : 
    5180       310288 :   if (tree else_goto = find_goto_label (else_))
    5181              :     {
    5182         4223 :       false_label = GOTO_DESTINATION (else_goto);
    5183         4223 :       else_ = NULL;
    5184         4223 :       else_se = false;
    5185              :     }
    5186              : 
    5187              :   /* If we aren't hijacking a label for the 'then' branch, it falls through.  */
    5188       310288 :   if (true_label)
    5189              :     true_label_p = &true_label;
    5190              :   else
    5191       305658 :     true_label_p = NULL;
    5192              : 
    5193              :   /* The 'else' branch also needs a label if it contains interesting code.  */
    5194       310288 :   if (false_label || else_se)
    5195              :     false_label_p = &false_label;
    5196              :   else
    5197              :     false_label_p = NULL;
    5198              : 
    5199              :   /* If there was nothing else in our arms, just forward the label(s).  */
    5200       149658 :   if (!then_se && !else_se)
    5201         8590 :     return shortcut_cond_r (pred, true_label_p, false_label_p,
    5202        12885 :                             EXPR_LOC_OR_LOC (expr, input_location), condition_uid);
    5203              : 
    5204              :   /* If our last subexpression already has a terminal label, reuse it.  */
    5205       305993 :   if (else_se)
    5206       160630 :     t = expr_last (else_);
    5207       145363 :   else if (then_se)
    5208       145363 :     t = expr_last (then_);
    5209              :   else
    5210              :     t = NULL;
    5211       305993 :   if (t && TREE_CODE (t) == LABEL_EXPR)
    5212         1013 :     end_label = LABEL_EXPR_LABEL (t);
    5213              : 
    5214              :   /* If we don't care about jumping to the 'else' branch, jump to the end
    5215              :      if the condition is false.  */
    5216       305993 :   if (!false_label_p)
    5217       145121 :     false_label_p = &end_label;
    5218              : 
    5219              :   /* We only want to emit these labels if we aren't hijacking them.  */
    5220       305993 :   emit_end = (end_label == NULL_TREE);
    5221       305993 :   emit_false = (false_label == NULL_TREE);
    5222              : 
    5223              :   /* We only emit the jump over the else clause if we have to--if the
    5224              :      then clause may fall through.  Otherwise we can wind up with a
    5225              :      useless jump and a useless label at the end of gimplified code,
    5226              :      which will cause us to think that this conditional as a whole
    5227              :      falls through even if it doesn't.  If we then inline a function
    5228              :      which ends with such a condition, that can cause us to issue an
    5229              :      inappropriate warning about control reaching the end of a
    5230              :      non-void function.  */
    5231       305993 :   jump_over_else = block_may_fallthru (then_);
    5232              : 
    5233       611355 :   pred = shortcut_cond_r (pred, true_label_p, false_label_p,
    5234       611355 :                           EXPR_LOC_OR_LOC (expr, input_location),
    5235              :                           condition_uid);
    5236              : 
    5237       305993 :   expr = NULL;
    5238       305993 :   append_to_statement_list (pred, &expr);
    5239              : 
    5240       305993 :   append_to_statement_list (then_, &expr);
    5241       305993 :   if (else_se)
    5242              :     {
    5243       160630 :       if (jump_over_else)
    5244              :         {
    5245       158101 :           tree last = expr_last (expr);
    5246       158101 :           t = build_and_jump (&end_label);
    5247       158101 :           if (rexpr_has_location (last))
    5248        37938 :             SET_EXPR_LOCATION (t, rexpr_location (last));
    5249       158101 :           append_to_statement_list (t, &expr);
    5250              :         }
    5251       160630 :       if (emit_false)
    5252              :         {
    5253       160630 :           t = build1 (LABEL_EXPR, void_type_node, false_label);
    5254       160630 :           append_to_statement_list (t, &expr);
    5255              :         }
    5256       160630 :       append_to_statement_list (else_, &expr);
    5257              :     }
    5258       305993 :   if (emit_end && end_label)
    5259              :     {
    5260       302214 :       t = build1 (LABEL_EXPR, void_type_node, end_label);
    5261       302214 :       append_to_statement_list (t, &expr);
    5262              :     }
    5263              : 
    5264       305993 :   return expr;
    5265              : }
    5266              : 
    5267              : /* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE.  */
    5268              : 
    5269              : tree
    5270     17071426 : gimple_boolify (tree expr)
    5271              : {
    5272     17071426 :   tree type = TREE_TYPE (expr);
    5273     17071426 :   location_t loc = EXPR_LOCATION (expr);
    5274              : 
    5275     17071426 :   if (TREE_CODE (expr) == NE_EXPR
    5276      5800563 :       && TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR
    5277     18029446 :       && integer_zerop (TREE_OPERAND (expr, 1)))
    5278              :     {
    5279       498466 :       tree call = TREE_OPERAND (expr, 0);
    5280       498466 :       tree fn = get_callee_fndecl (call);
    5281              : 
    5282              :       /* For __builtin_expect ((long) (x), y) recurse into x as well
    5283              :          if x is truth_value_p.  */
    5284       498466 :       if (fn
    5285       497483 :           && fndecl_built_in_p (fn, BUILT_IN_EXPECT)
    5286       638440 :           && call_expr_nargs (call) == 2)
    5287              :         {
    5288       139974 :           tree arg = CALL_EXPR_ARG (call, 0);
    5289       139974 :           if (arg)
    5290              :             {
    5291       139974 :               if (TREE_CODE (arg) == NOP_EXPR
    5292       139974 :                   && TREE_TYPE (arg) == TREE_TYPE (call))
    5293        66019 :                 arg = TREE_OPERAND (arg, 0);
    5294       139974 :               if (truth_value_p (TREE_CODE (arg)))
    5295              :                 {
    5296       116431 :                   arg = gimple_boolify (arg);
    5297       116431 :                   CALL_EXPR_ARG (call, 0)
    5298       232862 :                     = fold_convert_loc (loc, TREE_TYPE (call), arg);
    5299              :                 }
    5300              :             }
    5301              :         }
    5302              :     }
    5303              : 
    5304     17071426 :   switch (TREE_CODE (expr))
    5305              :     {
    5306      1400419 :     case TRUTH_AND_EXPR:
    5307      1400419 :     case TRUTH_OR_EXPR:
    5308      1400419 :     case TRUTH_XOR_EXPR:
    5309      1400419 :     case TRUTH_ANDIF_EXPR:
    5310      1400419 :     case TRUTH_ORIF_EXPR:
    5311              :       /* Also boolify the arguments of truth exprs.  */
    5312      1400419 :       TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
    5313              :       /* FALLTHRU */
    5314              : 
    5315      1834593 :     case TRUTH_NOT_EXPR:
    5316      1834593 :       TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
    5317              : 
    5318              :       /* These expressions always produce boolean results.  */
    5319      1834593 :       if (TREE_CODE (type) != BOOLEAN_TYPE)
    5320       309200 :         TREE_TYPE (expr) = boolean_type_node;
    5321              :       return expr;
    5322              : 
    5323         5500 :     case ANNOTATE_EXPR:
    5324         5500 :       switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (expr, 1)))
    5325              :         {
    5326         5500 :         case annot_expr_ivdep_kind:
    5327         5500 :         case annot_expr_unroll_kind:
    5328         5500 :         case annot_expr_no_vector_kind:
    5329         5500 :         case annot_expr_vector_kind:
    5330         5500 :         case annot_expr_parallel_kind:
    5331         5500 :         case annot_expr_maybe_infinite_kind:
    5332         5500 :           TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
    5333         5500 :           if (TREE_CODE (type) != BOOLEAN_TYPE)
    5334         3399 :             TREE_TYPE (expr) = boolean_type_node;
    5335              :           return expr;
    5336            0 :         default:
    5337            0 :           gcc_unreachable ();
    5338              :         }
    5339              : 
    5340     15231333 :     default:
    5341     15231333 :       if (COMPARISON_CLASS_P (expr))
    5342              :         {
    5343              :           /* These expressions always produce boolean results.  */
    5344     13324108 :           if (TREE_CODE (type) != BOOLEAN_TYPE)
    5345      1607011 :             TREE_TYPE (expr) = boolean_type_node;
    5346              :           return expr;
    5347              :         }
    5348              :       /* Other expressions that get here must have boolean values, but
    5349              :          might need to be converted to the appropriate mode.  */
    5350      1907225 :       if (TREE_CODE (type) == BOOLEAN_TYPE)
    5351              :         return expr;
    5352       204635 :       return fold_convert_loc (loc, boolean_type_node, expr);
    5353              :     }
    5354              : }
    5355              : 
    5356              : /* Given a conditional expression *EXPR_P without side effects, gimplify
    5357              :    its operands.  New statements are inserted to PRE_P.  */
    5358              : 
    5359              : static enum gimplify_status
    5360        45819 : gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
    5361              : {
    5362        45819 :   tree expr = *expr_p, cond;
    5363        45819 :   enum gimplify_status ret, tret;
    5364        45819 :   enum tree_code code;
    5365              : 
    5366        45819 :   cond = gimple_boolify (COND_EXPR_COND (expr));
    5367              : 
    5368              :   /* We need to handle && and || specially, as their gimplification
    5369              :      creates pure cond_expr, thus leading to an infinite cycle otherwise.  */
    5370        45819 :   code = TREE_CODE (cond);
    5371        45819 :   if (code == TRUTH_ANDIF_EXPR)
    5372           39 :     TREE_SET_CODE (cond, TRUTH_AND_EXPR);
    5373        45780 :   else if (code == TRUTH_ORIF_EXPR)
    5374         4607 :     TREE_SET_CODE (cond, TRUTH_OR_EXPR);
    5375        45819 :   ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_val, fb_rvalue);
    5376        45819 :   COND_EXPR_COND (*expr_p) = cond;
    5377              : 
    5378        45819 :   tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
    5379              :                         is_gimple_val, fb_rvalue);
    5380        45819 :   ret = MIN (ret, tret);
    5381        45819 :   tret = gimplify_expr (&COND_EXPR_ELSE (expr), pre_p, NULL,
    5382              :                         is_gimple_val, fb_rvalue);
    5383              : 
    5384        45819 :   return MIN (ret, tret);
    5385              : }
    5386              : 
    5387              : /* Return true if evaluating EXPR could trap.
    5388              :    EXPR is GENERIC, while tree_could_trap_p can be called
    5389              :    only on GIMPLE.  */
    5390              : 
    5391              : bool
    5392     16774763 : generic_expr_could_trap_p (tree expr)
    5393              : {
    5394     16774763 :   unsigned i, n;
    5395              : 
    5396     16774763 :   if (!expr || is_gimple_val (expr))
    5397              :     return false;
    5398              : 
    5399      9350362 :   if (!EXPR_P (expr) || tree_could_trap_p (expr))
    5400              :     return true;
    5401              : 
    5402      6868856 :   n = TREE_OPERAND_LENGTH (expr);
    5403     16420028 :   for (i = 0; i < n; i++)
    5404     11895680 :     if (generic_expr_could_trap_p (TREE_OPERAND (expr, i)))
    5405              :       return true;
    5406              : 
    5407              :   return false;
    5408              : }
    5409              : 
    5410              : /* Associate the condition STMT with the discriminator UID.  STMTs that are
    5411              :    broken down with ANDIF/ORIF from the same Boolean expression should be given
    5412              :    the same UID; 'if (a && b && c) { if (d || e) ... } ...' should yield the
    5413              :    { a: 1, b: 1, c: 1, d: 2, e: 2 } when gimplification is done.  This is used
    5414              :    for condition coverage.  */
    5415              : static void
    5416      5552335 : gimple_associate_condition_with_expr (struct function *fn, gcond *stmt,
    5417              :                                       unsigned uid)
    5418              : {
    5419      5552335 :   if (!condition_coverage_flag)
    5420              :     return;
    5421              : 
    5422          657 :   if (!fn->cond_uids)
    5423          144 :     fn->cond_uids = new hash_map <gcond*, unsigned> ();
    5424              : 
    5425          657 :   fn->cond_uids->put (stmt, uid);
    5426              : }
    5427              : 
    5428              : /*  Convert the conditional expression pointed to by EXPR_P '(p) ? a : b;'
    5429              :     into
    5430              : 
    5431              :     if (p)                      if (p)
    5432              :       t1 = a;                     a;
    5433              :     else                or      else
    5434              :       t1 = b;                     b;
    5435              :     t1;
    5436              : 
    5437              :     The second form is used when *EXPR_P is of type void.
    5438              : 
    5439              :     PRE_P points to the list where side effects that must happen before
    5440              :       *EXPR_P should be stored.  */
    5441              : 
    5442              : static enum gimplify_status
    5443      6329445 : gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
    5444              : {
    5445      6329445 :   tree expr = *expr_p;
    5446      6329445 :   tree type = TREE_TYPE (expr);
    5447      6329445 :   location_t loc = EXPR_LOCATION (expr);
    5448      6329445 :   tree tmp, arm1, arm2;
    5449      6329445 :   enum gimplify_status ret;
    5450      6329445 :   tree label_true, label_false, label_cont;
    5451      6329445 :   bool have_then_clause_p, have_else_clause_p;
    5452      6329445 :   gcond *cond_stmt;
    5453      6329445 :   enum tree_code pred_code;
    5454      6329445 :   gimple_seq seq = NULL;
    5455              : 
    5456              :   /* If this COND_EXPR has a value, copy the values into a temporary within
    5457              :      the arms.  */
    5458      6329445 :   if (!VOID_TYPE_P (type))
    5459              :     {
    5460       420940 :       tree then_ = TREE_OPERAND (expr, 1), else_ = TREE_OPERAND (expr, 2);
    5461       420940 :       tree result;
    5462              : 
    5463              :       /* If either an rvalue is ok or we do not require an lvalue, create the
    5464              :          temporary.  But we cannot do that if the type is addressable.  */
    5465       420940 :       if (((fallback & fb_rvalue) || !(fallback & fb_lvalue))
    5466       420933 :           && !TREE_ADDRESSABLE (type))
    5467              :         {
    5468       420933 :           if (gimplify_ctxp->allow_rhs_cond_expr
    5469              :               /* If either branch has side effects or could trap, it can't be
    5470              :                  evaluated unconditionally.  */
    5471        45819 :               && !TREE_SIDE_EFFECTS (then_)
    5472        45819 :               && !generic_expr_could_trap_p (then_)
    5473        45819 :               && !TREE_SIDE_EFFECTS (else_)
    5474       466752 :               && !generic_expr_could_trap_p (else_))
    5475        45819 :             return gimplify_pure_cond_expr (expr_p, pre_p);
    5476              : 
    5477       375114 :           tmp = create_tmp_var (type, "iftmp");
    5478       375114 :           result = tmp;
    5479              :         }
    5480              : 
    5481              :       /* Otherwise, only create and copy references to the values.  */
    5482              :       else
    5483              :         {
    5484            7 :           type = build_pointer_type (type);
    5485              : 
    5486            7 :           if (!VOID_TYPE_P (TREE_TYPE (then_)))
    5487            7 :             then_ = build_fold_addr_expr_loc (loc, then_);
    5488              : 
    5489            7 :           if (!VOID_TYPE_P (TREE_TYPE (else_)))
    5490            7 :             else_ = build_fold_addr_expr_loc (loc, else_);
    5491              : 
    5492            7 :           expr
    5493            7 :             = build3 (COND_EXPR, type, TREE_OPERAND (expr, 0), then_, else_);
    5494              : 
    5495            7 :           tmp = create_tmp_var (type, "iftmp");
    5496            7 :           result = build_simple_mem_ref_loc (loc, tmp);
    5497              :         }
    5498              : 
    5499              :       /* Build the new then clause, `tmp = then_;'.  But don't build the
    5500              :          assignment if the value is void; in C++ it can be if it's a throw.  */
    5501       375121 :       if (!VOID_TYPE_P (TREE_TYPE (then_)))
    5502       293545 :         TREE_OPERAND (expr, 1) = build2 (INIT_EXPR, type, tmp, then_);
    5503              : 
    5504              :       /* Similarly, build the new else clause, `tmp = else_;'.  */
    5505       375121 :       if (!VOID_TYPE_P (TREE_TYPE (else_)))
    5506       364449 :         TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, type, tmp, else_);
    5507              : 
    5508       375121 :       TREE_TYPE (expr) = void_type_node;
    5509       375121 :       recalculate_side_effects (expr);
    5510              : 
    5511              :       /* Move the COND_EXPR to the prequeue.  */
    5512       375121 :       gimplify_stmt (&expr, pre_p);
    5513              : 
    5514       375121 :       *expr_p = result;
    5515       375121 :       return GS_ALL_DONE;
    5516              :     }
    5517              : 
    5518              :   /* Remove any COMPOUND_EXPR so the following cases will be caught.  */
    5519      5923268 :   STRIP_TYPE_NOPS (TREE_OPERAND (expr, 0));
    5520      5908505 :   if (TREE_CODE (TREE_OPERAND (expr, 0)) == COMPOUND_EXPR)
    5521        81105 :     gimplify_compound_expr (&TREE_OPERAND (expr, 0), pre_p, true);
    5522              : 
    5523              :   /* Make sure the condition has BOOLEAN_TYPE.  */
    5524      5908505 :   TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
    5525              : 
    5526              :   /* Break apart && and || conditions.  */
    5527      5908505 :   if (TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ANDIF_EXPR
    5528      5908505 :       || TREE_CODE (TREE_OPERAND (expr, 0)) == TRUTH_ORIF_EXPR)
    5529              :     {
    5530       355388 :       expr = shortcut_cond_expr (expr, next_cond_uid ());
    5531              : 
    5532       355388 :       if (expr != *expr_p)
    5533              :         {
    5534       355388 :           *expr_p = expr;
    5535              : 
    5536              :           /* We can't rely on gimplify_expr to re-gimplify the expanded
    5537              :              form properly, as cleanups might cause the target labels to be
    5538              :              wrapped in a TRY_FINALLY_EXPR.  To prevent that, we need to
    5539              :              set up a conditional context.  */
    5540       355388 :           gimple_push_condition ();
    5541       355388 :           gimplify_stmt (expr_p, &seq);
    5542       355388 :           gimple_pop_condition (pre_p);
    5543       355388 :           gimple_seq_add_seq (pre_p, seq);
    5544              : 
    5545       355388 :           return GS_ALL_DONE;
    5546              :         }
    5547              :     }
    5548              : 
    5549              :   /* Now do the normal gimplification.  */
    5550              : 
    5551              :   /* Gimplify condition.  */
    5552      5553117 :   ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
    5553              :                        is_gimple_condexpr_for_cond, fb_rvalue);
    5554      5553117 :   if (ret == GS_ERROR)
    5555              :     return GS_ERROR;
    5556      5552335 :   gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
    5557              : 
    5558      5552335 :   gimple_push_condition ();
    5559              : 
    5560      5552335 :   have_then_clause_p = have_else_clause_p = false;
    5561      5552335 :   label_true = find_goto_label (TREE_OPERAND (expr, 1));
    5562      5552335 :   if (label_true
    5563      1293241 :       && DECL_CONTEXT (GOTO_DESTINATION (label_true)) == current_function_decl
    5564              :       /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
    5565              :          have different locations, otherwise we end up with incorrect
    5566              :          location information on the branches.  */
    5567      6845576 :       && (optimize
    5568       231179 :           || !EXPR_HAS_LOCATION (expr)
    5569       204270 :           || !rexpr_has_location (label_true)
    5570        67970 :           || EXPR_LOCATION (expr) == rexpr_location (label_true)))
    5571              :     {
    5572      1292066 :       have_then_clause_p = true;
    5573      1292066 :       label_true = GOTO_DESTINATION (label_true);
    5574              :     }
    5575              :   else
    5576      4260269 :     label_true = create_artificial_label (UNKNOWN_LOCATION);
    5577      5552335 :   label_false = find_goto_label (TREE_OPERAND (expr, 2));
    5578      5552335 :   if (label_false
    5579       735470 :       && DECL_CONTEXT (GOTO_DESTINATION (label_false)) == current_function_decl
    5580              :       /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
    5581              :          have different locations, otherwise we end up with incorrect
    5582              :          location information on the branches.  */
    5583      6287805 :       && (optimize
    5584       104855 :           || !EXPR_HAS_LOCATION (expr)
    5585       103973 :           || !rexpr_has_location (label_false)
    5586          112 :           || EXPR_LOCATION (expr) == rexpr_location (label_false)))
    5587              :     {
    5588       735370 :       have_else_clause_p = true;
    5589       735370 :       label_false = GOTO_DESTINATION (label_false);
    5590              :     }
    5591              :   else
    5592      4816965 :     label_false = create_artificial_label (UNKNOWN_LOCATION);
    5593              : 
    5594      5552335 :   unsigned cond_uid = 0;
    5595      5552335 :   if (cond_uids)
    5596          467 :     if (unsigned *v = cond_uids->get (expr))
    5597          447 :       cond_uid = *v;
    5598          447 :   if (cond_uid == 0)
    5599      5551888 :     cond_uid = next_cond_uid ();
    5600              : 
    5601      5552335 :   gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
    5602              :                                  &arm2);
    5603      5552335 :   cond_stmt = gimple_build_cond (pred_code, arm1, arm2, label_true,
    5604              :                                  label_false);
    5605      5552335 :   gimple_set_location (cond_stmt, EXPR_LOCATION (expr));
    5606      5552335 :   gimple_associate_condition_with_expr (cfun, cond_stmt, cond_uid);
    5607      5552335 :   copy_warning (cond_stmt, COND_EXPR_COND (expr));
    5608      5552335 :   gimplify_seq_add_stmt (&seq, cond_stmt);
    5609      5552335 :   gimple_stmt_iterator gsi = gsi_last (seq);
    5610      5552335 :   maybe_fold_stmt (&gsi);
    5611              : 
    5612      5552335 :   label_cont = NULL_TREE;
    5613      5552335 :   if (!have_then_clause_p)
    5614              :     {
    5615              :       /* For if (...) {} else { code; } put label_true after
    5616              :          the else block.  */
    5617      4260269 :       if (TREE_OPERAND (expr, 1) == NULL_TREE
    5618       202681 :           && !have_else_clause_p
    5619      4261039 :           && TREE_OPERAND (expr, 2) != NULL_TREE)
    5620              :         {
    5621              :           /* For if (0) {} else { code; } tell -Wimplicit-fallthrough
    5622              :              handling that label_cont == label_true can be only reached
    5623              :              through fallthrough from { code; }.  */
    5624          770 :           if (integer_zerop (COND_EXPR_COND (expr)))
    5625            0 :             UNUSED_LABEL_P (label_true) = 1;
    5626              :           label_cont = label_true;
    5627              :         }
    5628              :       else
    5629              :         {
    5630      4259499 :           bool then_side_effects
    5631      4259499 :             = (TREE_OPERAND (expr, 1)
    5632      4259499 :                && TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)));
    5633      4259499 :           gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
    5634      4259499 :           have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
    5635              :           /* For if (...) { code; } else {} or
    5636              :              if (...) { code; } else goto label; or
    5637              :              if (...) { code; return; } else { ... }
    5638              :              label_cont isn't needed.  */
    5639      4259499 :           if (!have_else_clause_p
    5640      4056442 :               && TREE_OPERAND (expr, 2) != NULL_TREE
    5641      7088709 :               && gimple_seq_may_fallthru (seq))
    5642              :             {
    5643      1965030 :               gimple *g;
    5644      1965030 :               label_cont = create_artificial_label (UNKNOWN_LOCATION);
    5645              : 
    5646              :               /* For if (0) { non-side-effect-code } else { code }
    5647              :                  tell -Wimplicit-fallthrough handling that label_cont can
    5648              :                  be only reached through fallthrough from { code }.  */
    5649      1965030 :               if (integer_zerop (COND_EXPR_COND (expr)))
    5650              :                 {
    5651        76487 :                   UNUSED_LABEL_P (label_true) = 1;
    5652        76487 :                   if (!then_side_effects)
    5653        12376 :                     UNUSED_LABEL_P (label_cont) = 1;
    5654              :                 }
    5655              : 
    5656      1965030 :               g = gimple_build_goto (label_cont);
    5657              : 
    5658              :               /* GIMPLE_COND's are very low level; they have embedded
    5659              :                  gotos.  This particular embedded goto should not be marked
    5660              :                  with the location of the original COND_EXPR, as it would
    5661              :                  correspond to the COND_EXPR's condition, not the ELSE or the
    5662              :                  THEN arms.  To avoid marking it with the wrong location, flag
    5663              :                  it as "no location".  */
    5664      1965030 :               gimple_set_do_not_emit_location (g);
    5665              : 
    5666      1965030 :               gimplify_seq_add_stmt (&seq, g);
    5667              :             }
    5668              :         }
    5669              :     }
    5670      5552335 :   if (!have_else_clause_p)
    5671              :     {
    5672              :       /* For if (1) { code } or if (1) { code } else { non-side-effect-code }
    5673              :          tell -Wimplicit-fallthrough handling that label_false can be only
    5674              :          reached through fallthrough from { code }.  */
    5675      4816965 :       if (integer_nonzerop (COND_EXPR_COND (expr))
    5676      4816965 :           && (TREE_OPERAND (expr, 2) == NULL_TREE
    5677        56892 :               || !TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2))))
    5678         7864 :         UNUSED_LABEL_P (label_false) = 1;
    5679      4816965 :       gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
    5680      4816965 :       have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
    5681              :     }
    5682      5552335 :   if (label_cont)
    5683      1965800 :     gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
    5684              : 
    5685      5552335 :   gimple_pop_condition (pre_p);
    5686      5552335 :   gimple_seq_add_seq (pre_p, seq);
    5687              : 
    5688      5552335 :   if (ret == GS_ERROR)
    5689              :     ; /* Do nothing.  */
    5690      5552335 :   else if (have_then_clause_p || have_else_clause_p)
    5691              :     ret = GS_ALL_DONE;
    5692              :   else
    5693              :     {
    5694              :       /* Both arms are empty; replace the COND_EXPR with its predicate.  */
    5695         2958 :       expr = TREE_OPERAND (expr, 0);
    5696         2958 :       gimplify_stmt (&expr, pre_p);
    5697              :     }
    5698              : 
    5699      5552335 :   *expr_p = NULL;
    5700      5552335 :   return ret;
    5701              : }
    5702              : 
    5703              : /* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression,
    5704              :    to be marked addressable.
    5705              : 
    5706              :    We cannot rely on such an expression being directly markable if a temporary
    5707              :    has been created by the gimplification.  In this case, we create another
    5708              :    temporary and initialize it with a copy, which will become a store after we
    5709              :    mark it addressable.  This can happen if the front-end passed us something
    5710              :    that it could not mark addressable yet, like a Fortran pass-by-reference
    5711              :    parameter (int) floatvar.  */
    5712              : 
    5713              : static void
    5714     57401282 : prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
    5715              : {
    5716     63021817 :   while (handled_component_p (*expr_p))
    5717      5620535 :     expr_p = &TREE_OPERAND (*expr_p, 0);
    5718              : 
    5719              :   /* Do not allow an SSA name as the temporary.  */
    5720     57401282 :   if (is_gimple_reg (*expr_p))
    5721        12133 :     *expr_p = internal_get_tmp_var (*expr_p, seq_p, NULL, false, false, true);
    5722     57401282 : }
    5723              : 
    5724              : /* A subroutine of gimplify_modify_expr.  Replace a MODIFY_EXPR with
    5725              :    a call to __builtin_memcpy.  */
    5726              : 
    5727              : static enum gimplify_status
    5728         1106 : gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
    5729              :                                 gimple_seq *seq_p)
    5730              : {
    5731         1106 :   tree t, to, to_ptr, from, from_ptr;
    5732         1106 :   gcall *gs;
    5733         1106 :   location_t loc = EXPR_LOCATION (*expr_p);
    5734              : 
    5735         1106 :   to = TREE_OPERAND (*expr_p, 0);
    5736         1106 :   from = TREE_OPERAND (*expr_p, 1);
    5737         1106 :   gcc_assert (ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (to)))
    5738              :               && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (from))));
    5739              : 
    5740              :   /* Mark the RHS addressable.  Beware that it may not be possible to do so
    5741              :      directly if a temporary has been created by the gimplification.  */
    5742         1106 :   prepare_gimple_addressable (&from, seq_p);
    5743              : 
    5744         1106 :   mark_addressable (from);
    5745         1106 :   from_ptr = build_fold_addr_expr_loc (loc, from);
    5746         1106 :   gimplify_arg (&from_ptr, seq_p, loc);
    5747              : 
    5748         1106 :   mark_addressable (to);
    5749         1106 :   to_ptr = build_fold_addr_expr_loc (loc, to);
    5750         1106 :   gimplify_arg (&to_ptr, seq_p, loc);
    5751              : 
    5752         1106 :   t = builtin_decl_implicit (BUILT_IN_MEMCPY);
    5753              : 
    5754         1106 :   gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
    5755         1106 :   gimple_call_set_alloca_for_var (gs, true);
    5756              : 
    5757         1106 :   if (want_value)
    5758              :     {
    5759              :       /* tmp = memcpy() */
    5760            8 :       t = create_tmp_var (TREE_TYPE (to_ptr));
    5761            8 :       gimple_call_set_lhs (gs, t);
    5762            8 :       gimplify_seq_add_stmt (seq_p, gs);
    5763              : 
    5764            8 :       *expr_p = build_simple_mem_ref (t);
    5765            8 :       return GS_ALL_DONE;
    5766              :     }
    5767              : 
    5768         1098 :   gimplify_seq_add_stmt (seq_p, gs);
    5769         1098 :   *expr_p = NULL;
    5770         1098 :   return GS_ALL_DONE;
    5771              : }
    5772              : 
    5773              : /* A subroutine of gimplify_modify_expr.  Replace a MODIFY_EXPR with
    5774              :    a call to __builtin_memset.  In this case we know that the RHS is
    5775              :    a CONSTRUCTOR with an empty element list.  */
    5776              : 
    5777              : static enum gimplify_status
    5778           84 : gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
    5779              :                                 gimple_seq *seq_p)
    5780              : {
    5781           84 :   tree t, from, to, to_ptr;
    5782           84 :   gcall *gs;
    5783           84 :   location_t loc = EXPR_LOCATION (*expr_p);
    5784              : 
    5785              :   /* Assert our assumptions, to abort instead of producing wrong code
    5786              :      silently if they are not met.  Beware that the RHS CONSTRUCTOR might
    5787              :      not be immediately exposed.  */
    5788           84 :   from = TREE_OPERAND (*expr_p, 1);
    5789           84 :   if (TREE_CODE (from) == WITH_SIZE_EXPR)
    5790           84 :     from = TREE_OPERAND (from, 0);
    5791              : 
    5792           84 :   gcc_assert (TREE_CODE (from) == CONSTRUCTOR
    5793              :               && vec_safe_is_empty (CONSTRUCTOR_ELTS (from)));
    5794              : 
    5795              :   /* Now proceed.  */
    5796           84 :   to = TREE_OPERAND (*expr_p, 0);
    5797           84 :   gcc_assert (ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (to))));
    5798              : 
    5799           84 :   to_ptr = build_fold_addr_expr_loc (loc, to);
    5800           84 :   gimplify_arg (&to_ptr, seq_p, loc);
    5801           84 :   t = builtin_decl_implicit (BUILT_IN_MEMSET);
    5802              : 
    5803           84 :   gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
    5804              : 
    5805           84 :   if (want_value)
    5806              :     {
    5807              :       /* tmp = memset() */
    5808            0 :       t = create_tmp_var (TREE_TYPE (to_ptr));
    5809            0 :       gimple_call_set_lhs (gs, t);
    5810            0 :       gimplify_seq_add_stmt (seq_p, gs);
    5811              : 
    5812            0 :       *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
    5813            0 :       return GS_ALL_DONE;
    5814              :     }
    5815              : 
    5816           84 :   gimplify_seq_add_stmt (seq_p, gs);
    5817           84 :   *expr_p = NULL;
    5818           84 :   return GS_ALL_DONE;
    5819              : }
    5820              : 
    5821              : /* A subroutine of gimplify_init_ctor_preeval.  Called via walk_tree,
    5822              :    determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
    5823              :    assignment.  Return non-null if we detect a potential overlap.  */
    5824              : 
    5825              : struct gimplify_init_ctor_preeval_data
    5826              : {
    5827              :   /* The base decl of the lhs object.  May be NULL, in which case we
    5828              :      have to assume the lhs is indirect.  */
    5829              :   tree lhs_base_decl;
    5830              : 
    5831              :   /* The alias set of the lhs object.  */
    5832              :   alias_set_type lhs_alias_set;
    5833              : };
    5834              : 
    5835              : static tree
    5836       116410 : gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
    5837              : {
    5838       116410 :   struct gimplify_init_ctor_preeval_data *data
    5839              :     = (struct gimplify_init_ctor_preeval_data *) xdata;
    5840       116410 :   tree t = *tp;
    5841              : 
    5842              :   /* If we find the base object, obviously we have overlap.  */
    5843       116410 :   if (data->lhs_base_decl == t)
    5844              :     return t;
    5845              : 
    5846              :   /* If the constructor component is indirect, determine if we have a
    5847              :      potential overlap with the lhs.  The only bits of information we
    5848              :      have to go on at this point are addressability and alias sets.  */
    5849       116409 :   if ((INDIRECT_REF_P (t)
    5850       116409 :        || TREE_CODE (t) == MEM_REF)
    5851          651 :       && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
    5852       116925 :       && alias_sets_conflict_p (data->lhs_alias_set, get_alias_set (t)))
    5853              :     return t;
    5854              : 
    5855              :   /* If the constructor component is a call, determine if it can hide a
    5856              :      potential overlap with the lhs through an INDIRECT_REF like above.
    5857              :      ??? Ugh - this is completely broken.  In fact this whole analysis
    5858              :      doesn't look conservative.  */
    5859       115893 :   if (TREE_CODE (t) == CALL_EXPR)
    5860              :     {
    5861            0 :       tree type, fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (t)));
    5862              : 
    5863            0 :       for (type = TYPE_ARG_TYPES (fntype); type; type = TREE_CHAIN (type))
    5864            0 :         if (POINTER_TYPE_P (TREE_VALUE (type))
    5865            0 :             && (!data->lhs_base_decl || TREE_ADDRESSABLE (data->lhs_base_decl))
    5866            0 :             && alias_sets_conflict_p (data->lhs_alias_set,
    5867              :                                       get_alias_set
    5868            0 :                                         (TREE_TYPE (TREE_VALUE (type)))))
    5869              :           return t;
    5870              :     }
    5871              : 
    5872       115893 :   if (IS_TYPE_OR_DECL_P (t))
    5873        10968 :     *walk_subtrees = 0;
    5874              :   return NULL;
    5875              : }
    5876              : 
    5877              : /* A subroutine of gimplify_init_constructor.  Pre-evaluate EXPR,
    5878              :    force values that overlap with the lhs (as described by *DATA)
    5879              :    into temporaries.  */
    5880              : 
    5881              : static void
    5882       418193 : gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
    5883              :                             struct gimplify_init_ctor_preeval_data *data)
    5884              : {
    5885       418193 :   enum gimplify_status one;
    5886              : 
    5887              :   /* If the value is constant, then there's nothing to pre-evaluate.  */
    5888       418193 :   if (TREE_CONSTANT (*expr_p))
    5889              :     {
    5890              :       /* Ensure it does not have side effects, it might contain a reference to
    5891              :          the object we're initializing.  */
    5892       199982 :       gcc_assert (!TREE_SIDE_EFFECTS (*expr_p));
    5893              :       return;
    5894              :     }
    5895              : 
    5896              :   /* If the type has non-trivial constructors, we can't pre-evaluate.  */
    5897       218211 :   if (TREE_ADDRESSABLE (TREE_TYPE (*expr_p)))
    5898              :     return;
    5899              : 
    5900              :   /* Recurse for nested constructors.  */
    5901       218211 :   if (TREE_CODE (*expr_p) == CONSTRUCTOR)
    5902              :     {
    5903        73929 :       unsigned HOST_WIDE_INT ix;
    5904        73929 :       constructor_elt *ce;
    5905        73929 :       vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (*expr_p);
    5906              : 
    5907       272066 :       FOR_EACH_VEC_SAFE_ELT (v, ix, ce)
    5908       198137 :         gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
    5909              : 
    5910              :       return;
    5911              :     }
    5912              : 
    5913              :   /* If this is a variable sized type, we must remember the size.  */
    5914       144282 :   maybe_with_size_expr (expr_p);
    5915              : 
    5916              :   /* Gimplify the constructor element to something appropriate for the rhs
    5917              :      of a MODIFY_EXPR.  Given that we know the LHS is an aggregate, we know
    5918              :      the gimplifier will consider this a store to memory.  Doing this
    5919              :      gimplification now means that we won't have to deal with complicated
    5920              :      language-specific trees, nor trees like SAVE_EXPR that can induce
    5921              :      exponential search behavior.  */
    5922       144282 :   one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
    5923       144282 :   if (one == GS_ERROR)
    5924              :     {
    5925            0 :       *expr_p = NULL;
    5926            0 :       return;
    5927              :     }
    5928              : 
    5929              :   /* If we gimplified to a bare decl, we can be sure that it doesn't overlap
    5930              :      with the lhs, since "a = { .x=a }" doesn't make sense.  This will
    5931              :      always be true for all scalars, since is_gimple_mem_rhs insists on a
    5932              :      temporary variable for them.  */
    5933       144282 :   if (DECL_P (*expr_p))
    5934              :     return;
    5935              : 
    5936              :   /* If this is of variable size, we have no choice but to assume it doesn't
    5937              :      overlap since we can't make a temporary for it.  */
    5938       104846 :   if (TREE_CODE (TYPE_SIZE (TREE_TYPE (*expr_p))) != INTEGER_CST)
    5939              :     return;
    5940              : 
    5941              :   /* Otherwise, we must search for overlap ...  */
    5942       104846 :   if (!walk_tree (expr_p, gimplify_init_ctor_preeval_1, data, NULL))
    5943              :     return;
    5944              : 
    5945              :   /* ... and if found, force the value into a temporary.  */
    5946          517 :   *expr_p = get_formal_tmp_var (*expr_p, pre_p);
    5947              : }
    5948              : 
    5949              : /* A subroutine of gimplify_init_ctor_eval.  Create a loop for
    5950              :    a RANGE_EXPR in a CONSTRUCTOR for an array.
    5951              : 
    5952              :       var = lower;
    5953              :     loop_entry:
    5954              :       object[var] = value;
    5955              :       if (var == upper)
    5956              :         goto loop_exit;
    5957              :       var = var + 1;
    5958              :       goto loop_entry;
    5959              :     loop_exit:
    5960              : 
    5961              :    We increment var _after_ the loop exit check because we might otherwise
    5962              :    fail if upper == TYPE_MAX_VALUE (type for upper).
    5963              : 
    5964              :    Note that we never have to deal with SAVE_EXPRs here, because this has
    5965              :    already been taken care of for us, in gimplify_init_ctor_preeval().  */
    5966              : 
    5967              : static void gimplify_init_ctor_eval (tree, vec<constructor_elt, va_gc> *,
    5968              :                                      gimple_seq *, bool);
    5969              : 
    5970              : static void
    5971          579 : gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
    5972              :                                tree value, tree array_elt_type,
    5973              :                                gimple_seq *pre_p, bool cleared)
    5974              : {
    5975          579 :   tree loop_entry_label, loop_exit_label, fall_thru_label;
    5976          579 :   tree var, var_type, cref, tmp;
    5977              : 
    5978          579 :   loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
    5979          579 :   loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
    5980          579 :   fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
    5981              : 
    5982              :   /* Create and initialize the index variable.  */
    5983          579 :   var_type = TREE_TYPE (upper);
    5984          579 :   var = create_tmp_var (var_type);
    5985          579 :   gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
    5986              : 
    5987              :   /* Add the loop entry label.  */
    5988          579 :   gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
    5989              : 
    5990              :   /* Build the reference.  */
    5991          579 :   cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
    5992              :                  var, NULL_TREE, NULL_TREE);
    5993              : 
    5994              :   /* If we are a constructor, just call gimplify_init_ctor_eval to do
    5995              :      the store.  Otherwise just assign value to the reference.  */
    5996              : 
    5997          579 :   if (TREE_CODE (value) == CONSTRUCTOR)
    5998              :     /* NB we might have to call ourself recursively through
    5999              :        gimplify_init_ctor_eval if the value is a constructor.  */
    6000          129 :     gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
    6001              :                              pre_p, cleared);
    6002              :   else
    6003              :     {
    6004          450 :       if (gimplify_expr (&value, pre_p, NULL, is_gimple_val, fb_rvalue)
    6005              :           != GS_ERROR)
    6006          450 :         gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
    6007              :     }
    6008              : 
    6009              :   /* We exit the loop when the index var is equal to the upper bound.  */
    6010         1158 :   gimplify_seq_add_stmt (pre_p,
    6011          579 :                          gimple_build_cond (EQ_EXPR, var, upper,
    6012              :                                             loop_exit_label, fall_thru_label));
    6013              : 
    6014          579 :   gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
    6015              : 
    6016              :   /* Otherwise, increment the index var...  */
    6017          579 :   tmp = build2 (PLUS_EXPR, var_type, var,
    6018              :                 fold_convert (var_type, integer_one_node));
    6019          579 :   gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
    6020              : 
    6021              :   /* ...and jump back to the loop entry.  */
    6022          579 :   gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
    6023              : 
    6024              :   /* Add the loop exit label.  */
    6025          579 :   gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
    6026          579 : }
    6027              : 
    6028              : /* A subroutine of gimplify_init_constructor.  Generate individual
    6029              :    MODIFY_EXPRs for a CONSTRUCTOR.  OBJECT is the LHS against which the
    6030              :    assignments should happen.  ELTS is the CONSTRUCTOR_ELTS of the
    6031              :    CONSTRUCTOR.  CLEARED is true if the entire LHS object has been
    6032              :    zeroed first.  */
    6033              : 
    6034              : static void
    6035      1274527 : gimplify_init_ctor_eval (tree object, vec<constructor_elt, va_gc> *elts,
    6036              :                          gimple_seq *pre_p, bool cleared)
    6037              : {
    6038      1274527 :   tree array_elt_type = NULL;
    6039      1274527 :   unsigned HOST_WIDE_INT ix;
    6040      1274527 :   tree purpose, value;
    6041              : 
    6042      1274527 :   if (TREE_CODE (TREE_TYPE (object)) == ARRAY_TYPE)
    6043       142377 :     array_elt_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (object)));
    6044              : 
    6045      4708648 :   FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
    6046              :     {
    6047      3434121 :       tree cref;
    6048              : 
    6049              :       /* NULL values are created above for gimplification errors.  */
    6050      3434121 :       if (value == NULL)
    6051       327849 :         continue;
    6052              : 
    6053      3434121 :       if (cleared && initializer_zerop (value))
    6054       327104 :         continue;
    6055              : 
    6056              :       /* ??? Here's to hoping the front end fills in all of the indices,
    6057              :          so we don't have to figure out what's missing ourselves.  */
    6058      3107017 :       gcc_assert (purpose);
    6059              : 
    6060              :       /* Skip zero-sized fields, unless value has side-effects.  This can
    6061              :          happen with calls to functions returning a empty type, which
    6062              :          we shouldn't discard.  As a number of downstream passes don't
    6063              :          expect sets of empty type fields, we rely on the gimplification of
    6064              :          the MODIFY_EXPR we make below to drop the assignment statement.  */
    6065      3107017 :       if (!TREE_SIDE_EFFECTS (value)
    6066      2812563 :           && TREE_CODE (purpose) == FIELD_DECL
    6067      5446286 :           && is_empty_type (TREE_TYPE (purpose)))
    6068          166 :         continue;
    6069              : 
    6070              :       /* If we have a RANGE_EXPR, we have to build a loop to assign the
    6071              :          whole range.  */
    6072      3106851 :       if (TREE_CODE (purpose) == RANGE_EXPR)
    6073              :         {
    6074          595 :           tree lower = TREE_OPERAND (purpose, 0);
    6075          595 :           tree upper = TREE_OPERAND (purpose, 1);
    6076              : 
    6077              :           /* If the lower bound is equal to upper, just treat it as if
    6078              :              upper was the index.  */
    6079          595 :           if (simple_cst_equal (lower, upper))
    6080              :             purpose = upper;
    6081              :           else
    6082              :             {
    6083          579 :               gimplify_init_ctor_eval_range (object, lower, upper, value,
    6084              :                                              array_elt_type, pre_p, cleared);
    6085          579 :               continue;
    6086              :             }
    6087              :         }
    6088              : 
    6089      3106272 :       if (array_elt_type)
    6090              :         {
    6091              :           /* Do not use bitsizetype for ARRAY_REF indices.  */
    6092       563537 :           if (TYPE_DOMAIN (TREE_TYPE (object)))
    6093       563537 :             purpose
    6094       563537 :               = fold_convert (TREE_TYPE (TYPE_DOMAIN (TREE_TYPE (object))),
    6095              :                               purpose);
    6096       563537 :           cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
    6097              :                          purpose, NULL_TREE, NULL_TREE);
    6098              :         }
    6099              :       else
    6100              :         {
    6101      2542735 :           gcc_assert (TREE_CODE (purpose) == FIELD_DECL);
    6102      2542735 :           cref = build3 (COMPONENT_REF, TREE_TYPE (purpose),
    6103              :                          unshare_expr (object), purpose, NULL_TREE);
    6104              :         }
    6105              : 
    6106      3106272 :       if (TREE_CODE (value) == CONSTRUCTOR
    6107      3106272 :           && TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE)
    6108       302915 :         gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
    6109              :                                  pre_p, cleared);
    6110      2803357 :       else if (TREE_CODE (value) == RAW_DATA_CST)
    6111              :         {
    6112           43 :           if (RAW_DATA_LENGTH (value) <= 32)
    6113              :             {
    6114           13 :               for (unsigned int i = 0; i < (unsigned) RAW_DATA_LENGTH (value);
    6115              :                    ++i)
    6116           12 :                 if (!cleared || RAW_DATA_POINTER (value)[i])
    6117              :                   {
    6118           12 :                     if (i)
    6119              :                       {
    6120           11 :                         tree p
    6121           11 :                           = fold_build2 (PLUS_EXPR, TREE_TYPE (purpose),
    6122              :                                          purpose,
    6123              :                                          build_int_cst (TREE_TYPE (purpose),
    6124              :                                                         i));
    6125           11 :                         cref = build4 (ARRAY_REF, array_elt_type,
    6126              :                                        unshare_expr (object), p, NULL_TREE,
    6127              :                                        NULL_TREE);
    6128              :                       }
    6129           12 :                     tree init
    6130           12 :                       = build2 (INIT_EXPR, TREE_TYPE (cref), cref,
    6131           12 :                                 build_int_cst (TREE_TYPE (value),
    6132           12 :                                                RAW_DATA_UCHAR_ELT (value, i)));
    6133           12 :                     gimplify_and_add (init, pre_p);
    6134           12 :                     ggc_free (init);
    6135              :                   }
    6136              :             }
    6137              :           else
    6138              :             {
    6139           42 :               tree rtype = build_array_type_nelts (TREE_TYPE (value),
    6140           42 :                                                    RAW_DATA_LENGTH (value));
    6141           42 :               tree rctor = build_constructor_single (rtype, bitsize_zero_node,
    6142              :                                                      value);
    6143           42 :               tree addr = build_fold_addr_expr (cref);
    6144           42 :               cref = build2 (MEM_REF, rtype, addr,
    6145              :                              build_int_cst (ptr_type_node, 0));
    6146           42 :               rctor = tree_output_constant_def (rctor);
    6147           42 :               if (!useless_type_conversion_p (rtype, TREE_TYPE (rctor)))
    6148            4 :                 rctor = build1 (VIEW_CONVERT_EXPR, rtype, rctor);
    6149           42 :               if (gimplify_expr (&cref, pre_p, NULL, is_gimple_lvalue,
    6150              :                                  fb_lvalue) != GS_ERROR)
    6151           84 :                 gimplify_seq_add_stmt (pre_p,
    6152           42 :                                        gimple_build_assign (cref, rctor));
    6153              :             }
    6154              :         }
    6155              :       else
    6156              :         {
    6157      2803314 :           tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
    6158      2803314 :           gimplify_and_add (init, pre_p);
    6159      2803314 :           ggc_free (init);
    6160              :         }
    6161              :     }
    6162      1274527 : }
    6163              : 
    6164              : /* Return the appropriate RHS predicate for this LHS.  */
    6165              : 
    6166              : gimple_predicate
    6167     49838234 : rhs_predicate_for (tree lhs)
    6168              : {
    6169     49838234 :   if (is_gimple_reg (lhs))
    6170              :     return is_gimple_reg_rhs_or_call;
    6171              :   else
    6172     11747990 :     return is_gimple_mem_rhs_or_call;
    6173              : }
    6174              : 
    6175              : /* Return the initial guess for an appropriate RHS predicate for this LHS,
    6176              :    before the LHS has been gimplified.  */
    6177              : 
    6178              : static gimple_predicate
    6179     48623094 : initial_rhs_predicate_for (tree lhs)
    6180              : {
    6181     48623094 :   if (is_gimple_reg_type (TREE_TYPE (lhs)))
    6182              :     return is_gimple_reg_rhs_or_call;
    6183              :   else
    6184      2462897 :     return is_gimple_mem_rhs_or_call;
    6185              : }
    6186              : 
    6187              : /* Gimplify a C99 compound literal expression.  This just means adding
    6188              :    the DECL_EXPR before the current statement and using its anonymous
    6189              :    decl instead.  */
    6190              : 
    6191              : static enum gimplify_status
    6192        37242 : gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p,
    6193              :                                 bool (*gimple_test_f) (tree),
    6194              :                                 fallback_t fallback)
    6195              : {
    6196        37242 :   tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (*expr_p);
    6197        37242 :   tree decl = DECL_EXPR_DECL (decl_s);
    6198        37242 :   tree init = DECL_INITIAL (decl);
    6199              :   /* Mark the decl as addressable if the compound literal
    6200              :      expression is addressable now, otherwise it is marked too late
    6201              :      after we gimplify the initialization expression.  */
    6202        37242 :   if (TREE_ADDRESSABLE (*expr_p))
    6203          549 :     TREE_ADDRESSABLE (decl) = 1;
    6204              :   /* Otherwise, if we don't need an lvalue and have a literal directly
    6205              :      substitute it.  Check if it matches the gimple predicate, as
    6206              :      otherwise we'd generate a new temporary, and we can as well just
    6207              :      use the decl we already have.  */
    6208        36693 :   else if (!TREE_ADDRESSABLE (decl)
    6209        36693 :            && !TREE_THIS_VOLATILE (decl)
    6210        36688 :            && init
    6211        36680 :            && (fallback & fb_lvalue) == 0
    6212        73208 :            && gimple_test_f (init))
    6213              :     {
    6214        35423 :       *expr_p = init;
    6215        35423 :       return GS_OK;
    6216              :     }
    6217              : 
    6218              :   /* If the decl is not addressable, then it is being used in some
    6219              :      expression or on the right hand side of a statement, and it can
    6220              :      be put into a readonly data section.  */
    6221         1819 :   if (!TREE_ADDRESSABLE (decl) && (fallback & fb_lvalue) == 0)
    6222         1097 :     TREE_READONLY (decl) = 1;
    6223              : 
    6224              :   /* This decl isn't mentioned in the enclosing block, so add it to the
    6225              :      list of temps.  FIXME it seems a bit of a kludge to say that
    6226              :      anonymous artificial vars aren't pushed, but everything else is.  */
    6227         1819 :   if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
    6228            2 :     gimple_add_tmp_var (decl);
    6229              : 
    6230         1819 :   gimplify_and_add (decl_s, pre_p);
    6231         1819 :   *expr_p = decl;
    6232         1819 :   return GS_OK;
    6233              : }
    6234              : 
    6235              : /* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
    6236              :    return a new CONSTRUCTOR if something changed.  */
    6237              : 
    6238              : static tree
    6239      1900202 : optimize_compound_literals_in_ctor (tree orig_ctor)
    6240              : {
    6241      1900202 :   tree ctor = orig_ctor;
    6242      1900202 :   vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
    6243      1900202 :   unsigned int idx, num = vec_safe_length (elts);
    6244              : 
    6245      6297029 :   for (idx = 0; idx < num; idx++)
    6246              :     {
    6247      4396827 :       tree value = (*elts)[idx].value;
    6248      4396827 :       tree newval = value;
    6249      4396827 :       if (TREE_CODE (value) == CONSTRUCTOR)
    6250       546074 :         newval = optimize_compound_literals_in_ctor (value);
    6251      3850753 :       else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
    6252              :         {
    6253          103 :           tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (value);
    6254          103 :           tree decl = DECL_EXPR_DECL (decl_s);
    6255          103 :           tree init = DECL_INITIAL (decl);
    6256              : 
    6257          103 :           if (!TREE_ADDRESSABLE (value)
    6258          103 :               && !TREE_ADDRESSABLE (decl)
    6259          103 :               && init
    6260          103 :               && TREE_CODE (init) == CONSTRUCTOR)
    6261           52 :             newval = optimize_compound_literals_in_ctor (init);
    6262              :         }
    6263      4396827 :       if (newval == value)
    6264      4396767 :         continue;
    6265              : 
    6266           60 :       if (ctor == orig_ctor)
    6267              :         {
    6268           49 :           ctor = copy_node (orig_ctor);
    6269           98 :           CONSTRUCTOR_ELTS (ctor) = vec_safe_copy (elts);
    6270           49 :           elts = CONSTRUCTOR_ELTS (ctor);
    6271              :         }
    6272           60 :       (*elts)[idx].value = newval;
    6273              :     }
    6274      1900202 :   return ctor;
    6275              : }
    6276              : 
    6277              : /* A subroutine of gimplify_modify_expr.  Break out elements of a
    6278              :    CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
    6279              : 
    6280              :    Note that we still need to clear any elements that don't have explicit
    6281              :    initializers, so if not all elements are initialized we keep the
    6282              :    original MODIFY_EXPR, we just remove all of the constructor elements.
    6283              : 
    6284              :    If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
    6285              :    GS_ERROR if we would have to create a temporary when gimplifying
    6286              :    this constructor.  Otherwise, return GS_OK.
    6287              : 
    6288              :    If NOTIFY_TEMP_CREATION is false, just do the gimplification.  */
    6289              : 
    6290              : static enum gimplify_status
    6291      1354076 : gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
    6292              :                            bool want_value, bool notify_temp_creation)
    6293              : {
    6294      1354076 :   tree object, ctor, type;
    6295      1354076 :   enum gimplify_status ret;
    6296      1354076 :   vec<constructor_elt, va_gc> *elts;
    6297      1354076 :   bool cleared = false;
    6298      1354076 :   bool is_empty_ctor = false;
    6299      1354076 :   bool is_init_expr = (TREE_CODE (*expr_p) == INIT_EXPR);
    6300              : 
    6301      1354076 :   gcc_assert (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR);
    6302              : 
    6303      1354076 :   if (!notify_temp_creation)
    6304              :     {
    6305      1345401 :       ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
    6306              :                            is_gimple_lvalue, fb_lvalue);
    6307      1345401 :       if (ret == GS_ERROR)
    6308              :         return ret;
    6309              :     }
    6310              : 
    6311      1354076 :   object = TREE_OPERAND (*expr_p, 0);
    6312      1354076 :   ctor = TREE_OPERAND (*expr_p, 1)
    6313      1354076 :     = optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
    6314      1354076 :   type = TREE_TYPE (ctor);
    6315      1354076 :   elts = CONSTRUCTOR_ELTS (ctor);
    6316      1354076 :   ret = GS_ALL_DONE;
    6317              : 
    6318      1354076 :   switch (TREE_CODE (type))
    6319              :     {
    6320      1345374 :     case RECORD_TYPE:
    6321      1345374 :     case UNION_TYPE:
    6322      1345374 :     case QUAL_UNION_TYPE:
    6323      1345374 :     case ARRAY_TYPE:
    6324      1345374 :       {
    6325              :         /* Use readonly data for initializers of this or smaller size
    6326              :            regardless of the num_nonzero_elements / num_unique_nonzero_elements
    6327              :            ratio.  */
    6328      1345374 :         const HOST_WIDE_INT min_unique_size = 64;
    6329              :         /* If num_nonzero_elements / num_unique_nonzero_elements ratio
    6330              :            is smaller than this, use readonly data.  */
    6331      1345374 :         const int unique_nonzero_ratio = 8;
    6332              :         /* True if a single access of the object must be ensured.  This is the
    6333              :            case if the target is volatile, the type is non-addressable and more
    6334              :            than one field need to be assigned.  */
    6335      1345374 :         const bool ensure_single_access
    6336      1345374 :           = TREE_THIS_VOLATILE (object)
    6337          259 :             && !TREE_ADDRESSABLE (type)
    6338      1345579 :             && vec_safe_length (elts) > 1;
    6339      1345374 :         struct gimplify_init_ctor_preeval_data preeval_data;
    6340      1345374 :         HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
    6341      1345374 :         HOST_WIDE_INT num_unique_nonzero_elements;
    6342      1345374 :         ctor_completeness complete_p;
    6343      1345374 :         bool valid_const_initializer;
    6344              : 
    6345              :         /* Aggregate types must lower constructors to initialization of
    6346              :            individual elements.  The exception is that a CONSTRUCTOR node
    6347              :            with no elements indicates zero-initialization of the whole.  */
    6348      1345374 :         if (vec_safe_is_empty (elts))
    6349              :           {
    6350       339451 :             if (notify_temp_creation)
    6351        10211 :               return GS_OK;
    6352              : 
    6353              :             /* The var will be initialized and so appear on lhs of
    6354              :                assignment, it can't be TREE_READONLY anymore.  */
    6355       339403 :             if (VAR_P (object))
    6356       189260 :               TREE_READONLY (object) = 0;
    6357              : 
    6358              :             is_empty_ctor = true;
    6359       343368 :             break;
    6360              :           }
    6361              : 
    6362              :         /* Fetch information about the constructor to direct later processing.
    6363              :            We might want to make static versions of it in various cases, and
    6364              :            can only do so if it known to be a valid constant initializer.  */
    6365      1005923 :         valid_const_initializer
    6366      1005923 :           = categorize_ctor_elements (ctor, &num_nonzero_elements,
    6367              :                                       &num_unique_nonzero_elements,
    6368              :                                       &num_ctor_elements, &complete_p);
    6369              : 
    6370              :         /* If a const aggregate variable is being initialized, then it
    6371              :            should never be a lose to promote the variable to be static.  */
    6372      1005923 :         if (valid_const_initializer
    6373       623496 :             && num_nonzero_elements > 1
    6374       456010 :             && TREE_READONLY (object)
    6375         7682 :             && VAR_P (object)
    6376         7305 :             && !DECL_REGISTER (object)
    6377         7298 :             && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)
    6378         5147 :                 || DECL_MERGEABLE (object))
    6379              :             /* For ctors that have many repeated nonzero elements
    6380              :                represented through RANGE_EXPRs, prefer initializing
    6381              :                those through runtime loops over copies of large amounts
    6382              :                of data from readonly data section.  */
    6383      1005923 :             && (num_unique_nonzero_elements
    6384         3965 :                 > num_nonzero_elements / unique_nonzero_ratio
    6385            0 :                 || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
    6386              :                     <= (unsigned HOST_WIDE_INT) min_unique_size)))
    6387              :           {
    6388         3965 :             if (notify_temp_creation)
    6389              :               return GS_ERROR;
    6390              : 
    6391         3965 :             DECL_INITIAL (object) = ctor;
    6392         3965 :             TREE_STATIC (object) = 1;
    6393         3965 :             if (!DECL_NAME (object) || DECL_NAMELESS (object))
    6394         2999 :               DECL_NAME (object) = create_tmp_var_name ("C");
    6395         3965 :             walk_tree (&DECL_INITIAL (object), force_labels_r, NULL, NULL);
    6396              : 
    6397              :             /* ??? C++ doesn't automatically append a .<number> to the
    6398              :                assembler name, and even when it does, it looks at FE private
    6399              :                data structures to figure out what that number should be,
    6400              :                which are not set for this variable.  I suppose this is
    6401              :                important for local statics for inline functions, which aren't
    6402              :                "local" in the object file sense.  So in order to get a unique
    6403              :                TU-local symbol, we must invoke the lhd version now.  */
    6404         3965 :             lhd_set_decl_assembler_name (object);
    6405              : 
    6406         3965 :             *expr_p = NULL_TREE;
    6407         3965 :             break;
    6408              :           }
    6409              : 
    6410              :         /* The var will be initialized and so appear on lhs of
    6411              :            assignment, it can't be TREE_READONLY anymore.  */
    6412      1001958 :         if (VAR_P (object) && !notify_temp_creation)
    6413       790299 :           TREE_READONLY (object) = 0;
    6414              : 
    6415              :         /* If there are "lots" of initialized elements, even discounting
    6416              :            those that are not address constants (and thus *must* be
    6417              :            computed at runtime), then partition the constructor into
    6418              :            constant and non-constant parts.  Block copy the constant
    6419              :            parts in, then generate code for the non-constant parts.  */
    6420              :         /* TODO.  There's code in cp/typeck.cc to do this.  */
    6421              : 
    6422      1001958 :         if (int_size_in_bytes (TREE_TYPE (ctor)) < 0)
    6423              :           /* store_constructor will ignore the clearing of variable-sized
    6424              :              objects.  Initializers for such objects must explicitly set
    6425              :              every field that needs to be set.  */
    6426              :           cleared = false;
    6427      1001938 :         else if (complete_p.sparse)
    6428              :           /* If the constructor isn't complete, clear the whole object
    6429              :              beforehand, unless CONSTRUCTOR_NO_CLEARING is set on it.
    6430              : 
    6431              :              ??? This ought not to be needed.  For any element not present
    6432              :              in the initializer, we should simply set them to zero.  Except
    6433              :              we'd need to *find* the elements that are not present, and that
    6434              :              requires trickery to avoid quadratic compile-time behavior in
    6435              :              large cases or excessive memory use in small cases.  */
    6436       192427 :           cleared = !CONSTRUCTOR_NO_CLEARING (ctor);
    6437       809511 :         else if (num_ctor_elements - num_nonzero_elements
    6438       809511 :                  > CLEAR_RATIO (optimize_function_for_speed_p (cfun))
    6439       809511 :                  && num_nonzero_elements < num_ctor_elements / 4)
    6440              :           /* If there are "lots" of zeros, it's more efficient to clear
    6441              :              the memory and then set the nonzero elements.  */
    6442              :           cleared = true;
    6443       808486 :         else if (ensure_single_access && num_nonzero_elements == 0)
    6444              :           /* If a single access to the target must be ensured and all elements
    6445              :              are zero, then it's optimal to clear whatever their number.  */
    6446              :           cleared = true;
    6447              :         /* If the object is small enough to go in registers, and it's
    6448              :            not required to be constructed in memory, clear it first.
    6449              :            That will avoid wasting cycles preserving any padding bits
    6450              :            that might be there, and if there aren't any, the compiler
    6451              :            is smart enough to optimize the clearing out.  */
    6452       808477 :         else if ((complete_p.sparse || complete_p.padded_union
    6453       807989 :                   || complete_p.padded_non_union)
    6454        14988 :                  && !TREE_ADDRESSABLE (ctor)
    6455        14974 :                  && !TREE_THIS_VOLATILE (object)
    6456        14971 :                  && (TYPE_MODE (type) != BLKmode || TYPE_NO_FORCE_BLK (type))
    6457       815741 :                  && optimize)
    6458              :           cleared = true;
    6459              :         else
    6460              :           cleared = false;
    6461              : 
    6462              :         /* If there are "lots" of initialized elements, and all of them
    6463              :            are valid address constants, then the entire initializer can
    6464              :            be dropped to memory, and then memcpy'd out.  Don't do this
    6465              :            for sparse arrays, though, as it's more efficient to follow
    6466              :            the standard CONSTRUCTOR behavior of memset followed by
    6467              :            individual element initialization.  Also don't do this for small
    6468              :            all-zero initializers (which aren't big enough to merit
    6469              :            clearing), and don't try to make bitwise copies of
    6470              :            TREE_ADDRESSABLE types.  */
    6471      1001958 :         if (valid_const_initializer
    6472       619531 :             && !complete_p.sparse
    6473       442210 :             && !(cleared || num_nonzero_elements == 0)
    6474       345059 :             && !TREE_ADDRESSABLE (type))
    6475              :           {
    6476       343176 :             HOST_WIDE_INT size = int_size_in_bytes (type);
    6477       343176 :             unsigned int align;
    6478              : 
    6479              :             /* ??? We can still get unbounded array types, at least
    6480              :                from the C++ front end.  This seems wrong, but attempt
    6481              :                to work around it for now.  */
    6482       343176 :             if (size < 0)
    6483              :               {
    6484            9 :                 size = int_size_in_bytes (TREE_TYPE (object));
    6485            9 :                 if (size >= 0)
    6486            0 :                   TREE_TYPE (ctor) = type = TREE_TYPE (object);
    6487              :               }
    6488              : 
    6489              :             /* Find the maximum alignment we can assume for the object.  */
    6490              :             /* ??? Make use of DECL_OFFSET_ALIGN.  */
    6491       343176 :             if (DECL_P (object))
    6492       328820 :               align = DECL_ALIGN (object);
    6493              :             else
    6494        14356 :               align = TYPE_ALIGN (type);
    6495              : 
    6496              :             /* Do a block move either if the size is so small as to make
    6497              :                each individual move a sub-unit move on average, or if it
    6498              :                is so large as to make individual moves inefficient.  */
    6499       343176 :             if (size > 0
    6500       343167 :                 && num_nonzero_elements > 1
    6501              :                 /* For ctors that have many repeated nonzero elements
    6502              :                    represented through RANGE_EXPRs, prefer initializing
    6503              :                    those through runtime loops over copies of large amounts
    6504              :                    of data from readonly data section.  */
    6505       303779 :                 && (num_unique_nonzero_elements
    6506       303779 :                     > num_nonzero_elements / unique_nonzero_ratio
    6507           56 :                     || size <= min_unique_size)
    6508       646899 :                 && (size < num_nonzero_elements
    6509       303617 :                     || !can_move_by_pieces (size, align)))
    6510              :               {
    6511         2746 :                 if (notify_temp_creation)
    6512              :                   return GS_ERROR;
    6513              : 
    6514         1375 :                 walk_tree (&ctor, force_labels_r, NULL, NULL);
    6515         1375 :                 ctor = tree_output_constant_def (ctor);
    6516         1375 :                 if (!useless_type_conversion_p (type, TREE_TYPE (ctor)))
    6517            0 :                   ctor = build1 (VIEW_CONVERT_EXPR, type, ctor);
    6518         1375 :                 TREE_OPERAND (*expr_p, 1) = ctor;
    6519              : 
    6520              :                 /* This is no longer an assignment of a CONSTRUCTOR, but
    6521              :                    we still may have processing to do on the LHS.  So
    6522              :                    pretend we didn't do anything here to let that happen.  */
    6523         1375 :                 return GS_UNHANDLED;
    6524              :               }
    6525              :           }
    6526              : 
    6527       994339 :         if (!cleared)
    6528              :           {
    6529       799244 :             if (complete_p.padded_non_union
    6530         7927 :                 && warn_zero_init_padding_bits >= ZERO_INIT_PADDING_BITS_ALL)
    6531           12 :                 warning (OPT_Wzero_init_padding_bits_,
    6532              :                          "padding might not be initialized to zero; "
    6533              :                          "if code relies on it being zero, consider "
    6534              :                          "using %<-fzero-init-padding-bits=all%>");
    6535       799232 :             else if (complete_p.padded_union
    6536          120 :                      && warn_zero_init_padding_bits
    6537              :                         >= ZERO_INIT_PADDING_BITS_UNIONS)
    6538           14 :                 warning (OPT_Wzero_init_padding_bits_,
    6539              :                          "padding might not be initialized to zero; "
    6540              :                          "if code relies on it being zero, consider "
    6541              :                          "using %<-fzero-init-padding-bits=unions%> "
    6542              :                          "or %<-fzero-init-padding-bits=all%>");
    6543              :           }
    6544              : 
    6545              :         /* If a single access to the target must be ensured and there are
    6546              :            nonzero elements or the zero elements are not assigned en masse,
    6547              :            initialize the target from a temporary.  */
    6548       999212 :         if (ensure_single_access && (num_nonzero_elements > 0 || !cleared))
    6549              :           {
    6550          167 :             if (notify_temp_creation)
    6551              :               return GS_ERROR;
    6552              : 
    6553          161 :             tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
    6554          161 :             TREE_OPERAND (*expr_p, 0) = temp;
    6555          161 :             *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
    6556              :                               *expr_p,
    6557              :                               build2 (MODIFY_EXPR, void_type_node,
    6558              :                                       object, temp));
    6559          161 :             return GS_OK;
    6560              :           }
    6561              : 
    6562       999045 :         if (notify_temp_creation)
    6563              :           return GS_OK;
    6564              : 
    6565              :         /* If there are nonzero elements and if needed, pre-evaluate to capture
    6566              :            elements overlapping with the lhs into temporaries.  We must do this
    6567              :            before clearing to fetch the values before they are zeroed-out.  */
    6568       991795 :         if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
    6569              :           {
    6570       220056 :             preeval_data.lhs_base_decl = get_base_address (object);
    6571       220056 :             if (!DECL_P (preeval_data.lhs_base_decl))
    6572        41350 :               preeval_data.lhs_base_decl = NULL;
    6573       220056 :             preeval_data.lhs_alias_set = get_alias_set (object);
    6574              : 
    6575       220056 :             gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
    6576              :                                         pre_p, post_p, &preeval_data);
    6577              :           }
    6578              : 
    6579       991795 :         bool ctor_has_side_effects_p
    6580       991795 :           = TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 1));
    6581              : 
    6582       991795 :         if (cleared)
    6583              :           {
    6584              :             /* Zap the CONSTRUCTOR element list, which simplifies this case.
    6585              :                Note that we still have to gimplify, in order to handle the
    6586              :                case of variable sized types.  Avoid shared tree structures.  */
    6587       199723 :             CONSTRUCTOR_ELTS (ctor) = NULL;
    6588       199723 :             TREE_SIDE_EFFECTS (ctor) = 0;
    6589       199723 :             object = unshare_expr (object);
    6590       199723 :             gimplify_stmt (expr_p, pre_p);
    6591              :           }
    6592              : 
    6593              :         /* If we have not block cleared the object, or if there are nonzero
    6594              :            elements in the constructor, or if the constructor has side effects,
    6595              :            add assignments to the individual scalar fields of the object.  */
    6596       199723 :         if (!cleared
    6597       199723 :             || num_nonzero_elements > 0
    6598        20708 :             || ctor_has_side_effects_p)
    6599       971483 :           gimplify_init_ctor_eval (object, elts, pre_p, cleared);
    6600              : 
    6601       991795 :         *expr_p = NULL_TREE;
    6602              :       }
    6603       991795 :       break;
    6604              : 
    6605            0 :     case COMPLEX_TYPE:
    6606            0 :       {
    6607            0 :         tree r, i;
    6608              : 
    6609            0 :         if (notify_temp_creation)
    6610              :           return GS_OK;
    6611              : 
    6612              :         /* Extract the real and imaginary parts out of the ctor.  */
    6613            0 :         gcc_assert (elts->length () == 2);
    6614            0 :         r = (*elts)[0].value;
    6615            0 :         i = (*elts)[1].value;
    6616            0 :         if (r == NULL || i == NULL)
    6617              :           {
    6618            0 :             tree zero = build_zero_cst (TREE_TYPE (type));
    6619            0 :             if (r == NULL)
    6620            0 :               r = zero;
    6621            0 :             if (i == NULL)
    6622            0 :               i = zero;
    6623              :           }
    6624              : 
    6625              :         /* Complex types have either COMPLEX_CST or COMPLEX_EXPR to
    6626              :            represent creation of a complex value.  */
    6627            0 :         if (TREE_CONSTANT (r) && TREE_CONSTANT (i))
    6628              :           {
    6629            0 :             ctor = build_complex (type, r, i);
    6630            0 :             TREE_OPERAND (*expr_p, 1) = ctor;
    6631              :           }
    6632              :         else
    6633              :           {
    6634            0 :             ctor = build2 (COMPLEX_EXPR, type, r, i);
    6635            0 :             TREE_OPERAND (*expr_p, 1) = ctor;
    6636            0 :             ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
    6637              :                                  pre_p,
    6638              :                                  post_p,
    6639            0 :                                  rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
    6640              :                                  fb_rvalue);
    6641              :           }
    6642              :       }
    6643              :       break;
    6644              : 
    6645         8702 :     case VECTOR_TYPE:
    6646         8702 :       {
    6647         8702 :         unsigned HOST_WIDE_INT ix;
    6648         8702 :         constructor_elt *ce;
    6649              : 
    6650         8702 :         if (notify_temp_creation)
    6651      1354076 :           return GS_OK;
    6652              : 
    6653              :         /* Vector types use CONSTRUCTOR all the way through gimple
    6654              :            compilation as a general initializer.  */
    6655        75894 :         FOR_EACH_VEC_SAFE_ELT (elts, ix, ce)
    6656              :           {
    6657        67192 :             enum gimplify_status tret;
    6658        67192 :             tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
    6659              :                                   fb_rvalue);
    6660        67192 :             if (tret == GS_ERROR)
    6661              :               ret = GS_ERROR;
    6662        67191 :             else if (TREE_STATIC (ctor)
    6663        67224 :                      && !initializer_constant_valid_p (ce->value,
    6664           33 :                                                        TREE_TYPE (ce->value)))
    6665           33 :               TREE_STATIC (ctor) = 0;
    6666              :           }
    6667         8702 :         recompute_constructor_flags (ctor);
    6668              : 
    6669              :         /* Go ahead and simplify constant constructors to VECTOR_CST.  */
    6670         8702 :         if (TREE_CONSTANT (ctor))
    6671              :           {
    6672         2705 :             bool constant_p = true;
    6673              :             tree value;
    6674              : 
    6675              :             /* Even when ctor is constant, it might contain non-*_CST
    6676              :                elements, such as addresses or trapping values like
    6677              :                1.0/0.0 - 1.0/0.0.  Such expressions don't belong
    6678              :                in VECTOR_CST nodes.  */
    6679         2705 :             FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
    6680         2483 :               if (!CONSTANT_CLASS_P (value))
    6681              :                 {
    6682              :                   constant_p = false;
    6683              :                   break;
    6684              :                 }
    6685              : 
    6686          222 :             if (constant_p)
    6687              :               {
    6688          222 :                 TREE_OPERAND (*expr_p, 1) = build_vector_from_ctor (type, elts);
    6689          222 :                 break;
    6690              :               }
    6691              :           }
    6692              : 
    6693         8480 :         if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
    6694          944 :           TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
    6695              :       }
    6696              :       break;
    6697              : 
    6698            0 :     default:
    6699              :       /* So how did we get a CONSTRUCTOR for a scalar type?  */
    6700            0 :       gcc_unreachable ();
    6701              :     }
    6702              : 
    6703      1343865 :   if (ret == GS_ERROR)
    6704              :     return GS_ERROR;
    6705              :   /* If we have gimplified both sides of the initializer but have
    6706              :      not emitted an assignment, do so now.   */
    6707      1343864 :   if (*expr_p
    6708              :       /* If the type is an empty type, we don't need to emit the
    6709              :          assignment. */
    6710      1343864 :       && !is_empty_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
    6711              :     {
    6712       344030 :       tree lhs = TREE_OPERAND (*expr_p, 0);
    6713       344030 :       tree rhs = TREE_OPERAND (*expr_p, 1);
    6714       344030 :       if (want_value && object == lhs)
    6715           12 :         lhs = unshare_expr (lhs);
    6716       344030 :       gassign *init = gimple_build_assign (lhs, rhs);
    6717       344030 :       gimplify_seq_add_stmt (pre_p, init);
    6718              :     }
    6719      1343864 :   if (want_value)
    6720              :     {
    6721              :       *expr_p = object;
    6722      1343864 :       ret = GS_OK;
    6723              :     }
    6724              :   else
    6725              :     {
    6726      1343845 :       *expr_p = NULL;
    6727      1343845 :       ret = GS_ALL_DONE;
    6728              :     }
    6729              : 
    6730              :   /* If the user requests to initialize automatic variables, we
    6731              :      should initialize paddings inside the variable.  Add a call to
    6732              :      __builtin_clear_pading (&object, 0, for_auto_init = true) to
    6733              :      initialize paddings of object always to zero regardless of
    6734              :      INIT_TYPE.  Note, we will not insert this call if the aggregate
    6735              :      variable has be completely cleared already or it's initialized
    6736              :      with an empty constructor.  We cannot insert this call if the
    6737              :      variable is a gimple register since __builtin_clear_padding will take
    6738              :      the address of the variable.  As a result, if a long double/_Complex long
    6739              :      double variable will be spilled into stack later, its padding cannot
    6740              :      be cleared with __builtin_clear_padding.  We should clear its padding
    6741              :      when it is spilled into memory.  */
    6742      1343864 :   if (is_init_expr
    6743       955790 :       && !is_gimple_reg (object)
    6744       950356 :       && clear_padding_type_may_have_padding_p (type)
    6745       905119 :       && ((AGGREGATE_TYPE_P (type) && !cleared && !is_empty_ctor)
    6746       229881 :           || !AGGREGATE_TYPE_P (type))
    6747       675238 :       && var_needs_auto_init_p (object)
    6748      1379585 :       && flag_auto_var_init != AUTO_INIT_CXX26)
    6749           41 :     gimple_add_padding_init_for_auto_var (object, false, pre_p);
    6750              : 
    6751              :   return ret;
    6752              : }
    6753              : 
    6754              : /* Given a pointer value OP0, return a simplified version of an
    6755              :    indirection through OP0, or NULL_TREE if no simplification is
    6756              :    possible.  This may only be applied to a rhs of an expression.
    6757              :    Note that the resulting type may be different from the type pointed
    6758              :    to in the sense that it is still compatible from the langhooks
    6759              :    point of view. */
    6760              : 
    6761              : static tree
    6762       533116 : gimple_fold_indirect_ref_rhs (tree t)
    6763              : {
    6764            0 :   return gimple_fold_indirect_ref (t);
    6765              : }
    6766              : 
    6767              : /* Subroutine of gimplify_modify_expr to do simplifications of
    6768              :    MODIFY_EXPRs based on the code of the RHS.  We loop for as long as
    6769              :    something changes.  */
    6770              : 
    6771              : static enum gimplify_status
    6772     99328693 : gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
    6773              :                           gimple_seq *pre_p, gimple_seq *post_p,
    6774              :                           bool want_value)
    6775              : {
    6776     99328693 :   enum gimplify_status ret = GS_UNHANDLED;
    6777     99985823 :   bool changed;
    6778              : 
    6779     98487572 :   do
    6780              :     {
    6781     99985823 :       changed = false;
    6782     99985823 :       switch (TREE_CODE (*from_p))
    6783              :         {
    6784     12031594 :         case VAR_DECL:
    6785              :           /* If we're assigning from a read-only variable initialized with
    6786              :              a constructor and not volatile, do the direct assignment from
    6787              :              the constructor, but only if the target is not volatile either
    6788              :              since this latter assignment might end up being done on a per
    6789              :              field basis.  However, if the target is volatile and the type
    6790              :              is aggregate and non-addressable, gimplify_init_constructor
    6791              :              knows that it needs to ensure a single access to the target
    6792              :              and it will return GS_OK only in this case.  */
    6793     12031594 :           if (TREE_READONLY (*from_p)
    6794        95412 :               && DECL_INITIAL (*from_p)
    6795        61554 :               && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR
    6796         8675 :               && !TREE_THIS_VOLATILE (*from_p)
    6797     12040269 :               && (!TREE_THIS_VOLATILE (*to_p)
    6798            6 :                   || (AGGREGATE_TYPE_P (TREE_TYPE (*to_p))
    6799            6 :                       && !TREE_ADDRESSABLE (TREE_TYPE (*to_p)))))
    6800              :             {
    6801         8675 :               tree old_from = *from_p;
    6802         8675 :               enum gimplify_status subret;
    6803              : 
    6804              :               /* Move the constructor into the RHS.  */
    6805         8675 :               *from_p = unshare_expr (DECL_INITIAL (*from_p));
    6806              : 
    6807              :               /* Let's see if gimplify_init_constructor will need to put
    6808              :                  it in memory.  */
    6809         8675 :               subret = gimplify_init_constructor (expr_p, NULL, NULL,
    6810              :                                                   false, true);
    6811         8675 :               if (subret == GS_ERROR)
    6812              :                 {
    6813              :                   /* If so, revert the change.  */
    6814         1377 :                   *from_p = old_from;
    6815              :                 }
    6816              :               else
    6817              :                 {
    6818              :                   ret = GS_OK;
    6819              :                   changed = true;
    6820              :                 }
    6821              :             }
    6822              :           break;
    6823       541348 :         case INDIRECT_REF:
    6824       541348 :           if (!TREE_ADDRESSABLE (TREE_TYPE (*from_p)))
    6825              :             /* If we have code like
    6826              : 
    6827              :              *(const A*)(A*)&x
    6828              : 
    6829              :              where the type of "x" is a (possibly cv-qualified variant
    6830              :              of "A"), treat the entire expression as identical to "x".
    6831              :              This kind of code arises in C++ when an object is bound
    6832              :              to a const reference, and if "x" is a TARGET_EXPR we want
    6833              :              to take advantage of the optimization below.  But not if
    6834              :              the type is TREE_ADDRESSABLE; then C++17 says that the
    6835              :              TARGET_EXPR needs to be a temporary.  */
    6836      1066232 :             if (tree t
    6837       533116 :                 = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0)))
    6838              :               {
    6839       130795 :                 bool volatile_p = TREE_THIS_VOLATILE (*from_p);
    6840       130795 :                 if (TREE_THIS_VOLATILE (t) != volatile_p)
    6841              :                   {
    6842            5 :                     if (DECL_P (t))
    6843            0 :                       t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
    6844              :                                                     build_fold_addr_expr (t));
    6845            5 :                     if (REFERENCE_CLASS_P (t))
    6846            5 :                       TREE_THIS_VOLATILE (t) = volatile_p;
    6847              :                   }
    6848       130795 :                 *from_p = t;
    6849       130795 :                 ret = GS_OK;
    6850       130795 :                 changed = true;
    6851              :               }
    6852              :           break;
    6853              : 
    6854       199969 :         case TARGET_EXPR:
    6855       199969 :           {
    6856              :             /* If we are initializing something from a TARGET_EXPR, strip the
    6857              :                TARGET_EXPR and initialize it directly, if possible.  This can't
    6858              :                be done if the initializer is void, since that implies that the
    6859              :                temporary is set in some non-trivial way.
    6860              : 
    6861              :                ??? What about code that pulls out the temp and uses it
    6862              :                elsewhere? I think that such code never uses the TARGET_EXPR as
    6863              :                an initializer.  If I'm wrong, we'll die because the temp won't
    6864              :                have any RTL.  In that case, I guess we'll need to replace
    6865              :                references somehow.  */
    6866       199969 :             tree init = TARGET_EXPR_INITIAL (*from_p);
    6867              : 
    6868       199969 :             if (init
    6869       199253 :                 && (TREE_CODE (*expr_p) != MODIFY_EXPR
    6870        52058 :                     || !TARGET_EXPR_NO_ELIDE (*from_p))
    6871       399004 :                 && !VOID_TYPE_P (TREE_TYPE (init)))
    6872              :               {
    6873       183379 :                 *from_p = init;
    6874       183379 :                 ret = GS_OK;
    6875       183379 :                 changed = true;
    6876              :               }
    6877              :           }
    6878              :           break;
    6879              : 
    6880       335295 :         case COMPOUND_EXPR:
    6881              :           /* Remove any COMPOUND_EXPR in the RHS so the following cases will be
    6882              :              caught.  */
    6883       335295 :           gimplify_compound_expr (from_p, pre_p, true);
    6884       335295 :           ret = GS_OK;
    6885       335295 :           changed = true;
    6886       335295 :           break;
    6887              : 
    6888      1366225 :         case CONSTRUCTOR:
    6889              :           /* If we already made some changes, let the front end have a
    6890              :              crack at this before we break it down.  */
    6891      1366225 :           if (ret != GS_UNHANDLED)
    6892              :             break;
    6893              : 
    6894              :           /* If we're initializing from a CONSTRUCTOR, break this into
    6895              :              individual MODIFY_EXPRs.  */
    6896      1345401 :           ret = gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
    6897              :                                            false);
    6898      1345401 :           return ret;
    6899              : 
    6900       227627 :         case COND_EXPR:
    6901              :           /* If we're assigning to a non-register type, push the assignment
    6902              :              down into the branches.  This is mandatory for ADDRESSABLE types,
    6903              :              since we cannot generate temporaries for such, but it saves a
    6904              :              copy in other cases as well.
    6905              :              Also avoid an extra temporary and copy when assigning to
    6906              :              a register.  */
    6907       227627 :           if (!is_gimple_reg_type (TREE_TYPE (*from_p))
    6908       227627 :               || (is_gimple_reg (*to_p) && !gimplify_ctxp->allow_rhs_cond_expr))
    6909              :             {
    6910              :               /* This code should mirror the code in gimplify_cond_expr. */
    6911       145900 :               enum tree_code code = TREE_CODE (*expr_p);
    6912       145900 :               tree cond = *from_p;
    6913       145900 :               tree result = *to_p;
    6914              : 
    6915       145900 :               ret = gimplify_expr (&result, pre_p, post_p,
    6916              :                                    is_gimple_lvalue, fb_lvalue);
    6917       145900 :               if (ret != GS_ERROR)
    6918       145900 :                 ret = GS_OK;
    6919              : 
    6920              :               /* If we are going to write RESULT more than once, clear
    6921              :                  TREE_READONLY flag, otherwise we might incorrectly promote
    6922              :                  the variable to static const and initialize it at compile
    6923              :                  time in one of the branches.  */
    6924       145900 :               if (VAR_P (result)
    6925       144878 :                   && TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node
    6926       281705 :                   && TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
    6927       135704 :                 TREE_READONLY (result) = 0;
    6928       145900 :               if (TREE_TYPE (TREE_OPERAND (cond, 1)) != void_type_node)
    6929       136691 :                 TREE_OPERAND (cond, 1)
    6930       273382 :                   = build2 (code, void_type_node, result,
    6931       136691 :                             TREE_OPERAND (cond, 1));
    6932       145900 :               if (TREE_TYPE (TREE_OPERAND (cond, 2)) != void_type_node)
    6933       145799 :                 TREE_OPERAND (cond, 2)
    6934       291598 :                   = build2 (code, void_type_node, unshare_expr (result),
    6935       145799 :                             TREE_OPERAND (cond, 2));
    6936              : 
    6937       145900 :               TREE_TYPE (cond) = void_type_node;
    6938       145900 :               recalculate_side_effects (cond);
    6939              : 
    6940       145900 :               if (want_value)
    6941              :                 {
    6942           68 :                   gimplify_and_add (cond, pre_p);
    6943           68 :                   *expr_p = unshare_expr (result);
    6944              :                 }
    6945              :               else
    6946              :                 *expr_p = cond;
    6947       145900 :               return ret;
    6948              :             }
    6949              :           break;
    6950              : 
    6951     10373877 :         case CALL_EXPR:
    6952              :           /* For calls that return in memory, give *to_p as the CALL_EXPR's
    6953              :              return slot so that we don't generate a temporary.  */
    6954     10373877 :           if (!CALL_EXPR_RETURN_SLOT_OPT (*from_p)
    6955     10373877 :               && aggregate_value_p (*from_p, *from_p))
    6956              :             {
    6957       253727 :               bool use_target;
    6958              : 
    6959       253727 :               if (!(rhs_predicate_for (*to_p))(*from_p))
    6960              :                 /* If we need a temporary, *to_p isn't accurate.  */
    6961              :                 use_target = false;
    6962              :               /* It's OK to use the return slot directly unless it's an NRV. */
    6963       252906 :               else if (TREE_CODE (*to_p) == RESULT_DECL
    6964         6779 :                        && DECL_NAME (*to_p) == NULL_TREE
    6965       259541 :                        && needs_to_live_in_memory (*to_p))
    6966              :                 use_target = true;
    6967       246271 :               else if (is_gimple_reg_type (TREE_TYPE (*to_p))
    6968       246271 :                        || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
    6969              :                 /* Don't force regs into memory.  */
    6970              :                 use_target = false;
    6971       231713 :               else if (TREE_CODE (*expr_p) == INIT_EXPR)
    6972              :                 /* It's OK to use the target directly if it's being
    6973              :                    initialized. */
    6974              :                 use_target = true;
    6975        14653 :               else if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p)))
    6976              :                        != INTEGER_CST)
    6977              :                 /* Always use the target and thus RSO for variable-sized types.
    6978              :                    GIMPLE cannot deal with a variable-sized assignment
    6979              :                    embedded in a call statement.  */
    6980              :                 use_target = true;
    6981        14625 :               else if (TREE_CODE (*to_p) != SSA_NAME
    6982        14625 :                       && (!is_gimple_variable (*to_p)
    6983        11288 :                           || needs_to_live_in_memory (*to_p)))
    6984              :                 /* Don't use the original target if it's already addressable;
    6985              :                    if its address escapes, and the called function uses the
    6986              :                    NRV optimization, a conforming program could see *to_p
    6987              :                    change before the called function returns; see c++/19317.
    6988              :                    When optimizing, the return_slot pass marks more functions
    6989              :                    as safe after we have escape info.  */
    6990              :                 use_target = false;
    6991              :               else
    6992              :                 use_target = true;
    6993              : 
    6994              :               if (use_target)
    6995              :                 {
    6996       225914 :                   CALL_EXPR_RETURN_SLOT_OPT (*from_p) = 1;
    6997       225914 :                   mark_addressable (*to_p);
    6998              :                 }
    6999              :             }
    7000              :           break;
    7001              : 
    7002         1560 :         case WITH_SIZE_EXPR:
    7003              :           /* Likewise for calls that return an aggregate of non-constant size,
    7004              :              since we would not be able to generate a temporary at all.  */
    7005         1560 :           if (TREE_CODE (TREE_OPERAND (*from_p, 0)) == CALL_EXPR)
    7006              :             {
    7007          350 :               *from_p = TREE_OPERAND (*from_p, 0);
    7008              :               /* We don't change ret in this case because the
    7009              :                  WITH_SIZE_EXPR might have been added in
    7010              :                  gimplify_modify_expr, so returning GS_OK would lead to an
    7011              :                  infinite loop.  */
    7012          350 :               changed = true;
    7013              :             }
    7014              :           break;
    7015              : 
    7016              :           /* If we're initializing from a container, push the initialization
    7017              :              inside it.  */
    7018         1994 :         case CLEANUP_POINT_EXPR:
    7019         1994 :         case BIND_EXPR:
    7020         1994 :         case STATEMENT_LIST:
    7021         1994 :           {
    7022         1994 :             tree wrap = *from_p;
    7023         1994 :             tree t;
    7024              : 
    7025         1994 :             ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
    7026              :                                  fb_lvalue);
    7027         1994 :             if (ret != GS_ERROR)
    7028         1994 :               ret = GS_OK;
    7029              : 
    7030         1994 :             t = voidify_wrapper_expr (wrap, *expr_p);
    7031         1994 :             gcc_assert (t == *expr_p);
    7032              : 
    7033         1994 :             if (want_value)
    7034              :               {
    7035            6 :                 gimplify_and_add (wrap, pre_p);
    7036            6 :                 *expr_p = unshare_expr (*to_p);
    7037              :               }
    7038              :             else
    7039         1988 :               *expr_p = wrap;
    7040              :             return GS_OK;
    7041              :           }
    7042              : 
    7043      9841463 :         case NOP_EXPR:
    7044              :           /* Pull out compound literal expressions from a NOP_EXPR.
    7045              :              Those are created in the C FE to drop qualifiers during
    7046              :              lvalue conversion.  */
    7047      9841463 :           if ((TREE_CODE (TREE_OPERAND (*from_p, 0)) == COMPOUND_LITERAL_EXPR)
    7048      9841463 :               && tree_ssa_useless_type_conversion (*from_p))
    7049              :             {
    7050           13 :               *from_p = TREE_OPERAND (*from_p, 0);
    7051           13 :               ret = GS_OK;
    7052           13 :               changed = true;
    7053              :             }
    7054              :           break;
    7055              : 
    7056         4956 :         case COMPOUND_LITERAL_EXPR:
    7057         4956 :           {
    7058         4956 :             tree complit = TREE_OPERAND (*expr_p, 1);
    7059         4956 :             tree decl_s = COMPOUND_LITERAL_EXPR_DECL_EXPR (complit);
    7060         4956 :             tree decl = DECL_EXPR_DECL (decl_s);
    7061         4956 :             tree init = DECL_INITIAL (decl);
    7062              : 
    7063              :             /* struct T x = (struct T) { 0, 1, 2 } can be optimized
    7064              :                into struct T x = { 0, 1, 2 } if the address of the
    7065              :                compound literal has never been taken.  */
    7066         4956 :             if (!TREE_ADDRESSABLE (complit)
    7067         4956 :                 && !TREE_ADDRESSABLE (decl)
    7068         4956 :                 && init)
    7069              :               {
    7070         4956 :                 *expr_p = copy_node (*expr_p);
    7071         4956 :                 TREE_OPERAND (*expr_p, 1) = init;
    7072         4956 :                 return GS_OK;
    7073              :               }
    7074              :           }
    7075              : 
    7076              :         default:
    7077              :           break;
    7078              :         }
    7079              :     }
    7080              :   while (changed);
    7081              : 
    7082              :   return ret;
    7083              : }
    7084              : 
    7085              : 
    7086              : /* Return true if T looks like a valid GIMPLE statement.  */
    7087              : 
    7088              : static bool
    7089     19697441 : is_gimple_stmt (tree t)
    7090              : {
    7091     19697441 :   const enum tree_code code = TREE_CODE (t);
    7092              : 
    7093     19697441 :   switch (code)
    7094              :     {
    7095      1775837 :     case NOP_EXPR:
    7096              :       /* The only valid NOP_EXPR is the empty statement.  */
    7097      1775837 :       return IS_EMPTY_STMT (t);
    7098              : 
    7099            0 :     case BIND_EXPR:
    7100            0 :     case COND_EXPR:
    7101              :       /* These are only valid if they're void.  */
    7102            0 :       return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
    7103              : 
    7104              :     case SWITCH_EXPR:
    7105              :     case GOTO_EXPR:
    7106              :     case RETURN_EXPR:
    7107              :     case LABEL_EXPR:
    7108              :     case CASE_LABEL_EXPR:
    7109              :     case TRY_CATCH_EXPR:
    7110              :     case TRY_FINALLY_EXPR:
    7111              :     case EH_FILTER_EXPR:
    7112              :     case CATCH_EXPR:
    7113              :     case ASM_EXPR:
    7114              :     case STATEMENT_LIST:
    7115              :     case OACC_PARALLEL:
    7116              :     case OACC_KERNELS:
    7117              :     case OACC_SERIAL:
    7118              :     case OACC_DATA:
    7119              :     case OACC_HOST_DATA:
    7120              :     case OACC_DECLARE:
    7121              :     case OACC_UPDATE:
    7122              :     case OACC_ENTER_DATA:
    7123              :     case OACC_EXIT_DATA:
    7124              :     case OACC_CACHE:
    7125              :     case OMP_PARALLEL:
    7126              :     case OMP_FOR:
    7127              :     case OMP_SIMD:
    7128              :     case OMP_DISTRIBUTE:
    7129              :     case OMP_LOOP:
    7130              :     case OMP_TILE:
    7131              :     case OMP_UNROLL:
    7132              :     case OACC_LOOP:
    7133              :     case OMP_SCAN:
    7134              :     case OMP_SCOPE:
    7135              :     case OMP_DISPATCH:
    7136              :     case OMP_SECTIONS:
    7137              :     case OMP_SECTION:
    7138              :     case OMP_STRUCTURED_BLOCK:
    7139              :     case OMP_SINGLE:
    7140              :     case OMP_MASTER:
    7141              :     case OMP_MASKED:
    7142              :     case OMP_TASKGROUP:
    7143              :     case OMP_ORDERED:
    7144              :     case OMP_CRITICAL:
    7145              :     case OMP_METADIRECTIVE:
    7146              :     case OMP_TASK:
    7147              :     case OMP_TARGET:
    7148              :     case OMP_TARGET_DATA:
    7149              :     case OMP_TARGET_UPDATE:
    7150              :     case OMP_TARGET_ENTER_DATA:
    7151              :     case OMP_TARGET_EXIT_DATA:
    7152              :     case OMP_TASKLOOP:
    7153              :     case OMP_TEAMS:
    7154              :       /* These are always void.  */
    7155              :       return true;
    7156              : 
    7157              :     case CALL_EXPR:
    7158              :     case MODIFY_EXPR:
    7159              :     case PREDICT_EXPR:
    7160              :       /* These are valid regardless of their type.  */
    7161              :       return true;
    7162              : 
    7163              :     default:
    7164              :       return false;
    7165              :     }
    7166              : }
    7167              : 
    7168              : 
    7169              : /* Promote partial stores to COMPLEX variables to total stores.  *EXPR_P is
    7170              :    a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a gimple register.
    7171              : 
    7172              :    IMPORTANT NOTE: This promotion is performed by introducing a load of the
    7173              :    other, unmodified part of the complex object just before the total store.
    7174              :    As a consequence, if the object is still uninitialized, an undefined value
    7175              :    will be loaded into a register, which may result in a spurious exception
    7176              :    if the register is floating-point and the value happens to be a signaling
    7177              :    NaN for example.  Then the fully-fledged complex operations lowering pass
    7178              :    followed by a DCE pass are necessary in order to fix things up.  */
    7179              : 
    7180              : static enum gimplify_status
    7181         1942 : gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
    7182              :                                    bool want_value)
    7183              : {
    7184         1942 :   enum tree_code code, ocode;
    7185         1942 :   tree lhs, rhs, new_rhs, other, realpart, imagpart;
    7186              : 
    7187         1942 :   lhs = TREE_OPERAND (*expr_p, 0);
    7188         1942 :   rhs = TREE_OPERAND (*expr_p, 1);
    7189         1942 :   code = TREE_CODE (lhs);
    7190         1942 :   lhs = TREE_OPERAND (lhs, 0);
    7191              : 
    7192         1942 :   ocode = code == REALPART_EXPR ? IMAGPART_EXPR : REALPART_EXPR;
    7193         1942 :   other = build1 (ocode, TREE_TYPE (rhs), lhs);
    7194         1942 :   suppress_warning (other);
    7195         1942 :   other = get_formal_tmp_var (other, pre_p);
    7196              : 
    7197         1942 :   realpart = code == REALPART_EXPR ? rhs : other;
    7198          957 :   imagpart = code == REALPART_EXPR ? other : rhs;
    7199              : 
    7200         1942 :   if (TREE_CONSTANT (realpart) && TREE_CONSTANT (imagpart))
    7201            0 :     new_rhs = build_complex (TREE_TYPE (lhs), realpart, imagpart);
    7202              :   else
    7203         1942 :     new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
    7204              : 
    7205         1942 :   gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
    7206         1942 :   *expr_p = (want_value) ? rhs : NULL_TREE;
    7207              : 
    7208         1942 :   return GS_ALL_DONE;
    7209              : }
    7210              : 
    7211              : /* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
    7212              : 
    7213              :       modify_expr
    7214              :               : varname '=' rhs
    7215              :               | '*' ID '=' rhs
    7216              : 
    7217              :     PRE_P points to the list where side effects that must happen before
    7218              :         *EXPR_P should be stored.
    7219              : 
    7220              :     POST_P points to the list where side effects that must happen after
    7221              :         *EXPR_P should be stored.
    7222              : 
    7223              :     WANT_VALUE is nonzero iff we want to use the value of this expression
    7224              :         in another expression.  */
    7225              : 
    7226              : static enum gimplify_status
    7227     51338796 : gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
    7228              :                       bool want_value)
    7229              : {
    7230     51338796 :   tree *from_p = &TREE_OPERAND (*expr_p, 1);
    7231     51338796 :   tree *to_p = &TREE_OPERAND (*expr_p, 0);
    7232     51338796 :   enum gimplify_status ret = GS_UNHANDLED;
    7233     51338796 :   gimple *assign;
    7234     51338796 :   location_t loc = EXPR_LOCATION (*expr_p);
    7235     51338796 :   gimple_stmt_iterator gsi;
    7236              : 
    7237     51338796 :   if (error_operand_p (*from_p) || error_operand_p (*to_p))
    7238              :     return GS_ERROR;
    7239              : 
    7240     51338768 :   gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
    7241              :               || TREE_CODE (*expr_p) == INIT_EXPR);
    7242              : 
    7243              :   /* Trying to simplify a clobber using normal logic doesn't work,
    7244              :      so handle it here.  */
    7245     51338768 :   if (TREE_CLOBBER_P (*from_p))
    7246              :     {
    7247       632860 :       ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
    7248       632860 :       if (ret == GS_ERROR)
    7249              :         return ret;
    7250       632860 :       gcc_assert (!want_value);
    7251       632860 :       if (!VAR_P (*to_p) && TREE_CODE (*to_p) != MEM_REF)
    7252              :         {
    7253          208 :           tree addr = get_initialized_tmp_var (build_fold_addr_expr (*to_p),
    7254              :                                                pre_p, post_p);
    7255          208 :           *to_p = build_simple_mem_ref_loc (EXPR_LOCATION (*to_p), addr);
    7256              :         }
    7257       632860 :       gimplify_seq_add_stmt (pre_p, gimple_build_assign (*to_p, *from_p));
    7258       632860 :       *expr_p = NULL;
    7259       632860 :       return GS_ALL_DONE;
    7260              :     }
    7261              : 
    7262              :   /* Convert initialization from an empty variable-size CONSTRUCTOR to
    7263              :      memset.  */
    7264     50705908 :   if (TREE_TYPE (*from_p) != error_mark_node
    7265     50705908 :       && TYPE_SIZE_UNIT (TREE_TYPE (*from_p))
    7266     50705908 :       && !poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (*from_p)))
    7267         1593 :       && TREE_CODE (*from_p) == CONSTRUCTOR
    7268     50706012 :       && CONSTRUCTOR_NELTS (*from_p) == 0)
    7269              :     {
    7270           84 :       maybe_with_size_expr (from_p);
    7271           84 :       gcc_assert (TREE_CODE (*from_p) == WITH_SIZE_EXPR);
    7272           84 :       return gimplify_modify_expr_to_memset (expr_p,
    7273           84 :                                              TREE_OPERAND (*from_p, 1),
    7274           84 :                                              want_value, pre_p);
    7275              :     }
    7276              : 
    7277              :   /* Insert pointer conversions required by the middle-end that are not
    7278              :      required by the frontend.  This fixes middle-end type checking for
    7279              :      for example gcc.dg/redecl-6.c.  */
    7280     50705824 :   if (POINTER_TYPE_P (TREE_TYPE (*to_p)))
    7281              :     {
    7282     13789318 :       STRIP_USELESS_TYPE_CONVERSION (*from_p);
    7283     13789318 :       if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p)))
    7284          754 :         *from_p = fold_convert_loc (loc, TREE_TYPE (*to_p), *from_p);
    7285              :     }
    7286              : 
    7287              :   /* See if any simplifications can be done based on what the RHS is.  */
    7288     50705824 :   ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
    7289              :                                   want_value);
    7290     50705824 :   if (ret != GS_UNHANDLED)
    7291              :     return ret;
    7292              : 
    7293              :   /* For empty types only gimplify the left hand side and right hand
    7294              :      side as statements and throw away the assignment.  Do this after
    7295              :      gimplify_modify_expr_rhs so we handle TARGET_EXPRs of addressable
    7296              :      types properly.  */
    7297     48625153 :   if (is_empty_type (TREE_TYPE (*from_p))
    7298        13733 :       && !want_value
    7299              :       /* Don't do this for calls that return addressable types, expand_call
    7300              :          relies on those having a lhs.  */
    7301     48638879 :       && !(TREE_ADDRESSABLE (TREE_TYPE (*from_p))
    7302        11667 :            && TREE_CODE (*from_p) == CALL_EXPR))
    7303              :     {
    7304         2059 :       suppress_warning (*from_p, OPT_Wunused_result);
    7305         2059 :       gimplify_stmt (from_p, pre_p);
    7306         2059 :       gimplify_stmt (to_p, pre_p);
    7307         2059 :       *expr_p = NULL_TREE;
    7308         2059 :       return GS_ALL_DONE;
    7309              :     }
    7310              : 
    7311              :   /* If the value being copied is of variable width, compute the length
    7312              :      of the copy into a WITH_SIZE_EXPR.   Note that we need to do this
    7313              :      before gimplifying any of the operands so that we can resolve any
    7314              :      PLACEHOLDER_EXPRs in the size.  Also note that the RTL expander uses
    7315              :      the size of the expression to be copied, not of the destination, so
    7316              :      that is what we must do here.  */
    7317     48623094 :   maybe_with_size_expr (from_p);
    7318              : 
    7319              :   /* As a special case, we have to temporarily allow for assignments
    7320              :      with a CALL_EXPR on the RHS.  Since in GIMPLE a function call is
    7321              :      a toplevel statement, when gimplifying the GENERIC expression
    7322              :      MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
    7323              :      GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
    7324              : 
    7325              :      Instead, we need to create the tuple GIMPLE_CALL <a, foo>.  To
    7326              :      prevent gimplify_expr from trying to create a new temporary for
    7327              :      foo's LHS, we tell it that it should only gimplify until it
    7328              :      reaches the CALL_EXPR.  On return from gimplify_expr, the newly
    7329              :      created GIMPLE_CALL <foo> will be the last statement in *PRE_P
    7330              :      and all we need to do here is set 'a' to be its LHS.  */
    7331              : 
    7332              :   /* Gimplify the RHS first for C++17 and bug 71104.  */
    7333     48623094 :   gimple_predicate initial_pred = initial_rhs_predicate_for (*to_p);
    7334     48623094 :   ret = gimplify_expr (from_p, pre_p, post_p, initial_pred, fb_rvalue);
    7335     48623094 :   if (ret == GS_ERROR)
    7336              :     return ret;
    7337              : 
    7338              :   /* Then gimplify the LHS.  */
    7339              :   /* If we gimplified the RHS to a CALL_EXPR and that call may return
    7340              :      twice we have to make sure to gimplify into non-SSA as otherwise
    7341              :      the abnormal edge added later will make those defs not dominate
    7342              :      their uses.
    7343              :      ???  Technically this applies only to the registers used in the
    7344              :      resulting non-register *TO_P.  */
    7345     48622944 :   bool saved_into_ssa = gimplify_ctxp->into_ssa;
    7346     48622944 :   if (saved_into_ssa
    7347     46228697 :       && TREE_CODE (*from_p) == CALL_EXPR
    7348     53910203 :       && call_expr_flags (*from_p) & ECF_RETURNS_TWICE)
    7349         1539 :     gimplify_ctxp->into_ssa = false;
    7350     48622944 :   ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
    7351     48622944 :   gimplify_ctxp->into_ssa = saved_into_ssa;
    7352     48622944 :   if (ret == GS_ERROR)
    7353              :     return ret;
    7354              : 
    7355              :   /* Now that the LHS is gimplified, re-gimplify the RHS if our initial
    7356              :      guess for the predicate was wrong.  */
    7357     48622869 :   gimple_predicate final_pred = rhs_predicate_for (*to_p);
    7358     48622869 :   if (final_pred != initial_pred)
    7359              :     {
    7360      8258957 :       ret = gimplify_expr (from_p, pre_p, post_p, final_pred, fb_rvalue);
    7361      8258957 :       if (ret == GS_ERROR)
    7362              :         return ret;
    7363              :     }
    7364              : 
    7365              :   /* In case of va_arg internal fn wrapped in a WITH_SIZE_EXPR, add the type
    7366              :      size as argument to the call.  */
    7367     48622869 :   if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
    7368              :     {
    7369         1457 :       tree call = TREE_OPERAND (*from_p, 0);
    7370         1457 :       tree vlasize = TREE_OPERAND (*from_p, 1);
    7371              : 
    7372         1457 :       if (TREE_CODE (call) == CALL_EXPR
    7373         1457 :           && CALL_EXPR_IFN (call) == IFN_VA_ARG)
    7374              :         {
    7375           95 :           int nargs = call_expr_nargs (call);
    7376           95 :           tree type = TREE_TYPE (call);
    7377           95 :           tree ap = CALL_EXPR_ARG (call, 0);
    7378           95 :           tree tag = CALL_EXPR_ARG (call, 1);
    7379           95 :           tree aptag = CALL_EXPR_ARG (call, 2);
    7380           95 :           tree newcall = build_call_expr_internal_loc (EXPR_LOCATION (call),
    7381              :                                                        IFN_VA_ARG, type,
    7382              :                                                        nargs + 1, ap, tag,
    7383              :                                                        aptag, vlasize);
    7384           95 :           TREE_OPERAND (*from_p, 0) = newcall;
    7385              :         }
    7386              :     }
    7387              : 
    7388              :   /* Now see if the above changed *from_p to something we handle specially.  */
    7389     48622869 :   ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
    7390              :                                   want_value);
    7391     48622869 :   if (ret != GS_UNHANDLED)
    7392              :     return ret;
    7393              : 
    7394              :   /* If we've got a variable sized assignment between two lvalues (i.e. does
    7395              :      not involve a call), then we can make things a bit more straightforward
    7396              :      by converting the assignment to memcpy or memset.  */
    7397     48621906 :   if (TREE_CODE (*from_p) == WITH_SIZE_EXPR)
    7398              :     {
    7399         1107 :       tree from = TREE_OPERAND (*from_p, 0);
    7400         1107 :       tree size = TREE_OPERAND (*from_p, 1);
    7401              : 
    7402         1107 :       if (TREE_CODE (from) == CONSTRUCTOR)
    7403            0 :         return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
    7404         1107 :       else if (is_gimple_addressable (from)
    7405         1107 :                && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (*to_p)))
    7406         2213 :                && ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (from))))
    7407              :         {
    7408         1106 :           *from_p = from;
    7409         1106 :           return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
    7410         1106 :                                                  pre_p);
    7411              :         }
    7412              :     }
    7413              : 
    7414              :   /* Transform partial stores to non-addressable complex variables into
    7415              :      total stores.  This allows us to use real instead of virtual operands
    7416              :      for these variables, which improves optimization.  */
    7417     48620800 :   if ((TREE_CODE (*to_p) == REALPART_EXPR
    7418     48620800 :        || TREE_CODE (*to_p) == IMAGPART_EXPR)
    7419     48620800 :       && is_gimple_reg (TREE_OPERAND (*to_p, 0)))
    7420         1942 :     return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
    7421              : 
    7422              :   /* Try to alleviate the effects of the gimplification creating artificial
    7423              :      temporaries (see for example is_gimple_reg_rhs) on the debug info, but
    7424              :      make sure not to create DECL_DEBUG_EXPR links across functions.  */
    7425     48618858 :   if (!gimplify_ctxp->into_ssa
    7426      2393321 :       && VAR_P (*from_p)
    7427       472395 :       && DECL_IGNORED_P (*from_p)
    7428       351314 :       && DECL_P (*to_p)
    7429       138578 :       && !DECL_IGNORED_P (*to_p)
    7430        38239 :       && decl_function_context (*to_p) == current_function_decl
    7431     48651517 :       && decl_function_context (*from_p) == current_function_decl)
    7432              :     {
    7433        32654 :       if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
    7434        27363 :         DECL_NAME (*from_p)
    7435        54726 :           = create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
    7436        32654 :       DECL_HAS_DEBUG_EXPR_P (*from_p) = 1;
    7437        32654 :       SET_DECL_DEBUG_EXPR (*from_p, *to_p);
    7438              :    }
    7439              : 
    7440     48618858 :   if (want_value && TREE_THIS_VOLATILE (*to_p))
    7441          522 :     *from_p = get_initialized_tmp_var (*from_p, pre_p, post_p);
    7442              : 
    7443     48618858 :   if (TREE_CODE (*from_p) == CALL_EXPR)
    7444              :     {
    7445              :       /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
    7446              :          instead of a GIMPLE_ASSIGN.  */
    7447      4964589 :       gcall *call_stmt;
    7448      4964589 :       if (CALL_EXPR_FN (*from_p) == NULL_TREE)
    7449              :         {
    7450              :           /* Gimplify internal functions created in the FEs.  */
    7451       344234 :           int nargs = call_expr_nargs (*from_p), i;
    7452       344234 :           enum internal_fn ifn = CALL_EXPR_IFN (*from_p);
    7453       344234 :           auto_vec<tree> vargs (nargs);
    7454              : 
    7455      1732502 :           for (i = 0; i < nargs; i++)
    7456              :             {
    7457      1044034 :               gimplify_arg (&CALL_EXPR_ARG (*from_p, i), pre_p,
    7458      1044034 :                             EXPR_LOCATION (*from_p));
    7459      1044034 :               vargs.quick_push (CALL_EXPR_ARG (*from_p, i));
    7460              :             }
    7461       344234 :           call_stmt = gimple_build_call_internal_vec (ifn, vargs);
    7462       344234 :           gimple_call_set_nothrow (call_stmt, TREE_NOTHROW (*from_p));
    7463       688468 :           gimple_set_location (call_stmt, EXPR_LOCATION (*expr_p));
    7464       344234 :         }
    7465              :       else
    7466              :         {
    7467      4620355 :           tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
    7468      4620355 :           CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
    7469      4620355 :           STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
    7470      4620355 :           tree fndecl = get_callee_fndecl (*from_p);
    7471      4620355 :           if (fndecl
    7472      4504565 :               && fndecl_built_in_p (fndecl, BUILT_IN_EXPECT)
    7473      4759272 :               && call_expr_nargs (*from_p) == 3)
    7474        67925 :             call_stmt = gimple_build_call_internal (IFN_BUILTIN_EXPECT, 3,
    7475        67925 :                                                     CALL_EXPR_ARG (*from_p, 0),
    7476        67925 :                                                     CALL_EXPR_ARG (*from_p, 1),
    7477        67925 :                                                     CALL_EXPR_ARG (*from_p, 2));
    7478              :           else
    7479              :             {
    7480      4552430 :               call_stmt = gimple_build_call_from_tree (*from_p, fnptrtype);
    7481              :             }
    7482              :         }
    7483      4964589 :       notice_special_calls (call_stmt);
    7484      4964589 :       if (!gimple_call_noreturn_p (call_stmt) || !should_remove_lhs_p (*to_p))
    7485      4964345 :         gimple_call_set_lhs (call_stmt, *to_p);
    7486          244 :       else if (TREE_CODE (*to_p) == SSA_NAME)
    7487              :         /* The above is somewhat premature, avoid ICEing later for a
    7488              :            SSA name w/o a definition.  We may have uses in the GIMPLE IL.
    7489              :            ???  This doesn't make it a default-def.  */
    7490          137 :         SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
    7491              : 
    7492              :       assign = call_stmt;
    7493              :     }
    7494              :   else
    7495              :     {
    7496     43654269 :       assign = gimple_build_assign (*to_p, *from_p);
    7497     43654269 :       gimple_set_location (assign, EXPR_LOCATION (*expr_p));
    7498     43654269 :       if (COMPARISON_CLASS_P (*from_p))
    7499      1258396 :         copy_warning (assign, *from_p);
    7500              :     }
    7501              : 
    7502     48618858 :   if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
    7503              :     {
    7504              :       /* We should have got an SSA name from the start.  */
    7505     35983286 :       gcc_assert (TREE_CODE (*to_p) == SSA_NAME
    7506              :                   || ! gimple_in_ssa_p (cfun));
    7507              :     }
    7508              : 
    7509     48618858 :   gimplify_seq_add_stmt (pre_p, assign);
    7510     48618858 :   gsi = gsi_last (*pre_p);
    7511     48618858 :   maybe_fold_stmt (&gsi);
    7512              : 
    7513     48618858 :   if (want_value)
    7514              :     {
    7515       696031 :       *expr_p = TREE_THIS_VOLATILE (*to_p) ? *from_p : unshare_expr (*to_p);
    7516       696031 :       return GS_OK;
    7517              :     }
    7518              :   else
    7519     47922827 :     *expr_p = NULL;
    7520              : 
    7521     47922827 :   return GS_ALL_DONE;
    7522              : }
    7523              : 
    7524              : /* Gimplify a comparison between two variable-sized objects.  Do this
    7525              :    with a call to BUILT_IN_MEMCMP.  */
    7526              : 
    7527              : static enum gimplify_status
    7528            0 : gimplify_variable_sized_compare (tree *expr_p)
    7529              : {
    7530            0 :   location_t loc = EXPR_LOCATION (*expr_p);
    7531            0 :   tree op0 = TREE_OPERAND (*expr_p, 0);
    7532            0 :   tree op1 = TREE_OPERAND (*expr_p, 1);
    7533            0 :   tree t, arg, dest, src, expr;
    7534              : 
    7535            0 :   arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
    7536            0 :   arg = unshare_expr (arg);
    7537            0 :   arg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, op0);
    7538            0 :   src = build_fold_addr_expr_loc (loc, op1);
    7539            0 :   dest = build_fold_addr_expr_loc (loc, op0);
    7540            0 :   t = builtin_decl_implicit (BUILT_IN_MEMCMP);
    7541            0 :   t = build_call_expr_loc (loc, t, 3, dest, src, arg);
    7542              : 
    7543            0 :   expr
    7544            0 :     = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
    7545            0 :   SET_EXPR_LOCATION (expr, loc);
    7546            0 :   *expr_p = expr;
    7547              : 
    7548            0 :   return GS_OK;
    7549              : }
    7550              : 
    7551              : /* Gimplify a comparison between two aggregate objects of integral scalar
    7552              :    mode as a comparison between the bitwise equivalent scalar values.  */
    7553              : 
    7554              : static enum gimplify_status
    7555           16 : gimplify_scalar_mode_aggregate_compare (tree *expr_p)
    7556              : {
    7557           16 :   const location_t loc = EXPR_LOCATION (*expr_p);
    7558           16 :   const enum tree_code code = TREE_CODE (*expr_p);
    7559           16 :   tree op0 = TREE_OPERAND (*expr_p, 0);
    7560           16 :   tree op1 = TREE_OPERAND (*expr_p, 1);
    7561           16 :   tree type = TREE_TYPE (op0);
    7562           16 :   tree scalar_type = lang_hooks.types.type_for_mode (TYPE_MODE (type), 1);
    7563              : 
    7564           16 :   op0 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op0);
    7565           16 :   op1 = fold_build1_loc (loc, VIEW_CONVERT_EXPR, scalar_type, op1);
    7566              : 
    7567              :   /* We need to perform ordering comparisons in memory order like memcmp and,
    7568              :      therefore, may need to byte-swap operands for little-endian targets.  */
    7569           16 :   if (code != EQ_EXPR && code != NE_EXPR)
    7570              :     {
    7571            0 :       gcc_assert (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN);
    7572            0 :       gcc_assert (TREE_CODE (scalar_type) == INTEGER_TYPE);
    7573            0 :       tree fndecl;
    7574              : 
    7575            0 :       if (BYTES_BIG_ENDIAN)
    7576              :         fndecl = NULL_TREE;
    7577              :       else
    7578            0 :         switch (int_size_in_bytes (scalar_type))
    7579              :           {
    7580              :           case 1:
    7581              :             fndecl = NULL_TREE;
    7582              :             break;
    7583            0 :           case 2:
    7584            0 :             fndecl = builtin_decl_implicit (BUILT_IN_BSWAP16);
    7585              :             break;
    7586            0 :           case 4:
    7587            0 :             fndecl = builtin_decl_implicit (BUILT_IN_BSWAP32);
    7588              :             break;
    7589            0 :           case 8:
    7590            0 :             fndecl = builtin_decl_implicit (BUILT_IN_BSWAP64);
    7591              :             break;
    7592            0 :           case 16:
    7593            0 :             fndecl = builtin_decl_implicit (BUILT_IN_BSWAP128);
    7594              :             break;
    7595            0 :           default:
    7596            0 :             gcc_unreachable ();
    7597              :           }
    7598              : 
    7599            0 :       if (fndecl)
    7600              :         {
    7601            0 :           op0 = build_call_expr_loc (loc, fndecl, 1, op0);
    7602            0 :           op1 = build_call_expr_loc (loc, fndecl, 1, op1);
    7603              :         }
    7604              :     }
    7605              : 
    7606           16 :   *expr_p = fold_build2_loc (loc, code, TREE_TYPE (*expr_p), op0, op1);
    7607              : 
    7608           16 :   return GS_OK;
    7609              : }
    7610              : 
    7611              : /* Gimplify an expression sequence.  This function gimplifies each
    7612              :    expression and rewrites the original expression with the last
    7613              :    expression of the sequence in GIMPLE form.
    7614              : 
    7615              :    PRE_P points to the list where the side effects for all the
    7616              :        expressions in the sequence will be emitted.
    7617              : 
    7618              :    WANT_VALUE is true when the result of the last COMPOUND_EXPR is used.  */
    7619              : 
    7620              : static enum gimplify_status
    7621      1134828 : gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
    7622              : {
    7623      1134828 :   tree t = *expr_p;
    7624              : 
    7625      1227188 :   do
    7626              :     {
    7627      1227188 :       tree *sub_p = &TREE_OPERAND (t, 0);
    7628              : 
    7629      1227188 :       if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
    7630       215151 :         gimplify_compound_expr (sub_p, pre_p, false);
    7631              :       else
    7632      1012037 :         gimplify_stmt (sub_p, pre_p);
    7633              : 
    7634      1227188 :       t = TREE_OPERAND (t, 1);
    7635              :     }
    7636      1227188 :   while (TREE_CODE (t) == COMPOUND_EXPR);
    7637              : 
    7638      1134828 :   *expr_p = t;
    7639      1134828 :   if (want_value)
    7640              :     return GS_OK;
    7641              :   else
    7642              :     {
    7643       631993 :       gimplify_stmt (expr_p, pre_p);
    7644       631993 :       return GS_ALL_DONE;
    7645              :     }
    7646              : }
    7647              : 
    7648              : /* Gimplify a SAVE_EXPR node.  EXPR_P points to the expression to
    7649              :    gimplify.  After gimplification, EXPR_P will point to a new temporary
    7650              :    that holds the original value of the SAVE_EXPR node.
    7651              : 
    7652              :    PRE_P points to the list where side effects that must happen before
    7653              :    *EXPR_P should be stored.  */
    7654              : 
    7655              : static enum gimplify_status
    7656       444592 : gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
    7657              : {
    7658       444592 :   enum gimplify_status ret = GS_ALL_DONE;
    7659       444592 :   tree val;
    7660              : 
    7661       444592 :   gcc_assert (TREE_CODE (*expr_p) == SAVE_EXPR);
    7662       444592 :   val = TREE_OPERAND (*expr_p, 0);
    7663              : 
    7664       444592 :   if (val && TREE_TYPE (val) == error_mark_node)
    7665              :     return GS_ERROR;
    7666              : 
    7667              :   /* If the SAVE_EXPR has not been resolved, then evaluate it once.  */
    7668       444590 :   if (!SAVE_EXPR_RESOLVED_P (*expr_p))
    7669              :     {
    7670              :       /* The operand may be a void-valued expression.  It is
    7671              :          being executed only for its side-effects.  */
    7672       170893 :       if (TREE_TYPE (val) == void_type_node)
    7673              :         {
    7674          751 :           ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
    7675              :                                is_gimple_stmt, fb_none);
    7676          751 :           val = NULL;
    7677              :         }
    7678              :       else
    7679              :         /* The temporary may not be an SSA name as later abnormal and EH
    7680              :            control flow may invalidate use/def domination.  When in SSA
    7681              :            form then assume there are no such issues and SAVE_EXPRs only
    7682              :            appear via GENERIC foldings.  */
    7683       340284 :         val = get_initialized_tmp_var (val, pre_p, post_p,
    7684              :                                        gimple_in_ssa_p (cfun));
    7685              : 
    7686       170893 :       TREE_OPERAND (*expr_p, 0) = val;
    7687       170893 :       SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
    7688              :     }
    7689              : 
    7690       444590 :   *expr_p = val;
    7691              : 
    7692       444590 :   return ret;
    7693              : }
    7694              : 
    7695              : /* Rewrite the ADDR_EXPR node pointed to by EXPR_P
    7696              : 
    7697              :       unary_expr
    7698              :               : ...
    7699              :               | '&' varname
    7700              :               ...
    7701              : 
    7702              :     PRE_P points to the list where side effects that must happen before
    7703              :         *EXPR_P should be stored.
    7704              : 
    7705              :     POST_P points to the list where side effects that must happen after
    7706              :         *EXPR_P should be stored.  */
    7707              : 
    7708              : static enum gimplify_status
    7709     34440966 : gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
    7710              : {
    7711     34440966 :   tree expr = *expr_p;
    7712     34440966 :   tree op0 = TREE_OPERAND (expr, 0);
    7713     34440966 :   enum gimplify_status ret;
    7714     34440966 :   location_t loc = EXPR_LOCATION (*expr_p);
    7715              : 
    7716     34440966 :   switch (TREE_CODE (op0))
    7717              :     {
    7718       100847 :     case INDIRECT_REF:
    7719       100847 :     do_indirect_ref:
    7720              :       /* Check if we are dealing with an expression of the form '&*ptr'.
    7721              :          While the front end folds away '&*ptr' into 'ptr', these
    7722              :          expressions may be generated internally by the compiler (e.g.,
    7723              :          builtins like __builtin_va_end).  */
    7724              :       /* Caution: the silent array decomposition semantics we allow for
    7725              :          ADDR_EXPR means we can't always discard the pair.  */
    7726              :       /* Gimplification of the ADDR_EXPR operand may drop
    7727              :          cv-qualification conversions, so make sure we add them if
    7728              :          needed.  */
    7729       100847 :       {
    7730       100847 :         tree op00 = TREE_OPERAND (op0, 0);
    7731       100847 :         tree t_expr = TREE_TYPE (expr);
    7732       100847 :         tree t_op00 = TREE_TYPE (op00);
    7733              : 
    7734       100847 :         if (!useless_type_conversion_p (t_expr, t_op00))
    7735            0 :           op00 = fold_convert_loc (loc, TREE_TYPE (expr), op00);
    7736       100847 :         *expr_p = op00;
    7737       100847 :         ret = GS_OK;
    7738              :       }
    7739       100847 :       break;
    7740              : 
    7741            0 :     case VIEW_CONVERT_EXPR:
    7742              :       /* Take the address of our operand and then convert it to the type of
    7743              :          this ADDR_EXPR.
    7744              : 
    7745              :          ??? The interactions of VIEW_CONVERT_EXPR and aliasing is not at
    7746              :          all clear.  The impact of this transformation is even less clear.  */
    7747              : 
    7748              :       /* If the operand is a useless conversion, look through it.  Doing so
    7749              :          guarantees that the ADDR_EXPR and its operand will remain of the
    7750              :          same type.  */
    7751            0 :       if (tree_ssa_useless_type_conversion (TREE_OPERAND (op0, 0)))
    7752            0 :         op0 = TREE_OPERAND (op0, 0);
    7753              : 
    7754            0 :       *expr_p = fold_convert_loc (loc, TREE_TYPE (expr),
    7755              :                                   build_fold_addr_expr_loc (loc,
    7756            0 :                                                         TREE_OPERAND (op0, 0)));
    7757            0 :       ret = GS_OK;
    7758            0 :       break;
    7759              : 
    7760        66224 :     case MEM_REF:
    7761        66224 :       if (integer_zerop (TREE_OPERAND (op0, 1)))
    7762        37980 :         goto do_indirect_ref;
    7763              : 
    7764              :       /* fall through */
    7765              : 
    7766     34357565 :     default:
    7767              :       /* If we see a call to a declared builtin or see its address
    7768              :          being taken (we can unify those cases here) then we can mark
    7769              :          the builtin for implicit generation by GCC.  */
    7770     34357565 :       if (TREE_CODE (op0) == FUNCTION_DECL
    7771     17085496 :           && fndecl_built_in_p (op0, BUILT_IN_NORMAL)
    7772     38343793 :           && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
    7773      1300853 :         set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
    7774              : 
    7775              :       /* We use fb_either here because the C frontend sometimes takes
    7776              :          the address of a call that returns a struct; see
    7777              :          gcc.dg/c99-array-lval-1.c.  The gimplifier will correctly make
    7778              :          the implied temporary explicit.  */
    7779              : 
    7780              :       /* Make the operand addressable.  */
    7781     34357565 :       ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
    7782              :                            is_gimple_addressable, fb_either);
    7783     34357565 :       if (ret == GS_ERROR)
    7784              :         break;
    7785              : 
    7786              :       /* Then mark it.  Beware that it may not be possible to do so directly
    7787              :          if a temporary has been created by the gimplification.  */
    7788     34357561 :       prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p);
    7789              : 
    7790     34357561 :       op0 = TREE_OPERAND (expr, 0);
    7791              : 
    7792              :       /* For various reasons, the gimplification of the expression
    7793              :          may have made a new INDIRECT_REF.  */
    7794     34357561 :       if (INDIRECT_REF_P (op0)
    7795     34357561 :           || (TREE_CODE (op0) == MEM_REF
    7796        45690 :               && integer_zerop (TREE_OPERAND (op0, 1))))
    7797        17446 :         goto do_indirect_ref;
    7798              : 
    7799     34340115 :       mark_addressable (TREE_OPERAND (expr, 0));
    7800              : 
    7801              :       /* The FEs may end up building ADDR_EXPRs early on a decl with
    7802              :          an incomplete type.  Re-build ADDR_EXPRs in canonical form
    7803              :          here.  */
    7804     34340115 :       if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr))))
    7805       153404 :         *expr_p = build_fold_addr_expr (op0);
    7806              : 
    7807              :       /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly.  */
    7808     34340115 :       if (TREE_CODE (*expr_p) == ADDR_EXPR)
    7809     34340115 :         recompute_tree_invariant_for_addr_expr (*expr_p);
    7810              : 
    7811              :       /* If we re-built the ADDR_EXPR add a conversion to the original type
    7812              :          if required.  */
    7813     34340115 :       if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p)))
    7814            0 :         *expr_p = fold_convert (TREE_TYPE (expr), *expr_p);
    7815              : 
    7816              :       break;
    7817              :     }
    7818              : 
    7819     34440966 :   return ret;
    7820              : }
    7821              : 
    7822              : /* Return the number of times character C occurs in string S.  */
    7823              : 
    7824              : static int
    7825        94940 : num_occurrences (int c, const char *s)
    7826              : {
    7827        94940 :   int n = 0;
    7828       257441 :   while (*s)
    7829       162501 :     n += (*s++ == c);
    7830        94940 :   return n;
    7831              : }
    7832              : 
    7833              : /* A subroutine of gimplify_asm_expr.  Check that all operands have
    7834              :    the same number of alternatives.  Return -1 if this is violated.  Otherwise
    7835              :    return the number of alternatives.  */
    7836              : 
    7837              : static int
    7838       166200 : num_alternatives (const_tree link)
    7839              : {
    7840       166200 :   if (link == nullptr)
    7841              :     return 0;
    7842              : 
    7843        48799 :   const char *constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
    7844        48799 :   int num = num_occurrences (',', constraint);
    7845              : 
    7846        48799 :   if (num + 1 > MAX_RECOG_ALTERNATIVES)
    7847              :     return -1;
    7848              : 
    7849        94940 :   for (link = TREE_CHAIN (link); link; link = TREE_CHAIN (link))
    7850              :     {
    7851        46141 :       constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
    7852        92282 :       if (num_occurrences (',', constraint) != num)
    7853              :         return -1;
    7854              :     }
    7855        48799 :   return num + 1;
    7856              : }
    7857              : 
    7858              : /* Gimplify the operands of an ASM_EXPR.  Input operands should be a gimple
    7859              :    value; output operands should be a gimple lvalue.  */
    7860              : 
    7861              : static enum gimplify_status
    7862        83100 : gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
    7863              : {
    7864        83100 :   tree expr;
    7865        83100 :   int noutputs;
    7866        83100 :   const char **oconstraints;
    7867        83100 :   int i;
    7868        83100 :   tree link;
    7869        83100 :   const char *constraint;
    7870        83100 :   bool allows_mem, allows_reg, is_inout;
    7871        83100 :   enum gimplify_status ret, tret;
    7872        83100 :   gasm *stmt;
    7873        83100 :   vec<tree, va_gc> *inputs;
    7874        83100 :   vec<tree, va_gc> *outputs;
    7875        83100 :   vec<tree, va_gc> *clobbers;
    7876        83100 :   vec<tree, va_gc> *labels;
    7877        83100 :   tree link_next;
    7878              : 
    7879        83100 :   expr = *expr_p;
    7880        83100 :   noutputs = list_length (ASM_OUTPUTS (expr));
    7881        83100 :   oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
    7882              : 
    7883        83100 :   inputs = NULL;
    7884        83100 :   outputs = NULL;
    7885        83100 :   clobbers = NULL;
    7886        83100 :   labels = NULL;
    7887              : 
    7888        83100 :   int num_alternatives_out = num_alternatives (ASM_OUTPUTS (expr));
    7889        83100 :   int num_alternatives_in = num_alternatives (ASM_INPUTS (expr));
    7890        83100 :   if (num_alternatives_out == -1 || num_alternatives_in == -1
    7891        83100 :       || (num_alternatives_out > 0 && num_alternatives_in > 0
    7892        17276 :           && num_alternatives_out != num_alternatives_in))
    7893              :     {
    7894            0 :       error ("operand constraints for %<asm%> differ "
    7895              :              "in number of alternatives");
    7896            0 :       return GS_ERROR;
    7897              :     }
    7898        83100 :   int num_alternatives = MAX (num_alternatives_out, num_alternatives_in);
    7899              : 
    7900        83100 :   gimplify_reg_info reg_info (num_alternatives, noutputs);
    7901              : 
    7902        83100 :   link_next = NULL_TREE;
    7903       163440 :   for (link = ASM_CLOBBERS (expr); link; link = link_next)
    7904              :     {
    7905              :       /* The clobber entry could also be an error marker.  */
    7906        80340 :       if (TREE_CODE (TREE_VALUE (link)) == STRING_CST)
    7907              :         {
    7908        80317 :           const char *regname= TREE_STRING_POINTER (TREE_VALUE (link));
    7909        80317 :           int regno = decode_reg_name (regname);
    7910        80317 :           if (regno >= 0)
    7911        41263 :             reg_info.set_clobbered (regno);
    7912              :         }
    7913        80340 :       link_next = TREE_CHAIN (link);
    7914        80340 :       TREE_CHAIN (link) = NULL_TREE;
    7915        80340 :       vec_safe_push (clobbers, link);
    7916              :     }
    7917              : 
    7918        83100 :   ret = GS_ALL_DONE;
    7919        83100 :   link_next = NULL_TREE;
    7920       144340 :   for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
    7921              :     {
    7922        61273 :       bool ok;
    7923        61273 :       size_t constraint_len;
    7924              : 
    7925        61273 :       if (error_operand_p (TREE_VALUE (link)))
    7926              :         return GS_ERROR;
    7927        61252 :       link_next = TREE_CHAIN (link);
    7928              : 
    7929       122504 :       oconstraints[i]
    7930        61252 :         = constraint
    7931        61252 :         = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
    7932        61252 :       constraint_len = strlen (constraint);
    7933        61252 :       if (constraint_len == 0)
    7934            0 :         continue;
    7935              : 
    7936        61252 :       reg_info.operand = TREE_VALUE (link);
    7937        61252 :       ok = parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
    7938              :                                     &allows_reg, &is_inout, &reg_info);
    7939        61252 :       if (!ok)
    7940              :         {
    7941           11 :           ret = GS_ERROR;
    7942           11 :           is_inout = false;
    7943              :         }
    7944              : 
    7945              :       /* If we can't make copies, we can only accept memory.
    7946              :          Similarly for VLAs.  */
    7947        61252 :       tree outtype = TREE_TYPE (TREE_VALUE (link));
    7948        61252 :       if (TREE_ADDRESSABLE (outtype)
    7949        61229 :           || !COMPLETE_TYPE_P (outtype)
    7950       122440 :           || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (outtype)))
    7951              :         {
    7952          288 :           if (allows_mem)
    7953          276 :             allows_reg = 0;
    7954              :           else
    7955              :             {
    7956           12 :               error ("impossible constraint in %<asm%>");
    7957           12 :               error ("non-memory output %d must stay in memory", i);
    7958           12 :               return GS_ERROR;
    7959              :             }
    7960              :         }
    7961              : 
    7962        61240 :       if (!allows_reg && allows_mem)
    7963         2079 :         mark_addressable (TREE_VALUE (link));
    7964              : 
    7965        61240 :       tree orig = TREE_VALUE (link);
    7966       113760 :       tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
    7967              :                             is_inout ? is_gimple_min_lval : is_gimple_lvalue,
    7968              :                             fb_lvalue | fb_mayfail);
    7969        61240 :       if (tret == GS_ERROR)
    7970              :         {
    7971            0 :           if (orig != error_mark_node)
    7972            0 :             error ("invalid lvalue in %<asm%> output %d", i);
    7973              :           ret = tret;
    7974              :         }
    7975              : 
    7976              :       /* If the gimplified operand is a register we do not allow memory.  */
    7977        61240 :       if (allows_reg
    7978        59158 :           && allows_mem
    7979        67435 :           && (is_gimple_reg (TREE_VALUE (link))
    7980          267 :               || (handled_component_p (TREE_VALUE (link))
    7981           36 :                   && is_gimple_reg (TREE_OPERAND (TREE_VALUE (link), 0)))))
    7982         5929 :         allows_mem = 0;
    7983              : 
    7984              :       /* If the constraint does not allow memory make sure we gimplify
    7985              :          it to a register if it is not already but its base is.  This
    7986              :          happens for complex and vector components.  */
    7987        61240 :       if (!allows_mem)
    7988              :         {
    7989        58895 :           tree op = TREE_VALUE (link);
    7990        58895 :           if (! is_gimple_val (op)
    7991        21375 :               && is_gimple_reg_type (TREE_TYPE (op))
    7992        80269 :               && is_gimple_reg (get_base_address (op)))
    7993              :             {
    7994           19 :               tree tem = create_tmp_reg (TREE_TYPE (op));
    7995           19 :               tree ass;
    7996           19 :               if (is_inout)
    7997              :                 {
    7998            7 :                   ass = build2 (MODIFY_EXPR, TREE_TYPE (tem),
    7999              :                                 tem, unshare_expr (op));
    8000            7 :                   gimplify_and_add (ass, pre_p);
    8001              :                 }
    8002           19 :               ass = build2 (MODIFY_EXPR, TREE_TYPE (tem), op, tem);
    8003           19 :               gimplify_and_add (ass, post_p);
    8004              : 
    8005           19 :               TREE_VALUE (link) = tem;
    8006           19 :               tret = GS_OK;
    8007              :             }
    8008              :         }
    8009              : 
    8010        61240 :       vec_safe_push (outputs, link);
    8011        61240 :       TREE_CHAIN (link) = NULL_TREE;
    8012              : 
    8013        61240 :       if (is_inout)
    8014              :         {
    8015              :           /* An input/output operand.  To give the optimizers more
    8016              :              flexibility, split it into separate input and output
    8017              :              operands.  */
    8018         8720 :           tree input;
    8019              :           /* Buffer big enough to format a 32-bit UINT_MAX into.  */
    8020         8720 :           char buf[11];
    8021              : 
    8022              :           /* Turn the in/out constraint into an output constraint.  */
    8023         8720 :           char *p = xstrdup (constraint);
    8024         8720 :           p[0] = '=';
    8025         8720 :           TREE_PURPOSE (link) = unshare_expr (TREE_PURPOSE (link));
    8026         8720 :           TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
    8027              : 
    8028              :           /* And add a matching input constraint.  */
    8029         8720 :           if (allows_reg)
    8030              :             {
    8031         8219 :               sprintf (buf, "%u", i);
    8032              : 
    8033              :               /* If there are multiple alternatives in the constraint,
    8034              :                  handle each of them individually.  Those that allow register
    8035              :                  will be replaced with operand number, the others will stay
    8036              :                  unchanged.  */
    8037         8219 :               if (strchr (p, ',') != NULL)
    8038              :                 {
    8039          100 :                   size_t len = 0, buflen = strlen (buf);
    8040          100 :                   char *beg, *end, *str, *dst;
    8041              : 
    8042          100 :                   for (beg = p + 1;;)
    8043              :                     {
    8044          200 :                       end = strchr (beg, ',');
    8045          200 :                       if (end == NULL)
    8046          100 :                         end = strchr (beg, '\0');
    8047          200 :                       if ((size_t) (end - beg) < buflen)
    8048           28 :                         len += buflen + 1;
    8049              :                       else
    8050          172 :                         len += end - beg + 1;
    8051          200 :                       if (*end)
    8052          100 :                         beg = end + 1;
    8053              :                       else
    8054              :                         break;
    8055              :                     }
    8056              : 
    8057          100 :                   str = (char *) alloca (len);
    8058          100 :                   for (beg = p + 1, dst = str;;)
    8059              :                     {
    8060          200 :                       const char *tem;
    8061          200 :                       bool mem_p, reg_p, inout_p;
    8062              : 
    8063          200 :                       end = strchr (beg, ',');
    8064          200 :                       if (end)
    8065          100 :                         *end = '\0';
    8066          200 :                       beg[-1] = '=';
    8067          200 :                       tem = beg - 1;
    8068          200 :                       parse_output_constraint (&tem, i, 0, 0, &mem_p, &reg_p,
    8069              :                                                &inout_p, nullptr);
    8070          200 :                       if (dst != str)
    8071          100 :                         *dst++ = ',';
    8072          200 :                       if (reg_p)
    8073              :                         {
    8074          115 :                           memcpy (dst, buf, buflen);
    8075          115 :                           dst += buflen;
    8076              :                         }
    8077              :                       else
    8078              :                         {
    8079           85 :                           if (end)
    8080            0 :                             len = end - beg;
    8081              :                           else
    8082           85 :                             len = strlen (beg);
    8083           85 :                           memcpy (dst, beg, len);
    8084           85 :                           dst += len;
    8085              :                         }
    8086          200 :                       if (end)
    8087          100 :                         beg = end + 1;
    8088              :                       else
    8089              :                         break;
    8090          100 :                     }
    8091          100 :                   *dst = '\0';
    8092          100 :                   input = build_string (dst - str, str);
    8093              :                 }
    8094              :               else
    8095         8119 :                 input = build_string (strlen (buf), buf);
    8096              :             }
    8097              :           else
    8098          501 :             input = build_string (constraint_len - 1, constraint + 1);
    8099              : 
    8100         8720 :           free (p);
    8101              : 
    8102         8720 :           input = build_tree_list (build_tree_list (NULL_TREE, input),
    8103         8720 :                                    unshare_expr (TREE_VALUE (link)));
    8104         8720 :           ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
    8105              :         }
    8106              :     }
    8107              : 
    8108              :   /* After all output operands have been gimplified, verify that each output
    8109              :      operand is used at most once in case of hard register constraints.  Thus,
    8110              :      error out in cases like
    8111              :        asm ("" : "={0}" (x), "={1}" (x));
    8112              :      or even for
    8113              :        asm ("" : "=r" (x), "={1}" (x));
    8114              : 
    8115              :      FIXME: Ideally we would also error out for cases like
    8116              :        int x;
    8117              :        asm ("" : "=r" (x), "=r" (x));
    8118              :      However, since code like that was previously accepted, erroring out now might
    8119              :      break existing code.  On the other hand, we already error out for register
    8120              :      asm like
    8121              :        register int x asm ("0");
    8122              :        asm ("" : "=r" (x), "=r" (x));
    8123              :      Thus, maybe it wouldn't be too bad to also error out in the former
    8124              :      non-register-asm case.
    8125              :   */
    8126       144303 :   for (unsigned i = 0; i < vec_safe_length (outputs); ++i)
    8127              :     {
    8128        61238 :       tree link = (*outputs)[i];
    8129        61238 :       tree op1 = TREE_VALUE (link);
    8130        61238 :       const char *constraint
    8131        61238 :         = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
    8132        61238 :       if (strchr (constraint, '{') != nullptr)
    8133        61378 :         for (unsigned j = 0; j < vec_safe_length (outputs); ++j)
    8134              :           {
    8135          142 :             if (i == j)
    8136           95 :               continue;
    8137           47 :             tree link2 = (*outputs)[j];
    8138           47 :             tree op2 = TREE_VALUE (link2);
    8139           47 :             if (op1 == op2)
    8140              :               {
    8141            2 :                 error ("multiple outputs to lvalue %qE", op2);
    8142            2 :                 return GS_ERROR;
    8143              :               }
    8144              :           }
    8145              :     }
    8146              : 
    8147        83065 :   link_next = NULL_TREE;
    8148        83065 :   int input_num = 0;
    8149       125390 :   for (link = ASM_INPUTS (expr); link; ++input_num, ++i, link = link_next)
    8150              :     {
    8151        42383 :       if (error_operand_p (TREE_VALUE (link)))
    8152              :         return GS_ERROR;
    8153        42334 :       link_next = TREE_CHAIN (link);
    8154        42334 :       constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
    8155        42334 :       reg_info.operand = TREE_VALUE (link);
    8156        42334 :       bool ok = parse_input_constraint (&constraint, input_num, 0, noutputs, 0,
    8157              :                                         oconstraints, &allows_mem, &allows_reg,
    8158              :                                         &reg_info);
    8159        42334 :       if (!ok)
    8160              :         {
    8161           30 :           ret = GS_ERROR;
    8162           30 :           is_inout = false;
    8163              :         }
    8164              : 
    8165              :       /* If we can't make copies, we can only accept memory.  */
    8166        42334 :       tree intype = TREE_TYPE (TREE_VALUE (link));
    8167        42334 :       if (TREE_ADDRESSABLE (intype)
    8168        42308 :           || !COMPLETE_TYPE_P (intype)
    8169        84587 :           || !tree_fits_poly_uint64_p (TYPE_SIZE_UNIT (intype)))
    8170              :         {
    8171          297 :           if (allows_mem)
    8172          288 :             allows_reg = 0;
    8173              :           else
    8174              :             {
    8175            9 :               error ("impossible constraint in %<asm%>");
    8176            9 :               error ("non-memory input %d must stay in memory", i);
    8177            9 :               return GS_ERROR;
    8178              :             }
    8179              :         }
    8180              : 
    8181              :       /* If the operand is a memory input, it should be an lvalue.  */
    8182        42325 :       if (!allows_reg && allows_mem)
    8183              :         {
    8184         2392 :           tree inputv = TREE_VALUE (link);
    8185         2392 :           STRIP_NOPS (inputv);
    8186         2392 :           if (TREE_CODE (inputv) == PREDECREMENT_EXPR
    8187              :               || TREE_CODE (inputv) == PREINCREMENT_EXPR
    8188              :               || TREE_CODE (inputv) == POSTDECREMENT_EXPR
    8189         2392 :               || TREE_CODE (inputv) == POSTINCREMENT_EXPR
    8190         2380 :               || TREE_CODE (inputv) == MODIFY_EXPR
    8191         4770 :               || VOID_TYPE_P (TREE_TYPE (inputv)))
    8192           38 :             TREE_VALUE (link) = error_mark_node;
    8193         2392 :           tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
    8194              :                                 is_gimple_lvalue, fb_lvalue | fb_mayfail);
    8195         2392 :           if (tret != GS_ERROR)
    8196              :             {
    8197              :               /* Unlike output operands, memory inputs are not guaranteed
    8198              :                  to be lvalues by the FE, and while the expressions are
    8199              :                  marked addressable there, if it is e.g. a statement
    8200              :                  expression, temporaries in it might not end up being
    8201              :                  addressable.  They might be already used in the IL and thus
    8202              :                  it is too late to make them addressable now though.  */
    8203         2346 :               tree x = TREE_VALUE (link);
    8204         2488 :               while (handled_component_p (x))
    8205          142 :                 x = TREE_OPERAND (x, 0);
    8206         2346 :               if (TREE_CODE (x) == MEM_REF
    8207         2346 :                   && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
    8208            0 :                 x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
    8209         2346 :               if ((VAR_P (x)
    8210              :                    || TREE_CODE (x) == PARM_DECL
    8211              :                    || TREE_CODE (x) == RESULT_DECL)
    8212         1489 :                   && !TREE_ADDRESSABLE (x)
    8213           23 :                   && is_gimple_reg (x))
    8214              :                 {
    8215           17 :                   warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
    8216           17 :                                                input_location), 0,
    8217              :                               "memory input %d is not directly addressable",
    8218              :                               i);
    8219           17 :                   prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
    8220              :                 }
    8221              :             }
    8222         2392 :           mark_addressable (TREE_VALUE (link));
    8223         2392 :           if (tret == GS_ERROR)
    8224              :             {
    8225           46 :               if (inputv != error_mark_node)
    8226           46 :                 error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
    8227              :                           "memory input %d is not directly addressable", i);
    8228              :               ret = tret;
    8229              :             }
    8230              :         }
    8231              :       else
    8232              :         {
    8233        39933 :           tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
    8234              :                                 is_gimple_asm_val, fb_rvalue);
    8235        39933 :           if (tret == GS_ERROR)
    8236           46 :             ret = tret;
    8237              :         }
    8238              : 
    8239        42325 :       TREE_CHAIN (link) = NULL_TREE;
    8240        42325 :       vec_safe_push (inputs, link);
    8241              :     }
    8242              : 
    8243        83007 :   link_next = NULL_TREE;
    8244        83954 :   for (link = ASM_LABELS (expr); link; link = link_next)
    8245              :     {
    8246          947 :       link_next = TREE_CHAIN (link);
    8247          947 :       TREE_CHAIN (link) = NULL_TREE;
    8248          947 :       vec_safe_push (labels, link);
    8249              :     }
    8250              : 
    8251              :   /* Do not add ASMs with errors to the gimple IL stream.  */
    8252        83007 :   if (ret != GS_ERROR)
    8253              :     {
    8254        82924 :       stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
    8255              :                                    inputs, outputs, clobbers, labels);
    8256              : 
    8257              :       /* asm is volatile if it was marked by the user as volatile or
    8258              :          there are no outputs or this is an asm goto.  */
    8259        90438 :       gimple_asm_set_volatile (stmt,
    8260        82924 :                                ASM_VOLATILE_P (expr)
    8261         7528 :                                || noutputs == 0
    8262              :                                || labels);
    8263        82924 :       gimple_asm_set_basic (stmt, ASM_BASIC_P (expr));
    8264        82924 :       gimple_asm_set_inline (stmt, ASM_INLINE_P (expr));
    8265              : 
    8266        82924 :       gimplify_seq_add_stmt (pre_p, stmt);
    8267              :     }
    8268              : 
    8269              :   return ret;
    8270        83100 : }
    8271              : 
    8272              : /* Gimplify a CLEANUP_POINT_EXPR.  Currently this works by adding
    8273              :    GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
    8274              :    gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
    8275              :    return to this function.
    8276              : 
    8277              :    FIXME should we complexify the prequeue handling instead?  Or use flags
    8278              :    for all the cleanups and let the optimizer tighten them up?  The current
    8279              :    code seems pretty fragile; it will break on a cleanup within any
    8280              :    non-conditional nesting.  But any such nesting would be broken, anyway;
    8281              :    we can't write a TRY_FINALLY_EXPR that starts inside a nesting construct
    8282              :    and continues out of it.  We can do that at the RTL level, though, so
    8283              :    having an optimizer to tighten up try/finally regions would be a Good
    8284              :    Thing.  */
    8285              : 
    8286              : static enum gimplify_status
    8287      5531759 : gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
    8288              : {
    8289      5531759 :   gimple_stmt_iterator iter;
    8290      5531759 :   gimple_seq body_sequence = NULL;
    8291              : 
    8292      5531759 :   tree temp = voidify_wrapper_expr (*expr_p, NULL);
    8293              : 
    8294              :   /* We only care about the number of conditions between the innermost
    8295              :      CLEANUP_POINT_EXPR and the cleanup.  So save and reset the count and
    8296              :      any cleanups collected outside the CLEANUP_POINT_EXPR.  */
    8297      5531759 :   int old_conds = gimplify_ctxp->conditions;
    8298      5531759 :   gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
    8299      5531759 :   bool old_in_cleanup_point_expr = gimplify_ctxp->in_cleanup_point_expr;
    8300      5531759 :   gimplify_ctxp->conditions = 0;
    8301      5531759 :   gimplify_ctxp->conditional_cleanups = NULL;
    8302      5531759 :   gimplify_ctxp->in_cleanup_point_expr = true;
    8303              : 
    8304      5531759 :   gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
    8305              : 
    8306      5531759 :   gimplify_ctxp->conditions = old_conds;
    8307      5531759 :   gimplify_ctxp->conditional_cleanups = old_cleanups;
    8308      5531759 :   gimplify_ctxp->in_cleanup_point_expr = old_in_cleanup_point_expr;
    8309              : 
    8310     28601269 :   for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
    8311              :     {
    8312     17584542 :       gimple *wce = gsi_stmt (iter);
    8313              : 
    8314     17584542 :       if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
    8315              :         {
    8316       674730 :           if (gsi_one_before_end_p (iter))
    8317              :             {
    8318              :               /* Note that gsi_insert_seq_before and gsi_remove do not
    8319              :                  scan operands, unlike some other sequence mutators.  */
    8320         3118 :               if (!gimple_wce_cleanup_eh_only (wce))
    8321         3118 :                 gsi_insert_seq_before_without_update (&iter,
    8322              :                                                       gimple_wce_cleanup (wce),
    8323              :                                                       GSI_SAME_STMT);
    8324         3118 :               gsi_remove (&iter, true);
    8325         3118 :               break;
    8326              :             }
    8327              :           else
    8328              :             {
    8329       671612 :               gtry *gtry;
    8330       671612 :               gimple_seq seq;
    8331       671612 :               enum gimple_try_flags kind;
    8332              : 
    8333       671612 :               if (gimple_wce_cleanup_eh_only (wce))
    8334              :                 kind = GIMPLE_TRY_CATCH;
    8335              :               else
    8336       654177 :                 kind = GIMPLE_TRY_FINALLY;
    8337       671612 :               seq = gsi_split_seq_after (iter);
    8338              : 
    8339       671612 :               gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
    8340              :               /* Do not use gsi_replace here, as it may scan operands.
    8341              :                  We want to do a simple structural modification only.  */
    8342       671612 :               gsi_set_stmt (&iter, gtry);
    8343      1343224 :               iter = gsi_start (gtry->eval);
    8344              :             }
    8345              :         }
    8346              :       else
    8347     16909812 :         gsi_next (&iter);
    8348              :     }
    8349              : 
    8350      5531759 :   gimplify_seq_add_seq (pre_p, body_sequence);
    8351      5531759 :   if (temp)
    8352              :     {
    8353              :       *expr_p = temp;
    8354              :       return GS_OK;
    8355              :     }
    8356              :   else
    8357              :     {
    8358      5166936 :       *expr_p = NULL;
    8359      5166936 :       return GS_ALL_DONE;
    8360              :     }
    8361              : }
    8362              : 
    8363              : /* Insert a cleanup marker for gimplify_cleanup_point_expr.  CLEANUP
    8364              :    is the cleanup action required.  EH_ONLY is true if the cleanup should
    8365              :    only be executed if an exception is thrown, not on normal exit.
    8366              :    If FORCE_UNCOND is true perform the cleanup unconditionally;  this is
    8367              :    only valid for clobbers.  */
    8368              : 
    8369              : static void
    8370       679871 : gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p,
    8371              :                      bool force_uncond = false)
    8372              : {
    8373       679871 :   gimple *wce;
    8374       679871 :   gimple_seq cleanup_stmts = NULL;
    8375              : 
    8376              :   /* Errors can result in improperly nested cleanups.  Which results in
    8377              :      confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR.  */
    8378       679871 :   if (seen_error ())
    8379         5141 :     return;
    8380              : 
    8381       674730 :   if (gimple_conditional_context ())
    8382              :     {
    8383              :       /* If we're in a conditional context, this is more complex.  We only
    8384              :          want to run the cleanup if we actually ran the initialization that
    8385              :          necessitates it, but we want to run it after the end of the
    8386              :          conditional context.  So we wrap the try/finally around the
    8387              :          condition and use a flag to determine whether or not to actually
    8388              :          run the destructor.  Thus
    8389              : 
    8390              :            test ? f(A()) : 0
    8391              : 
    8392              :          becomes (approximately)
    8393              : 
    8394              :            flag = 0;
    8395              :            try {
    8396              :              if (test) { A::A(temp); flag = 1; val = f(temp); }
    8397              :              else { val = 0; }
    8398              :            } finally {
    8399              :              if (flag) A::~A(temp);
    8400              :            }
    8401              :            val
    8402              :       */
    8403        16154 :       if (force_uncond)
    8404              :         {
    8405        15284 :           gimplify_stmt (&cleanup, &cleanup_stmts);
    8406        15284 :           wce = gimple_build_wce (cleanup_stmts);
    8407        15284 :           gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
    8408              :         }
    8409              :       else
    8410              :         {
    8411          870 :           tree flag = create_tmp_var (boolean_type_node, "cleanup");
    8412          870 :           gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
    8413          870 :           gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
    8414              : 
    8415          870 :           cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
    8416          870 :           gimplify_stmt (&cleanup, &cleanup_stmts);
    8417          870 :           wce = gimple_build_wce (cleanup_stmts);
    8418          870 :           gimple_wce_set_cleanup_eh_only (wce, eh_only);
    8419              : 
    8420          870 :           gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
    8421          870 :           gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
    8422          870 :           gimplify_seq_add_stmt (pre_p, ftrue);
    8423              : 
    8424              :           /* Because of this manipulation, and the EH edges that jump
    8425              :              threading cannot redirect, the temporary (VAR) will appear
    8426              :              to be used uninitialized.  Don't warn.  */
    8427          870 :           suppress_warning (var, OPT_Wuninitialized);
    8428              :         }
    8429              :     }
    8430              :   else
    8431              :     {
    8432       658576 :       gimplify_stmt (&cleanup, &cleanup_stmts);
    8433       658576 :       wce = gimple_build_wce (cleanup_stmts);
    8434       658576 :       gimple_wce_set_cleanup_eh_only (wce, eh_only);
    8435       658576 :       gimplify_seq_add_stmt (pre_p, wce);
    8436              :     }
    8437              : }
    8438              : 
    8439              : /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR.  */
    8440              : 
    8441              : static enum gimplify_status
    8442       882656 : gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
    8443              : {
    8444       882656 :   tree targ = *expr_p;
    8445       882656 :   tree temp = TARGET_EXPR_SLOT (targ);
    8446       882656 :   tree init = TARGET_EXPR_INITIAL (targ);
    8447       882656 :   enum gimplify_status ret;
    8448              : 
    8449       882656 :   bool unpoison_empty_seq = false;
    8450       882656 :   gimple_stmt_iterator unpoison_it;
    8451              : 
    8452       882656 :   if (init)
    8453              :     {
    8454       848429 :       gimple_seq init_pre_p = NULL;
    8455       848429 :       bool is_vla = false;
    8456              : 
    8457              :       /* TARGET_EXPR temps aren't part of the enclosing block, so add it
    8458              :          to the temps list.  Handle also variable length TARGET_EXPRs.  */
    8459       848429 :       if (!poly_int_tree_p (DECL_SIZE (temp)))
    8460              :         {
    8461           44 :           if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
    8462            1 :             gimplify_type_sizes (TREE_TYPE (temp), &init_pre_p);
    8463              :           /* FIXME: this is correct only when the size of the type does
    8464              :              not depend on expressions evaluated in init.  */
    8465           44 :           gimplify_vla_decl (temp, &init_pre_p);
    8466           44 :           is_vla = true;
    8467              :         }
    8468              :       else
    8469              :         {
    8470              :           /* Save location where we need to place unpoisoning.  It's possible
    8471              :              that a variable will be converted to needs_to_live_in_memory.  */
    8472       848385 :           unpoison_it = gsi_last (*pre_p);
    8473       848385 :           unpoison_empty_seq = gsi_end_p (unpoison_it);
    8474              : 
    8475       848385 :           gimple_add_tmp_var (temp);
    8476              :         }
    8477              : 
    8478       848429 :       if (var_needs_auto_init_p (temp) && VOID_TYPE_P (TREE_TYPE (init)))
    8479              :         {
    8480        59608 :           gimple_add_init_for_auto_var (temp, flag_auto_var_init, &init_pre_p);
    8481        59608 :           if ((flag_auto_var_init & ~AUTO_INIT_CXX26) == AUTO_INIT_PATTERN
    8482            0 :               && !is_gimple_reg (temp)
    8483        59608 :               && clear_padding_type_may_have_padding_p (TREE_TYPE (temp)))
    8484            0 :             gimple_add_padding_init_for_auto_var (temp, is_vla, &init_pre_p);
    8485              :         }
    8486              : 
    8487              :       /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
    8488              :          expression is supposed to initialize the slot.  */
    8489       848429 :       if (VOID_TYPE_P (TREE_TYPE (init)))
    8490       301007 :         ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
    8491              :                              fb_none);
    8492              :       else
    8493              :         {
    8494       547422 :           tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
    8495       547422 :           init = init_expr;
    8496       547422 :           ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
    8497              :                                fb_none);
    8498       547422 :           init = NULL;
    8499       547422 :           ggc_free (init_expr);
    8500              :         }
    8501       848429 :       if (ret == GS_ERROR)
    8502              :         {
    8503              :           /* PR c++/28266 Make sure this is expanded only once. */
    8504           10 :           TARGET_EXPR_INITIAL (targ) = NULL_TREE;
    8505           10 :           return GS_ERROR;
    8506              :         }
    8507              : 
    8508       848419 :       if (init)
    8509            0 :         gimplify_and_add (init, &init_pre_p);
    8510              : 
    8511              :       /* Add a clobber for the temporary going out of scope, like
    8512              :          gimplify_bind_expr.  But only if we did not promote the
    8513              :          temporary to static storage.  */
    8514       848419 :       if (gimplify_ctxp->in_cleanup_point_expr
    8515       704186 :           && !TREE_STATIC (temp)
    8516      1551055 :           && needs_to_live_in_memory (temp))
    8517              :         {
    8518       515597 :           if (flag_stack_reuse == SR_ALL)
    8519              :             {
    8520       515117 :               tree clobber = build_clobber (TREE_TYPE (temp),
    8521              :                                             CLOBBER_STORAGE_END);
    8522       515117 :               clobber = build2 (MODIFY_EXPR, TREE_TYPE (temp), temp, clobber);
    8523       515117 :               gimple_push_cleanup (temp, clobber, false, pre_p, true);
    8524              :             }
    8525       515597 :           if (asan_poisoned_variables
    8526          480 :               && DECL_ALIGN (temp) <= MAX_SUPPORTED_STACK_ALIGNMENT
    8527          480 :               && !TREE_STATIC (temp)
    8528          480 :               && dbg_cnt (asan_use_after_scope)
    8529       516077 :               && !gimplify_omp_ctxp)
    8530              :             {
    8531          472 :               tree asan_cleanup = build_asan_poison_call_expr (temp);
    8532          472 :               if (asan_cleanup)
    8533              :                 {
    8534          472 :                   if (unpoison_empty_seq)
    8535          217 :                     unpoison_it = gsi_start (*pre_p);
    8536              : 
    8537          472 :                   asan_poison_variable (temp, false, &unpoison_it,
    8538              :                                         unpoison_empty_seq);
    8539          472 :                   gimple_push_cleanup (temp, asan_cleanup, false, pre_p);
    8540              :                 }
    8541              :             }
    8542              :         }
    8543              : 
    8544       848419 :       gimple_seq_add_seq (pre_p, init_pre_p);
    8545              : 
    8546              :       /* If needed, push the cleanup for the temp.  */
    8547       848419 :       if (TARGET_EXPR_CLEANUP (targ))
    8548       164282 :         gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
    8549       164282 :                              CLEANUP_EH_ONLY (targ), pre_p);
    8550              : 
    8551              :       /* Only expand this once.  */
    8552       848419 :       TREE_OPERAND (targ, 3) = init;
    8553       848419 :       TARGET_EXPR_INITIAL (targ) = NULL_TREE;
    8554              :     }
    8555              :   else
    8556              :     /* We should have expanded this before.  */
    8557        34227 :     gcc_assert (DECL_SEEN_IN_BIND_EXPR_P (temp));
    8558              : 
    8559       882646 :   *expr_p = temp;
    8560       882646 :   return GS_OK;
    8561              : }
    8562              : 
    8563              : /* Gimplification of expression trees.  */
    8564              : 
    8565              : /* Gimplify an expression which appears at statement context.  The
    8566              :    corresponding GIMPLE statements are added to *SEQ_P.  If *SEQ_P is
    8567              :    NULL, a new sequence is allocated.
    8568              : 
    8569              :    Return true if we actually added a statement to the queue.  */
    8570              : 
    8571              : bool
    8572    104784023 : gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
    8573              : {
    8574    104784023 :   gimple_seq_node last;
    8575              : 
    8576    104784023 :   last = gimple_seq_last (*seq_p);
    8577    104784023 :   gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
    8578    104784023 :   return last != gimple_seq_last (*seq_p);
    8579              : }
    8580              : 
    8581              : /* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
    8582              :    to CTX.  If entries already exist, force them to be some flavor of private.
    8583              :    If there is no enclosing parallel, do nothing.  */
    8584              : 
    8585              : void
    8586       126226 : omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
    8587              : {
    8588       126226 :   splay_tree_node n;
    8589              : 
    8590       126226 :   if (decl == NULL || !DECL_P (decl) || ctx->region_type == ORT_NONE)
    8591              :     return;
    8592              : 
    8593        36987 :   do
    8594              :     {
    8595        36987 :       n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
    8596        36987 :       if (n != NULL)
    8597              :         {
    8598         4302 :           if (n->value & GOVD_SHARED)
    8599          183 :             n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
    8600         4119 :           else if (n->value & GOVD_MAP)
    8601           58 :             n->value |= GOVD_MAP_TO_ONLY;
    8602              :           else
    8603              :             return;
    8604              :         }
    8605        32685 :       else if ((ctx->region_type & ORT_TARGET) != 0)
    8606              :         {
    8607         7027 :           if (ctx->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
    8608         4268 :             omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
    8609              :           else
    8610         2759 :             omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
    8611              :         }
    8612        25658 :       else if (ctx->region_type != ORT_WORKSHARE
    8613              :                && ctx->region_type != ORT_TASKGROUP
    8614        23829 :                && ctx->region_type != ORT_SIMD
    8615        23205 :                && ctx->region_type != ORT_ACC
    8616        23088 :                && !(ctx->region_type & ORT_TARGET_DATA))
    8617        14507 :         omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
    8618              : 
    8619        32926 :       ctx = ctx->outer_context;
    8620              :     }
    8621        32926 :   while (ctx);
    8622              : }
    8623              : 
    8624              : /* Similarly for each of the type sizes of TYPE.  */
    8625              : 
    8626              : static void
    8627        40253 : omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
    8628              : {
    8629        40253 :   if (type == NULL || type == error_mark_node)
    8630              :     return;
    8631        40249 :   type = TYPE_MAIN_VARIANT (type);
    8632              : 
    8633        40249 :   if (ctx->privatized_types->add (type))
    8634              :     return;
    8635              : 
    8636        31315 :   switch (TREE_CODE (type))
    8637              :     {
    8638        13592 :     case INTEGER_TYPE:
    8639        13592 :     case ENUMERAL_TYPE:
    8640        13592 :     case BOOLEAN_TYPE:
    8641        13592 :     case REAL_TYPE:
    8642        13592 :     case FIXED_POINT_TYPE:
    8643        13592 :       omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
    8644        13592 :       omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
    8645        13592 :       break;
    8646              : 
    8647         5418 :     case ARRAY_TYPE:
    8648         5418 :       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
    8649         5418 :       omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
    8650         5418 :       break;
    8651              : 
    8652         2502 :     case RECORD_TYPE:
    8653         2502 :     case UNION_TYPE:
    8654         2502 :     case QUAL_UNION_TYPE:
    8655         2502 :       {
    8656         2502 :         tree field;
    8657        26645 :         for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    8658        24143 :           if (TREE_CODE (field) == FIELD_DECL)
    8659              :             {
    8660         8997 :               omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
    8661         8997 :               omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
    8662              :             }
    8663              :       }
    8664              :       break;
    8665              : 
    8666         9153 :     case POINTER_TYPE:
    8667         9153 :     case REFERENCE_TYPE:
    8668         9153 :       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
    8669         9153 :       break;
    8670              : 
    8671              :     default:
    8672              :       break;
    8673              :     }
    8674              : 
    8675        31315 :   omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
    8676        31315 :   omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
    8677        31315 :   lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
    8678              : }
    8679              : 
    8680              : /* Add an entry for DECL in the OMP context CTX with FLAGS.  */
    8681              : 
    8682              : static void
    8683       717971 : omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
    8684              : {
    8685       717971 :   splay_tree_node n;
    8686       717971 :   unsigned int nflags;
    8687       717971 :   tree t;
    8688              : 
    8689       717971 :   if (error_operand_p (decl) || ctx->region_type == ORT_NONE)
    8690              :     return;
    8691              : 
    8692              :   /* Never elide decls whose type has TREE_ADDRESSABLE set.  This means
    8693              :      there are constructors involved somewhere.  Exception is a shared clause,
    8694              :      there is nothing privatized in that case.  */
    8695       717823 :   if ((flags & GOVD_SHARED) == 0
    8696       717823 :       && (TREE_ADDRESSABLE (TREE_TYPE (decl))
    8697       657298 :           || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))))
    8698         7758 :     flags |= GOVD_SEEN;
    8699              : 
    8700       717823 :   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
    8701       717823 :   if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
    8702              :     {
    8703              :       /* We shouldn't be re-adding the decl with the same data
    8704              :          sharing class.  */
    8705          828 :       gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
    8706          828 :       nflags = n->value | flags;
    8707              :       /* The only combination of data sharing classes we should see is
    8708              :          FIRSTPRIVATE and LASTPRIVATE.  However, OpenACC permits
    8709              :          reduction variables to be used in data sharing clauses.  */
    8710          828 :       gcc_assert ((ctx->region_type & ORT_ACC) != 0
    8711              :                   || ((nflags & GOVD_DATA_SHARE_CLASS)
    8712              :                       == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE))
    8713              :                   || (flags & GOVD_DATA_SHARE_CLASS) == 0);
    8714          828 :       n->value = nflags;
    8715          828 :       return;
    8716              :     }
    8717              : 
    8718              :   /* When adding a variable-sized variable, we have to handle all sorts
    8719              :      of additional bits of data: the pointer replacement variable, and
    8720              :      the parameters of the type.  */
    8721       716995 :   if (DECL_SIZE (decl) && !poly_int_tree_p (DECL_SIZE (decl)))
    8722              :     {
    8723              :       /* Add the pointer replacement variable as PRIVATE if the variable
    8724              :          replacement is private, else FIRSTPRIVATE since we'll need the
    8725              :          address of the original variable either for SHARED, or for the
    8726              :          copy into or out of the context.  */
    8727         1330 :       if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
    8728              :         {
    8729         1238 :           if (flags & GOVD_MAP)
    8730              :             nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
    8731          531 :           else if (flags & GOVD_PRIVATE)
    8732              :             nflags = GOVD_PRIVATE;
    8733          441 :           else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
    8734           50 :                     && (flags & GOVD_FIRSTPRIVATE))
    8735          431 :                    || (ctx->region_type == ORT_TARGET_DATA
    8736            6 :                        && (flags & GOVD_DATA_SHARE_CLASS) == 0))
    8737              :             nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
    8738              :           else
    8739         1238 :             nflags = GOVD_FIRSTPRIVATE;
    8740         1238 :           nflags |= flags & GOVD_SEEN;
    8741         1238 :           t = DECL_VALUE_EXPR (decl);
    8742         1238 :           gcc_assert (INDIRECT_REF_P (t));
    8743         1238 :           t = TREE_OPERAND (t, 0);
    8744         1238 :           gcc_assert (DECL_P (t));
    8745         1238 :           omp_add_variable (ctx, t, nflags);
    8746              :         }
    8747              : 
    8748              :       /* Add all of the variable and type parameters (which should have
    8749              :          been gimplified to a formal temporary) as FIRSTPRIVATE.  */
    8750         1330 :       omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
    8751         1330 :       omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
    8752         1330 :       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
    8753              : 
    8754              :       /* The variable-sized variable itself is never SHARED, only some form
    8755              :          of PRIVATE.  The sharing would take place via the pointer variable
    8756              :          which we remapped above.  */
    8757         1330 :       if (flags & GOVD_SHARED)
    8758          284 :         flags = GOVD_SHARED | GOVD_DEBUG_PRIVATE
    8759          284 :                 | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
    8760              : 
    8761              :       /* We're going to make use of the TYPE_SIZE_UNIT at least in the
    8762              :          alloca statement we generate for the variable, so make sure it
    8763              :          is available.  This isn't automatically needed for the SHARED
    8764              :          case, since we won't be allocating local storage then.
    8765              :          For local variables TYPE_SIZE_UNIT might not be gimplified yet,
    8766              :          in this case omp_notice_variable will be called later
    8767              :          on when it is gimplified.  */
    8768         1046 :       else if (! (flags & (GOVD_LOCAL | GOVD_MAP))
    8769         1046 :                && DECL_P (TYPE_SIZE_UNIT (TREE_TYPE (decl))))
    8770          275 :         omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
    8771              :     }
    8772       715665 :   else if ((flags & (GOVD_MAP | GOVD_LOCAL)) == 0
    8773       715665 :            && omp_privatize_by_reference (decl))
    8774              :     {
    8775         9937 :       omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
    8776              : 
    8777              :       /* Similar to the direct variable sized case above, we'll need the
    8778              :          size of references being privatized.  */
    8779         9937 :       if ((flags & GOVD_SHARED) == 0)
    8780              :         {
    8781         6217 :           t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
    8782         6217 :           if (t && DECL_P (t))
    8783         1398 :             omp_notice_variable (ctx, t, true);
    8784              :         }
    8785              :     }
    8786              : 
    8787       716995 :   if (n != NULL)
    8788         1870 :     n->value |= flags;
    8789              :   else
    8790       715125 :     splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
    8791              : 
    8792              :   /* For reductions clauses in OpenACC loop directives, by default create a
    8793              :      copy clause on the enclosing parallel construct for carrying back the
    8794              :      results.  */
    8795       716995 :   if (ctx->region_type == ORT_ACC && (flags & GOVD_REDUCTION))
    8796              :     {
    8797         4716 :       struct gimplify_omp_ctx *outer_ctx = ctx->outer_context;
    8798         6454 :       while (outer_ctx)
    8799              :         {
    8800         5788 :           n = splay_tree_lookup (outer_ctx->variables, (splay_tree_key)decl);
    8801         5788 :           if (n != NULL)
    8802              :             {
    8803              :               /* Ignore local variables and explicitly declared clauses.  */
    8804         3990 :               if (n->value & (GOVD_LOCAL | GOVD_EXPLICIT))
    8805              :                 break;
    8806          443 :               else if (outer_ctx->region_type == ORT_ACC_KERNELS)
    8807              :                 {
    8808              :                   /* According to the OpenACC spec, such a reduction variable
    8809              :                      should already have a copy map on a kernels construct,
    8810              :                      verify that here.  */
    8811          143 :                   gcc_assert (!(n->value & GOVD_FIRSTPRIVATE)
    8812              :                               && (n->value & GOVD_MAP));
    8813              :                 }
    8814          300 :               else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
    8815              :                 {
    8816              :                   /* Remove firstprivate and make it a copy map.  */
    8817          150 :                   n->value &= ~GOVD_FIRSTPRIVATE;
    8818          150 :                   n->value |= GOVD_MAP;
    8819              :                 }
    8820              :             }
    8821         1798 :           else if (outer_ctx->region_type == ORT_ACC_PARALLEL)
    8822              :             {
    8823          503 :               splay_tree_insert (outer_ctx->variables, (splay_tree_key)decl,
    8824              :                                  GOVD_MAP | GOVD_SEEN);
    8825          503 :               break;
    8826              :             }
    8827         1738 :           outer_ctx = outer_ctx->outer_context;
    8828              :         }
    8829              :     }
    8830              : }
    8831              : 
    8832              : /* Notice a threadprivate variable DECL used in OMP context CTX.
    8833              :    This just prints out diagnostics about threadprivate variable uses
    8834              :    in untied tasks.  If DECL2 is non-NULL, prevent this warning
    8835              :    on that variable.  */
    8836              : 
    8837              : static bool
    8838        14183 : omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
    8839              :                                    tree decl2)
    8840              : {
    8841        14183 :   splay_tree_node n;
    8842        14183 :   struct gimplify_omp_ctx *octx;
    8843              : 
    8844        28798 :   for (octx = ctx; octx; octx = octx->outer_context)
    8845        14615 :     if ((octx->region_type & ORT_TARGET) != 0
    8846        14615 :         || octx->order_concurrent)
    8847              :       {
    8848          112 :         n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
    8849          112 :         if (n == NULL)
    8850              :           {
    8851           20 :             if (octx->order_concurrent)
    8852              :               {
    8853           20 :                 error ("threadprivate variable %qE used in a region with"
    8854           20 :                        " %<order(concurrent)%> clause", DECL_NAME (decl));
    8855           20 :                 inform (octx->location, "enclosing region");
    8856              :               }
    8857              :             else
    8858              :               {
    8859            0 :                 error ("threadprivate variable %qE used in target region",
    8860            0 :                        DECL_NAME (decl));
    8861            0 :                 inform (octx->location, "enclosing target region");
    8862              :               }
    8863           20 :             splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
    8864              :           }
    8865          112 :         if (decl2)
    8866            0 :           splay_tree_insert (octx->variables, (splay_tree_key)decl2, 0);
    8867              :       }
    8868              : 
    8869        14183 :   if (ctx->region_type != ORT_UNTIED_TASK)
    8870              :     return false;
    8871           37 :   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
    8872           37 :   if (n == NULL)
    8873              :     {
    8874            6 :       error ("threadprivate variable %qE used in untied task",
    8875            6 :              DECL_NAME (decl));
    8876            6 :       inform (ctx->location, "enclosing task");
    8877            6 :       splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
    8878              :     }
    8879           37 :   if (decl2)
    8880            4 :     splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
    8881              :   return false;
    8882              : }
    8883              : 
    8884              : /* Return true if global var DECL is device resident.  */
    8885              : 
    8886              : static bool
    8887          642 : device_resident_p (tree decl)
    8888              : {
    8889          642 :   tree attr = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (decl));
    8890              : 
    8891          642 :   if (!attr)
    8892              :     return false;
    8893              : 
    8894            0 :   for (tree t = TREE_VALUE (attr); t; t = TREE_PURPOSE (t))
    8895              :     {
    8896            0 :       tree c = TREE_VALUE (t);
    8897            0 :       if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DEVICE_RESIDENT)
    8898              :         return true;
    8899              :     }
    8900              : 
    8901              :   return false;
    8902              : }
    8903              : 
    8904              : /* Return true if DECL has an ACC DECLARE attribute.  */
    8905              : 
    8906              : static bool
    8907         9101 : is_oacc_declared (tree decl)
    8908              : {
    8909         9101 :   tree t = TREE_CODE (decl) == MEM_REF ? TREE_OPERAND (decl, 0) : decl;
    8910         9101 :   tree declared = lookup_attribute ("oacc declare target", DECL_ATTRIBUTES (t));
    8911         9101 :   return declared != NULL_TREE;
    8912              : }
    8913              : 
    8914              : /* Determine outer default flags for DECL mentioned in an OMP region
    8915              :    but not declared in an enclosing clause.
    8916              : 
    8917              :    ??? Some compiler-generated variables (like SAVE_EXPRs) could be
    8918              :    remapped firstprivate instead of shared.  To some extent this is
    8919              :    addressed in omp_firstprivatize_type_sizes, but not
    8920              :    effectively.  */
    8921              : 
    8922              : static unsigned
    8923        48030 : omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
    8924              :                     bool in_code, unsigned flags)
    8925              : {
    8926        48030 :   enum omp_clause_default_kind default_kind = ctx->default_kind;
    8927        48030 :   enum omp_clause_default_kind kind;
    8928              : 
    8929        48030 :   kind = lang_hooks.decls.omp_predetermined_sharing (decl);
    8930        48030 :   if (ctx->region_type & ORT_TASK)
    8931              :     {
    8932         3994 :       tree detach_clause = omp_find_clause (ctx->clauses, OMP_CLAUSE_DETACH);
    8933              : 
    8934              :       /* The event-handle specified by a detach clause should always be firstprivate,
    8935              :          regardless of the current default.  */
    8936         4206 :       if (detach_clause && OMP_CLAUSE_DECL (detach_clause) == decl)
    8937              :         kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
    8938              :     }
    8939        48030 :   if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
    8940              :     default_kind = kind;
    8941        45213 :   else if (VAR_P (decl) && TREE_STATIC (decl) && DECL_IN_CONSTANT_POOL (decl))
    8942              :     default_kind = OMP_CLAUSE_DEFAULT_SHARED;
    8943              :   /* For C/C++ default({,first}private), variables with static storage duration
    8944              :      declared in a namespace or global scope and referenced in construct
    8945              :      must be explicitly specified, i.e. acts as default(none).  */
    8946        45212 :   else if ((default_kind == OMP_CLAUSE_DEFAULT_PRIVATE
    8947        45212 :             || default_kind == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
    8948          371 :            && VAR_P (decl)
    8949          328 :            && is_global_var (decl)
    8950          184 :            && (DECL_FILE_SCOPE_P (decl)
    8951          104 :                || (DECL_CONTEXT (decl)
    8952          104 :                    && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
    8953        45340 :            && !lang_GNU_Fortran ())
    8954              :     default_kind = OMP_CLAUSE_DEFAULT_NONE;
    8955              : 
    8956        47901 :   switch (default_kind)
    8957              :     {
    8958          267 :     case OMP_CLAUSE_DEFAULT_NONE:
    8959          267 :       {
    8960          267 :         const char *rtype;
    8961              : 
    8962          267 :         if (ctx->region_type & ORT_PARALLEL)
    8963              :           rtype = "parallel";
    8964          108 :         else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
    8965              :           rtype = "taskloop";
    8966           72 :         else if (ctx->region_type & ORT_TASK)
    8967              :           rtype = "task";
    8968           36 :         else if (ctx->region_type & ORT_TEAMS)
    8969              :           rtype = "teams";
    8970              :         else
    8971            0 :           gcc_unreachable ();
    8972              : 
    8973          267 :         error ("%qE not specified in enclosing %qs",
    8974          267 :                DECL_NAME (lang_hooks.decls.omp_report_decl (decl)), rtype);
    8975          267 :         inform (ctx->location, "enclosing %qs", rtype);
    8976              :       }
    8977              :       /* FALLTHRU */
    8978        44373 :     case OMP_CLAUSE_DEFAULT_SHARED:
    8979        44373 :       flags |= GOVD_SHARED;
    8980        44373 :       break;
    8981          155 :     case OMP_CLAUSE_DEFAULT_PRIVATE:
    8982          155 :       flags |= GOVD_PRIVATE;
    8983          155 :       break;
    8984          280 :     case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
    8985          280 :       flags |= GOVD_FIRSTPRIVATE;
    8986          280 :       break;
    8987         3222 :     case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
    8988              :       /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED.  */
    8989         3222 :       gcc_assert ((ctx->region_type & ORT_TASK) != 0);
    8990         3222 :       if (struct gimplify_omp_ctx *octx = ctx->outer_context)
    8991              :         {
    8992         2164 :           omp_notice_variable (octx, decl, in_code);
    8993         5158 :           for (; octx; octx = octx->outer_context)
    8994              :             {
    8995         2938 :               splay_tree_node n2;
    8996              : 
    8997         2938 :               n2 = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
    8998         2938 :               if ((octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)) != 0
    8999            5 :                   && (n2 == NULL || (n2->value & GOVD_DATA_SHARE_CLASS) == 0))
    9000            5 :                 continue;
    9001         2933 :               if (n2 && (n2->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED)
    9002              :                 {
    9003          898 :                   flags |= GOVD_FIRSTPRIVATE;
    9004          898 :                   goto found_outer;
    9005              :                 }
    9006         2035 :               if ((octx->region_type & (ORT_PARALLEL | ORT_TEAMS)) != 0)
    9007              :                 {
    9008         1210 :                   flags |= GOVD_SHARED;
    9009         1210 :                   goto found_outer;
    9010              :                 }
    9011              :             }
    9012              :         }
    9013              : 
    9014         1114 :       if (TREE_CODE (decl) == PARM_DECL
    9015         1114 :           || (!is_global_var (decl)
    9016          294 :               && DECL_CONTEXT (decl) == current_function_decl))
    9017          734 :         flags |= GOVD_FIRSTPRIVATE;
    9018              :       else
    9019          380 :         flags |= GOVD_SHARED;
    9020        48030 :     found_outer:
    9021              :       break;
    9022              : 
    9023            0 :     default:
    9024            0 :       gcc_unreachable ();
    9025              :     }
    9026              : 
    9027        48030 :   return flags;
    9028              : }
    9029              : 
    9030              : /* Return string name for types of OpenACC constructs from ORT_* values.  */
    9031              : 
    9032              : static const char *
    9033          570 : oacc_region_type_name (enum omp_region_type region_type)
    9034              : {
    9035          570 :   switch (region_type)
    9036              :     {
    9037              :     case ORT_ACC_DATA:
    9038              :       return "data";
    9039          140 :     case ORT_ACC_PARALLEL:
    9040          140 :       return "parallel";
    9041          140 :     case ORT_ACC_KERNELS:
    9042          140 :       return "kernels";
    9043          140 :     case ORT_ACC_SERIAL:
    9044          140 :       return "serial";
    9045            0 :     default:
    9046            0 :       gcc_unreachable ();
    9047              :     }
    9048              : }
    9049              : 
    9050              : /* Determine outer default flags for DECL mentioned in an OACC region
    9051              :    but not declared in an enclosing clause.  */
    9052              : 
    9053              : static unsigned
    9054         8839 : oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags)
    9055              : {
    9056         8839 :   struct gimplify_omp_ctx *ctx_default = ctx;
    9057              :   /* If no 'default' clause appears on this compute construct...  */
    9058         8839 :   if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_SHARED)
    9059              :     {
    9060              :       /* ..., see if one appears on a lexically containing 'data'
    9061              :          construct.  */
    9062         9618 :       while ((ctx_default = ctx_default->outer_context))
    9063              :         {
    9064         1534 :           if (ctx_default->region_type == ORT_ACC_DATA
    9065         1534 :               && ctx_default->default_kind != OMP_CLAUSE_DEFAULT_SHARED)
    9066              :             break;
    9067              :         }
    9068              :       /* If not, reset.  */
    9069         8260 :       if (!ctx_default)
    9070         8663 :         ctx_default = ctx;
    9071              :     }
    9072              : 
    9073         8839 :   bool on_device = false;
    9074         8839 :   bool is_private = false;
    9075         8839 :   bool declared = is_oacc_declared (decl);
    9076         8839 :   tree type = TREE_TYPE (decl);
    9077              : 
    9078         8839 :   if (omp_privatize_by_reference (decl))
    9079          338 :     type = TREE_TYPE (type);
    9080              : 
    9081              :   /* For Fortran COMMON blocks, only used variables in those blocks are
    9082              :      transferred and remapped.  The block itself will have a private clause to
    9083              :      avoid transferring the data twice.
    9084              :      The hook evaluates to false by default.  For a variable in Fortran's COMMON
    9085              :      or EQUIVALENCE block, returns 'true' (as we have shared=false) - as only
    9086              :      the variables in such a COMMON/EQUIVALENCE block shall be privatized not
    9087              :      the whole block.  For C++ and Fortran, it can also be true under certain
    9088              :      other conditions, if DECL_HAS_VALUE_EXPR.  */
    9089         8839 :   if (RECORD_OR_UNION_TYPE_P (type))
    9090          983 :     is_private = lang_hooks.decls.omp_disregard_value_expr (decl, false);
    9091              : 
    9092         8839 :   if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0
    9093         8839 :       && is_global_var (decl)
    9094          642 :       && device_resident_p (decl)
    9095         8839 :       && !is_private)
    9096              :     {
    9097            0 :       on_device = true;
    9098            0 :       flags |= GOVD_MAP_TO_ONLY;
    9099              :     }
    9100              : 
    9101         8839 :   switch (ctx->region_type)
    9102              :     {
    9103         1460 :     case ORT_ACC_KERNELS:
    9104         1460 :       if (is_private)
    9105            0 :         flags |= GOVD_FIRSTPRIVATE;
    9106         1460 :       else if (AGGREGATE_TYPE_P (type))
    9107              :         {
    9108              :           /* Aggregates default to 'present_or_copy', or 'present'.  */
    9109          415 :           if (ctx_default->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
    9110          397 :             flags |= GOVD_MAP;
    9111              :           else
    9112           18 :             flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
    9113              :         }
    9114              :       else
    9115              :         /* Scalars default to 'copy'.  */
    9116         1045 :         flags |= GOVD_MAP | GOVD_MAP_FORCE;
    9117              : 
    9118              :       break;
    9119              : 
    9120         7379 :     case ORT_ACC_PARALLEL:
    9121         7379 :     case ORT_ACC_SERIAL:
    9122         7379 :       if (is_private)
    9123            0 :         flags |= GOVD_FIRSTPRIVATE;
    9124         7379 :       else if (on_device || declared)
    9125           17 :         flags |= GOVD_MAP;
    9126         7362 :       else if (AGGREGATE_TYPE_P (type))
    9127              :         {
    9128              :           /* Aggregates default to 'present_or_copy', or 'present'.  */
    9129         3697 :           if (ctx_default->default_kind != OMP_CLAUSE_DEFAULT_PRESENT)
    9130         3431 :             flags |= GOVD_MAP;
    9131              :           else
    9132          266 :             flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
    9133              :         }
    9134              :       else
    9135              :         /* Scalars default to 'firstprivate'.  */
    9136         3665 :         flags |= GOVD_FIRSTPRIVATE;
    9137              : 
    9138              :       break;
    9139              : 
    9140            0 :     default:
    9141            0 :       gcc_unreachable ();
    9142              :     }
    9143              : 
    9144         8839 :   if (DECL_ARTIFICIAL (decl))
    9145              :     ; /* We can get compiler-generated decls, and should not complain
    9146              :          about them.  */
    9147         8528 :   else if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_NONE)
    9148              :     {
    9149          420 :       error ("%qE not specified in enclosing OpenACC %qs construct",
    9150          210 :              DECL_NAME (lang_hooks.decls.omp_report_decl (decl)),
    9151              :              oacc_region_type_name (ctx->region_type));
    9152          210 :       if (ctx_default != ctx)
    9153          150 :         inform (ctx->location, "enclosing OpenACC %qs construct and",
    9154              :                 oacc_region_type_name (ctx->region_type));
    9155          210 :       inform (ctx_default->location,
    9156              :               "enclosing OpenACC %qs construct with %qs clause",
    9157              :               oacc_region_type_name (ctx_default->region_type),
    9158              :               "default(none)");
    9159              :     }
    9160         8318 :   else if (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_PRESENT)
    9161              :     ; /* Handled above.  */
    9162              :   else
    9163         7785 :     gcc_checking_assert (ctx_default->default_kind == OMP_CLAUSE_DEFAULT_SHARED);
    9164              : 
    9165         8839 :   return flags;
    9166              : }
    9167              : 
    9168              : /* Record the fact that DECL was used within the OMP context CTX.
    9169              :    IN_CODE is true when real code uses DECL, and false when we should
    9170              :    merely emit default(none) errors.  Return true if DECL is going to
    9171              :    be remapped and thus DECL shouldn't be gimplified into its
    9172              :    DECL_VALUE_EXPR (if any).  */
    9173              : 
    9174              : static bool
    9175      3916722 : omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
    9176              : {
    9177      3916722 :   splay_tree_node n;
    9178      3916722 :   unsigned flags = in_code ? GOVD_SEEN : 0;
    9179      3916722 :   bool ret = false, shared;
    9180              : 
    9181      3916722 :   if (error_operand_p (decl))
    9182              :     return false;
    9183              : 
    9184      3916722 :   if (DECL_ARTIFICIAL (decl))
    9185              :     {
    9186      2236488 :       tree attr = lookup_attribute ("omp allocate var", DECL_ATTRIBUTES (decl));
    9187      2236488 :       if (attr)
    9188          531 :         decl = TREE_VALUE (TREE_VALUE (attr));
    9189              :     }
    9190              : 
    9191      3916722 :   if (ctx->region_type == ORT_NONE)
    9192          248 :     return lang_hooks.decls.omp_disregard_value_expr (decl, false);
    9193              : 
    9194      3916474 :   if (is_global_var (decl))
    9195              :     {
    9196              :       /* Threadprivate variables are predetermined.  */
    9197       502590 :       if (DECL_THREAD_LOCAL_P (decl))
    9198        13565 :         return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
    9199              : 
    9200       489025 :       if (DECL_HAS_VALUE_EXPR_P (decl))
    9201              :         {
    9202         4380 :           if (ctx->region_type & ORT_ACC)
    9203              :             /* For OpenACC, defer expansion of value to avoid transferring
    9204              :                privatized common block data instead of im-/explicitly
    9205              :                transferred variables which are in common blocks.  */
    9206              :             ;
    9207              :           else
    9208              :             {
    9209         2104 :               tree value = get_base_address (DECL_VALUE_EXPR (decl));
    9210              : 
    9211         2104 :               if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
    9212          618 :                 return omp_notice_threadprivate_variable (ctx, decl, value);
    9213              :             }
    9214              :         }
    9215              : 
    9216       488407 :       if (gimplify_omp_ctxp->outer_context == NULL
    9217       114470 :           && VAR_P (decl)
    9218       602877 :           && oacc_get_fn_attrib (current_function_decl))
    9219              :         {
    9220          765 :           location_t loc = DECL_SOURCE_LOCATION (decl);
    9221              : 
    9222          765 :           if (lookup_attribute ("omp declare target link",
    9223          765 :                                 DECL_ATTRIBUTES (decl)))
    9224              :             {
    9225           48 :               error_at (loc,
    9226              :                         "%qE with %<link%> clause used in %<routine%> function",
    9227           24 :                         DECL_NAME (decl));
    9228           24 :               return false;
    9229              :             }
    9230          741 :           else if (!lookup_attribute ("omp declare target",
    9231          741 :                                       DECL_ATTRIBUTES (decl)))
    9232              :             {
    9233          132 :               error_at (loc,
    9234              :                         "%qE requires a %<declare%> directive for use "
    9235           66 :                         "in a %<routine%> function", DECL_NAME (decl));
    9236           66 :               return false;
    9237              :             }
    9238              :         }
    9239              :     }
    9240              : 
    9241      3902201 :   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
    9242      3902201 :   if ((ctx->region_type & ORT_TARGET) != 0)
    9243              :     {
    9244       852995 :       if (n == NULL)
    9245              :         {
    9246        45110 :           unsigned nflags = flags;
    9247        45110 :           if ((ctx->region_type & ORT_ACC) == 0)
    9248              :             {
    9249        34156 :               bool is_declare_target = false;
    9250        34156 :               if (is_global_var (decl)
    9251        34156 :                   && varpool_node::get_create (decl)->offloadable)
    9252              :                 {
    9253         7054 :                   struct gimplify_omp_ctx *octx;
    9254         7054 :                   for (octx = ctx->outer_context;
    9255         7062 :                        octx; octx = octx->outer_context)
    9256              :                     {
    9257            9 :                       n = splay_tree_lookup (octx->variables,
    9258              :                                              (splay_tree_key)decl);
    9259            9 :                       if (n
    9260            9 :                           && (n->value & GOVD_DATA_SHARE_CLASS) != GOVD_SHARED
    9261            9 :                           && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
    9262              :                         break;
    9263              :                     }
    9264         7054 :                   is_declare_target = octx == NULL;
    9265              :                 }
    9266         7054 :               if (!is_declare_target)
    9267              :                 {
    9268        27103 :                   int gdmk;
    9269        27103 :                   enum omp_clause_defaultmap_kind kind;
    9270        27103 :                   if (lang_hooks.decls.omp_allocatable_p (decl))
    9271              :                     gdmk = GDMK_ALLOCATABLE;
    9272        26754 :                   else if (lang_hooks.decls.omp_scalar_target_p (decl))
    9273              :                     gdmk = GDMK_SCALAR_TARGET;
    9274        26679 :                   else if (lang_hooks.decls.omp_scalar_p (decl, false))
    9275              :                     gdmk = GDMK_SCALAR;
    9276        11183 :                   else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
    9277        11183 :                            || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
    9278         3105 :                                && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
    9279              :                                    == POINTER_TYPE)))
    9280              :                     gdmk = GDMK_POINTER;
    9281              :                   else
    9282              :                     gdmk = GDMK_AGGREGATE;
    9283        27103 :                   kind = lang_hooks.decls.omp_predetermined_mapping (decl);
    9284        27103 :                   if (kind != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
    9285              :                     {
    9286         1096 :                       if (kind == OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE)
    9287          101 :                         nflags |= GOVD_FIRSTPRIVATE;
    9288          995 :                       else if (kind == OMP_CLAUSE_DEFAULTMAP_TO)
    9289          995 :                         nflags |= GOVD_MAP | GOVD_MAP_TO_ONLY;
    9290              :                       else
    9291            0 :                         gcc_unreachable ();
    9292              :                     }
    9293        26007 :                   else if (ctx->defaultmap[gdmk] == 0)
    9294              :                     {
    9295           75 :                       tree d = lang_hooks.decls.omp_report_decl (decl);
    9296           75 :                       error ("%qE not specified in enclosing %<target%>",
    9297           75 :                              DECL_NAME (d));
    9298           75 :                       inform (ctx->location, "enclosing %<target%>");
    9299              :                     }
    9300        25932 :                   else if (ctx->defaultmap[gdmk]
    9301        25932 :                            & (GOVD_MAP_0LEN_ARRAY | GOVD_FIRSTPRIVATE))
    9302         9136 :                     nflags |= ctx->defaultmap[gdmk];
    9303        16796 :                   else if (ctx->defaultmap[gdmk] & GOVD_MAP_FORCE_PRESENT)
    9304              :                     {
    9305           42 :                       gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
    9306           42 :                       nflags |= ctx->defaultmap[gdmk] | GOVD_MAP_ALLOC_ONLY;
    9307              :                     }
    9308              :                   else
    9309              :                     {
    9310        16754 :                       gcc_assert (ctx->defaultmap[gdmk] & GOVD_MAP);
    9311        16754 :                       nflags |= ctx->defaultmap[gdmk] & ~GOVD_MAP;
    9312              :                     }
    9313              :                 }
    9314              :             }
    9315              : 
    9316        45110 :           struct gimplify_omp_ctx *octx = ctx->outer_context;
    9317        45110 :           if ((ctx->region_type & ORT_ACC) && octx)
    9318              :             {
    9319              :               /* Look in outer OpenACC contexts, to see if there's a
    9320              :                  data attribute for this variable.  */
    9321         3535 :               omp_notice_variable (octx, decl, in_code);
    9322              : 
    9323         8842 :               for (; octx; octx = octx->outer_context)
    9324              :                 {
    9325         3883 :                   if (!(octx->region_type & (ORT_TARGET_DATA | ORT_TARGET)))
    9326              :                     break;
    9327         3883 :                   splay_tree_node n2
    9328         3883 :                     = splay_tree_lookup (octx->variables,
    9329              :                                          (splay_tree_key) decl);
    9330         3883 :                   if (n2)
    9331              :                     {
    9332         2111 :                       if (octx->region_type == ORT_ACC_HOST_DATA)
    9333            4 :                         error ("variable %qE declared in enclosing "
    9334            4 :                                "%<host_data%> region", DECL_NAME (decl));
    9335         2111 :                       nflags |= GOVD_MAP;
    9336         2111 :                       if (octx->region_type == ORT_ACC_DATA
    9337         2107 :                           && (n2->value & GOVD_MAP_0LEN_ARRAY))
    9338          288 :                         nflags |= GOVD_MAP_0LEN_ARRAY;
    9339         2111 :                       goto found_outer;
    9340              :                     }
    9341              :                 }
    9342              :             }
    9343              : 
    9344        42999 :           if ((nflags & ~(GOVD_MAP_TO_ONLY | GOVD_MAP_FROM_ONLY
    9345              :                           | GOVD_MAP_ALLOC_ONLY)) == flags)
    9346              :             {
    9347        32725 :               tree type = TREE_TYPE (decl);
    9348        32725 :               location_t loc = DECL_SOURCE_LOCATION (decl);
    9349              : 
    9350        32725 :               if (gimplify_omp_ctxp->target_firstprivatize_array_bases
    9351        32725 :                   && omp_privatize_by_reference (decl))
    9352           28 :                 type = TREE_TYPE (type);
    9353              : 
    9354        32725 :               if (!verify_type_context (loc, TCTX_OMP_MAP_IMP_REF, type))
    9355              :                 /* Check if TYPE can appear in a target region.
    9356              :                    verify_type_context has already issued an error if it
    9357              :                    can't.  */
    9358            0 :                 nflags |= GOVD_MAP | GOVD_EXPLICIT;
    9359        32725 :               else if (!omp_mappable_type (type))
    9360              :                 {
    9361            8 :                   error ("%qD referenced in target region does not have "
    9362              :                          "a mappable type", decl);
    9363            8 :                   nflags |= GOVD_MAP | GOVD_EXPLICIT;
    9364              :                 }
    9365              :               else
    9366              :                 {
    9367        32717 :                   if ((ctx->region_type & ORT_ACC) != 0)
    9368         8839 :                     nflags = oacc_default_clause (ctx, decl, flags);
    9369              :                   else
    9370        23878 :                     nflags |= GOVD_MAP;
    9371              :                 }
    9372              :             }
    9373        10274 :         found_outer:
    9374        45110 :           omp_add_variable (ctx, decl, nflags);
    9375        45110 :           if (ctx->region_type & ORT_ACC)
    9376              :             /* For OpenACC, as remarked above, defer expansion.  */
    9377              :             shared = false;
    9378              :           else
    9379        34156 :             shared = (nflags & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0;
    9380        45110 :           ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
    9381              :         }
    9382              :       else
    9383              :         {
    9384       807885 :           if (ctx->region_type & ORT_ACC)
    9385              :             /* For OpenACC, as remarked above, defer expansion.  */
    9386              :             shared = false;
    9387              :           else
    9388       511460 :             shared = ((n->value | flags)
    9389       511460 :                       & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0;
    9390       807885 :           ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
    9391              :           /* If nothing changed, there's nothing left to do.  */
    9392       807885 :           if ((n->value & flags) == flags)
    9393              :             return ret;
    9394        16656 :           flags |= n->value;
    9395        16656 :           n->value = flags;
    9396              :         }
    9397        61766 :       goto do_outer;
    9398              :     }
    9399              : 
    9400      3049206 :   if (n == NULL)
    9401              :     {
    9402      1183679 :       if (ctx->region_type == ORT_WORKSHARE
    9403              :           || ctx->region_type == ORT_TASKGROUP
    9404       561941 :           || ctx->region_type == ORT_SIMD
    9405       288998 :           || ctx->region_type == ORT_ACC
    9406        92745 :           || (ctx->region_type & ORT_TARGET_DATA) != 0)
    9407      1135649 :         goto do_outer;
    9408              : 
    9409        48030 :       flags = omp_default_clause (ctx, decl, in_code, flags);
    9410              : 
    9411        48030 :       if ((flags & GOVD_PRIVATE)
    9412        48030 :           && lang_hooks.decls.omp_private_outer_ref (decl))
    9413            6 :         flags |= GOVD_PRIVATE_OUTER_REF;
    9414              : 
    9415        48030 :       omp_add_variable (ctx, decl, flags);
    9416              : 
    9417        48030 :       shared = (flags & GOVD_SHARED) != 0;
    9418        48030 :       ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
    9419        48030 :       goto do_outer;
    9420              :     }
    9421              : 
    9422              :   /* Don't mark as GOVD_SEEN addressable temporaries seen only in simd
    9423              :      lb, b or incr expressions, those shouldn't be turned into simd arrays.  */
    9424      1865527 :   if (ctx->region_type == ORT_SIMD
    9425       151440 :       && ctx->in_for_exprs
    9426           70 :       && ((n->value & (GOVD_PRIVATE | GOVD_SEEN | GOVD_EXPLICIT))
    9427              :           == GOVD_PRIVATE))
    9428      1865527 :     flags &= ~GOVD_SEEN;
    9429              : 
    9430      1865527 :   if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
    9431        31919 :       && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
    9432      1897407 :       && DECL_SIZE (decl))
    9433              :     {
    9434        31879 :       tree size;
    9435        31879 :       if (!poly_int_tree_p (DECL_SIZE (decl)))
    9436              :         {
    9437          148 :           splay_tree_node n2;
    9438          148 :           tree t = DECL_VALUE_EXPR (decl);
    9439          148 :           gcc_assert (INDIRECT_REF_P (t));
    9440          148 :           t = TREE_OPERAND (t, 0);
    9441          148 :           gcc_assert (DECL_P (t));
    9442          148 :           n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
    9443          148 :           n2->value |= GOVD_SEEN;
    9444              :         }
    9445        31731 :       else if (omp_privatize_by_reference (decl)
    9446         4193 :                && (size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
    9447        35887 :                && !poly_int_tree_p (size))
    9448              :         {
    9449         1337 :           splay_tree_node n2;
    9450         1337 :           gcc_assert (DECL_P (size));
    9451         1337 :           n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) size);
    9452         1337 :           if (n2)
    9453          629 :             omp_notice_variable (ctx, size, true);
    9454              :         }
    9455              :     }
    9456              : 
    9457      1865527 :   if (ctx->region_type & ORT_ACC)
    9458              :     /* For OpenACC, as remarked above, defer expansion.  */
    9459              :     shared = false;
    9460              :   else
    9461      1683592 :     shared = ((flags | n->value) & GOVD_SHARED) != 0;
    9462      1865527 :   ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
    9463              : 
    9464              :   /* If nothing changed, there's nothing left to do.  */
    9465      1865527 :   if ((n->value & flags) == flags)
    9466              :     return ret;
    9467        31880 :   flags |= n->value;
    9468        31880 :   n->value = flags;
    9469              : 
    9470      1277325 :  do_outer:
    9471              :   /* If the variable is private in the current context, then we don't
    9472              :      need to propagate anything to an outer context.  */
    9473      1277325 :   if ((flags & GOVD_PRIVATE) && !(flags & GOVD_PRIVATE_OUTER_REF))
    9474              :     return ret;
    9475      1266919 :   if ((flags & (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
    9476              :       == (GOVD_LINEAR | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
    9477              :     return ret;
    9478      1266859 :   if ((flags & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
    9479              :                 | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
    9480              :       == (GOVD_LASTPRIVATE | GOVD_LINEAR_LASTPRIVATE_NO_OUTER))
    9481              :     return ret;
    9482      1266859 :   if (ctx->outer_context
    9483      1266859 :       && omp_notice_variable (ctx->outer_context, decl, in_code))
    9484         2151 :     return true;
    9485              :   return ret;
    9486              : }
    9487              : 
    9488              : /* Verify that DECL is private within CTX.  If there's specific information
    9489              :    to the contrary in the innermost scope, generate an error.  */
    9490              : 
    9491              : static bool
    9492        50339 : omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
    9493              : {
    9494        96124 :   splay_tree_node n;
    9495              : 
    9496        96124 :   n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
    9497        96124 :   if (n != NULL)
    9498              :     {
    9499        17992 :       if (n->value & GOVD_SHARED)
    9500              :         {
    9501          407 :           if (ctx == gimplify_omp_ctxp)
    9502              :             {
    9503            0 :               if (simd)
    9504            0 :                 error ("iteration variable %qE is predetermined linear",
    9505            0 :                        DECL_NAME (decl));
    9506              :               else
    9507            0 :                 error ("iteration variable %qE should be private",
    9508            0 :                        DECL_NAME (decl));
    9509            0 :               n->value = GOVD_PRIVATE;
    9510            0 :               return true;
    9511              :             }
    9512              :           else
    9513              :             return false;
    9514              :         }
    9515        17585 :       else if ((n->value & GOVD_EXPLICIT) != 0
    9516         9735 :                && (ctx == gimplify_omp_ctxp
    9517          340 :                    || (ctx->region_type == ORT_COMBINED_PARALLEL
    9518          220 :                        && gimplify_omp_ctxp->outer_context == ctx)))
    9519              :         {
    9520         9615 :           if ((n->value & GOVD_FIRSTPRIVATE) != 0)
    9521            4 :             error ("iteration variable %qE should not be firstprivate",
    9522            4 :                    DECL_NAME (decl));
    9523         9611 :           else if ((n->value & GOVD_REDUCTION) != 0)
    9524            8 :             error ("iteration variable %qE should not be reduction",
    9525            8 :                    DECL_NAME (decl));
    9526         9603 :           else if (simd != 1 && (n->value & GOVD_LINEAR) != 0)
    9527           58 :             error ("iteration variable %qE should not be linear",
    9528           58 :                    DECL_NAME (decl));
    9529              :         }
    9530        17585 :       return (ctx == gimplify_omp_ctxp
    9531        17585 :               || (ctx->region_type == ORT_COMBINED_PARALLEL
    9532         2618 :                   && gimplify_omp_ctxp->outer_context == ctx));
    9533              :     }
    9534              : 
    9535        78132 :   if (ctx->region_type != ORT_WORKSHARE
    9536              :       && ctx->region_type != ORT_TASKGROUP
    9537        49558 :       && ctx->region_type != ORT_SIMD
    9538        36229 :       && ctx->region_type != ORT_ACC)
    9539              :     return false;
    9540        54076 :   else if (ctx->outer_context)
    9541              :     return omp_is_private (ctx->outer_context, decl, simd);
    9542              :   return false;
    9543              : }
    9544              : 
    9545              : /* Return true if DECL is private within a parallel region
    9546              :    that binds to the current construct's context or in parallel
    9547              :    region's REDUCTION clause.  */
    9548              : 
    9549              : static bool
    9550        11608 : omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate)
    9551              : {
    9552        11680 :   splay_tree_node n;
    9553              : 
    9554        11680 :   do
    9555              :     {
    9556        11680 :       ctx = ctx->outer_context;
    9557        11680 :       if (ctx == NULL)
    9558              :         {
    9559         2786 :           if (is_global_var (decl))
    9560              :             return false;
    9561              : 
    9562              :           /* References might be private, but might be shared too,
    9563              :              when checking for copyprivate, assume they might be
    9564              :              private, otherwise assume they might be shared.  */
    9565         1292 :           if (copyprivate)
    9566              :             return true;
    9567              : 
    9568         1246 :           if (omp_privatize_by_reference (decl))
    9569              :             return false;
    9570              : 
    9571              :           /* Treat C++ privatized non-static data members outside
    9572              :              of the privatization the same.  */
    9573         1200 :           if (omp_member_access_dummy_var (decl))
    9574              :             return false;
    9575              : 
    9576         1144 :           return true;
    9577              :         }
    9578              : 
    9579         8894 :       n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
    9580              : 
    9581         8894 :       if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
    9582         1291 :           && (n == NULL || (n->value & GOVD_DATA_SHARE_CLASS) == 0))
    9583              :         {
    9584          242 :           if ((ctx->region_type & ORT_TARGET_DATA) != 0
    9585          238 :               || n == NULL
    9586          230 :               || (n->value & GOVD_MAP) == 0)
    9587           12 :             continue;
    9588              :           return false;
    9589              :         }
    9590              : 
    9591         7603 :       if (n != NULL)
    9592              :         {
    9593         5397 :           if ((n->value & GOVD_LOCAL) != 0
    9594         5397 :               && omp_member_access_dummy_var (decl))
    9595              :             return false;
    9596         5358 :           return (n->value & GOVD_SHARED) == 0;
    9597              :         }
    9598              : 
    9599         3255 :       if (ctx->region_type == ORT_WORKSHARE
    9600              :           || ctx->region_type == ORT_TASKGROUP
    9601         3199 :           || ctx->region_type == ORT_SIMD
    9602         3195 :           || ctx->region_type == ORT_ACC)
    9603           60 :         continue;
    9604              : 
    9605              :       break;
    9606              :     }
    9607              :   while (1);
    9608              :   return false;
    9609              : }
    9610              : 
    9611              : /* Callback for walk_tree to find a DECL_EXPR for the given DECL.  */
    9612              : 
    9613              : static tree
    9614         3148 : find_decl_expr (tree *tp, int *walk_subtrees, void *data)
    9615              : {
    9616         3148 :   tree t = *tp;
    9617              : 
    9618              :   /* If this node has been visited, unmark it and keep looking.  */
    9619         3148 :   if (TREE_CODE (t) == DECL_EXPR && DECL_EXPR_DECL (t) == (tree) data)
    9620              :     return t;
    9621              : 
    9622         2724 :   if (IS_TYPE_OR_DECL_P (t))
    9623          452 :     *walk_subtrees = 0;
    9624              :   return NULL_TREE;
    9625              : }
    9626              : 
    9627              : 
    9628              : /* Gimplify the affinity clause but effectively ignore it.
    9629              :    Generate:
    9630              :      var = begin;
    9631              :      if ((step > 1) ? var <= end : var > end)
    9632              :        locatator_var_expr;  */
    9633              : 
    9634              : static void
    9635          510 : gimplify_omp_affinity (tree *list_p, gimple_seq *pre_p)
    9636              : {
    9637          510 :   tree last_iter = NULL_TREE;
    9638          510 :   tree last_bind = NULL_TREE;
    9639          510 :   tree label = NULL_TREE;
    9640          510 :   tree *last_body = NULL;
    9641         1287 :   for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
    9642          777 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
    9643              :       {
    9644          777 :         tree t = OMP_CLAUSE_DECL (c);
    9645          777 :         if (OMP_ITERATOR_DECL_P (t))
    9646              :           {
    9647          389 :             if (TREE_VALUE (t) == null_pointer_node)
    9648          201 :               continue;
    9649          188 :             if (TREE_PURPOSE (t) != last_iter)
    9650              :               {
    9651          127 :                 if (last_bind)
    9652              :                   {
    9653            9 :                     append_to_statement_list (label, last_body);
    9654            9 :                     gimplify_and_add (last_bind, pre_p);
    9655            9 :                     last_bind = NULL_TREE;
    9656              :                   }
    9657          274 :                 for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
    9658              :                   {
    9659          147 :                     if (gimplify_expr (&OMP_ITERATOR_BEGIN (it), pre_p, NULL,
    9660              :                                        is_gimple_val, fb_rvalue) == GS_ERROR
    9661          147 :                         || gimplify_expr (&OMP_ITERATOR_END (it), pre_p, NULL,
    9662              :                                           is_gimple_val, fb_rvalue) == GS_ERROR
    9663          147 :                         || gimplify_expr (&OMP_ITERATOR_STEP (it), pre_p, NULL,
    9664              :                                           is_gimple_val, fb_rvalue) == GS_ERROR
    9665          294 :                         || (gimplify_expr (&OMP_ITERATOR_ORIG_STEP (it), pre_p,
    9666              :                                            NULL, is_gimple_val, fb_rvalue)
    9667              :                             == GS_ERROR))
    9668            0 :                       return;
    9669              :                   }
    9670          127 :             last_iter = TREE_PURPOSE (t);
    9671          127 :             tree block = OMP_ITERATOR_BLOCK (TREE_PURPOSE (t));
    9672          127 :             last_bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block),
    9673              :                                 NULL, block);
    9674          127 :             last_body = &BIND_EXPR_BODY (last_bind);
    9675          127 :             tree cond = NULL_TREE;
    9676          127 :             location_t loc = OMP_CLAUSE_LOCATION (c);
    9677          274 :             for (tree it = TREE_PURPOSE (t); it; it = TREE_CHAIN (it))
    9678              :               {
    9679          147 :                 tree var = OMP_ITERATOR_VAR (it);
    9680          147 :                 tree begin = OMP_ITERATOR_BEGIN (it);
    9681          147 :                 tree end = OMP_ITERATOR_END (it);
    9682          147 :                 tree step = OMP_ITERATOR_STEP (it);
    9683          147 :                 loc = DECL_SOURCE_LOCATION (var);
    9684          147 :                 tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node,
    9685              :                                        var, begin);
    9686          147 :                 append_to_statement_list_force (tem, last_body);
    9687              : 
    9688          147 :                 tree cond1 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
    9689          147 :                                step, build_zero_cst (TREE_TYPE (step)));
    9690          147 :                 tree cond2 = fold_build2_loc (loc, LE_EXPR, boolean_type_node,
    9691              :                                               var, end);
    9692          147 :                 tree cond3 = fold_build2_loc (loc, GT_EXPR, boolean_type_node,
    9693              :                                               var, end);
    9694          147 :                 cond1 = fold_build3_loc (loc, COND_EXPR, boolean_type_node,
    9695              :                                          cond1, cond2, cond3);
    9696          147 :                 if (cond)
    9697           20 :                   cond = fold_build2_loc (loc, TRUTH_AND_EXPR,
    9698              :                                           boolean_type_node, cond, cond1);
    9699              :                 else
    9700              :                   cond = cond1;
    9701              :               }
    9702          127 :             tree cont_label = create_artificial_label (loc);
    9703          127 :             label = build1 (LABEL_EXPR, void_type_node, cont_label);
    9704          127 :             tree tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
    9705              :                                         void_node,
    9706              :                                         build_and_jump (&cont_label));
    9707          127 :             append_to_statement_list_force (tem, last_body);
    9708              :               }
    9709          188 :             if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
    9710              :               {
    9711            0 :                 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t), 0),
    9712              :                                           last_body);
    9713            0 :                 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
    9714              :               }
    9715          188 :             if (error_operand_p (TREE_VALUE (t)))
    9716              :               return;
    9717          188 :             append_to_statement_list_force (TREE_VALUE (t), last_body);
    9718          188 :             TREE_VALUE (t) = null_pointer_node;
    9719              :           }
    9720              :         else
    9721              :           {
    9722          388 :             if (last_bind)
    9723              :               {
    9724            9 :                 append_to_statement_list (label, last_body);
    9725            9 :                 gimplify_and_add (last_bind, pre_p);
    9726            9 :                 last_bind = NULL_TREE;
    9727              :               }
    9728          388 :             if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
    9729              :               {
    9730            0 :                 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
    9731              :                                NULL, is_gimple_val, fb_rvalue);
    9732            0 :                 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
    9733              :               }
    9734          388 :             if (error_operand_p (OMP_CLAUSE_DECL (c)))
    9735              :               return;
    9736          388 :             if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
    9737              :                                is_gimple_lvalue, fb_lvalue) == GS_ERROR)
    9738              :               return;
    9739          388 :             gimplify_and_add (OMP_CLAUSE_DECL (c), pre_p);
    9740              :           }
    9741              :       }
    9742          510 :   if (last_bind)
    9743              :     {
    9744          109 :       append_to_statement_list (label, last_body);
    9745          109 :       gimplify_and_add (last_bind, pre_p);
    9746              :     }
    9747              :   return;
    9748              : }
    9749              : 
    9750              : /* Returns a tree expression containing the total iteration count of the
    9751              :    OpenMP iterator IT.  */
    9752              : 
    9753              : static tree
    9754          391 : compute_omp_iterator_count (tree it, gimple_seq *pre_p)
    9755              : {
    9756          391 :   tree tcnt = size_one_node;
    9757          861 :   for (; it; it = TREE_CHAIN (it))
    9758              :     {
    9759          470 :       if (gimplify_expr (&OMP_ITERATOR_BEGIN (it), pre_p, NULL,
    9760              :                          is_gimple_val, fb_rvalue) == GS_ERROR
    9761          470 :           || gimplify_expr (&OMP_ITERATOR_END (it), pre_p, NULL,
    9762              :                             is_gimple_val, fb_rvalue) == GS_ERROR
    9763          470 :           || gimplify_expr (&OMP_ITERATOR_STEP (it), pre_p, NULL,
    9764              :                             is_gimple_val, fb_rvalue) == GS_ERROR
    9765          940 :           || (gimplify_expr (&OMP_ITERATOR_ORIG_STEP (it), pre_p, NULL,
    9766              :                              is_gimple_val, fb_rvalue) == GS_ERROR))
    9767            0 :         return NULL_TREE;
    9768          470 :       tree var = OMP_ITERATOR_VAR (it);
    9769          470 :       tree begin = OMP_ITERATOR_BEGIN (it);
    9770          470 :       tree end = OMP_ITERATOR_END (it);
    9771          470 :       tree step = OMP_ITERATOR_STEP (it);
    9772          470 :       tree orig_step = OMP_ITERATOR_ORIG_STEP (it);
    9773          470 :       tree type = TREE_TYPE (var);
    9774          470 :       tree stype = TREE_TYPE (step);
    9775          470 :       location_t loc = DECL_SOURCE_LOCATION (var);
    9776          470 :       tree endmbegin;
    9777              :       /* Compute count for this iterator as
    9778              :          orig_step > 0
    9779              :          ? (begin < end ? (end - begin + (step - 1)) / step : 0)
    9780              :          : (begin > end ? (end - begin + (step + 1)) / step : 0)
    9781              :          and compute product of those for the entire clause.  */
    9782          470 :       if (POINTER_TYPE_P (type))
    9783           42 :         endmbegin = fold_build2_loc (loc, POINTER_DIFF_EXPR, stype, end, begin);
    9784              :       else
    9785          428 :         endmbegin = fold_build2_loc (loc, MINUS_EXPR, type, end, begin);
    9786              :       /* Account for iteration stopping on the end value in Fortran rather
    9787              :          than before it.  */
    9788          470 :       tree stepm1 = step;
    9789          470 :       tree stepp1 = step;
    9790          470 :       if (!lang_GNU_Fortran ())
    9791              :         {
    9792          372 :           stepm1 = fold_build2_loc (loc, MINUS_EXPR, stype, step,
    9793              :                                     build_int_cst (stype, 1));
    9794          372 :           stepp1 = fold_build2_loc (loc, PLUS_EXPR, stype, step,
    9795              :                                     build_int_cst (stype, 1));
    9796              :         }
    9797          470 :       tree pos = fold_build2_loc (loc, PLUS_EXPR, stype,
    9798              :                                   unshare_expr (endmbegin), stepm1);
    9799          470 :       pos = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype, pos, step);
    9800          470 :       tree neg = fold_build2_loc (loc, PLUS_EXPR, stype, endmbegin, stepp1);
    9801          470 :       if (TYPE_UNSIGNED (stype))
    9802              :         {
    9803           31 :           neg = fold_build1_loc (loc, NEGATE_EXPR, stype, neg);
    9804           31 :           step = fold_build1_loc (loc, NEGATE_EXPR, stype, step);
    9805              :         }
    9806          470 :       neg = fold_build2_loc (loc, TRUNC_DIV_EXPR, stype, neg, step);
    9807          470 :       step = NULL_TREE;
    9808          470 :       tree_code cmp_op = lang_GNU_Fortran () ? LE_EXPR : LT_EXPR;
    9809          470 :       tree cond = fold_build2_loc (loc, cmp_op, boolean_type_node, begin, end);
    9810          470 :       pos = fold_build3_loc (loc, COND_EXPR, stype, cond, pos,
    9811              :                              build_int_cst (stype, 0));
    9812          470 :       cond = fold_build2_loc (loc, cmp_op, boolean_type_node, end, begin);
    9813          470 :       neg = fold_build3_loc (loc, COND_EXPR, stype, cond, neg,
    9814              :                              build_int_cst (stype, 0));
    9815          470 :       tree osteptype = TREE_TYPE (orig_step);
    9816          470 :       cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node, orig_step,
    9817              :                               build_int_cst (osteptype, 0));
    9818          470 :       tree cnt = fold_build3_loc (loc, COND_EXPR, stype, cond, pos, neg);
    9819          470 :       cnt = fold_convert_loc (loc, sizetype, cnt);
    9820          470 :       if (gimplify_expr (&cnt, pre_p, NULL, is_gimple_val,
    9821              :                          fb_rvalue) == GS_ERROR)
    9822              :         return NULL_TREE;
    9823          470 :       tcnt = size_binop_loc (loc, MULT_EXPR, tcnt, cnt);
    9824              :     }
    9825          391 :   if (gimplify_expr (&tcnt, pre_p, NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
    9826              :     return NULL_TREE;
    9827              : 
    9828          391 :   return tcnt;
    9829              : }
    9830              : 
    9831              : /* Build loops iterating over the space defined by the OpenMP iterator IT.
    9832              :    Returns a pointer to the BIND_EXPR_BODY in the innermost loop body.
    9833              :    LAST_BIND is set to point to the BIND_EXPR containing the whole loop.  */
    9834              : 
    9835              : static tree *
    9836          391 : build_omp_iterator_loop (tree it, gimple_seq *pre_p, tree *last_bind)
    9837              : {
    9838          391 :   if (*last_bind)
    9839           31 :     gimplify_and_add (*last_bind, pre_p);
    9840          391 :   tree block = OMP_ITERATOR_BLOCK (it);
    9841          476 :   tree block_stmts = lang_GNU_Fortran () ? BLOCK_SUBBLOCKS (block) : NULL_TREE;
    9842          391 :   *last_bind = build3 (BIND_EXPR, void_type_node,
    9843          391 :                        BLOCK_VARS (block), NULL, block);
    9844          391 :   TREE_SIDE_EFFECTS (*last_bind) = 1;
    9845          391 :   tree *p = &BIND_EXPR_BODY (*last_bind);
    9846         1252 :   for (; it; it = TREE_CHAIN (it))
    9847              :     {
    9848          470 :       tree var = OMP_ITERATOR_VAR (it);
    9849          470 :       tree begin = OMP_ITERATOR_BEGIN (it);
    9850          470 :       tree end = OMP_ITERATOR_END (it);
    9851          470 :       tree step = OMP_ITERATOR_STEP (it);
    9852          470 :       tree orig_step = OMP_ITERATOR_ORIG_STEP (it);
    9853          470 :       block = OMP_ITERATOR_BLOCK (it);
    9854          470 :       tree type = TREE_TYPE (var);
    9855          470 :       location_t loc = DECL_SOURCE_LOCATION (var);
    9856              :       /* Emit:
    9857              :          var = begin;
    9858              :          goto cond_label;
    9859              :          beg_label:
    9860              :          ...
    9861              :          var = var + step;
    9862              :          cond_label:
    9863              :          if (orig_step > 0) {
    9864              :            if (var < end) goto beg_label;  // <= for Fortran
    9865              :          } else {
    9866              :            if (var > end) goto beg_label;  // >= for Fortran
    9867              :          }
    9868              :          for each iterator, with inner iterators added to
    9869              :          the ... above.  */
    9870          470 :       tree beg_label = create_artificial_label (loc);
    9871          470 :       tree cond_label = NULL_TREE;
    9872          470 :       tree tem = build2_loc (loc, MODIFY_EXPR, void_type_node, var, begin);
    9873          470 :       append_to_statement_list_force (tem, p);
    9874          470 :       tem = build_and_jump (&cond_label);
    9875          470 :       append_to_statement_list_force (tem, p);
    9876          470 :       tem = build1 (LABEL_EXPR, void_type_node, beg_label);
    9877          470 :       append_to_statement_list (tem, p);
    9878          470 :       tree bind = build3 (BIND_EXPR, void_type_node, NULL_TREE,
    9879              :                           NULL_TREE, NULL_TREE);
    9880          470 :       TREE_SIDE_EFFECTS (bind) = 1;
    9881          470 :       SET_EXPR_LOCATION (bind, loc);
    9882          470 :       append_to_statement_list_force (bind, p);
    9883          470 :       if (POINTER_TYPE_P (type))
    9884           42 :         tem = build2_loc (loc, POINTER_PLUS_EXPR, type,
    9885              :                           var, fold_convert_loc (loc, sizetype, step));
    9886              :       else
    9887          428 :         tem = build2_loc (loc, PLUS_EXPR, type, var, step);
    9888          470 :       tem = build2_loc (loc, MODIFY_EXPR, void_type_node, var, tem);
    9889          470 :       append_to_statement_list_force (tem, p);
    9890          470 :       tem = build1 (LABEL_EXPR, void_type_node, cond_label);
    9891          470 :       append_to_statement_list (tem, p);
    9892          842 :       tree cond = fold_build2_loc (loc, lang_GNU_Fortran () ? LE_EXPR : LT_EXPR,
    9893              :                                    boolean_type_node, var, end);
    9894          470 :       tree pos = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
    9895              :                                   build_and_jump (&beg_label), void_node);
    9896          842 :       cond = fold_build2_loc (loc, lang_GNU_Fortran () ? GE_EXPR : GT_EXPR,
    9897              :                               boolean_type_node, var, end);
    9898          470 :       tree neg = fold_build3_loc (loc, COND_EXPR, void_type_node, cond,
    9899              :                                   build_and_jump (&beg_label), void_node);
    9900          470 :       tree osteptype = TREE_TYPE (orig_step);
    9901          470 :       cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node, orig_step,
    9902              :                               build_int_cst (osteptype, 0));
    9903          470 :       tem = fold_build3_loc (loc, COND_EXPR, void_type_node, cond, pos, neg);
    9904          470 :       append_to_statement_list_force (tem, p);
    9905          470 :       p = &BIND_EXPR_BODY (bind);
    9906              :       /* The Fortran front-end stashes statements into the BLOCK_SUBBLOCKS
    9907              :          of the last element of the first iterator.  These should go into the
    9908              :          body of the innermost loop.  */
    9909          470 :       if (!TREE_CHAIN (it))
    9910          391 :         append_to_statement_list_force (block_stmts, p);
    9911              :     }
    9912              : 
    9913          391 :   return p;
    9914              : }
    9915              : 
    9916              : 
    9917              : /* Callback for walk_tree to find a VAR_DECL (stored in DATA) in the
    9918              :    tree TP.  */
    9919              : 
    9920              : static tree
    9921         3900 : find_var_decl (tree *tp, int *, void *data)
    9922              : {
    9923         3900 :   if (*tp == (tree) data)
    9924          369 :     return *tp;
    9925              : 
    9926              :   return NULL_TREE;
    9927              : }
    9928              : 
    9929              : /* Returns an element-by-element copy of OMP iterator tree IT.  If
    9930              :    EXPAND is true, force the result to be an expanded iterator; otherwise
    9931              :    it makes the copy the same size as IT.  */
    9932              : static tree
    9933          337 : copy_omp_iterator (tree it, bool expand = false)
    9934              : {
    9935          337 :   int elem_count = TREE_VEC_LENGTH (it);
    9936          337 :   tree new_it =
    9937          337 :     (expand ? make_expanded_omp_iterator () : make_tree_vec (elem_count));
    9938         2359 :   for (int i = 0; i < TREE_VEC_LENGTH (it); i++)
    9939         2022 :     TREE_VEC_ELT (new_it, i) = TREE_VEC_ELT (it, i);
    9940          337 :   return new_it;
    9941              : }
    9942              : 
    9943              : /* Helper function for walk_tree in remap_omp_iterator_var.  */
    9944              : 
    9945              : static tree
    9946         1063 : remap_omp_iterator_var_1 (tree *tp, int *, void *data)
    9947              : {
    9948         1063 :   tree old_var = ((tree *) data)[0];
    9949         1063 :   tree new_var = ((tree *) data)[1];
    9950              : 
    9951         1063 :   if (*tp == old_var)
    9952          106 :     *tp = new_var;
    9953         1063 :   return NULL_TREE;
    9954              : }
    9955              : 
    9956              : /* Replace instances of OLD_VAR in TP with NEW_VAR.  */
    9957              : 
    9958              : static void
    9959          212 : remap_omp_iterator_var (tree *tp, tree old_var, tree new_var)
    9960              : {
    9961          212 :   tree vars[2] = { old_var, new_var };
    9962          212 :   walk_tree (tp, remap_omp_iterator_var_1, vars, NULL);
    9963          212 : }
    9964              : 
    9965              : /* Scan through all clauses using OpenMP iterators in LIST_P.  If any
    9966              :    clauses have iterators with variables that are not used by the clause
    9967              :    decl or size, issue a warning and replace the iterator with a copy with
    9968              :    the unused variables removed.  */
    9969              : 
    9970              : static void
    9971        27824 : remove_unused_omp_iterator_vars (tree *list_p)
    9972              : {
    9973        27824 :   auto_vec< vec<tree> > iter_vars;
    9974        27824 :   auto_vec<tree> new_iterators;
    9975              : 
    9976        81122 :   for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
    9977              :     {
    9978        53298 :       if (!OMP_CLAUSE_HAS_ITERATORS (c))
    9979        53234 :         continue;
    9980          288 :       auto_vec<tree> vars;
    9981          288 :       bool need_new_iterators = false;
    9982          734 :       for (tree it = OMP_CLAUSE_ITERATORS (c); it; it = TREE_CHAIN (it))
    9983              :         {
    9984          446 :           tree var = OMP_ITERATOR_VAR (it);
    9985          446 :           tree t = walk_tree (&OMP_CLAUSE_DECL (c), find_var_decl, var, NULL);
    9986          446 :           if (t == NULL_TREE)
    9987          143 :             t = walk_tree (&OMP_CLAUSE_SIZE (c), find_var_decl, var, NULL);
    9988          143 :           if (t == NULL_TREE)
    9989              :             need_new_iterators = true;
    9990              :           else
    9991          369 :             vars.safe_push (var);
    9992              :         }
    9993          288 :       if (!need_new_iterators)
    9994          211 :         continue;
    9995           77 :       if (vars.is_empty ())
    9996              :         {
    9997              :           /* No iteration variables are used in the clause - remove the
    9998              :              iterator from the clause.  */
    9999           13 :           OMP_CLAUSE_ITERATORS (c) = NULL_TREE;
   10000           13 :           continue;
   10001              :         }
   10002              : 
   10003              :       /* If a new iterator has been created for the current set of used
   10004              :          iterator variables, then use that as the iterator.  Otherwise,
   10005              :          create a new iterator for the current iterator variable set. */
   10006              :       unsigned i;
   10007          106 :       for (i = 0; i < iter_vars.length (); i++)
   10008              :         {
   10009          124 :           if (vars.length () != iter_vars[i].length ())
   10010            0 :             continue;
   10011              :           bool identical_p = true;
   10012          150 :           for (unsigned j = 0; j < vars.length () && identical_p; j++)
   10013           88 :             identical_p = vars[j] == iter_vars[i][j];
   10014              : 
   10015           62 :           if (identical_p)
   10016              :             break;
   10017              :         }
   10018           64 :       if (i < iter_vars.length ())
   10019           20 :         OMP_CLAUSE_ITERATORS (c) = new_iterators[i];
   10020              :       else
   10021              :         {
   10022           44 :           tree new_iters = NULL_TREE;
   10023           44 :           tree *new_iters_p = &new_iters;
   10024           44 :           tree new_vars = NULL_TREE;
   10025           44 :           tree *new_vars_p = &new_vars;
   10026           44 :           i = 0;
   10027          140 :           for (tree it = OMP_CLAUSE_ITERATORS (c); it && i < vars.length();
   10028           96 :                it = TREE_CHAIN (it))
   10029              :             {
   10030           96 :               tree var = OMP_ITERATOR_VAR (it);
   10031           96 :               if (var == vars[i])
   10032              :                 {
   10033           74 :                   *new_iters_p = copy_omp_iterator (it);
   10034           74 :                   *new_vars_p = build_decl (OMP_CLAUSE_LOCATION (c), VAR_DECL,
   10035           74 :                                             DECL_NAME (var), TREE_TYPE (var));
   10036           74 :                   DECL_ARTIFICIAL (*new_vars_p) = 1;
   10037           74 :                   DECL_CONTEXT (*new_vars_p) = DECL_CONTEXT (var);
   10038           74 :                   OMP_ITERATOR_VAR (*new_iters_p) = *new_vars_p;
   10039           74 :                   new_iters_p = &TREE_CHAIN (*new_iters_p);
   10040           74 :                   new_vars_p = &DECL_CHAIN (*new_vars_p);
   10041           74 :                   i++;
   10042              :                 }
   10043              :             }
   10044           44 :           tree old_block = OMP_ITERATOR_BLOCK (OMP_CLAUSE_ITERATORS (c));
   10045           44 :           tree new_block = make_node (BLOCK);
   10046           44 :           BLOCK_VARS (new_block) = new_vars;
   10047           44 :           if (BLOCK_SUBBLOCKS (old_block))
   10048              :             {
   10049            4 :               BLOCK_SUBBLOCKS (new_block) = BLOCK_SUBBLOCKS (old_block);
   10050            4 :               BLOCK_SUBBLOCKS (old_block) = NULL_TREE;
   10051              :             }
   10052           44 :           OMP_ITERATOR_BLOCK (new_iters) = new_block;
   10053           44 :           new_iterators.safe_push (new_iters);
   10054           44 :           iter_vars.safe_push (vars.copy ());
   10055           44 :           OMP_CLAUSE_ITERATORS (c) = new_iters;
   10056              :         }
   10057              : 
   10058              :       /* Remap clause to use the new variables.  */
   10059           64 :       i = 0;
   10060          170 :       for (tree it = OMP_CLAUSE_ITERATORS (c); it; it = TREE_CHAIN (it))
   10061              :         {
   10062          106 :           tree old_var = vars[i++];
   10063          106 :           tree new_var = OMP_ITERATOR_VAR (it);
   10064          106 :           remap_omp_iterator_var (&OMP_CLAUSE_DECL (c), old_var, new_var);
   10065          106 :           remap_omp_iterator_var (&OMP_CLAUSE_SIZE (c), old_var, new_var);
   10066              :         }
   10067          288 :     }
   10068              : 
   10069        27868 :   for (unsigned i = 0; i < iter_vars.length (); i++)
   10070           44 :     iter_vars[i].release ();
   10071        27824 : }
   10072              : 
   10073          272 : struct iterator_loop_info_t
   10074              : {
   10075              :   tree bind;
   10076              :   tree count;
   10077              :   tree index;
   10078              :   tree body_label;
   10079              :   auto_vec<tree> clauses;
   10080              : };
   10081              : 
   10082              : typedef hash_map<tree, iterator_loop_info_t> iterator_loop_info_map_t;
   10083              : 
   10084              : /* Builds a loop to expand any OpenMP iterators in the clauses in LIST_P,
   10085              :    reusing any previously built loops if they use the same set of iterators.
   10086              :    Generated Gimple statements are placed into LOOPS_SEQ_P.  The clause
   10087              :    iterators are updated with information on how and where to insert code into
   10088              :    the loop body.  */
   10089              : 
   10090              : static void
   10091        27824 : build_omp_iterators_loops (tree *list_p, gimple_seq *loops_seq_p)
   10092              : {
   10093        27824 :   iterator_loop_info_map_t loops;
   10094              : 
   10095        81122 :   for (tree c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
   10096              :     {
   10097        53298 :       if (!OMP_CLAUSE_HAS_ITERATORS (c))
   10098        53035 :         continue;
   10099              : 
   10100          275 :       bool built_p;
   10101          275 :       iterator_loop_info_t &loop
   10102          275 :         = loops.get_or_insert (OMP_CLAUSE_ITERATORS (c), &built_p);
   10103              : 
   10104          275 :       if (!built_p)
   10105              :         {
   10106          136 :           loop.count = compute_omp_iterator_count (OMP_CLAUSE_ITERATORS (c),
   10107              :                                                    loops_seq_p);
   10108          136 :           if (!loop.count)
   10109            0 :             continue;
   10110          136 :           if (integer_zerop (loop.count))
   10111            8 :             warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
   10112              :                         "iteration count is zero");
   10113              : 
   10114          136 :           loop.bind = NULL_TREE;
   10115          136 :           tree *body = build_omp_iterator_loop (OMP_CLAUSE_ITERATORS (c),
   10116              :                                                 loops_seq_p, &loop.bind);
   10117              : 
   10118          136 :           loop.index = create_tmp_var (sizetype);
   10119          136 :           SET_EXPR_LOCATION (loop.bind, OMP_CLAUSE_LOCATION (c));
   10120              : 
   10121              :           /* BEFORE LOOP:  */
   10122              :           /* idx = -1;  */
   10123              :           /* This should be initialized to before the individual elements,
   10124              :              as idx is pre-incremented in the loop body.  */
   10125          136 :           gimple *assign = gimple_build_assign (loop.index, size_int (-1));
   10126          136 :           gimple_seq_add_stmt (loops_seq_p, assign);
   10127              : 
   10128              :           /* IN LOOP BODY:  */
   10129              :           /* Create a label so we can find this point later.  */
   10130          136 :           loop.body_label = create_artificial_label (OMP_CLAUSE_LOCATION (c));
   10131          136 :           tree tem = build1 (LABEL_EXPR, void_type_node, loop.body_label);
   10132          136 :           append_to_statement_list_force (tem, body);
   10133              : 
   10134              :           /* idx += 2;  */
   10135          136 :           tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   10136              :                             void_type_node, loop.index,
   10137              :                             size_binop (PLUS_EXPR, loop.index, size_int (2)));
   10138          136 :           append_to_statement_list_force (tem, body);
   10139              :         }
   10140              : 
   10141              :       /* Create array to hold expanded values.  */
   10142          275 :       tree last_count_2 = size_binop (MULT_EXPR, loop.count, size_int (2));
   10143          275 :       tree arr_length = size_binop (PLUS_EXPR, last_count_2, size_int (1));
   10144          275 :       tree elems = NULL_TREE;
   10145          275 :       if (TREE_CONSTANT (arr_length))
   10146              :         {
   10147          263 :           tree type = build_array_type (ptr_type_node,
   10148              :                                         build_index_type (arr_length));
   10149          263 :           elems = create_tmp_var_raw (type, "omp_iter_data");
   10150          263 :           TREE_ADDRESSABLE (elems) = 1;
   10151          263 :           gimple_add_tmp_var (elems);
   10152              :         }
   10153              :       else
   10154              :         {
   10155              :           /* Handle dynamic sizes.  */
   10156           12 :           sorry ("dynamic iterator sizes not implemented yet");
   10157           12 :           OMP_CLAUSE_ITERATORS (c) = NULL_TREE;
   10158           12 :           continue;
   10159              :         }
   10160              : 
   10161              :       /* BEFORE LOOP:  */
   10162              :       /* elems[0] = count;  */
   10163          263 :       tree lhs = build4 (ARRAY_REF, ptr_type_node, elems, size_int (0),
   10164              :                          NULL_TREE, NULL_TREE);
   10165          263 :       tree tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   10166              :                              void_type_node, lhs, loop.count);
   10167          263 :       gimplify_and_add (tem, loops_seq_p);
   10168              : 
   10169              :       /* Make a copy of the iterator with extra info at the end.  */
   10170          263 :       tree new_iterator = copy_omp_iterator (OMP_CLAUSE_ITERATORS (c), true);
   10171          263 :       OMP_ITERATOR_LABEL (new_iterator) = loop.body_label;
   10172          263 :       OMP_ITERATOR_INDEX (new_iterator) = loop.index;
   10173          263 :       OMP_ITERATOR_ELEMS (new_iterator) = elems;
   10174          263 :       TREE_CHAIN (new_iterator) = TREE_CHAIN (OMP_CLAUSE_ITERATORS (c));
   10175          263 :       OMP_CLAUSE_ITERATORS (c) = new_iterator;
   10176              : 
   10177          263 :       loop.clauses.safe_push (c);
   10178              :     }
   10179              : 
   10180              :   /* Now gimplify and add all the loops that were built.  */
   10181        27960 :   for (hash_map<tree, iterator_loop_info_t>::iterator it = loops.begin ();
   10182        55784 :        it != loops.end (); ++it)
   10183          136 :     gimplify_and_add ((*it).second.bind, loops_seq_p);
   10184        27824 : }
   10185              : 
   10186              : /* Helper function for enter_omp_iterator_loop_context.  */
   10187              : 
   10188              : static gimple_seq *
   10189         2950 : enter_omp_iterator_loop_context_1 (tree iterator, gimple_seq *loops_seq_p)
   10190              : {
   10191              :   /* Drill into the nested bind expressions to get to the loop body.  */
   10192         2950 :   for (gimple_stmt_iterator gsi = gsi_start (*loops_seq_p);
   10193        19569 :        !gsi_end_p (gsi); gsi_next (&gsi))
   10194              :     {
   10195        18965 :       gimple *stmt = gsi_stmt (gsi);
   10196              : 
   10197        18965 :       switch (gimple_code (stmt))
   10198              :         {
   10199         2252 :         case GIMPLE_BIND:
   10200         2252 :           {
   10201         2252 :             gbind *bind_stmt = as_a<gbind *> (stmt);
   10202         2252 :             gimple_push_bind_expr (bind_stmt);
   10203         2252 :             gimple_seq *bind_body_p = gimple_bind_body_ptr (bind_stmt);
   10204         2252 :             gimple_seq *seq =
   10205         2252 :               enter_omp_iterator_loop_context_1 (iterator, bind_body_p);
   10206         2252 :             if (seq)
   10207              :               return seq;
   10208          604 :             gimple_pop_bind_expr ();
   10209              :           }
   10210          604 :           break;
   10211            3 :         case GIMPLE_TRY:
   10212            3 :           {
   10213            3 :             gimple_seq *try_eval_p = gimple_try_eval_ptr (stmt);
   10214            3 :             gimple_seq *seq =
   10215            3 :               enter_omp_iterator_loop_context_1 (iterator, try_eval_p);
   10216            3 :             if (seq)
   10217              :               return seq;
   10218              :           }
   10219              :           break;
   10220         2994 :         case GIMPLE_LABEL:
   10221         2994 :           {
   10222         2994 :             glabel *label_stmt = as_a<glabel *> (stmt);
   10223         2994 :             tree label = gimple_label_label (label_stmt);
   10224         2994 :             if (label == OMP_ITERATOR_LABEL (iterator))
   10225              :               return loops_seq_p;
   10226              :           }
   10227              :           break;
   10228              :         default:
   10229              :           break;
   10230              :         }
   10231              :     }
   10232              : 
   10233              :   return NULL;
   10234              : }
   10235              : 
   10236              : /* Enter the Gimplification context in LOOPS_SEQ_P for the iterator loop
   10237              :    associated with OpenMP clause C.  Returns the gimple_seq for the loop body
   10238              :    if C has OpenMP iterators, or ALT_SEQ_P if not.  */
   10239              : 
   10240              : static gimple_seq *
   10241        65274 : enter_omp_iterator_loop_context (tree c, gimple_seq *loops_seq_p,
   10242              :                                  gimple_seq *alt_seq_p)
   10243              : {
   10244        65274 :   if (!OMP_CLAUSE_HAS_ITERATORS (c))
   10245              :     return alt_seq_p;
   10246              : 
   10247          695 :   push_gimplify_context ();
   10248              : 
   10249          695 :   gimple_seq *seq = enter_omp_iterator_loop_context_1 (OMP_CLAUSE_ITERATORS (c),
   10250              :                                                        loops_seq_p);
   10251          695 :   gcc_assert (seq);
   10252              :   return seq;
   10253              : }
   10254              : 
   10255              : /* Enter the Gimplification context in STMT for the iterator loop associated
   10256              :    with OpenMP clause C.  Returns the gimple_seq for the loop body if C has
   10257              :    OpenMP iterators, or ALT_SEQ_P if not.  */
   10258              : 
   10259              : gimple_seq *
   10260          434 : enter_omp_iterator_loop_context (tree c, gomp_target *stmt,
   10261              :                                  gimple_seq *alt_seq_p)
   10262              : {
   10263          434 :   gimple_seq *loops_seq_p = gimple_omp_target_iterator_loops_ptr (stmt);
   10264          434 :   return enter_omp_iterator_loop_context (c, loops_seq_p, alt_seq_p);
   10265              : }
   10266              : 
   10267              : /* Exit the Gimplification context for the OpenMP clause C.  */
   10268              : 
   10269              : void
   10270        65364 : exit_omp_iterator_loop_context (tree c)
   10271              : {
   10272        65364 :   if (!OMP_CLAUSE_HAS_ITERATORS (c))
   10273              :     return;
   10274         2343 :   while (!gimplify_ctxp->bind_expr_stack.is_empty ())
   10275         1648 :     gimple_pop_bind_expr ();
   10276          695 :   pop_gimplify_context (NULL);
   10277              : }
   10278              : 
   10279              : /* If *LIST_P contains any OpenMP depend clauses with iterators,
   10280              :    lower all the depend clauses by populating corresponding depend
   10281              :    array.  Returns 0 if there are no such depend clauses, or
   10282              :    2 if all depend clauses should be removed, 1 otherwise.  */
   10283              : 
   10284              : static int
   10285         1905 : gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
   10286              : {
   10287         1905 :   tree c;
   10288         1905 :   gimple *g;
   10289         1905 :   size_t n[5] = { 0, 0, 0, 0, 0 };
   10290         1905 :   bool unused[5];
   10291         1905 :   tree counts[5] = { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
   10292         1905 :   tree last_iter = NULL_TREE, last_count = NULL_TREE;
   10293         1905 :   size_t i, j;
   10294         1905 :   location_t first_loc = UNKNOWN_LOCATION;
   10295              : 
   10296         6250 :   for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
   10297         4345 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
   10298              :       {
   10299         2207 :         switch (OMP_CLAUSE_DEPEND_KIND (c))
   10300              :           {
   10301              :           case OMP_CLAUSE_DEPEND_IN:
   10302              :             i = 2;
   10303              :             break;
   10304              :           case OMP_CLAUSE_DEPEND_OUT:
   10305              :           case OMP_CLAUSE_DEPEND_INOUT:
   10306              :             i = 0;
   10307              :             break;
   10308              :           case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
   10309              :             i = 1;
   10310              :             break;
   10311              :           case OMP_CLAUSE_DEPEND_DEPOBJ:
   10312              :             i = 3;
   10313              :             break;
   10314              :           case OMP_CLAUSE_DEPEND_INOUTSET:
   10315              :             i = 4;
   10316              :             break;
   10317            0 :           default:
   10318            0 :             gcc_unreachable ();
   10319              :           }
   10320         2207 :         tree t = OMP_CLAUSE_DECL (c);
   10321         2207 :         if (first_loc == UNKNOWN_LOCATION)
   10322         1905 :           first_loc = OMP_CLAUSE_LOCATION (c);
   10323         2207 :         if (OMP_ITERATOR_DECL_P (t))
   10324              :           {
   10325          302 :             if (TREE_PURPOSE (t) != last_iter)
   10326              :               {
   10327          255 :                 tree tcnt = compute_omp_iterator_count (TREE_PURPOSE (t),
   10328              :                                                         pre_p);
   10329          255 :                 if (!tcnt)
   10330              :                   return 2;
   10331          255 :                 last_iter = TREE_PURPOSE (t);
   10332          255 :                 last_count = tcnt;
   10333              :               }
   10334          302 :             if (counts[i] == NULL_TREE)
   10335          248 :               counts[i] = last_count;
   10336              :             else
   10337           54 :               counts[i] = size_binop_loc (OMP_CLAUSE_LOCATION (c),
   10338              :                                           PLUS_EXPR, counts[i], last_count);
   10339              :           }
   10340              :         else
   10341         1905 :           n[i]++;
   10342              :       }
   10343        10620 :   for (i = 0; i < 5; i++)
   10344         8925 :     if (counts[i])
   10345              :       break;
   10346         1905 :   if (i == 5)
   10347              :     return 0;
   10348              : 
   10349          210 :   tree total = size_zero_node;
   10350         1260 :   for (i = 0; i < 5; i++)
   10351              :     {
   10352         1050 :       unused[i] = counts[i] == NULL_TREE && n[i] == 0;
   10353         1050 :       if (counts[i] == NULL_TREE)
   10354          802 :         counts[i] = size_zero_node;
   10355         1050 :       if (n[i])
   10356           44 :         counts[i] = size_binop (PLUS_EXPR, counts[i], size_int (n[i]));
   10357         1050 :       if (gimplify_expr (&counts[i], pre_p, NULL, is_gimple_val,
   10358              :                          fb_rvalue) == GS_ERROR)
   10359              :         return 2;
   10360         1050 :       total = size_binop (PLUS_EXPR, total, counts[i]);
   10361              :     }
   10362              : 
   10363          210 :   if (gimplify_expr (&total, pre_p, NULL, is_gimple_val, fb_rvalue)
   10364              :       == GS_ERROR)
   10365              :     return 2;
   10366          210 :   bool is_old = unused[1] && unused[3] && unused[4];
   10367          210 :   tree totalpx = size_binop (PLUS_EXPR, unshare_expr (total),
   10368              :                              size_int (is_old ? 1 : 4));
   10369          210 :   if (!unused[4])
   10370            3 :     totalpx = size_binop (PLUS_EXPR, totalpx,
   10371              :                           size_binop (MULT_EXPR, counts[4], size_int (2)));
   10372          210 :   tree type = build_array_type (ptr_type_node, build_index_type (totalpx));
   10373          210 :   tree array = create_tmp_var_raw (type);
   10374          210 :   TREE_ADDRESSABLE (array) = 1;
   10375          210 :   if (!poly_int_tree_p (totalpx))
   10376              :     {
   10377           83 :       if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (array)))
   10378           83 :         gimplify_type_sizes (TREE_TYPE (array), pre_p);
   10379           83 :       if (gimplify_omp_ctxp)
   10380              :         {
   10381              :           struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   10382              :           while (ctx
   10383           22 :                  && (ctx->region_type == ORT_WORKSHARE
   10384              :                      || ctx->region_type == ORT_TASKGROUP
   10385           22 :                      || ctx->region_type == ORT_SIMD
   10386           22 :                      || ctx->region_type == ORT_ACC))
   10387            0 :             ctx = ctx->outer_context;
   10388           22 :           if (ctx)
   10389           22 :             omp_add_variable (ctx, array, GOVD_LOCAL | GOVD_SEEN);
   10390              :         }
   10391           83 :       gimplify_vla_decl (array, pre_p);
   10392              :     }
   10393              :   else
   10394          127 :     gimple_add_tmp_var (array);
   10395          210 :   tree r = build4 (ARRAY_REF, ptr_type_node, array, size_int (0), NULL_TREE,
   10396              :                    NULL_TREE);
   10397          210 :   tree tem;
   10398          210 :   if (!is_old)
   10399              :     {
   10400           31 :       tem = build2 (MODIFY_EXPR, void_type_node, r,
   10401              :                     build_int_cst (ptr_type_node, 0));
   10402           31 :       gimplify_and_add (tem, pre_p);
   10403           31 :       r = build4 (ARRAY_REF, ptr_type_node, array, size_int (1), NULL_TREE,
   10404              :                   NULL_TREE);
   10405              :     }
   10406          210 :   tem = build2 (MODIFY_EXPR, void_type_node, r,
   10407              :                 fold_convert (ptr_type_node, total));
   10408          210 :   gimplify_and_add (tem, pre_p);
   10409          816 :   for (i = 1; i < (is_old ? 2 : 4); i++)
   10410              :     {
   10411          272 :       r = build4 (ARRAY_REF, ptr_type_node, array, size_int (i + !is_old),
   10412              :                   NULL_TREE, NULL_TREE);
   10413          272 :       tem = build2 (MODIFY_EXPR, void_type_node, r, counts[i - 1]);
   10414          272 :       gimplify_and_add (tem, pre_p);
   10415              :     }
   10416              : 
   10417              :   tree cnts[6];
   10418          740 :   for (j = 5; j; j--)
   10419          740 :     if (!unused[j - 1])
   10420              :       break;
   10421         1260 :   for (i = 0; i < 5; i++)
   10422              :     {
   10423         1050 :       if (i && (i >= j || unused[i - 1]))
   10424              :         {
   10425          790 :           cnts[i] = cnts[i - 1];
   10426          790 :           continue;
   10427              :         }
   10428          260 :       cnts[i] = create_tmp_var (sizetype);
   10429          260 :       if (i == 0)
   10430          241 :         g = gimple_build_assign (cnts[i], size_int (is_old ? 2 : 5));
   10431              :       else
   10432              :         {
   10433           50 :           tree t;
   10434           50 :           if (is_old)
   10435           38 :             t = size_binop (PLUS_EXPR, counts[0], size_int (2));
   10436              :           else
   10437           12 :             t = size_binop (PLUS_EXPR, cnts[i - 1], counts[i - 1]);
   10438           50 :           if (gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue)
   10439              :               == GS_ERROR)
   10440            0 :             return 2;
   10441           50 :           g = gimple_build_assign (cnts[i], t);
   10442              :         }
   10443          260 :       gimple_seq_add_stmt (pre_p, g);
   10444              :     }
   10445          210 :   if (unused[4])
   10446          207 :     cnts[5] = NULL_TREE;
   10447              :   else
   10448              :     {
   10449            3 :       tree t = size_binop (PLUS_EXPR, total, size_int (5));
   10450            3 :       cnts[5] = create_tmp_var (sizetype);
   10451            3 :       g = gimple_build_assign (cnts[i], t);
   10452            3 :       gimple_seq_add_stmt (pre_p, g);
   10453              :     }
   10454              : 
   10455          210 :   last_iter = NULL_TREE;
   10456          210 :   tree last_bind = NULL_TREE;
   10457          210 :   tree *last_body = NULL;
   10458          573 :   for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
   10459          363 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
   10460              :       {
   10461          348 :         switch (OMP_CLAUSE_DEPEND_KIND (c))
   10462              :           {
   10463              :           case OMP_CLAUSE_DEPEND_IN:
   10464              :             i = 2;
   10465              :             break;
   10466              :           case OMP_CLAUSE_DEPEND_OUT:
   10467              :           case OMP_CLAUSE_DEPEND_INOUT:
   10468              :             i = 0;
   10469              :             break;
   10470              :           case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
   10471              :             i = 1;
   10472              :             break;
   10473              :           case OMP_CLAUSE_DEPEND_DEPOBJ:
   10474              :             i = 3;
   10475              :             break;
   10476              :           case OMP_CLAUSE_DEPEND_INOUTSET:
   10477              :             i = 4;
   10478              :             break;
   10479            0 :           default:
   10480            0 :             gcc_unreachable ();
   10481              :           }
   10482          348 :         tree t = OMP_CLAUSE_DECL (c);
   10483          348 :         if (OMP_ITERATOR_DECL_P (t))
   10484              :           {
   10485          302 :             if (TREE_PURPOSE (t) != last_iter)
   10486              :               {
   10487          255 :                 last_body = build_omp_iterator_loop (TREE_PURPOSE (t), pre_p,
   10488              :                                                      &last_bind);
   10489          255 :                 SET_EXPR_LOCATION (last_bind, OMP_CLAUSE_LOCATION (c));
   10490              :               }
   10491          302 :             last_iter = TREE_PURPOSE (t);
   10492          302 :             if (TREE_CODE (TREE_VALUE (t)) == COMPOUND_EXPR)
   10493              :               {
   10494            0 :                 append_to_statement_list (TREE_OPERAND (TREE_VALUE (t),
   10495              :                                           0), last_body);
   10496            0 :                 TREE_VALUE (t) = TREE_OPERAND (TREE_VALUE (t), 1);
   10497              :               }
   10498          302 :             if (error_operand_p (TREE_VALUE (t)))
   10499              :               return 2;
   10500          302 :             if (TREE_VALUE (t) != null_pointer_node)
   10501          296 :               TREE_VALUE (t) = build_fold_addr_expr (TREE_VALUE (t));
   10502          302 :             if (i == 4)
   10503              :               {
   10504            3 :                 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
   10505              :                             NULL_TREE, NULL_TREE);
   10506            3 :                 tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5],
   10507              :                                   NULL_TREE, NULL_TREE);
   10508            3 :                 r2 = build_fold_addr_expr_with_type (r2, ptr_type_node);
   10509            3 :                 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   10510              :                                   void_type_node, r, r2);
   10511            3 :                 append_to_statement_list_force (tem, last_body);
   10512            3 :                 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   10513              :                                   void_type_node, cnts[i],
   10514              :                                   size_binop (PLUS_EXPR, cnts[i],
   10515              :                                               size_int (1)));
   10516            3 :                 append_to_statement_list_force (tem, last_body);
   10517            3 :                 i = 5;
   10518              :               }
   10519          302 :             r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
   10520              :                         NULL_TREE, NULL_TREE);
   10521          604 :             tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   10522          302 :                               void_type_node, r, TREE_VALUE (t));
   10523          302 :             append_to_statement_list_force (tem, last_body);
   10524          302 :             if (i == 5)
   10525              :               {
   10526            3 :                 r = build4 (ARRAY_REF, ptr_type_node, array,
   10527              :                             size_binop (PLUS_EXPR, cnts[i], size_int (1)),
   10528              :                             NULL_TREE, NULL_TREE);
   10529            3 :                 tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
   10530            3 :                 tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   10531              :                                   void_type_node, r, tem);
   10532            3 :                 append_to_statement_list_force (tem, last_body);
   10533              :               }
   10534          302 :             tem = build2_loc (OMP_CLAUSE_LOCATION (c), MODIFY_EXPR,
   10535              :                               void_type_node, cnts[i],
   10536          302 :                               size_binop (PLUS_EXPR, cnts[i],
   10537              :                                           size_int (1 + (i == 5))));
   10538          302 :             append_to_statement_list_force (tem, last_body);
   10539          302 :             TREE_VALUE (t) = null_pointer_node;
   10540              :           }
   10541              :         else
   10542              :           {
   10543           46 :             if (last_bind)
   10544              :               {
   10545           18 :                 gimplify_and_add (last_bind, pre_p);
   10546           18 :                 last_bind = NULL_TREE;
   10547              :               }
   10548           46 :             if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
   10549              :               {
   10550            0 :                 gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
   10551              :                                NULL, is_gimple_val, fb_rvalue);
   10552            0 :                 OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
   10553              :               }
   10554           46 :             if (error_operand_p (OMP_CLAUSE_DECL (c)))
   10555              :               return 2;
   10556           46 :             if (OMP_CLAUSE_DECL (c) != null_pointer_node)
   10557           46 :               OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
   10558           46 :             if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
   10559              :                                is_gimple_val, fb_rvalue) == GS_ERROR)
   10560              :               return 2;
   10561           46 :             if (i == 4)
   10562              :               {
   10563            0 :                 r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
   10564              :                             NULL_TREE, NULL_TREE);
   10565            0 :                 tree r2 = build4 (ARRAY_REF, ptr_type_node, array, cnts[5],
   10566              :                                   NULL_TREE, NULL_TREE);
   10567            0 :                 r2 = build_fold_addr_expr_with_type (r2, ptr_type_node);
   10568            0 :                 tem = build2 (MODIFY_EXPR, void_type_node, r, r2);
   10569            0 :                 gimplify_and_add (tem, pre_p);
   10570            0 :                 g = gimple_build_assign (cnts[i], size_binop (PLUS_EXPR,
   10571              :                                                               cnts[i],
   10572              :                                                               size_int (1)));
   10573            0 :                 gimple_seq_add_stmt (pre_p, g);
   10574            0 :                 i = 5;
   10575              :               }
   10576           46 :             r = build4 (ARRAY_REF, ptr_type_node, array, cnts[i],
   10577              :                         NULL_TREE, NULL_TREE);
   10578           46 :             tem = build2 (MODIFY_EXPR, void_type_node, r, OMP_CLAUSE_DECL (c));
   10579           46 :             gimplify_and_add (tem, pre_p);
   10580           46 :             if (i == 5)
   10581              :               {
   10582            0 :                 r = build4 (ARRAY_REF, ptr_type_node, array,
   10583              :                             size_binop (PLUS_EXPR, cnts[i], size_int (1)),
   10584              :                             NULL_TREE, NULL_TREE);
   10585            0 :                 tem = build_int_cst (ptr_type_node, GOMP_DEPEND_INOUTSET);
   10586            0 :                 tem = build2 (MODIFY_EXPR, void_type_node, r, tem);
   10587            0 :                 append_to_statement_list_force (tem, last_body);
   10588            0 :                 gimplify_and_add (tem, pre_p);
   10589              :               }
   10590           46 :             g = gimple_build_assign (cnts[i],
   10591           46 :                                      size_binop (PLUS_EXPR, cnts[i],
   10592              :                                                  size_int (1 + (i == 5))));
   10593           46 :             gimple_seq_add_stmt (pre_p, g);
   10594              :           }
   10595              :       }
   10596          210 :   if (last_bind)
   10597          206 :     gimplify_and_add (last_bind, pre_p);
   10598          210 :   tree cond = boolean_false_node;
   10599          210 :   if (is_old)
   10600              :     {
   10601          179 :       if (!unused[0])
   10602           92 :         cond = build2_loc (first_loc, NE_EXPR, boolean_type_node, cnts[0],
   10603              :                            size_binop_loc (first_loc, PLUS_EXPR, counts[0],
   10604              :                                            size_int (2)));
   10605          179 :       if (!unused[2])
   10606          125 :         cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
   10607              :                            build2_loc (first_loc, NE_EXPR, boolean_type_node,
   10608              :                                        cnts[2],
   10609              :                                        size_binop_loc (first_loc, PLUS_EXPR,
   10610              :                                                        totalpx,
   10611              :                                                        size_int (1))));
   10612              :     }
   10613              :   else
   10614              :     {
   10615           31 :       tree prev = size_int (5);
   10616          186 :       for (i = 0; i < 5; i++)
   10617              :         {
   10618          155 :           if (unused[i])
   10619          112 :             continue;
   10620           43 :           prev = size_binop_loc (first_loc, PLUS_EXPR, counts[i], prev);
   10621           43 :           cond = build2_loc (first_loc, TRUTH_OR_EXPR, boolean_type_node, cond,
   10622              :                              build2_loc (first_loc, NE_EXPR, boolean_type_node,
   10623              :                                          cnts[i], unshare_expr (prev)));
   10624              :         }
   10625              :     }
   10626          210 :   tem = build3_loc (first_loc, COND_EXPR, void_type_node, cond,
   10627              :                     build_call_expr_loc (first_loc,
   10628              :                                          builtin_decl_explicit (BUILT_IN_TRAP),
   10629              :                                          0), void_node);
   10630          210 :   gimplify_and_add (tem, pre_p);
   10631          210 :   c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEPEND);
   10632          210 :   OMP_CLAUSE_DEPEND_KIND (c) = OMP_CLAUSE_DEPEND_LAST;
   10633          210 :   OMP_CLAUSE_DECL (c) = build_fold_addr_expr (array);
   10634          210 :   OMP_CLAUSE_CHAIN (c) = *list_p;
   10635          210 :   *list_p = c;
   10636          210 :   return 1;
   10637              : }
   10638              : 
   10639              : /* True if mapping node C maps, or unmaps, a (Fortran) array descriptor.  */
   10640              : 
   10641              : static bool
   10642       126114 : omp_map_clause_descriptor_p (tree c)
   10643              : {
   10644       126114 :   if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
   10645              :     return false;
   10646              : 
   10647       126110 :   if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_TO_PSET)
   10648              :     return true;
   10649              : 
   10650        82892 :   if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_RELEASE
   10651        74854 :        || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DELETE)
   10652        83374 :       && OMP_CLAUSE_RELEASE_DESCRIPTOR (c))
   10653         6135 :     return true;
   10654              : 
   10655              :   return false;
   10656              : }
   10657              : 
   10658              : /* For a set of mappings describing an array section pointed to by a struct
   10659              :    (or derived type, etc.) component, create an "alloc" or "release" node to
   10660              :    insert into a list following a GOMP_MAP_STRUCT node.  For some types of
   10661              :    mapping (e.g. Fortran arrays with descriptors), an additional mapping may
   10662              :    be created that is inserted into the list of mapping nodes attached to the
   10663              :    directive being processed -- not part of the sorted list of nodes after
   10664              :    GOMP_MAP_STRUCT.
   10665              : 
   10666              :    CODE is the code of the directive being processed.  GRP_START and GRP_END
   10667              :    are the first and last of two or three nodes representing this array section
   10668              :    mapping (e.g. a data movement node like GOMP_MAP_{TO,FROM}, optionally a
   10669              :    GOMP_MAP_TO_PSET, and finally a GOMP_MAP_ALWAYS_POINTER).  EXTRA_NODE is
   10670              :    filled with the additional node described above, if needed.
   10671              : 
   10672              :    This function does not add the new nodes to any lists itself.  It is the
   10673              :    responsibility of the caller to do that.  */
   10674              : 
   10675              : static tree
   10676         1729 : build_omp_struct_comp_nodes (enum tree_code code, tree grp_start, tree grp_end,
   10677              :                              tree *extra_node)
   10678              : {
   10679         1524 :   enum gomp_map_kind mkind
   10680         1729 :     = (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
   10681         1729 :       ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
   10682              : 
   10683         1729 :   gcc_assert (grp_start != grp_end);
   10684              : 
   10685         1729 :   tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
   10686         1729 :   OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
   10687         1729 :   OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (grp_end));
   10688         1729 :   OMP_CLAUSE_CHAIN (c2) = NULL_TREE;
   10689         1729 :   tree grp_mid = NULL_TREE;
   10690         1729 :   if (OMP_CLAUSE_CHAIN (grp_start) != grp_end)
   10691          197 :     grp_mid = OMP_CLAUSE_CHAIN (grp_start);
   10692              : 
   10693          197 :   if (grp_mid && omp_map_clause_descriptor_p (grp_mid))
   10694            0 :     OMP_CLAUSE_SIZE (c2) = OMP_CLAUSE_SIZE (grp_mid);
   10695              :   else
   10696         1729 :     OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
   10697              : 
   10698         1729 :   if (grp_mid
   10699          197 :       && OMP_CLAUSE_CODE (grp_mid) == OMP_CLAUSE_MAP
   10700         1926 :       && OMP_CLAUSE_MAP_KIND (grp_mid) == GOMP_MAP_ALWAYS_POINTER)
   10701              :     {
   10702            0 :       tree c3
   10703            0 :         = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
   10704            0 :       OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
   10705            0 :       OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (grp_mid));
   10706            0 :       OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
   10707            0 :       OMP_CLAUSE_CHAIN (c3) = NULL_TREE;
   10708              : 
   10709            0 :       *extra_node = c3;
   10710              :     }
   10711              :   else
   10712         1729 :     *extra_node = NULL_TREE;
   10713              : 
   10714         1729 :   return c2;
   10715              : }
   10716              : 
   10717              : /* Strip ARRAY_REFS or an indirect ref off BASE, find the containing object,
   10718              :    and set *BITPOSP and *POFFSETP to the bit offset of the access.
   10719              :    If BASE_REF is non-NULL and the containing object is a reference, set
   10720              :    *BASE_REF to that reference before dereferencing the object.
   10721              :    If BASE_REF is NULL, check that the containing object is a COMPONENT_REF or
   10722              :    has array type, else return NULL.  */
   10723              : 
   10724              : static tree
   10725         7741 : extract_base_bit_offset (tree base, poly_int64 *bitposp,
   10726              :                          poly_offset_int *poffsetp,
   10727              :                          bool *variable_offset,
   10728              :                          tree iterator)
   10729              : {
   10730         7741 :   tree offset;
   10731         7741 :   poly_int64 bitsize, bitpos;
   10732         7741 :   machine_mode mode;
   10733         7741 :   int unsignedp, reversep, volatilep = 0;
   10734         7741 :   poly_offset_int poffset;
   10735              : 
   10736         7741 :   STRIP_NOPS (base);
   10737              : 
   10738         7741 :   if (iterator)
   10739              :     {
   10740              :       /* Replace any iterator variables with the lower bound of the iterator.
   10741              :          This will give us the nominal offset and bit position of the first
   10742              :          element, which is all we should need to lay out the mappings.  The
   10743              :          actual locations of the iterated mappings are elsewhere.  */
   10744              :       tree it;
   10745           72 :       for (it = iterator; it; it = TREE_CHAIN (it))
   10746           39 :         base = simplify_replace_tree (base, OMP_ITERATOR_VAR (it),
   10747           39 :                                       OMP_ITERATOR_BEGIN (it));
   10748              :     }
   10749              : 
   10750         7741 :   base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
   10751              :                               &unsignedp, &reversep, &volatilep);
   10752              : 
   10753         7741 :   STRIP_NOPS (base);
   10754              : 
   10755         7741 :   if (offset && poly_int_tree_p (offset))
   10756              :     {
   10757            0 :       poffset = wi::to_poly_offset (offset);
   10758            0 :       *variable_offset = false;
   10759              :     }
   10760              :   else
   10761              :     {
   10762         7741 :       poffset = 0;
   10763         7741 :       *variable_offset = (offset != NULL_TREE);
   10764              :     }
   10765              : 
   10766         7741 :   if (maybe_ne (bitpos, 0))
   10767         5627 :     poffset += bits_to_bytes_round_down (bitpos);
   10768              : 
   10769         7741 :   *bitposp = bitpos;
   10770         7741 :   *poffsetp = poffset;
   10771              : 
   10772         7741 :   return base;
   10773              : }
   10774              : 
   10775              : /* Used for topological sorting of mapping groups.  UNVISITED means we haven't
   10776              :    started processing the group yet.  The TEMPORARY mark is used when we first
   10777              :    encounter a group on a depth-first traversal, and the PERMANENT mark is used
   10778              :    when we have processed all the group's children (i.e. all the base pointers
   10779              :    referred to by the group's mapping nodes, recursively).  */
   10780              : 
   10781              : enum omp_tsort_mark {
   10782              :   UNVISITED,
   10783              :   TEMPORARY,
   10784              :   PERMANENT
   10785              : };
   10786              : 
   10787              : /* Hash for trees based on operand_equal_p.  Like tree_operand_hash
   10788              :    but ignores side effects in the equality comparisons.  */
   10789              : 
   10790              : struct tree_operand_hash_no_se : tree_operand_hash
   10791              : {
   10792              :   static inline bool equal (const value_type &,
   10793              :                             const compare_type &);
   10794              : };
   10795              : 
   10796              : inline bool
   10797       415812 : tree_operand_hash_no_se::equal (const value_type &t1,
   10798              :                                 const compare_type &t2)
   10799              : {
   10800       415812 :   return operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS);
   10801              : }
   10802              : 
   10803              : /* A group of OMP_CLAUSE_MAP nodes that correspond to a single "map"
   10804              :    clause.  */
   10805              : 
   10806              : struct omp_mapping_group {
   10807              :   tree *grp_start;
   10808              :   tree grp_end;
   10809              :   omp_tsort_mark mark;
   10810              :   /* If we've removed the group but need to reindex, mark the group as
   10811              :      deleted.  */
   10812              :   bool deleted;
   10813              :   /* The group points to an already-created "GOMP_MAP_STRUCT
   10814              :      GOMP_MAP_ATTACH_DETACH" pair.  */
   10815              :   bool reprocess_struct;
   10816              :   /* The group should use "zero-length" allocations for pointers that are not
   10817              :      mapped "to" on the same directive.  */
   10818              :   bool fragile;
   10819              :   struct omp_mapping_group *sibling;
   10820              :   struct omp_mapping_group *next;
   10821              : };
   10822              : 
   10823              : DEBUG_FUNCTION void
   10824            0 : debug_mapping_group (omp_mapping_group *grp)
   10825              : {
   10826            0 :   tree tmp = OMP_CLAUSE_CHAIN (grp->grp_end);
   10827            0 :   OMP_CLAUSE_CHAIN (grp->grp_end) = NULL;
   10828            0 :   debug_generic_expr (*grp->grp_start);
   10829            0 :   OMP_CLAUSE_CHAIN (grp->grp_end) = tmp;
   10830            0 : }
   10831              : 
   10832              : /* Return the OpenMP "base pointer" of an expression EXPR, or NULL if there
   10833              :    isn't one.  */
   10834              : 
   10835              : static tree
   10836        36672 : omp_get_base_pointer (tree expr)
   10837              : {
   10838        36672 :   while (TREE_CODE (expr) == ARRAY_REF
   10839        44009 :          || TREE_CODE (expr) == COMPONENT_REF)
   10840         7337 :     expr = TREE_OPERAND (expr, 0);
   10841              : 
   10842        36672 :   if (INDIRECT_REF_P (expr)
   10843        36672 :       || (TREE_CODE (expr) == MEM_REF
   10844            1 :           && integer_zerop (TREE_OPERAND (expr, 1))))
   10845              :     {
   10846        10598 :       expr = TREE_OPERAND (expr, 0);
   10847        10635 :       while (TREE_CODE (expr) == COMPOUND_EXPR)
   10848           37 :         expr = TREE_OPERAND (expr, 1);
   10849        10598 :       if (TREE_CODE (expr) == POINTER_PLUS_EXPR)
   10850          841 :         expr = TREE_OPERAND (expr, 0);
   10851        10598 :       if (TREE_CODE (expr) == SAVE_EXPR)
   10852           31 :         expr = TREE_OPERAND (expr, 0);
   10853        10598 :       STRIP_NOPS (expr);
   10854        10598 :       return expr;
   10855              :     }
   10856              : 
   10857              :   return NULL_TREE;
   10858              : }
   10859              : 
   10860              : /* An attach or detach operation depends directly on the address being
   10861              :    attached/detached.  Return that address, or none if there are no
   10862              :    attachments/detachments.  */
   10863              : 
   10864              : static tree
   10865        16998 : omp_get_attachment (omp_mapping_group *grp)
   10866              : {
   10867        16998 :   tree node = *grp->grp_start;
   10868              : 
   10869        16998 :   switch (OMP_CLAUSE_MAP_KIND (node))
   10870              :     {
   10871        14038 :     case GOMP_MAP_TO:
   10872        14038 :     case GOMP_MAP_FROM:
   10873        14038 :     case GOMP_MAP_TOFROM:
   10874        14038 :     case GOMP_MAP_ALWAYS_FROM:
   10875        14038 :     case GOMP_MAP_ALWAYS_TO:
   10876        14038 :     case GOMP_MAP_ALWAYS_TOFROM:
   10877        14038 :     case GOMP_MAP_FORCE_FROM:
   10878        14038 :     case GOMP_MAP_FORCE_TO:
   10879        14038 :     case GOMP_MAP_FORCE_TOFROM:
   10880        14038 :     case GOMP_MAP_FORCE_PRESENT:
   10881        14038 :     case GOMP_MAP_PRESENT_ALLOC:
   10882        14038 :     case GOMP_MAP_PRESENT_FROM:
   10883        14038 :     case GOMP_MAP_PRESENT_TO:
   10884        14038 :     case GOMP_MAP_PRESENT_TOFROM:
   10885        14038 :     case GOMP_MAP_ALWAYS_PRESENT_FROM:
   10886        14038 :     case GOMP_MAP_ALWAYS_PRESENT_TO:
   10887        14038 :     case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   10888        14038 :     case GOMP_MAP_ALLOC:
   10889        14038 :     case GOMP_MAP_RELEASE:
   10890        14038 :     case GOMP_MAP_DELETE:
   10891        14038 :     case GOMP_MAP_FORCE_ALLOC:
   10892        14038 :       if (node == grp->grp_end)
   10893              :         return NULL_TREE;
   10894              : 
   10895         6645 :       node = OMP_CLAUSE_CHAIN (node);
   10896         6645 :       if (node && omp_map_clause_descriptor_p (node))
   10897              :         {
   10898         1038 :           gcc_assert (node != grp->grp_end);
   10899         1038 :           node = OMP_CLAUSE_CHAIN (node);
   10900              :         }
   10901         6645 :       if (node)
   10902         6645 :         switch (OMP_CLAUSE_MAP_KIND (node))
   10903              :           {
   10904              :           case GOMP_MAP_POINTER:
   10905              :           case GOMP_MAP_ALWAYS_POINTER:
   10906              :           case GOMP_MAP_FIRSTPRIVATE_POINTER:
   10907              :           case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   10908              :           case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
   10909              :           case GOMP_MAP_USES_ALLOCATORS:
   10910              :             return NULL_TREE;
   10911              : 
   10912         2559 :           case GOMP_MAP_ATTACH_DETACH:
   10913         2559 :           case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   10914         2559 :           case GOMP_MAP_DETACH:
   10915         2559 :             return OMP_CLAUSE_DECL (node);
   10916              : 
   10917            0 :           default:
   10918            0 :             internal_error ("unexpected mapping node");
   10919              :           }
   10920            0 :       return error_mark_node;
   10921              : 
   10922            0 :     case GOMP_MAP_TO_PSET:
   10923            0 :       gcc_assert (node != grp->grp_end);
   10924            0 :       node = OMP_CLAUSE_CHAIN (node);
   10925            0 :       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH
   10926            0 :           || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DETACH)
   10927            0 :         return OMP_CLAUSE_DECL (node);
   10928              :       else
   10929            0 :         internal_error ("unexpected mapping node");
   10930              :       return error_mark_node;
   10931              : 
   10932          541 :     case GOMP_MAP_ATTACH:
   10933          541 :     case GOMP_MAP_DETACH:
   10934          541 :       node = OMP_CLAUSE_CHAIN (node);
   10935          541 :       if (!node || *grp->grp_start == grp->grp_end)
   10936          541 :         return OMP_CLAUSE_DECL (*grp->grp_start);
   10937            0 :       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
   10938            0 :           || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   10939            0 :         return OMP_CLAUSE_DECL (*grp->grp_start);
   10940              :       else
   10941            0 :         internal_error ("unexpected mapping node");
   10942              :       return error_mark_node;
   10943              : 
   10944              :     case GOMP_MAP_STRUCT:
   10945              :     case GOMP_MAP_STRUCT_UNORD:
   10946              :     case GOMP_MAP_FORCE_DEVICEPTR:
   10947              :     case GOMP_MAP_DEVICE_RESIDENT:
   10948              :     case GOMP_MAP_LINK:
   10949              :     case GOMP_MAP_IF_PRESENT:
   10950              :     case GOMP_MAP_FIRSTPRIVATE:
   10951              :     case GOMP_MAP_FIRSTPRIVATE_INT:
   10952              :     case GOMP_MAP_USE_DEVICE_PTR:
   10953              :     case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   10954              :     case GOMP_MAP_USES_ALLOCATORS:
   10955              :       return NULL_TREE;
   10956              : 
   10957            0 :     default:
   10958            0 :       internal_error ("unexpected mapping node");
   10959              :     }
   10960              : 
   10961              :   return error_mark_node;
   10962              : }
   10963              : 
   10964              : /* Given a pointer START_P to the start of a group of related (e.g. pointer)
   10965              :    mappings, return the chain pointer to the end of that group in the list.  */
   10966              : 
   10967              : static tree *
   10968       111880 : omp_group_last (tree *start_p)
   10969              : {
   10970       111880 :   tree c = *start_p, nc, *grp_last_p = start_p;
   10971              : 
   10972       111880 :   gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP);
   10973              : 
   10974       111880 :   nc = OMP_CLAUSE_CHAIN (c);
   10975              : 
   10976       195017 :   if (!nc || OMP_CLAUSE_CODE (nc) != OMP_CLAUSE_MAP)
   10977              :     return grp_last_p;
   10978              : 
   10979        70900 :   switch (OMP_CLAUSE_MAP_KIND (c))
   10980              :     {
   10981              :     default:
   10982              :       while (nc
   10983       113904 :              && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
   10984       239227 :              && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
   10985       106726 :                  || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER
   10986        96033 :                  || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH_DETACH
   10987        83206 :                  || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_POINTER
   10988        57118 :                  || (OMP_CLAUSE_MAP_KIND (nc)
   10989              :                      == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)
   10990        57102 :                  || (OMP_CLAUSE_MAP_KIND (nc)
   10991              :                      == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)
   10992        56735 :                  || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH
   10993        56680 :                  || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ALWAYS_POINTER
   10994        54768 :                  || omp_map_clause_descriptor_p (nc)))
   10995              :         {
   10996        67059 :           tree nc2 = OMP_CLAUSE_CHAIN (nc);
   10997        67059 :           if (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH)
   10998              :             {
   10999              :               /* In the specific case we're doing "exit data" on an array
   11000              :                  slice of a reference-to-pointer struct component, we will see
   11001              :                  DETACH followed by ATTACH_DETACH here.  We want to treat that
   11002              :                  as a single group. In other cases DETACH might represent a
   11003              :                  stand-alone "detach" clause, so we don't want to consider
   11004              :                  that part of the group.  */
   11005           55 :               if (nc2
   11006           16 :                   && OMP_CLAUSE_CODE (nc2) == OMP_CLAUSE_MAP
   11007           71 :                   && OMP_CLAUSE_MAP_KIND (nc2) == GOMP_MAP_ATTACH_DETACH)
   11008            0 :                 goto consume_two_nodes;
   11009              :               else
   11010              :                 break;
   11011              :             }
   11012        67004 :           if (nc2
   11013        49076 :               && OMP_CLAUSE_CODE (nc2) == OMP_CLAUSE_MAP
   11014        42563 :               && (OMP_CLAUSE_MAP_KIND (nc)
   11015              :                   == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)
   11016        67020 :               && OMP_CLAUSE_MAP_KIND (nc2) == GOMP_MAP_ATTACH)
   11017              :             {
   11018           16 :             consume_two_nodes:
   11019           16 :               grp_last_p = &OMP_CLAUSE_CHAIN (nc);
   11020           16 :               c = nc2;
   11021           16 :               nc = OMP_CLAUSE_CHAIN (nc2);
   11022              :             }
   11023              :           else
   11024              :             {
   11025        66988 :               grp_last_p = &OMP_CLAUSE_CHAIN (c);
   11026        66988 :               c = nc;
   11027        66988 :               nc = nc2;
   11028              :             }
   11029              :         }
   11030              :       break;
   11031              : 
   11032          302 :     case GOMP_MAP_ATTACH:
   11033          302 :     case GOMP_MAP_DETACH:
   11034              :       /* This is a weird artifact of how directives are parsed: bare attach or
   11035              :          detach clauses get a subsequent (meaningless) FIRSTPRIVATE_POINTER or
   11036              :          FIRSTPRIVATE_REFERENCE node.  FIXME.  */
   11037          302 :       if (nc
   11038          302 :           && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
   11039          302 :           && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
   11040          302 :               || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER))
   11041            0 :         grp_last_p = &OMP_CLAUSE_CHAIN (c);
   11042              :       break;
   11043              : 
   11044           39 :     case GOMP_MAP_TO_PSET:
   11045           39 :       if (OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
   11046           39 :           && (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH
   11047           12 :               || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_DETACH))
   11048           39 :         grp_last_p = &OMP_CLAUSE_CHAIN (c);
   11049              :       break;
   11050              : 
   11051         5727 :     case GOMP_MAP_STRUCT:
   11052         5727 :     case GOMP_MAP_STRUCT_UNORD:
   11053         5727 :       {
   11054         5727 :         unsigned HOST_WIDE_INT num_mappings
   11055         5727 :           = tree_to_uhwi (OMP_CLAUSE_SIZE (c));
   11056         5727 :         if (OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_POINTER
   11057         5389 :             || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
   11058        10634 :             || OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_ATTACH_DETACH)
   11059         1134 :           grp_last_p = &OMP_CLAUSE_CHAIN (*grp_last_p);
   11060        14397 :         for (unsigned i = 0; i < num_mappings; i++)
   11061         8670 :           grp_last_p = &OMP_CLAUSE_CHAIN (*grp_last_p);
   11062              :       }
   11063              :       break;
   11064              :     }
   11065              : 
   11066              :   return grp_last_p;
   11067              : }
   11068              : 
   11069              : /* Walk through LIST_P, and return a list of groups of mappings found (e.g.
   11070              :    OMP_CLAUSE_MAP with GOMP_MAP_{TO/FROM/TOFROM} followed by one or two
   11071              :    associated GOMP_MAP_POINTER mappings).  Return a vector of omp_mapping_group
   11072              :    if we have more than one such group, else return NULL.  */
   11073              : 
   11074              : static void
   11075        90093 : omp_gather_mapping_groups_1 (tree *list_p, vec<omp_mapping_group> *groups,
   11076              :                              tree gather_sentinel)
   11077              : {
   11078        90093 :   for (tree *cp = list_p;
   11079       269321 :        *cp && *cp != gather_sentinel;
   11080       179228 :        cp = &OMP_CLAUSE_CHAIN (*cp))
   11081              :     {
   11082       179228 :       if (OMP_CLAUSE_CODE (*cp) != OMP_CLAUSE_MAP)
   11083        99219 :         continue;
   11084              : 
   11085        80009 :       tree *grp_last_p = omp_group_last (cp);
   11086        80009 :       omp_mapping_group grp;
   11087              : 
   11088        80009 :       grp.grp_start = cp;
   11089        80009 :       grp.grp_end = *grp_last_p;
   11090        80009 :       grp.mark = UNVISITED;
   11091        80009 :       grp.sibling = NULL;
   11092        80009 :       grp.deleted = false;
   11093        80009 :       grp.reprocess_struct = false;
   11094        80009 :       grp.fragile = false;
   11095        80009 :       grp.next = NULL;
   11096        80009 :       groups->safe_push (grp);
   11097              : 
   11098        80009 :       cp = grp_last_p;
   11099              :     }
   11100        90093 : }
   11101              : 
   11102              : static vec<omp_mapping_group> *
   11103        89775 : omp_gather_mapping_groups (tree *list_p)
   11104              : {
   11105        89775 :   vec<omp_mapping_group> *groups = new vec<omp_mapping_group> ();
   11106              : 
   11107        89775 :   omp_gather_mapping_groups_1 (list_p, groups, NULL_TREE);
   11108              : 
   11109        89775 :   if (groups->length () > 0)
   11110              :     return groups;
   11111              :   else
   11112              :     {
   11113        44730 :       delete groups;
   11114        44730 :       return NULL;
   11115              :     }
   11116              : }
   11117              : 
   11118              : /* A pointer mapping group GRP may define a block of memory starting at some
   11119              :    base address, and maybe also define a firstprivate pointer or firstprivate
   11120              :    reference that points to that block.  The return value is a node containing
   11121              :    the former, and the *FIRSTPRIVATE pointer is set if we have the latter.
   11122              :    If we define several base pointers, i.e. for a GOMP_MAP_STRUCT mapping,
   11123              :    return the number of consecutive chained nodes in CHAINED.  */
   11124              : 
   11125              : static tree
   11126        80403 : omp_group_base (omp_mapping_group *grp, unsigned int *chained,
   11127              :                 tree *firstprivate)
   11128              : {
   11129        80403 :   tree node = *grp->grp_start;
   11130              : 
   11131        80403 :   *firstprivate = NULL_TREE;
   11132        80403 :   *chained = 1;
   11133              : 
   11134        80403 :   switch (OMP_CLAUSE_MAP_KIND (node))
   11135              :     {
   11136        76205 :     case GOMP_MAP_TO:
   11137        76205 :     case GOMP_MAP_FROM:
   11138        76205 :     case GOMP_MAP_TOFROM:
   11139        76205 :     case GOMP_MAP_ALWAYS_FROM:
   11140        76205 :     case GOMP_MAP_ALWAYS_TO:
   11141        76205 :     case GOMP_MAP_ALWAYS_TOFROM:
   11142        76205 :     case GOMP_MAP_FORCE_FROM:
   11143        76205 :     case GOMP_MAP_FORCE_TO:
   11144        76205 :     case GOMP_MAP_FORCE_TOFROM:
   11145        76205 :     case GOMP_MAP_FORCE_PRESENT:
   11146        76205 :     case GOMP_MAP_PRESENT_ALLOC:
   11147        76205 :     case GOMP_MAP_PRESENT_FROM:
   11148        76205 :     case GOMP_MAP_PRESENT_TO:
   11149        76205 :     case GOMP_MAP_PRESENT_TOFROM:
   11150        76205 :     case GOMP_MAP_ALWAYS_PRESENT_FROM:
   11151        76205 :     case GOMP_MAP_ALWAYS_PRESENT_TO:
   11152        76205 :     case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   11153        76205 :     case GOMP_MAP_ALLOC:
   11154        76205 :     case GOMP_MAP_RELEASE:
   11155        76205 :     case GOMP_MAP_DELETE:
   11156        76205 :     case GOMP_MAP_FORCE_ALLOC:
   11157        76205 :     case GOMP_MAP_IF_PRESENT:
   11158        76205 :       if (node == grp->grp_end)
   11159              :         return node;
   11160              : 
   11161        34852 :       node = OMP_CLAUSE_CHAIN (node);
   11162        34852 :       if (!node)
   11163            0 :         internal_error ("unexpected mapping node");
   11164        34852 :       if (omp_map_clause_descriptor_p (node))
   11165              :         {
   11166        10754 :           if (node == grp->grp_end)
   11167            0 :             return *grp->grp_start;
   11168        10754 :           node = OMP_CLAUSE_CHAIN (node);
   11169              :         }
   11170        34852 :       switch (OMP_CLAUSE_MAP_KIND (node))
   11171              :         {
   11172        23539 :         case GOMP_MAP_POINTER:
   11173        23539 :         case GOMP_MAP_FIRSTPRIVATE_POINTER:
   11174        23539 :         case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   11175        23539 :         case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
   11176        23539 :           *firstprivate = OMP_CLAUSE_DECL (node);
   11177        23539 :           return *grp->grp_start;
   11178              : 
   11179        11313 :         case GOMP_MAP_ALWAYS_POINTER:
   11180        11313 :         case GOMP_MAP_ATTACH_DETACH:
   11181        11313 :         case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   11182        11313 :         case GOMP_MAP_DETACH:
   11183        11313 :           return *grp->grp_start;
   11184              : 
   11185            0 :         default:
   11186            0 :           internal_error ("unexpected mapping node");
   11187              :         }
   11188              :       return error_mark_node;
   11189              : 
   11190           26 :     case GOMP_MAP_TO_PSET:
   11191           26 :       gcc_assert (node != grp->grp_end);
   11192           26 :       node = OMP_CLAUSE_CHAIN (node);
   11193           26 :       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH
   11194           26 :           || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_DETACH)
   11195              :         return NULL_TREE;
   11196              :       else
   11197            0 :         internal_error ("unexpected mapping node");
   11198              :       return error_mark_node;
   11199              : 
   11200         1109 :     case GOMP_MAP_ATTACH:
   11201         1109 :     case GOMP_MAP_DETACH:
   11202         1109 :       node = OMP_CLAUSE_CHAIN (node);
   11203         1109 :       if (!node || *grp->grp_start == grp->grp_end)
   11204              :         return NULL_TREE;
   11205            0 :       if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
   11206            0 :           || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   11207              :         {
   11208              :           /* We're mapping the base pointer itself in a bare attach or detach
   11209              :              node.  This is a side effect of how parsing works, and the mapping
   11210              :              will be removed anyway (at least for enter/exit data directives).
   11211              :              We should ignore the mapping here.  FIXME.  */
   11212              :           return NULL_TREE;
   11213              :         }
   11214              :       else
   11215            0 :         internal_error ("unexpected mapping node");
   11216              :       return error_mark_node;
   11217              : 
   11218         2779 :     case GOMP_MAP_STRUCT:
   11219         2779 :     case GOMP_MAP_STRUCT_UNORD:
   11220         2779 :       {
   11221         2779 :         unsigned HOST_WIDE_INT num_mappings
   11222         2779 :           = tree_to_uhwi (OMP_CLAUSE_SIZE (node));
   11223         2779 :         node = OMP_CLAUSE_CHAIN (node);
   11224         2779 :         if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_POINTER
   11225         2779 :             || OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   11226              :           {
   11227          393 :             *firstprivate = OMP_CLAUSE_DECL (node);
   11228          393 :             node = OMP_CLAUSE_CHAIN (node);
   11229              :           }
   11230         2386 :         else if (OMP_CLAUSE_MAP_KIND (node) == GOMP_MAP_ATTACH_DETACH)
   11231          314 :           node = OMP_CLAUSE_CHAIN (node);
   11232         2779 :         *chained = num_mappings;
   11233         2779 :         return node;
   11234              :       }
   11235              : 
   11236              :     case GOMP_MAP_FORCE_DEVICEPTR:
   11237              :     case GOMP_MAP_DEVICE_RESIDENT:
   11238              :     case GOMP_MAP_LINK:
   11239              :     case GOMP_MAP_FIRSTPRIVATE:
   11240              :     case GOMP_MAP_FIRSTPRIVATE_INT:
   11241              :     case GOMP_MAP_USE_DEVICE_PTR:
   11242              :     case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   11243              :     case GOMP_MAP_USES_ALLOCATORS:
   11244              :       return NULL_TREE;
   11245              : 
   11246            0 :     case GOMP_MAP_FIRSTPRIVATE_POINTER:
   11247            0 :     case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   11248            0 :     case GOMP_MAP_POINTER:
   11249            0 :     case GOMP_MAP_ALWAYS_POINTER:
   11250            0 :     case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
   11251              :       /* These shouldn't appear by themselves.  */
   11252            0 :       if (!seen_error ())
   11253            0 :         internal_error ("unexpected pointer mapping node");
   11254            0 :       return error_mark_node;
   11255              : 
   11256            0 :     default:
   11257            0 :       gcc_unreachable ();
   11258              :     }
   11259              : 
   11260              :   return error_mark_node;
   11261              : }
   11262              : 
   11263              : /* Given a vector of omp_mapping_groups, build a hash table so we can look up
   11264              :    nodes by tree_operand_hash_no_se.  */
   11265              : 
   11266              : static void
   11267        45529 : omp_index_mapping_groups_1 (hash_map<tree_operand_hash_no_se,
   11268              :                                      omp_mapping_group *> *grpmap,
   11269              :                             vec<omp_mapping_group> *groups,
   11270              :                             tree reindex_sentinel)
   11271              : {
   11272        45529 :   omp_mapping_group *grp;
   11273        45529 :   unsigned int i;
   11274        45529 :   bool reindexing = reindex_sentinel != NULL_TREE, above_hwm = false;
   11275              : 
   11276       126386 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   11277              :     {
   11278        80857 :       if (reindexing && *grp->grp_start == reindex_sentinel)
   11279        80857 :         above_hwm = true;
   11280              : 
   11281        80857 :       if (reindexing && !above_hwm)
   11282        56925 :         continue;
   11283              : 
   11284        80557 :       if (grp->reprocess_struct)
   11285          154 :         continue;
   11286              : 
   11287        80403 :       tree fpp;
   11288        80403 :       unsigned int chained;
   11289        80403 :       tree node = omp_group_base (grp, &chained, &fpp);
   11290              : 
   11291        80403 :       if (node == error_mark_node || (!node && !fpp))
   11292         1419 :         continue;
   11293              : 
   11294              :       for (unsigned j = 0;
   11295       159412 :            node && j < chained;
   11296        80428 :            node = OMP_CLAUSE_CHAIN (node), j++)
   11297              :         {
   11298        80428 :           tree decl = OMP_CLAUSE_DECL (node);
   11299              :           /* Sometimes we see zero-offset MEM_REF instead of INDIRECT_REF,
   11300              :              meaning node-hash lookups don't work.  This is a workaround for
   11301              :              that, but ideally we should just create the INDIRECT_REF at
   11302              :              source instead.  FIXME.  */
   11303        80428 :           if (TREE_CODE (decl) == MEM_REF
   11304        80428 :               && integer_zerop (TREE_OPERAND (decl, 1)))
   11305            0 :             decl = build_fold_indirect_ref (TREE_OPERAND (decl, 0));
   11306              : 
   11307        80428 :           omp_mapping_group **prev = grpmap->get (decl);
   11308              : 
   11309        80428 :           if (prev && *prev == grp)
   11310              :             /* Empty.  */;
   11311        80428 :           else if (prev)
   11312              :             {
   11313              :               /* Mapping the same thing twice is normally diagnosed as an error,
   11314              :                  but can happen under some circumstances, e.g. in pr99928-16.c,
   11315              :                  the directive:
   11316              : 
   11317              :                  #pragma omp target simd reduction(+:a[:3]) \
   11318              :                                          map(always, tofrom: a[:6])
   11319              :                  ...
   11320              : 
   11321              :                  will result in two "a[0]" mappings (of different sizes).  */
   11322              : 
   11323          326 :               grp->sibling = (*prev)->sibling;
   11324          326 :               (*prev)->sibling = grp;
   11325              :             }
   11326              :           else
   11327        80102 :             grpmap->put (decl, grp);
   11328              :         }
   11329              : 
   11330        78984 :       if (!fpp)
   11331        55052 :         continue;
   11332              : 
   11333        23932 :       omp_mapping_group **prev = grpmap->get (fpp);
   11334        23932 :       if (prev && *prev != grp)
   11335              :         {
   11336           12 :           grp->sibling = (*prev)->sibling;
   11337           12 :           (*prev)->sibling = grp;
   11338              :         }
   11339              :       else
   11340        23920 :         grpmap->put (fpp, grp);
   11341              :     }
   11342        45529 : }
   11343              : 
   11344              : static hash_map<tree_operand_hash_no_se, omp_mapping_group *> *
   11345        45045 : omp_index_mapping_groups (vec<omp_mapping_group> *groups)
   11346              : {
   11347        45045 :   hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap
   11348        45045 :     = new hash_map<tree_operand_hash_no_se, omp_mapping_group *>;
   11349              : 
   11350        45045 :   omp_index_mapping_groups_1 (grpmap, groups, NULL_TREE);
   11351              : 
   11352        45045 :   return grpmap;
   11353              : }
   11354              : 
   11355              : /* Rebuild group map from partially-processed clause list (during
   11356              :    omp_build_struct_sibling_lists).  We have already processed nodes up until
   11357              :    a high-water mark (HWM).  This is a bit tricky because the list is being
   11358              :    reordered as it is scanned, but we know:
   11359              : 
   11360              :    1. The list after HWM has not been touched yet, so we can reindex it safely.
   11361              : 
   11362              :    2. The list before and including HWM has been altered, but remains
   11363              :       well-formed throughout the sibling-list building operation.
   11364              : 
   11365              :    so, we can do the reindex operation in two parts, on the processed and
   11366              :    then the unprocessed halves of the list.  */
   11367              : 
   11368              : static hash_map<tree_operand_hash_no_se, omp_mapping_group *> *
   11369          318 : omp_reindex_mapping_groups (tree *list_p,
   11370              :                             vec<omp_mapping_group> *groups,
   11371              :                             vec<omp_mapping_group> *processed_groups,
   11372              :                             tree sentinel)
   11373              : {
   11374          318 :   hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap
   11375          318 :     = new hash_map<tree_operand_hash_no_se, omp_mapping_group *>;
   11376              : 
   11377          318 :   processed_groups->truncate (0);
   11378              : 
   11379          318 :   omp_gather_mapping_groups_1 (list_p, processed_groups, sentinel);
   11380          318 :   omp_index_mapping_groups_1 (grpmap, processed_groups, NULL_TREE);
   11381          318 :   if (sentinel)
   11382          166 :     omp_index_mapping_groups_1 (grpmap, groups, sentinel);
   11383              : 
   11384          318 :   return grpmap;
   11385              : }
   11386              : 
   11387              : /* Find the immediately-containing struct for a component ref (etc.)
   11388              :    expression EXPR.  */
   11389              : 
   11390              : static tree
   11391        48181 : omp_containing_struct (tree expr)
   11392              : {
   11393        48181 :   tree expr0 = expr;
   11394              : 
   11395        48181 :   STRIP_NOPS (expr);
   11396              : 
   11397              :   /* Note: don't strip NOPs unless we're also stripping off array refs or a
   11398              :      component ref.  */
   11399        48181 :   if (TREE_CODE (expr) != ARRAY_REF && TREE_CODE (expr) != COMPONENT_REF)
   11400              :     return expr0;
   11401              : 
   11402        27293 :   while (TREE_CODE (expr) == ARRAY_REF)
   11403         3706 :     expr = TREE_OPERAND (expr, 0);
   11404              : 
   11405        23587 :   if (TREE_CODE (expr) == COMPONENT_REF)
   11406        21106 :     expr = TREE_OPERAND (expr, 0);
   11407              : 
   11408              :   return expr;
   11409              : }
   11410              : 
   11411              : /* Return TRUE if DECL describes a component that is part of a whole structure
   11412              :    that is mapped elsewhere in GRPMAP.  *MAPPED_BY_GROUP is set to the group
   11413              :    that maps that structure, if present.  */
   11414              : 
   11415              : static bool
   11416        25836 : omp_mapped_by_containing_struct (hash_map<tree_operand_hash_no_se,
   11417              :                                           omp_mapping_group *> *grpmap,
   11418              :                                  tree decl,
   11419              :                                  omp_mapping_group **mapped_by_group)
   11420              : {
   11421        25836 :   tree wsdecl = NULL_TREE;
   11422              : 
   11423        25836 :   *mapped_by_group = NULL;
   11424              : 
   11425        70526 :   while (true)
   11426              :     {
   11427        48181 :       wsdecl = omp_containing_struct (decl);
   11428        48181 :       if (wsdecl == decl)
   11429              :         break;
   11430        23587 :       omp_mapping_group **wholestruct = grpmap->get (wsdecl);
   11431        23587 :       if (!wholestruct
   11432        21015 :           && TREE_CODE (wsdecl) == MEM_REF
   11433        23588 :           && integer_zerop (TREE_OPERAND (wsdecl, 1)))
   11434              :         {
   11435            1 :           tree deref = TREE_OPERAND (wsdecl, 0);
   11436            1 :           deref = build_fold_indirect_ref (deref);
   11437            1 :           wholestruct = grpmap->get (deref);
   11438              :         }
   11439        23587 :       if (wholestruct)
   11440              :         {
   11441              :           /* An intermediate descriptor should not match here because the
   11442              :              pointee is actually not mapped by this group -- it is just a
   11443              :              zero-length alloc.  */
   11444         2572 :           tree desc = OMP_CLAUSE_CHAIN (*(*wholestruct)->grp_start);
   11445         2572 :           if (desc != NULL_TREE && omp_map_clause_descriptor_p (desc))
   11446         1330 :             goto next;
   11447         1242 :           *mapped_by_group = *wholestruct;
   11448         1242 :           return true;
   11449              :         }
   11450        21015 :     next:
   11451        22345 :       decl = wsdecl;
   11452        22345 :     }
   11453              : 
   11454              :   return false;
   11455              : }
   11456              : 
   11457              : /* Helper function for omp_tsort_mapping_groups.  Returns TRUE on success, or
   11458              :    FALSE on error.  */
   11459              : 
   11460              : static bool
   11461        20336 : omp_tsort_mapping_groups_1 (omp_mapping_group ***outlist,
   11462              :                             vec<omp_mapping_group> *groups,
   11463              :                             hash_map<tree_operand_hash_no_se,
   11464              :                                      omp_mapping_group *> *grpmap,
   11465              :                             omp_mapping_group *grp)
   11466              : {
   11467        20336 :   if (grp->mark == PERMANENT)
   11468              :     return true;
   11469        16998 :   if (grp->mark == TEMPORARY)
   11470              :     {
   11471            0 :       fprintf (stderr, "when processing group:\n");
   11472            0 :       debug_mapping_group (grp);
   11473            0 :       internal_error ("base pointer cycle detected");
   11474              :       return false;
   11475              :     }
   11476        16998 :   grp->mark = TEMPORARY;
   11477              : 
   11478        16998 :   tree attaches_to = omp_get_attachment (grp);
   11479              : 
   11480        16998 :   if (attaches_to)
   11481              :     {
   11482         3100 :       omp_mapping_group **basep = grpmap->get (attaches_to);
   11483              : 
   11484         3100 :       if (basep && *basep != grp)
   11485              :         {
   11486         2924 :           for (omp_mapping_group *w = *basep; w; w = w->sibling)
   11487         1462 :             if (!omp_tsort_mapping_groups_1 (outlist, groups, grpmap, w))
   11488              :               return false;
   11489              :         }
   11490              :     }
   11491              : 
   11492        16998 :   tree decl = OMP_CLAUSE_DECL (*grp->grp_start);
   11493              : 
   11494        23221 :   while (decl)
   11495              :     {
   11496        23221 :       tree base = omp_get_base_pointer (decl);
   11497              : 
   11498        23221 :       if (!base)
   11499              :         break;
   11500              : 
   11501         8986 :       omp_mapping_group **innerp = grpmap->get (base);
   11502         8986 :       omp_mapping_group *wholestruct;
   11503              : 
   11504              :       /* We should treat whole-structure mappings as if all (pointer, in this
   11505              :          case) members are mapped as individual list items.  Check if we have
   11506              :          such a whole-structure mapping, if we don't have an explicit reference
   11507              :          to the pointer member itself.  */
   11508         8986 :       if (!innerp
   11509         4172 :           && TREE_CODE (base) == COMPONENT_REF
   11510        11218 :           && omp_mapped_by_containing_struct (grpmap, base, &wholestruct))
   11511              :         innerp = &wholestruct;
   11512              : 
   11513         8986 :       if (innerp && *innerp != grp)
   11514              :         {
   11515         5538 :           for (omp_mapping_group *w = *innerp; w; w = w->sibling)
   11516         2775 :             if (!omp_tsort_mapping_groups_1 (outlist, groups, grpmap, w))
   11517            0 :               return false;
   11518              :           break;
   11519              :         }
   11520              : 
   11521         6223 :       decl = base;
   11522              :     }
   11523              : 
   11524        16998 :   grp->mark = PERMANENT;
   11525              : 
   11526              :   /* Emit grp to output list.  */
   11527              : 
   11528        16998 :   **outlist = grp;
   11529        16998 :   *outlist = &grp->next;
   11530              : 
   11531        16998 :   return true;
   11532              : }
   11533              : 
   11534              : /* Topologically sort GROUPS, so that OMP 5.0-defined base pointers come
   11535              :    before mappings that use those pointers.  This is an implementation of the
   11536              :    depth-first search algorithm, described e.g. at:
   11537              : 
   11538              :      https://en.wikipedia.org/wiki/Topological_sorting
   11539              : */
   11540              : 
   11541              : static omp_mapping_group *
   11542         8640 : omp_tsort_mapping_groups (vec<omp_mapping_group> *groups,
   11543              :                           hash_map<tree_operand_hash_no_se, omp_mapping_group *>
   11544              :                             *grpmap,
   11545              :                           bool enter_exit_data)
   11546              : {
   11547         8640 :   omp_mapping_group *grp, *outlist = NULL, **cursor;
   11548         8640 :   unsigned int i;
   11549         8640 :   bool saw_runtime_implicit = false;
   11550              : 
   11551         8640 :   cursor = &outlist;
   11552              : 
   11553        25638 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   11554              :     {
   11555        16998 :       if (grp->mark != PERMANENT)
   11556              :         {
   11557        16123 :           if (OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start))
   11558              :             {
   11559          683 :               saw_runtime_implicit = true;
   11560          683 :               continue;
   11561              :             }
   11562        15440 :           if (!omp_tsort_mapping_groups_1 (&cursor, groups, grpmap, grp))
   11563              :             return NULL;
   11564              :         }
   11565              :     }
   11566              : 
   11567         8640 :   if (!saw_runtime_implicit)
   11568         8358 :     return outlist;
   11569              : 
   11570         1634 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   11571              :     {
   11572         1352 :       if (grp->mark != PERMANENT
   11573         1352 :           && OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start))
   11574              :         {
   11575              :           /* Clear the flag for enter/exit data because it is currently
   11576              :              meaningless for those operations in libgomp.  */
   11577          659 :           if (enter_exit_data)
   11578          446 :             OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (*grp->grp_start) = 0;
   11579              : 
   11580          659 :           if (!omp_tsort_mapping_groups_1 (&cursor, groups, grpmap, grp))
   11581              :             return NULL;
   11582              :         }
   11583              :     }
   11584              : 
   11585          282 :   return outlist;
   11586              : }
   11587              : 
   11588              : /* Split INLIST into three parts:
   11589              : 
   11590              :      - "present" alloc/to/from groups
   11591              :      - other to/from groups
   11592              :      - other alloc/release/delete groups
   11593              : 
   11594              :    These sub-lists are then concatenated together to form the final list.
   11595              :    Each sub-list retains the order of the original list.
   11596              :    Note that ATTACH nodes are later moved to the end of the list in
   11597              :    gimplify_adjust_omp_clauses, for target regions.  */
   11598              : 
   11599              : static omp_mapping_group *
   11600         8640 : omp_segregate_mapping_groups (omp_mapping_group *inlist)
   11601              : {
   11602         8640 :   omp_mapping_group *ard_groups = NULL, *tf_groups = NULL;
   11603         8640 :   omp_mapping_group *p_groups = NULL;
   11604         8640 :   omp_mapping_group **ard_tail = &ard_groups, **tf_tail = &tf_groups;
   11605         8640 :   omp_mapping_group **p_tail = &p_groups;
   11606              : 
   11607        25638 :   for (omp_mapping_group *w = inlist; w;)
   11608              :     {
   11609        16998 :       tree c = *w->grp_start;
   11610        16998 :       omp_mapping_group *next = w->next;
   11611              : 
   11612        16998 :       gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP);
   11613              : 
   11614        16998 :       switch (OMP_CLAUSE_MAP_KIND (c))
   11615              :         {
   11616         1939 :         case GOMP_MAP_ALLOC:
   11617         1939 :         case GOMP_MAP_RELEASE:
   11618         1939 :         case GOMP_MAP_DELETE:
   11619         1939 :           *ard_tail = w;
   11620         1939 :           w->next = NULL;
   11621         1939 :           ard_tail = &w->next;
   11622         1939 :           break;
   11623              : 
   11624              :         /* These map types are all semantically identical, so are moved into a
   11625              :            single group.  They will each be changed into GOMP_MAP_FORCE_PRESENT
   11626              :            in gimplify_adjust_omp_clauses.  */
   11627          151 :         case GOMP_MAP_PRESENT_ALLOC:
   11628          151 :         case GOMP_MAP_PRESENT_FROM:
   11629          151 :         case GOMP_MAP_PRESENT_TO:
   11630          151 :         case GOMP_MAP_PRESENT_TOFROM:
   11631          151 :           *p_tail = w;
   11632          151 :           w->next = NULL;
   11633          151 :           p_tail = &w->next;
   11634          151 :           break;
   11635              : 
   11636        14908 :         default:
   11637        14908 :           *tf_tail = w;
   11638        14908 :           w->next = NULL;
   11639        14908 :           tf_tail = &w->next;
   11640              :         }
   11641              : 
   11642        16998 :       w = next;
   11643              :     }
   11644              : 
   11645              :   /* Now splice the lists together...  */
   11646         8640 :   *tf_tail = ard_groups;
   11647         8640 :   *p_tail = tf_groups;
   11648              : 
   11649         8640 :   return p_groups;
   11650              : }
   11651              : 
   11652              : /* Given a list LIST_P containing groups of mappings given by GROUPS, reorder
   11653              :    those groups based on the output list of omp_tsort_mapping_groups --
   11654              :    singly-linked, threaded through each element's NEXT pointer starting at
   11655              :    HEAD.  Each list element appears exactly once in that linked list.
   11656              : 
   11657              :    Each element of GROUPS may correspond to one or several mapping nodes.
   11658              :    Node groups are kept together, and in the reordered list, the positions of
   11659              :    the original groups are reused for the positions of the reordered list.
   11660              :    Hence if we have e.g.
   11661              : 
   11662              :      {to ptr ptr} firstprivate {tofrom ptr} ...
   11663              :       ^             ^           ^
   11664              :       first group  non-"map"    second group
   11665              : 
   11666              :    and say the second group contains a base pointer for the first so must be
   11667              :    moved before it, the resulting list will contain:
   11668              : 
   11669              :      {tofrom ptr} firstprivate {to ptr ptr} ...
   11670              :       ^ prev. second group      ^ prev. first group
   11671              : */
   11672              : 
   11673              : static tree *
   11674         8640 : omp_reorder_mapping_groups (vec<omp_mapping_group> *groups,
   11675              :                             omp_mapping_group *head,
   11676              :                             tree *list_p)
   11677              : {
   11678         8640 :   omp_mapping_group *grp;
   11679         8640 :   unsigned int i;
   11680         8640 :   unsigned numgroups = groups->length ();
   11681         8640 :   auto_vec<tree> old_heads (numgroups);
   11682         8640 :   auto_vec<tree *> old_headps (numgroups);
   11683         8640 :   auto_vec<tree> new_heads (numgroups);
   11684         8640 :   auto_vec<tree> old_succs (numgroups);
   11685         8640 :   bool map_at_start = (list_p == (*groups)[0].grp_start);
   11686              : 
   11687         8640 :   tree *new_grp_tail = NULL;
   11688              : 
   11689              :   /* Stash the start & end nodes of each mapping group before we start
   11690              :      modifying the list.  */
   11691        25638 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   11692              :     {
   11693        16998 :       old_headps.quick_push (grp->grp_start);
   11694        16998 :       old_heads.quick_push (*grp->grp_start);
   11695        16998 :       old_succs.quick_push (OMP_CLAUSE_CHAIN (grp->grp_end));
   11696              :     }
   11697              : 
   11698              :   /* And similarly, the heads of the groups in the order we want to rearrange
   11699              :      the list to.  */
   11700        25638 :   for (omp_mapping_group *w = head; w; w = w->next)
   11701        16998 :     new_heads.quick_push (*w->grp_start);
   11702              : 
   11703        25638 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   11704              :     {
   11705        16998 :       gcc_assert (head);
   11706              : 
   11707        16998 :       if (new_grp_tail && old_succs[i - 1] == old_heads[i])
   11708              :         {
   11709              :           /* a {b c d} {e f g} h i j   (original)
   11710              :              -->
   11711              :              a {k l m} {e f g} h i j   (inserted new group on last iter)
   11712              :              -->
   11713              :              a {k l m} {n o p} h i j   (this time, chain last group to new one)
   11714              :                       ^new_grp_tail
   11715              :           */
   11716         7736 :           *new_grp_tail = new_heads[i];
   11717              :         }
   11718         9262 :       else if (new_grp_tail)
   11719              :         {
   11720              :           /* a {b c d} e {f g h} i j k   (original)
   11721              :              -->
   11722              :              a {l m n} e {f g h} i j k   (gap after last iter's group)
   11723              :              -->
   11724              :              a {l m n} e {o p q} h i j   (chain last group to old successor)
   11725              :                       ^new_grp_tail
   11726              :            */
   11727          622 :           *new_grp_tail = old_succs[i - 1];
   11728          622 :           *old_headps[i] = new_heads[i];
   11729              :         }
   11730              :       else
   11731              :         {
   11732              :           /* The first inserted group -- point to new group, and leave end
   11733              :              open.
   11734              :              a {b c d} e f
   11735              :              -->
   11736              :              a {g h i...
   11737              :           */
   11738         8640 :           *grp->grp_start = new_heads[i];
   11739              :         }
   11740              : 
   11741        16998 :       new_grp_tail = &OMP_CLAUSE_CHAIN (head->grp_end);
   11742              : 
   11743        16998 :       head = head->next;
   11744              :     }
   11745              : 
   11746         8640 :   if (new_grp_tail)
   11747         8640 :     *new_grp_tail = old_succs[numgroups - 1];
   11748              : 
   11749         8640 :   gcc_assert (!head);
   11750              : 
   11751        12098 :   return map_at_start ? (*groups)[0].grp_start : list_p;
   11752         8640 : }
   11753              : 
   11754              : /* DECL is supposed to have lastprivate semantics in the outer contexts
   11755              :    of combined/composite constructs, starting with OCTX.
   11756              :    Add needed lastprivate, shared or map clause if no data sharing or
   11757              :    mapping clause are present.  IMPLICIT_P is true if it is an implicit
   11758              :    clause (IV on simd), in which case the lastprivate will not be
   11759              :    copied to some constructs.  */
   11760              : 
   11761              : static void
   11762        14658 : omp_lastprivate_for_combined_outer_constructs (struct gimplify_omp_ctx *octx,
   11763              :                                                tree decl, bool implicit_p)
   11764              : {
   11765        14658 :   struct gimplify_omp_ctx *orig_octx = octx;
   11766        26979 :   for (; octx; octx = octx->outer_context)
   11767              :     {
   11768        25901 :       if ((octx->region_type == ORT_COMBINED_PARALLEL
   11769        20865 :            || (octx->region_type & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS)
   11770        25332 :           && splay_tree_lookup (octx->variables,
   11771              :                                 (splay_tree_key) decl) == NULL)
   11772              :         {
   11773         3887 :           omp_add_variable (octx, decl, GOVD_SHARED | GOVD_SEEN);
   11774         3887 :           continue;
   11775              :         }
   11776        18375 :       if ((octx->region_type & ORT_TASK) != 0
   11777          575 :           && octx->combined_loop
   11778        18656 :           && splay_tree_lookup (octx->variables,
   11779              :                                 (splay_tree_key) decl) == NULL)
   11780              :         {
   11781          248 :           omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
   11782          248 :           continue;
   11783              :         }
   11784        22711 :       if (implicit_p
   11785        13619 :           && octx->region_type == ORT_WORKSHARE
   11786        10405 :           && octx->combined_loop
   11787        10300 :           && splay_tree_lookup (octx->variables,
   11788              :                                 (splay_tree_key) decl) == NULL
   11789        10300 :           && octx->outer_context
   11790         8907 :           && octx->outer_context->region_type == ORT_COMBINED_PARALLEL
   11791        22718 :           && splay_tree_lookup (octx->outer_context->variables,
   11792              :                                 (splay_tree_key) decl) == NULL)
   11793              :         {
   11794         4832 :           octx = octx->outer_context;
   11795         4832 :           omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
   11796         4832 :           continue;
   11797              :         }
   11798         5565 :       if ((octx->region_type == ORT_WORKSHARE || octx->region_type == ORT_ACC)
   11799         7482 :           && octx->combined_loop
   11800         7295 :           && splay_tree_lookup (octx->variables,
   11801              :                                 (splay_tree_key) decl) == NULL
   11802        19072 :           && !omp_check_private (octx, decl, false))
   11803              :         {
   11804         3354 :           omp_add_variable (octx, decl, GOVD_LASTPRIVATE | GOVD_SEEN);
   11805         3354 :           continue;
   11806              :         }
   11807         9693 :       if (octx->region_type == ORT_COMBINED_TARGET)
   11808              :         {
   11809         2008 :           splay_tree_node n = splay_tree_lookup (octx->variables,
   11810              :                                                  (splay_tree_key) decl);
   11811         2008 :           if (n == NULL)
   11812              :             {
   11813         1986 :               omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
   11814         1986 :               octx = octx->outer_context;
   11815              :             }
   11816           22 :           else if (!implicit_p
   11817           22 :                    && (n->value & GOVD_FIRSTPRIVATE_IMPLICIT))
   11818              :             {
   11819           12 :               n->value &= ~(GOVD_FIRSTPRIVATE
   11820              :                             | GOVD_FIRSTPRIVATE_IMPLICIT
   11821              :                             | GOVD_EXPLICIT);
   11822           12 :               omp_add_variable (octx, decl, GOVD_MAP | GOVD_SEEN);
   11823           12 :               octx = octx->outer_context;
   11824              :             }
   11825              :         }
   11826              :       break;
   11827              :     }
   11828        14658 :   if (octx && (implicit_p || octx != orig_octx))
   11829         4046 :     omp_notice_variable (octx, decl, true);
   11830        14658 : }
   11831              : 
   11832              : /* We might have indexed several groups for DECL, e.g. a "TO" mapping and also
   11833              :    a "FIRSTPRIVATE" mapping.  Return the one that isn't firstprivate, etc.  */
   11834              : 
   11835              : static omp_mapping_group *
   11836         6008 : omp_get_nonfirstprivate_group (hash_map<tree_operand_hash_no_se,
   11837              :                                         omp_mapping_group *> *grpmap,
   11838              :                                tree decl, bool allow_deleted = false)
   11839              : {
   11840         6008 :   omp_mapping_group **to_group_p = grpmap->get (decl);
   11841              : 
   11842         6008 :   if (!to_group_p)
   11843              :     return NULL;
   11844              : 
   11845         2475 :   omp_mapping_group *to_group = *to_group_p;
   11846              : 
   11847         3828 :   for (; to_group; to_group = to_group->sibling)
   11848              :     {
   11849         2512 :       tree grp_end = to_group->grp_end;
   11850         2512 :       switch (OMP_CLAUSE_MAP_KIND (grp_end))
   11851              :         {
   11852              :         case GOMP_MAP_FIRSTPRIVATE_POINTER:
   11853              :         case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   11854              :           break;
   11855              : 
   11856         1161 :         default:
   11857         1161 :           if (allow_deleted || !to_group->deleted)
   11858              :             return to_group;
   11859              :         }
   11860              :     }
   11861              : 
   11862              :   return NULL;
   11863              : }
   11864              : 
   11865              : /* Return TRUE if the directive (whose clauses are described by the hash table
   11866              :    of mapping groups, GRPMAP) maps DECL explicitly.  If TO_SPECIFICALLY is
   11867              :    true, only count TO mappings.  If ALLOW_DELETED is true, ignore the
   11868              :    "deleted" flag for groups.  If CONTAINED_IN_STRUCT is true, also return
   11869              :    TRUE if DECL is mapped as a member of a whole-struct mapping.  */
   11870              : 
   11871              : static bool
   11872         4450 : omp_directive_maps_explicitly (hash_map<tree_operand_hash_no_se,
   11873              :                                         omp_mapping_group *> *grpmap,
   11874              :                                tree decl, omp_mapping_group **base_group,
   11875              :                                bool to_specifically, bool allow_deleted,
   11876              :                                bool contained_in_struct)
   11877              : {
   11878         4450 :   omp_mapping_group *decl_group
   11879         4450 :     = omp_get_nonfirstprivate_group (grpmap, decl, allow_deleted);
   11880              : 
   11881         4450 :   *base_group = NULL;
   11882              : 
   11883         4450 :   if (decl_group)
   11884              :     {
   11885         1042 :       tree grp_first = *decl_group->grp_start;
   11886              :       /* We might be called during omp_build_struct_sibling_lists, when
   11887              :          GOMP_MAP_STRUCT might have been inserted at the start of the group.
   11888              :          Skip over that, and also possibly the node after it.  */
   11889         1042 :       if (OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_STRUCT
   11890         1042 :           || OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_STRUCT_UNORD)
   11891              :         {
   11892            6 :           grp_first = OMP_CLAUSE_CHAIN (grp_first);
   11893            6 :           if (OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_FIRSTPRIVATE_POINTER
   11894            6 :               || (OMP_CLAUSE_MAP_KIND (grp_first)
   11895              :                   == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   11896           12 :               || OMP_CLAUSE_MAP_KIND (grp_first) == GOMP_MAP_ATTACH_DETACH)
   11897            0 :             grp_first = OMP_CLAUSE_CHAIN (grp_first);
   11898              :         }
   11899         1042 :       enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first);
   11900         1042 :       if (!to_specifically
   11901          592 :           || GOMP_MAP_COPY_TO_P (first_kind)
   11902          382 :           || first_kind == GOMP_MAP_ALLOC)
   11903              :         {
   11904          960 :           *base_group = decl_group;
   11905          960 :           return true;
   11906              :         }
   11907              :     }
   11908              : 
   11909         3490 :   if (contained_in_struct
   11910         3490 :       && omp_mapped_by_containing_struct (grpmap, decl, base_group))
   11911              :     return true;
   11912              : 
   11913              :   return false;
   11914              : }
   11915              : 
   11916              : /* If we have mappings INNER and OUTER, where INNER is a component access and
   11917              :    OUTER is a mapping of the whole containing struct, check that the mappings
   11918              :    are compatible.  We'll be deleting the inner mapping, so we need to make
   11919              :    sure the outer mapping does (at least) the same transfers to/from the device
   11920              :    as the inner mapping.  */
   11921              : 
   11922              : bool
   11923          172 : omp_check_mapping_compatibility (location_t loc,
   11924              :                                  omp_mapping_group *outer,
   11925              :                                  omp_mapping_group *inner)
   11926              : {
   11927          172 :   tree first_outer = *outer->grp_start, first_inner = *inner->grp_start;
   11928              : 
   11929          172 :   gcc_assert (OMP_CLAUSE_CODE (first_outer) == OMP_CLAUSE_MAP);
   11930          172 :   gcc_assert (OMP_CLAUSE_CODE (first_inner) == OMP_CLAUSE_MAP);
   11931              : 
   11932          172 :   enum gomp_map_kind outer_kind = OMP_CLAUSE_MAP_KIND (first_outer);
   11933          172 :   enum gomp_map_kind inner_kind = OMP_CLAUSE_MAP_KIND (first_inner);
   11934              : 
   11935          172 :   if (outer_kind == inner_kind)
   11936              :     return true;
   11937              : 
   11938           70 :   switch (outer_kind)
   11939              :     {
   11940            0 :     case GOMP_MAP_ALWAYS_TO:
   11941            0 :       if (inner_kind == GOMP_MAP_FORCE_PRESENT
   11942            0 :           || inner_kind == GOMP_MAP_ALLOC
   11943            0 :           || inner_kind == GOMP_MAP_TO)
   11944              :         return true;
   11945              :       break;
   11946              : 
   11947            0 :     case GOMP_MAP_ALWAYS_FROM:
   11948            0 :       if (inner_kind == GOMP_MAP_FORCE_PRESENT
   11949            0 :           || inner_kind == GOMP_MAP_RELEASE
   11950              :           || inner_kind == GOMP_MAP_FROM)
   11951              :         return true;
   11952              :       break;
   11953              : 
   11954           10 :     case GOMP_MAP_TO:
   11955           10 :       if (inner_kind == GOMP_MAP_FORCE_PRESENT
   11956           10 :           || inner_kind == GOMP_MAP_ALLOC)
   11957              :         return true;
   11958              :       break;
   11959              : 
   11960            8 :     case GOMP_MAP_FROM:
   11961            8 :       if (inner_kind == GOMP_MAP_RELEASE
   11962            8 :           || inner_kind == GOMP_MAP_FORCE_PRESENT)
   11963              :         return true;
   11964              :       break;
   11965              : 
   11966           32 :     case GOMP_MAP_ALWAYS_TOFROM:
   11967           32 :     case GOMP_MAP_TOFROM:
   11968           32 :       if (inner_kind == GOMP_MAP_FORCE_PRESENT
   11969           32 :           || inner_kind == GOMP_MAP_ALLOC
   11970              :           || inner_kind == GOMP_MAP_TO
   11971           24 :           || inner_kind == GOMP_MAP_FROM
   11972           12 :           || inner_kind == GOMP_MAP_TOFROM)
   11973              :         return true;
   11974              :       break;
   11975              : 
   11976           28 :     default:
   11977           28 :       ;
   11978              :     }
   11979              : 
   11980           84 :   error_at (loc, "data movement for component %qE is not compatible with "
   11981           28 :             "movement for struct %qE", OMP_CLAUSE_DECL (first_inner),
   11982           28 :             OMP_CLAUSE_DECL (first_outer));
   11983              : 
   11984           28 :   return false;
   11985              : }
   11986              : 
   11987              : /* This function handles several cases where clauses on a mapping directive
   11988              :    can interact with each other.
   11989              : 
   11990              :    If we have a FIRSTPRIVATE_POINTER node and we're also mapping the pointer
   11991              :    on the same directive, change the mapping of the first node to
   11992              :    ATTACH_DETACH.  We should have detected that this will happen already in
   11993              :    c-omp.cc:c_omp_adjust_map_clauses and marked the appropriate decl
   11994              :    as addressable.  (If we didn't, bail out.)
   11995              : 
   11996              :    If we have a FIRSTPRIVATE_REFERENCE (for a reference to pointer) and we're
   11997              :    mapping the base pointer also, we may need to change the mapping type to
   11998              :    ATTACH_DETACH and synthesize an alloc node for the reference itself.
   11999              : 
   12000              :    If we have an ATTACH_DETACH node, this is an array section with a pointer
   12001              :    base.  If we're mapping the base on the same directive too, we can drop its
   12002              :    mapping.  However, if we have a reference to pointer, make other appropriate
   12003              :    adjustments to the mapping nodes instead.
   12004              : 
   12005              :    If we have an ATTACH_DETACH node with a Fortran pointer-set (array
   12006              :    descriptor) mapping for a derived-type component, and we're also mapping the
   12007              :    whole of the derived-type variable on another clause, the pointer-set
   12008              :    mapping is removed.
   12009              : 
   12010              :    If we have a component access but we're also mapping the whole of the
   12011              :    containing struct, drop the former access.
   12012              : 
   12013              :    If the expression is a component access, and we're also mapping a base
   12014              :    pointer used in that component access in the same expression, change the
   12015              :    mapping type of the latter to ALLOC (ready for processing by
   12016              :    omp_build_struct_sibling_lists).  */
   12017              : 
   12018              : void
   12019         8640 : omp_resolve_clause_dependencies (enum tree_code code,
   12020              :                                  vec<omp_mapping_group> *groups,
   12021              :                                  hash_map<tree_operand_hash_no_se,
   12022              :                                           omp_mapping_group *> *grpmap)
   12023              : {
   12024         8640 :   int i;
   12025         8640 :   omp_mapping_group *grp;
   12026         8640 :   bool repair_chain = false;
   12027              : 
   12028        24574 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   12029              :     {
   12030        15934 :       tree grp_end = grp->grp_end;
   12031        15934 :       tree decl = OMP_CLAUSE_DECL (grp_end);
   12032              : 
   12033        15934 :       gcc_assert (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP);
   12034              : 
   12035        15934 :       switch (OMP_CLAUSE_MAP_KIND (grp_end))
   12036              :         {
   12037         1242 :         case GOMP_MAP_FIRSTPRIVATE_POINTER:
   12038         1242 :           {
   12039         1242 :             omp_mapping_group *to_group
   12040         1242 :               = omp_get_nonfirstprivate_group (grpmap, decl);
   12041              : 
   12042         1242 :             if (!to_group || to_group == grp)
   12043         1217 :               continue;
   12044              : 
   12045           25 :             tree grp_first = *to_group->grp_start;
   12046           25 :             enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first);
   12047              : 
   12048           25 :             if ((GOMP_MAP_COPY_TO_P (first_kind)
   12049            7 :                  || first_kind == GOMP_MAP_ALLOC)
   12050           50 :                 && (OMP_CLAUSE_MAP_KIND (to_group->grp_end)
   12051              :                     != GOMP_MAP_FIRSTPRIVATE_POINTER))
   12052              :               {
   12053           25 :                 gcc_assert (TREE_ADDRESSABLE (OMP_CLAUSE_DECL (grp_end)));
   12054           25 :                 OMP_CLAUSE_SET_MAP_KIND (grp_end, GOMP_MAP_ATTACH_DETACH);
   12055              :               }
   12056              :           }
   12057              :           break;
   12058              : 
   12059          160 :         case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   12060          160 :           {
   12061          160 :             tree ptr = build_fold_indirect_ref (decl);
   12062              : 
   12063          160 :             omp_mapping_group *to_group
   12064          160 :               = omp_get_nonfirstprivate_group (grpmap, ptr);
   12065              : 
   12066          160 :             if (!to_group || to_group == grp)
   12067          156 :               continue;
   12068              : 
   12069            4 :             tree grp_first = *to_group->grp_start;
   12070            4 :             enum gomp_map_kind first_kind = OMP_CLAUSE_MAP_KIND (grp_first);
   12071              : 
   12072            4 :             if (GOMP_MAP_COPY_TO_P (first_kind)
   12073            4 :                 || first_kind == GOMP_MAP_ALLOC)
   12074              :               {
   12075            4 :                 OMP_CLAUSE_SET_MAP_KIND (grp_end, GOMP_MAP_ATTACH_DETACH);
   12076            4 :                 OMP_CLAUSE_DECL (grp_end) = ptr;
   12077            4 :                 if ((OMP_CLAUSE_CHAIN (*to_group->grp_start)
   12078            4 :                      == to_group->grp_end)
   12079            4 :                     && (OMP_CLAUSE_MAP_KIND (to_group->grp_end)
   12080              :                         == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   12081              :                   {
   12082            0 :                     gcc_assert (TREE_ADDRESSABLE
   12083              :                                   (OMP_CLAUSE_DECL (to_group->grp_end)));
   12084            0 :                     OMP_CLAUSE_SET_MAP_KIND (to_group->grp_end,
   12085              :                                              GOMP_MAP_ATTACH_DETACH);
   12086              : 
   12087            0 :                     location_t loc = OMP_CLAUSE_LOCATION (to_group->grp_end);
   12088            0 :                     tree alloc
   12089            0 :                       = build_omp_clause (loc, OMP_CLAUSE_MAP);
   12090            0 :                     OMP_CLAUSE_SET_MAP_KIND (alloc, GOMP_MAP_ALLOC);
   12091            0 :                     tree tmp = build_fold_addr_expr (OMP_CLAUSE_DECL
   12092              :                                                       (to_group->grp_end));
   12093            0 :                     tree char_ptr_type = build_pointer_type (char_type_node);
   12094            0 :                     OMP_CLAUSE_DECL (alloc)
   12095            0 :                       = build2 (MEM_REF, char_type_node,
   12096              :                                 tmp,
   12097              :                                 build_int_cst (char_ptr_type, 0));
   12098            0 :                     OMP_CLAUSE_SIZE (alloc) = TYPE_SIZE_UNIT (TREE_TYPE (tmp));
   12099              : 
   12100            0 :                     OMP_CLAUSE_CHAIN (alloc)
   12101            0 :                       = OMP_CLAUSE_CHAIN (*to_group->grp_start);
   12102            0 :                     OMP_CLAUSE_CHAIN (*to_group->grp_start) = alloc;
   12103              :                   }
   12104              :               }
   12105              :           }
   12106              :           break;
   12107              : 
   12108              :         case GOMP_MAP_ATTACH_DETACH:
   12109              :         case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
   12110              :           {
   12111         2626 :             tree base_ptr, referenced_ptr_node = NULL_TREE;
   12112              : 
   12113         2626 :             while (TREE_CODE (decl) == ARRAY_REF)
   12114            0 :               decl = TREE_OPERAND (decl, 0);
   12115              : 
   12116         2626 :             if (TREE_CODE (decl) == INDIRECT_REF)
   12117           13 :               decl = TREE_OPERAND (decl, 0);
   12118              : 
   12119              :             /* Only component accesses.  */
   12120         2626 :             if (DECL_P (decl))
   12121          230 :               continue;
   12122              : 
   12123              :             /* We want the pointer itself when checking if the base pointer is
   12124              :                mapped elsewhere in the same directive -- if we have a
   12125              :                reference to the pointer, don't use that.  */
   12126              : 
   12127         2396 :             if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
   12128         2396 :                 && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
   12129              :               {
   12130          394 :                 referenced_ptr_node = OMP_CLAUSE_CHAIN (*grp->grp_start);
   12131          394 :                 base_ptr = OMP_CLAUSE_DECL (referenced_ptr_node);
   12132              :               }
   12133              :             else
   12134              :               base_ptr = decl;
   12135              : 
   12136         1978 :             gomp_map_kind zlas_kind
   12137         2396 :               = (code == OACC_EXIT_DATA || code == OMP_TARGET_EXIT_DATA)
   12138         2396 :                 ? GOMP_MAP_DETACH : GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION;
   12139              : 
   12140         2396 :             if (TREE_CODE (TREE_TYPE (base_ptr)) == POINTER_TYPE)
   12141              :               {
   12142              :                 /* If we map the base TO, and we're doing an attachment, we can
   12143              :                    skip the TO mapping altogether and create an ALLOC mapping
   12144              :                    instead, since the attachment will overwrite the device
   12145              :                    pointer in that location immediately anyway.  Otherwise,
   12146              :                    change our mapping to
   12147              :                    GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION in case the
   12148              :                    attachment target has not been copied to the device already
   12149              :                    by some earlier directive.  */
   12150              : 
   12151         1972 :                 bool base_mapped_to = false;
   12152              : 
   12153         1972 :                 omp_mapping_group *base_group;
   12154              : 
   12155         1972 :                 if (omp_directive_maps_explicitly (grpmap, base_ptr,
   12156              :                                                    &base_group, false, true,
   12157              :                                                    false))
   12158              :                   {
   12159          450 :                     if (referenced_ptr_node)
   12160              :                       {
   12161          129 :                         base_mapped_to = true;
   12162          129 :                         if ((OMP_CLAUSE_MAP_KIND (base_group->grp_end)
   12163              :                              == GOMP_MAP_ATTACH_DETACH)
   12164          129 :                             && (OMP_CLAUSE_CHAIN (*base_group->grp_start)
   12165              :                                 == base_group->grp_end))
   12166              :                           {
   12167          258 :                             OMP_CLAUSE_CHAIN (*base_group->grp_start)
   12168          129 :                               = OMP_CLAUSE_CHAIN (base_group->grp_end);
   12169          129 :                             base_group->grp_end = *base_group->grp_start;
   12170          129 :                             repair_chain = true;
   12171              :                           }
   12172              :                       }
   12173              :                     else
   12174              :                       {
   12175          321 :                         base_group->deleted = true;
   12176          321 :                         OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end) = 1;
   12177              :                       }
   12178              :                   }
   12179              : 
   12180              :                 /* We're dealing with a reference to a pointer, and we are
   12181              :                    attaching both the reference and the pointer.  We know the
   12182              :                    reference itself is on the target, because we are going to
   12183              :                    create an ALLOC node for it in accumulate_sibling_list.  The
   12184              :                    pointer might be on the target already or it might not, but
   12185              :                    if it isn't then it's not an error, so use
   12186              :                    GOMP_MAP_ATTACH_ZLAS for it.  */
   12187         1972 :                 if (!base_mapped_to && referenced_ptr_node)
   12188           56 :                   OMP_CLAUSE_SET_MAP_KIND (referenced_ptr_node, zlas_kind);
   12189              : 
   12190         1972 :                 omp_mapping_group *struct_group;
   12191         1972 :                 tree desc;
   12192         1972 :                 if ((desc = OMP_CLAUSE_CHAIN (*grp->grp_start))
   12193         1972 :                     && omp_map_clause_descriptor_p (desc)
   12194         3050 :                     && omp_mapped_by_containing_struct (grpmap, decl,
   12195              :                                                         &struct_group))
   12196              :                   /* If we have a pointer set but we're mapping (or unmapping)
   12197              :                      the whole of the containing struct, we can remove the
   12198              :                      pointer set mapping.  */
   12199           15 :                   OMP_CLAUSE_CHAIN (*grp->grp_start) = OMP_CLAUSE_CHAIN (desc);
   12200              :               }
   12201          424 :             else if (TREE_CODE (TREE_TYPE (base_ptr)) == REFERENCE_TYPE
   12202          424 :                      && (TREE_CODE (TREE_TYPE (TREE_TYPE (base_ptr)))
   12203              :                          == ARRAY_TYPE)
   12204          562 :                      && OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION
   12205              :                           (*grp->grp_start))
   12206           92 :               OMP_CLAUSE_SET_MAP_KIND (grp->grp_end, zlas_kind);
   12207              :           }
   12208              :           break;
   12209              : 
   12210              :         case GOMP_MAP_ATTACH:
   12211              :           /* Ignore standalone attach here.  */
   12212              :           break;
   12213              : 
   12214        11839 :         default:
   12215        11839 :           {
   12216        11839 :             omp_mapping_group *struct_group;
   12217        11839 :             if (omp_mapped_by_containing_struct (grpmap, decl, &struct_group)
   12218        11839 :                 && *grp->grp_start == grp_end)
   12219              :               {
   12220           94 :                 omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end),
   12221              :                                                  struct_group, grp);
   12222              :                 /* Remove the whole of this mapping -- redundant.  */
   12223           94 :                 grp->deleted = true;
   12224              :               }
   12225              : 
   12226        11839 :             tree base = decl;
   12227        13451 :             while ((base = omp_get_base_pointer (base)))
   12228              :               {
   12229         1612 :                 omp_mapping_group *base_group;
   12230              : 
   12231         1612 :                 if (omp_directive_maps_explicitly (grpmap, base, &base_group,
   12232              :                                                    true, true, false))
   12233              :                   {
   12234          343 :                     tree grp_first = *base_group->grp_start;
   12235          343 :                     OMP_CLAUSE_SET_MAP_KIND (grp_first, GOMP_MAP_ALLOC);
   12236              :                   }
   12237              :               }
   12238              :           }
   12239              :         }
   12240              :     }
   12241              : 
   12242         8640 :   if (repair_chain)
   12243              :     {
   12244              :       /* Group start pointers may have become detached from the
   12245              :          OMP_CLAUSE_CHAIN of previous groups if elements were removed from the
   12246              :          end of those groups.  Fix that now.  */
   12247              :       tree *new_next = NULL;
   12248          716 :       FOR_EACH_VEC_ELT (*groups, i, grp)
   12249              :         {
   12250          587 :           if (new_next)
   12251          458 :             grp->grp_start = new_next;
   12252              : 
   12253          587 :           new_next = &OMP_CLAUSE_CHAIN (grp->grp_end);
   12254              :         }
   12255              :     }
   12256         8640 : }
   12257              : 
   12258              : /* Similar to omp_resolve_clause_dependencies, but for OpenACC.  The only
   12259              :    clause dependencies we handle for now are struct element mappings and
   12260              :    whole-struct mappings on the same directive, and duplicate clause
   12261              :    detection.  */
   12262              : 
   12263              : void
   12264         9462 : oacc_resolve_clause_dependencies (vec<omp_mapping_group> *groups,
   12265              :                                   hash_map<tree_operand_hash_no_se,
   12266              :                                            omp_mapping_group *> *grpmap)
   12267              : {
   12268         9462 :   int i;
   12269         9462 :   omp_mapping_group *grp;
   12270         9462 :   hash_set<tree_operand_hash> *seen_components = NULL;
   12271         9462 :   hash_set<tree_operand_hash> *shown_error = NULL;
   12272              : 
   12273        24643 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   12274              :     {
   12275        15181 :       tree grp_end = grp->grp_end;
   12276        15181 :       tree decl = OMP_CLAUSE_DECL (grp_end);
   12277              : 
   12278        15181 :       gcc_assert (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP);
   12279              : 
   12280        15181 :       if (DECL_P (grp_end))
   12281        14664 :         continue;
   12282              : 
   12283        15181 :       tree c = OMP_CLAUSE_DECL (*grp->grp_start);
   12284        16806 :       while (TREE_CODE (c) == ARRAY_REF)
   12285         1625 :         c = TREE_OPERAND (c, 0);
   12286        15181 :       if (TREE_CODE (c) != COMPONENT_REF)
   12287        14664 :         continue;
   12288          517 :       if (!seen_components)
   12289          474 :         seen_components = new hash_set<tree_operand_hash> ();
   12290          517 :       if (!shown_error)
   12291          474 :         shown_error = new hash_set<tree_operand_hash> ();
   12292          517 :       if (seen_components->contains (c)
   12293          517 :           && !shown_error->contains (c))
   12294              :         {
   12295           10 :           error_at (OMP_CLAUSE_LOCATION (grp_end),
   12296              :                     "%qE appears more than once in map clauses",
   12297            5 :                     OMP_CLAUSE_DECL (grp_end));
   12298            5 :           shown_error->add (c);
   12299              :         }
   12300              :       else
   12301          512 :         seen_components->add (c);
   12302              : 
   12303          517 :       omp_mapping_group *struct_group;
   12304          517 :       if (omp_mapped_by_containing_struct (grpmap, decl, &struct_group)
   12305          517 :           && *grp->grp_start == grp_end)
   12306              :         {
   12307           78 :           omp_check_mapping_compatibility (OMP_CLAUSE_LOCATION (grp_end),
   12308              :                                            struct_group, grp);
   12309              :           /* Remove the whole of this mapping -- redundant.  */
   12310           78 :           grp->deleted = true;
   12311              :         }
   12312              :     }
   12313              : 
   12314         9462 :   if (seen_components)
   12315          474 :     delete seen_components;
   12316         9462 :   if (shown_error)
   12317          474 :     delete shown_error;
   12318         9462 : }
   12319              : 
   12320              : /* Link node NEWNODE so it is pointed to by chain INSERT_AT.  NEWNODE's chain
   12321              :    is linked to the previous node pointed to by INSERT_AT.  */
   12322              : 
   12323              : static tree *
   12324         1135 : omp_siblist_insert_node_after (tree newnode, tree *insert_at)
   12325              : {
   12326         1135 :   OMP_CLAUSE_CHAIN (newnode) = *insert_at;
   12327         1135 :   *insert_at = newnode;
   12328         1135 :   return &OMP_CLAUSE_CHAIN (newnode);
   12329              : }
   12330              : 
   12331              : /* Move NODE (which is currently pointed to by the chain OLD_POS) so it is
   12332              :    pointed to by chain MOVE_AFTER instead.  */
   12333              : 
   12334              : static void
   12335         1320 : omp_siblist_move_node_after (tree node, tree *old_pos, tree *move_after)
   12336              : {
   12337         1320 :   gcc_assert (node == *old_pos);
   12338         1320 :   *old_pos = OMP_CLAUSE_CHAIN (node);
   12339         1320 :   OMP_CLAUSE_CHAIN (node) = *move_after;
   12340         1320 :   *move_after = node;
   12341         1320 : }
   12342              : 
   12343              : /* Move nodes from FIRST_PTR (pointed to by previous node's chain) to
   12344              :    LAST_NODE to after MOVE_AFTER chain.  Similar to below function, but no
   12345              :    new nodes are prepended to the list before splicing into the new position.
   12346              :    Return the position we should continue scanning the list at, or NULL to
   12347              :    stay where we were.  */
   12348              : 
   12349              : static tree *
   12350          254 : omp_siblist_move_nodes_after (tree *first_ptr, tree last_node,
   12351              :                               tree *move_after)
   12352              : {
   12353          254 :   if (first_ptr == move_after)
   12354              :     return NULL;
   12355              : 
   12356          243 :   tree tmp = *first_ptr;
   12357          243 :   *first_ptr = OMP_CLAUSE_CHAIN (last_node);
   12358          243 :   OMP_CLAUSE_CHAIN (last_node) = *move_after;
   12359          243 :   *move_after = tmp;
   12360              : 
   12361          243 :   return first_ptr;
   12362              : }
   12363              : 
   12364              : /* Concatenate two lists described by [FIRST_NEW, LAST_NEW_TAIL] and
   12365              :    [FIRST_PTR, LAST_NODE], and insert them in the OMP clause list after chain
   12366              :    pointer MOVE_AFTER.
   12367              : 
   12368              :    The latter list was previously part of the OMP clause list, and the former
   12369              :    (prepended) part is comprised of new nodes.
   12370              : 
   12371              :    We start with a list of nodes starting with a struct mapping node.  We
   12372              :    rearrange the list so that new nodes starting from FIRST_NEW and whose last
   12373              :    node's chain is LAST_NEW_TAIL comes directly after MOVE_AFTER, followed by
   12374              :    the group of mapping nodes we are currently processing (from the chain
   12375              :    FIRST_PTR to LAST_NODE).  The return value is the pointer to the next chain
   12376              :    we should continue processing from, or NULL to stay where we were.
   12377              : 
   12378              :    The transformation (in the case where MOVE_AFTER and FIRST_PTR are
   12379              :    different) is worked through below.  Here we are processing LAST_NODE, and
   12380              :    FIRST_PTR points at the preceding mapping clause:
   12381              : 
   12382              :   #. mapping node               chain
   12383              :   ---------------------------------------------------
   12384              :   A. struct_node                [->B]
   12385              :   B. comp_1                     [->C]
   12386              :   C. comp_2                     [->D (move_after)]
   12387              :   D. map_to_3                   [->E]
   12388              :   E. attach_3                   [->F (first_ptr)]
   12389              :   F. map_to_4                   [->G (continue_at)]
   12390              :   G. attach_4 (last_node)       [->H]
   12391              :   H. ...
   12392              : 
   12393              :      *last_new_tail = *first_ptr;
   12394              : 
   12395              :   I. new_node (first_new)       [->F (last_new_tail)]
   12396              : 
   12397              :      *first_ptr = OMP_CLAUSE_CHAIN (last_node)
   12398              : 
   12399              :   #. mapping node               chain
   12400              :   ----------------------------------------------------
   12401              :   A. struct_node                [->B]
   12402              :   B. comp_1                     [->C]
   12403              :   C. comp_2                     [->D (move_after)]
   12404              :   D. map_to_3                   [->E]
   12405              :   E. attach_3                   [->H (first_ptr)]
   12406              :   F. map_to_4                   [->G (continue_at)]
   12407              :   G. attach_4 (last_node)       [->H]
   12408              :   H. ...
   12409              : 
   12410              :   I. new_node (first_new)       [->F  (last_new_tail)]
   12411              : 
   12412              :      OMP_CLAUSE_CHAIN (last_node) = *move_after;
   12413              : 
   12414              :   #. mapping node               chain
   12415              :   ---------------------------------------------------
   12416              :   A. struct_node                [->B]
   12417              :   B. comp_1                     [->C]
   12418              :   C. comp_2                     [->D (move_after)]
   12419              :   D. map_to_3                   [->E]
   12420              :   E. attach_3                   [->H (continue_at)]
   12421              :   F. map_to_4                   [->G]
   12422              :   G. attach_4 (last_node)       [->D]
   12423              :   H. ...
   12424              : 
   12425              :   I. new_node (first_new)       [->F  (last_new_tail)]
   12426              : 
   12427              :      *move_after = first_new;
   12428              : 
   12429              :   #. mapping node               chain
   12430              :   ---------------------------------------------------
   12431              :   A. struct_node                [->B]
   12432              :   B. comp_1                     [->C]
   12433              :   C. comp_2                     [->I (move_after)]
   12434              :   D. map_to_3                   [->E]
   12435              :   E. attach_3                   [->H (continue_at)]
   12436              :   F. map_to_4                   [->G]
   12437              :   G. attach_4 (last_node)       [->D]
   12438              :   H. ...
   12439              :   I. new_node (first_new)       [->F (last_new_tail)]
   12440              : 
   12441              :   or, in order:
   12442              : 
   12443              :   #. mapping node               chain
   12444              :   ---------------------------------------------------
   12445              :   A. struct_node                [->B]
   12446              :   B. comp_1                     [->C]
   12447              :   C. comp_2                     [->I (move_after)]
   12448              :   I. new_node (first_new)       [->F (last_new_tail)]
   12449              :   F. map_to_4                   [->G]
   12450              :   G. attach_4 (last_node)       [->D]
   12451              :   D. map_to_3                   [->E]
   12452              :   E. attach_3                   [->H (continue_at)]
   12453              :   H. ...
   12454              : */
   12455              : 
   12456              : static tree *
   12457           71 : omp_siblist_move_concat_nodes_after (tree first_new, tree *last_new_tail,
   12458              :                                      tree *first_ptr, tree last_node,
   12459              :                                      tree *move_after)
   12460              : {
   12461           71 :   tree *continue_at = NULL;
   12462           71 :   *last_new_tail = *first_ptr;
   12463           71 :   if (first_ptr == move_after)
   12464           12 :     *move_after = first_new;
   12465              :   else
   12466              :     {
   12467           59 :       *first_ptr = OMP_CLAUSE_CHAIN (last_node);
   12468           59 :       continue_at = first_ptr;
   12469           59 :       OMP_CLAUSE_CHAIN (last_node) = *move_after;
   12470           59 :       *move_after = first_new;
   12471              :     }
   12472           71 :   return continue_at;
   12473              : }
   12474              : 
   12475              : static omp_addr_token *
   12476        11572 : omp_first_chained_access_token (vec<omp_addr_token *> &addr_tokens)
   12477              : {
   12478        11572 :   using namespace omp_addr_tokenizer;
   12479        11572 :   int idx = addr_tokens.length () - 1;
   12480        11572 :   gcc_assert (idx >= 0);
   12481        11572 :   if (addr_tokens[idx]->type != ACCESS_METHOD)
   12482              :     return addr_tokens[idx];
   12483        11603 :   while (idx > 0 && addr_tokens[idx - 1]->type == ACCESS_METHOD)
   12484              :     idx--;
   12485        11572 :   return addr_tokens[idx];
   12486              : }
   12487              : 
   12488              : /* Mapping struct members causes an additional set of nodes to be created,
   12489              :    starting with GOMP_MAP_STRUCT followed by a number of mappings equal to the
   12490              :    number of members being mapped, in order of ascending position (address or
   12491              :    bitwise).
   12492              : 
   12493              :    We scan through the list of mapping clauses, calling this function for each
   12494              :    struct member mapping we find, and build up the list of mappings after the
   12495              :    initial GOMP_MAP_STRUCT node.  For pointer members, these will be
   12496              :    newly-created ALLOC nodes.  For non-pointer members, the existing mapping is
   12497              :    moved into place in the sorted list.
   12498              : 
   12499              :      struct {
   12500              :        int *a;
   12501              :        int *b;
   12502              :        int c;
   12503              :        int *d;
   12504              :      };
   12505              : 
   12506              :      #pragma (acc|omp directive) copy(struct.a[0:n], struct.b[0:n], struct.c,
   12507              :                                       struct.d[0:n])
   12508              : 
   12509              :      GOMP_MAP_STRUCT (4)
   12510              :      [GOMP_MAP_FIRSTPRIVATE_REFERENCE -- for refs to structs]
   12511              :      GOMP_MAP_ALLOC  (struct.a)
   12512              :      GOMP_MAP_ALLOC  (struct.b)
   12513              :      GOMP_MAP_TO     (struct.c)
   12514              :      GOMP_MAP_ALLOC  (struct.d)
   12515              :      ...
   12516              : 
   12517              :    In the case where we are mapping references to pointers, or in Fortran if
   12518              :    we are mapping an array with a descriptor, additional nodes may be created
   12519              :    after the struct node list also.
   12520              : 
   12521              :    The return code is either a pointer to the next node to process (if the
   12522              :    list has been rearranged), else NULL to continue with the next node in the
   12523              :    original list.  */
   12524              : 
   12525              : static tree *
   12526         4767 : omp_accumulate_sibling_list (enum omp_region_type region_type,
   12527              :                              enum tree_code code,
   12528              :                              hash_map<tree_operand_hash, tree>
   12529              :                                *&struct_map_to_clause,
   12530              :                              hash_map<tree_operand_hash_no_se,
   12531              :                                       omp_mapping_group *> *group_map,
   12532              :                              tree *grp_start_p, tree grp_end,
   12533              :                              vec<omp_addr_token *> &addr_tokens, tree **inner,
   12534              :                              bool *fragile_p, bool reprocessing_struct,
   12535              :                              tree **added_tail)
   12536              : {
   12537         4767 :   using namespace omp_addr_tokenizer;
   12538         4767 :   poly_offset_int coffset;
   12539         4767 :   poly_int64 cbitpos;
   12540         4767 :   tree ocd = OMP_CLAUSE_DECL (grp_end);
   12541         4767 :   bool openmp = !(region_type & ORT_ACC);
   12542         4767 :   bool target = (region_type & ORT_TARGET) != 0;
   12543         4767 :   tree *continue_at = NULL;
   12544              : 
   12545         5080 :   while (TREE_CODE (ocd) == ARRAY_REF)
   12546          313 :     ocd = TREE_OPERAND (ocd, 0);
   12547              : 
   12548         4767 :   if (*fragile_p)
   12549              :     {
   12550          156 :       omp_mapping_group *to_group
   12551          156 :         = omp_get_nonfirstprivate_group (group_map, ocd, true);
   12552              : 
   12553          156 :       if (to_group)
   12554              :         return NULL;
   12555              :     }
   12556              : 
   12557         4679 :   omp_addr_token *last_token = omp_first_chained_access_token (addr_tokens);
   12558         4679 :   if (last_token->type == ACCESS_METHOD)
   12559              :     {
   12560         4679 :       switch (last_token->u.access_kind)
   12561              :         {
   12562          735 :         case ACCESS_REF:
   12563          735 :         case ACCESS_REF_TO_POINTER:
   12564          735 :         case ACCESS_REF_TO_POINTER_OFFSET:
   12565          735 :         case ACCESS_INDEXED_REF_TO_ARRAY:
   12566              :           /* We may see either a bare reference or a dereferenced
   12567              :              "convert_from_reference"-like one here.  Handle either way.  */
   12568          735 :           if (TREE_CODE (ocd) == INDIRECT_REF)
   12569           64 :             ocd = TREE_OPERAND (ocd, 0);
   12570          735 :           gcc_assert (TREE_CODE (TREE_TYPE (ocd)) == REFERENCE_TYPE);
   12571              :           break;
   12572              : 
   12573              :         default:
   12574              :           ;
   12575              :         }
   12576              :     }
   12577              : 
   12578         4679 :   bool variable_offset;
   12579         9358 :   tree iterators = OMP_CLAUSE_HAS_ITERATORS (grp_end)
   12580         4712 :                      ? OMP_CLAUSE_ITERATORS (grp_end) : NULL_TREE;
   12581         4679 :   tree base
   12582         4679 :     = extract_base_bit_offset (ocd, &cbitpos, &coffset, &variable_offset,
   12583         4679 :                                iterators);
   12584              : 
   12585         4679 :   int base_token;
   12586        23907 :   for (base_token = addr_tokens.length () - 1; base_token >= 0; base_token--)
   12587              :     {
   12588        19228 :       if (addr_tokens[base_token]->type == ARRAY_BASE
   12589        19228 :           || addr_tokens[base_token]->type == STRUCTURE_BASE)
   12590              :         break;
   12591              :     }
   12592              : 
   12593              :   /* The two expressions in the assertion below aren't quite the same: if we
   12594              :      have 'struct_base_decl access_indexed_array' for something like
   12595              :      "myvar[2].x" then base will be "myvar" and addr_tokens[base_token]->expr
   12596              :      will be "myvar[2]" -- the actual base of the structure.
   12597              :      The former interpretation leads to a strange situation where we get
   12598              :        struct(myvar) alloc(myvar[2].ptr1)
   12599              :      That is, the array of structures is kind of treated as one big structure
   12600              :      for the purposes of gathering sibling lists, etc.  */
   12601              :   /* gcc_assert (base == addr_tokens[base_token]->expr);  */
   12602              : 
   12603         4679 :   bool attach_detach = ((OMP_CLAUSE_MAP_KIND (grp_end)
   12604              :                          == GOMP_MAP_ATTACH_DETACH)
   12605         4679 :                         || (OMP_CLAUSE_MAP_KIND (grp_end)
   12606         4679 :                             == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION));
   12607         4679 :   bool has_descriptor = false;
   12608         4679 :   if (OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end)
   12609              :     {
   12610         3139 :       tree grp_mid = OMP_CLAUSE_CHAIN (*grp_start_p);
   12611         3139 :       if (grp_mid && omp_map_clause_descriptor_p (grp_mid))
   12612              :         has_descriptor = true;
   12613              :     }
   12614              : 
   12615         4679 :   if (!struct_map_to_clause || struct_map_to_clause->get (base) == NULL)
   12616              :     {
   12617         3060 :       enum gomp_map_kind str_kind = GOMP_MAP_STRUCT;
   12618              : 
   12619         3060 :       if (struct_map_to_clause == NULL)
   12620         2497 :         struct_map_to_clause = new hash_map<tree_operand_hash, tree>;
   12621              : 
   12622         3060 :       if (variable_offset)
   12623          274 :         str_kind = GOMP_MAP_STRUCT_UNORD;
   12624              : 
   12625         3060 :       tree l = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end), OMP_CLAUSE_MAP);
   12626              : 
   12627         3060 :       OMP_CLAUSE_SET_MAP_KIND (l, str_kind);
   12628         3060 :       OMP_CLAUSE_DECL (l) = unshare_expr (base);
   12629         3060 :       OMP_CLAUSE_SIZE (l) = size_int (1);
   12630              : 
   12631         3060 :       struct_map_to_clause->put (base, l);
   12632              : 
   12633              :       /* On first iterating through the clause list, we insert the struct node
   12634              :          just before the component access node that triggers the initial
   12635              :          omp_accumulate_sibling_list call for a particular sibling list (and
   12636              :          it then forms the first entry in that list).  When reprocessing
   12637              :          struct bases that are themselves component accesses, we insert the
   12638              :          struct node on an off-side list to avoid inserting the new
   12639              :          GOMP_MAP_STRUCT into the middle of the old one.  */
   12640         3060 :       tree *insert_node_pos = reprocessing_struct ? *added_tail : grp_start_p;
   12641              : 
   12642         3060 :       if (has_descriptor)
   12643              :         {
   12644          759 :           tree desc = OMP_CLAUSE_CHAIN (*grp_start_p);
   12645          759 :           if (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
   12646          187 :             OMP_CLAUSE_SET_MAP_KIND (desc, GOMP_MAP_RELEASE);
   12647          759 :           tree sc = *insert_node_pos;
   12648          759 :           OMP_CLAUSE_CHAIN (l) = desc;
   12649          759 :           OMP_CLAUSE_CHAIN (*grp_start_p) = OMP_CLAUSE_CHAIN (desc);
   12650          759 :           OMP_CLAUSE_CHAIN (desc) = sc;
   12651          759 :           *insert_node_pos = l;
   12652              :         }
   12653         2301 :       else if (attach_detach)
   12654              :         {
   12655         1396 :           tree extra_node;
   12656         1396 :           tree alloc_node
   12657         1396 :             = build_omp_struct_comp_nodes (code, *grp_start_p, grp_end,
   12658              :                                            &extra_node);
   12659         1396 :           tree *tail;
   12660         1396 :           OMP_CLAUSE_CHAIN (l) = alloc_node;
   12661              : 
   12662         1396 :           if (extra_node)
   12663              :             {
   12664            0 :               OMP_CLAUSE_CHAIN (extra_node) = *insert_node_pos;
   12665            0 :               OMP_CLAUSE_CHAIN (alloc_node) = extra_node;
   12666            0 :               tail = &OMP_CLAUSE_CHAIN (extra_node);
   12667              :             }
   12668              :           else
   12669              :             {
   12670         1396 :               OMP_CLAUSE_CHAIN (alloc_node) = *insert_node_pos;
   12671         1396 :               tail = &OMP_CLAUSE_CHAIN (alloc_node);
   12672              :             }
   12673              : 
   12674              :           /* For OpenMP semantics, we don't want to implicitly allocate
   12675              :              space for the pointer here for non-compute regions (e.g. "enter
   12676              :              data").  A FRAGILE_P node is only being created so that
   12677              :              omp-low.cc is able to rewrite the struct properly.
   12678              :              For references (to pointers), we want to actually allocate the
   12679              :              space for the reference itself in the sorted list following the
   12680              :              struct node.
   12681              :              For pointers, we want to allocate space if we had an explicit
   12682              :              mapping of the attachment point, but not otherwise.  */
   12683         1396 :           if (*fragile_p
   12684         1396 :               || (openmp
   12685              :                   && !target
   12686              :                   && attach_detach
   12687          234 :                   && TREE_CODE (TREE_TYPE (ocd)) == POINTER_TYPE
   12688           88 :                   && !OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end)))
   12689              :             {
   12690          133 :               if (!lang_GNU_Fortran ())
   12691              :                /* In Fortran, pointers are dereferenced automatically, but may
   12692              :                   be unassociated.  So we still want to allocate space for the
   12693              :                   pointer (as the base for an attach operation that should be
   12694              :                   present in the same directive's clause list also).  */
   12695          103 :                 OMP_CLAUSE_SIZE (alloc_node) = size_zero_node;
   12696          133 :               OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (alloc_node) = 1;
   12697              :             }
   12698              : 
   12699         1396 :           *insert_node_pos = l;
   12700              : 
   12701         1396 :           if (reprocessing_struct)
   12702              :             {
   12703              :               /* When reprocessing a struct node group used as the base of a
   12704              :                  subcomponent access, if we have a reference-to-pointer base,
   12705              :                  we will see:
   12706              :                    struct(**ptr) attach(*ptr)
   12707              :                  whereas for a non-reprocess-struct group, we see, e.g.:
   12708              :                    tofrom(**ptr) attach(*ptr) attach(ptr)
   12709              :                  and we create the "alloc" for the second "attach", i.e.
   12710              :                  for the reference itself.  When reprocessing a struct group we
   12711              :                  thus change the pointer attachment into a reference attachment
   12712              :                  by stripping the indirection.  (The attachment of the
   12713              :                  referenced pointer must happen elsewhere, either on the same
   12714              :                  directive, or otherwise.)  */
   12715          180 :               tree adecl = OMP_CLAUSE_DECL (alloc_node);
   12716              : 
   12717          180 :               if ((TREE_CODE (adecl) == INDIRECT_REF
   12718          148 :                    || (TREE_CODE (adecl) == MEM_REF
   12719            0 :                        && integer_zerop (TREE_OPERAND (adecl, 1))))
   12720           32 :                   && (TREE_CODE (TREE_TYPE (TREE_OPERAND (adecl, 0)))
   12721              :                       == REFERENCE_TYPE)
   12722          212 :                   && (TREE_CODE (TREE_TYPE (TREE_TYPE
   12723              :                         (TREE_OPERAND (adecl, 0)))) == POINTER_TYPE))
   12724           32 :                 OMP_CLAUSE_DECL (alloc_node) = TREE_OPERAND (adecl, 0);
   12725              : 
   12726          180 :               *added_tail = tail;
   12727              :             }
   12728              :         }
   12729              :       else
   12730              :         {
   12731          905 :           gcc_assert (*grp_start_p == grp_end);
   12732          905 :           if (reprocessing_struct)
   12733              :             {
   12734              :               /* If we don't have an attach/detach node, this is a
   12735              :                  "target data" directive or similar, not an offload region.
   12736              :                  Synthesize an "alloc" node using just the initiating
   12737              :                  GOMP_MAP_STRUCT decl.  */
   12738           16 :               gomp_map_kind k = (code == OMP_TARGET_EXIT_DATA
   12739           32 :                                  || code == OACC_EXIT_DATA)
   12740           32 :                                 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
   12741           32 :               tree alloc_node
   12742           32 :                 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
   12743              :                                     OMP_CLAUSE_MAP);
   12744           32 :               OMP_CLAUSE_SET_MAP_KIND (alloc_node, k);
   12745           32 :               OMP_CLAUSE_DECL (alloc_node) = unshare_expr (last_token->expr);
   12746           64 :               OMP_CLAUSE_SIZE (alloc_node)
   12747           32 :                 = TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (alloc_node)));
   12748              : 
   12749           32 :               OMP_CLAUSE_CHAIN (alloc_node) = OMP_CLAUSE_CHAIN (l);
   12750           32 :               OMP_CLAUSE_CHAIN (l) = alloc_node;
   12751           32 :               *insert_node_pos = l;
   12752           32 :               *added_tail = &OMP_CLAUSE_CHAIN (alloc_node);
   12753              :             }
   12754              :           else
   12755          873 :             grp_start_p = omp_siblist_insert_node_after (l, insert_node_pos);
   12756              :         }
   12757              : 
   12758         3060 :       unsigned last_access = base_token + 1;
   12759              : 
   12760         3060 :       while (last_access + 1 < addr_tokens.length ()
   12761         3395 :              && addr_tokens[last_access + 1]->type == ACCESS_METHOD)
   12762              :         last_access++;
   12763              : 
   12764         3060 :       if ((region_type & ORT_TARGET)
   12765         3060 :           && addr_tokens[base_token + 1]->type == ACCESS_METHOD)
   12766              :         {
   12767         1708 :           bool base_ref = false;
   12768         1708 :           access_method_kinds access_kind
   12769         1708 :             = addr_tokens[last_access]->u.access_kind;
   12770              : 
   12771         1708 :           switch (access_kind)
   12772              :             {
   12773              :             case ACCESS_DIRECT:
   12774              :             case ACCESS_INDEXED_ARRAY:
   12775         1060 :               return NULL;
   12776              : 
   12777          403 :             case ACCESS_REF:
   12778          403 :             case ACCESS_REF_TO_POINTER:
   12779          403 :             case ACCESS_REF_TO_POINTER_OFFSET:
   12780          403 :             case ACCESS_INDEXED_REF_TO_ARRAY:
   12781          403 :               base_ref = true;
   12782          403 :               break;
   12783              : 
   12784          866 :             default:
   12785          866 :               ;
   12786              :             }
   12787          866 :           tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
   12788              :                                       OMP_CLAUSE_MAP);
   12789          866 :           enum gomp_map_kind mkind;
   12790          866 :           omp_mapping_group *decl_group;
   12791          866 :           tree use_base;
   12792          866 :           switch (access_kind)
   12793              :             {
   12794          463 :             case ACCESS_POINTER:
   12795          463 :             case ACCESS_POINTER_OFFSET:
   12796          463 :               use_base = addr_tokens[last_access]->expr;
   12797          463 :               break;
   12798          198 :             case ACCESS_REF_TO_POINTER:
   12799          198 :             case ACCESS_REF_TO_POINTER_OFFSET:
   12800          198 :               use_base
   12801          198 :                 = build_fold_indirect_ref (addr_tokens[last_access]->expr);
   12802          198 :               break;
   12803          205 :             default:
   12804          205 :               use_base = addr_tokens[base_token]->expr;
   12805              :             }
   12806          866 :           bool mapped_to_p
   12807          866 :             = omp_directive_maps_explicitly (group_map, use_base, &decl_group,
   12808              :                                              true, false, true);
   12809          866 :           if (addr_tokens[base_token]->type == STRUCTURE_BASE
   12810          866 :               && DECL_P (addr_tokens[last_access]->expr)
   12811         1372 :               && !mapped_to_p)
   12812          444 :             mkind = base_ref ? GOMP_MAP_FIRSTPRIVATE_REFERENCE
   12813              :                              : GOMP_MAP_FIRSTPRIVATE_POINTER;
   12814              :           else
   12815              :             mkind = GOMP_MAP_ATTACH_DETACH;
   12816              : 
   12817          866 :           OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
   12818              :           /* If we have a reference to pointer base, we want to attach the
   12819              :              pointer here, not the reference.  The reference attachment happens
   12820              :              elsewhere.  */
   12821          866 :           bool ref_to_ptr
   12822          866 :             = (access_kind == ACCESS_REF_TO_POINTER
   12823          866 :                || access_kind == ACCESS_REF_TO_POINTER_OFFSET);
   12824          866 :           tree sdecl = addr_tokens[last_access]->expr;
   12825          866 :           tree sdecl_ptr = ref_to_ptr ? build_fold_indirect_ref (sdecl)
   12826              :                                       : sdecl;
   12827              :           /* For the FIRSTPRIVATE_REFERENCE after the struct node, we
   12828              :              want to use the reference itself for the decl, but we
   12829              :              still want to use the pointer to calculate the bias.  */
   12830          866 :           OMP_CLAUSE_DECL (c2) = (mkind == GOMP_MAP_ATTACH_DETACH)
   12831          866 :                                  ? sdecl_ptr : sdecl;
   12832          866 :           sdecl = sdecl_ptr;
   12833          866 :           tree baddr = build_fold_addr_expr (base);
   12834          866 :           baddr = fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end),
   12835              :                                     ptrdiff_type_node, baddr);
   12836          866 :           tree decladdr = fold_convert_loc (OMP_CLAUSE_LOCATION (grp_end),
   12837              :                                             ptrdiff_type_node, sdecl);
   12838          866 :           OMP_CLAUSE_SIZE (c2)
   12839          866 :             = fold_build2_loc (OMP_CLAUSE_LOCATION (grp_end), MINUS_EXPR,
   12840              :                                ptrdiff_type_node, baddr, decladdr);
   12841              :           /* Insert after struct node.  */
   12842          866 :           OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (l);
   12843          866 :           OMP_CLAUSE_CHAIN (l) = c2;
   12844              : 
   12845          866 :           if (addr_tokens[base_token]->type == STRUCTURE_BASE
   12846          866 :               && (addr_tokens[base_token]->u.structure_base_kind
   12847              :                   == BASE_COMPONENT_EXPR)
   12848          286 :               && mkind == GOMP_MAP_ATTACH_DETACH
   12849         1152 :               && addr_tokens[last_access]->u.access_kind != ACCESS_REF)
   12850              :             {
   12851          218 :               *inner = insert_node_pos;
   12852          218 :               if (openmp)
   12853          166 :                 *fragile_p = true;
   12854              :               return NULL;
   12855              :             }
   12856              :         }
   12857              : 
   12858         2000 :       if (addr_tokens[base_token]->type == STRUCTURE_BASE
   12859         2000 :           && (addr_tokens[base_token]->u.structure_base_kind
   12860              :               == BASE_COMPONENT_EXPR)
   12861         2467 :           && addr_tokens[last_access]->u.access_kind == ACCESS_REF)
   12862          100 :         *inner = insert_node_pos;
   12863              : 
   12864              :       return NULL;
   12865              :     }
   12866         1619 :   else if (struct_map_to_clause)
   12867              :     {
   12868         1619 :       tree *osc = struct_map_to_clause->get (base);
   12869         1619 :       tree *sc = NULL, *scp = NULL;
   12870              : 
   12871         1619 :       unsigned HOST_WIDE_INT i, elems = tree_to_uhwi (OMP_CLAUSE_SIZE (*osc));
   12872         1619 :       sc = &OMP_CLAUSE_CHAIN (*osc);
   12873              :       /* The struct mapping might be immediately followed by a
   12874              :          FIRSTPRIVATE_POINTER,  FIRSTPRIVATE_REFERENCE or an ATTACH_DETACH --
   12875              :          if it's an indirect access or a reference, or if the structure base
   12876              :          is not a decl.  The FIRSTPRIVATE_* nodes are removed in omp-low.cc
   12877              :          after they have been processed there, and ATTACH_DETACH nodes are
   12878              :          recomputed and moved out of the GOMP_MAP_STRUCT construct once
   12879              :          sibling list building is complete.  */
   12880         1619 :       if (OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_FIRSTPRIVATE_POINTER
   12881         1574 :           || OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_FIRSTPRIVATE_REFERENCE
   12882         3148 :           || OMP_CLAUSE_MAP_KIND (*sc) == GOMP_MAP_ATTACH_DETACH)
   12883          201 :         sc = &OMP_CLAUSE_CHAIN (*sc);
   12884         4108 :       for (i = 0; i < elems; i++, sc = &OMP_CLAUSE_CHAIN (*sc))
   12885         3062 :         if (attach_detach && sc == grp_start_p)
   12886              :           break;
   12887         3062 :         else if (TREE_CODE (OMP_CLAUSE_DECL (*sc)) != COMPONENT_REF
   12888          182 :                  && TREE_CODE (OMP_CLAUSE_DECL (*sc)) != INDIRECT_REF
   12889         3244 :                  && TREE_CODE (OMP_CLAUSE_DECL (*sc)) != ARRAY_REF)
   12890              :           break;
   12891              :         else
   12892              :           {
   12893         3062 :             tree sc_decl = OMP_CLAUSE_DECL (*sc);
   12894         3062 :             poly_offset_int offset;
   12895         3062 :             poly_int64 bitpos;
   12896              : 
   12897         3062 :             if (TREE_CODE (sc_decl) == ARRAY_REF)
   12898              :               {
   12899          366 :                 while (TREE_CODE (sc_decl) == ARRAY_REF)
   12900          184 :                   sc_decl = TREE_OPERAND (sc_decl, 0);
   12901          182 :                 if (TREE_CODE (sc_decl) != COMPONENT_REF
   12902          182 :                     || TREE_CODE (TREE_TYPE (sc_decl)) != ARRAY_TYPE)
   12903              :                   break;
   12904              :               }
   12905         2880 :             else if (INDIRECT_REF_P (sc_decl)
   12906            0 :                      && TREE_CODE (TREE_OPERAND (sc_decl, 0)) == COMPONENT_REF
   12907         2880 :                      && (TREE_CODE (TREE_TYPE (TREE_OPERAND (sc_decl, 0)))
   12908              :                          == REFERENCE_TYPE))
   12909            0 :               sc_decl = TREE_OPERAND (sc_decl, 0);
   12910              : 
   12911         3062 :             bool variable_offset2;
   12912         3062 :             tree iterators2 = OMP_CLAUSE_HAS_ITERATORS (*sc)
   12913         3062 :                                 ? OMP_CLAUSE_ITERATORS (*sc) : NULL_TREE;
   12914              : 
   12915         3062 :             tree base2 = extract_base_bit_offset (sc_decl, &bitpos, &offset,
   12916              :                                                   &variable_offset2,
   12917              :                                                   iterators2);
   12918         3062 :             if (!base2 || !operand_equal_p (base2, base, 0))
   12919              :               break;
   12920         3062 :             if (scp)
   12921          469 :               continue;
   12922         2842 :             if (variable_offset2)
   12923              :               {
   12924          341 :                 OMP_CLAUSE_SET_MAP_KIND (*osc, GOMP_MAP_STRUCT_UNORD);
   12925              : 
   12926          341 :                 if (has_descriptor)
   12927              :                   {
   12928              :                     /* Sort mapped components by offset. This is needed for
   12929              :                        libgomp to handle Fortran derived-type allocatable
   12930              :                        components transparently.  */
   12931              : 
   12932          323 :                     poly_int64 bitsize;
   12933          323 :                     tree offset, coffset;
   12934          323 :                     machine_mode mode;
   12935          323 :                     int unsignedp, reversep, volatilep;
   12936          323 :                     tree inner_ref1
   12937          323 :                       = get_inner_reference (sc_decl, &bitsize, &bitpos,
   12938              :                                              &offset, &mode, &unsignedp,
   12939              :                                              &reversep, &volatilep);
   12940          323 :                     tree osc_decl = ocd;
   12941          323 :                     STRIP_NOPS (osc_decl);
   12942          323 :                     tree inner_ref2
   12943          323 :                       = get_inner_reference (osc_decl, &bitsize, &bitpos,
   12944              :                                              &coffset, &mode, &unsignedp,
   12945              :                                              &reversep, &volatilep);
   12946          323 :                     gcc_assert (operand_equal_p (inner_ref1, inner_ref2, 0));
   12947          323 :                     tree offset_diff
   12948          323 :                       = fold_binary_to_constant (MINUS_EXPR, size_type_node,
   12949              :                                                  coffset, offset);
   12950          572 :                     if (offset_diff == NULL_TREE
   12951          323 :                         || TREE_INT_CST_ELT (offset_diff, 0) > 0)
   12952          249 :                       continue;
   12953              :                     else
   12954              :                       break;
   12955              :                   }
   12956              :               }
   12957         2501 :             else if ((region_type & ORT_ACC) != 0)
   12958              :               {
   12959              :                 /* For OpenACC, allow (ignore) duplicate struct accesses in
   12960              :                    the middle of a mapping clause, e.g. "mystruct->foo" in:
   12961              :                    copy(mystruct->foo->bar) copy(mystruct->foo->qux).  */
   12962          223 :                 if (reprocessing_struct
   12963            8 :                     && known_eq (coffset, offset)
   12964          223 :                     && known_eq (cbitpos, bitpos))
   12965           16 :                   return NULL;
   12966              :               }
   12967         2278 :             else if (known_eq (coffset, offset)
   12968         2278 :                      && known_eq (cbitpos, bitpos))
   12969              :               {
   12970              :                 /* Having two struct members at the same offset doesn't work,
   12971              :                    so make sure we don't.  (We're allowed to ignore this.
   12972              :                    Should we report the error?)  */
   12973              :                 /*error_at (OMP_CLAUSE_LOCATION (grp_end),
   12974              :                           "duplicate struct member %qE in map clauses",
   12975              :                           OMP_CLAUSE_DECL (grp_end));*/
   12976              :                 return NULL;
   12977              :               }
   12978         2503 :             if (maybe_lt (coffset, offset)
   12979         4231 :                 || (known_eq (coffset, offset)
   12980           20 :                     && maybe_lt (cbitpos, bitpos)))
   12981              :               {
   12982          775 :                 if (attach_detach)
   12983              :                   scp = sc;
   12984              :                 else
   12985              :                   break;
   12986              :               }
   12987              :           }
   12988              : 
   12989         1603 :       OMP_CLAUSE_SIZE (*osc)
   12990         1603 :         = size_binop (PLUS_EXPR, OMP_CLAUSE_SIZE (*osc), size_one_node);
   12991              : 
   12992         1603 :       if (reprocessing_struct)
   12993              :         {
   12994              :           /* If we're reprocessing a struct node, we don't want to do most of
   12995              :              the list manipulation below.  We only need to handle the (pointer
   12996              :              or reference) attach/detach case.  */
   12997            8 :           tree extra_node, alloc_node;
   12998            8 :           if (has_descriptor)
   12999            0 :             gcc_unreachable ();
   13000            8 :           else if (attach_detach)
   13001            8 :             alloc_node = build_omp_struct_comp_nodes (code, *grp_start_p,
   13002              :                                                       grp_end, &extra_node);
   13003              :           else
   13004              :             {
   13005              :               /* If we don't have an attach/detach node, this is a
   13006              :                  "target data" directive or similar, not an offload region.
   13007              :                  Synthesize an "alloc" node using just the initiating
   13008              :                  GOMP_MAP_STRUCT decl.  */
   13009            0 :               gomp_map_kind k = (code == OMP_TARGET_EXIT_DATA
   13010            0 :                                  || code == OACC_EXIT_DATA)
   13011            0 :                                 ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
   13012            0 :               alloc_node
   13013            0 :                 = build_omp_clause (OMP_CLAUSE_LOCATION (grp_end),
   13014              :                                     OMP_CLAUSE_MAP);
   13015            0 :               OMP_CLAUSE_SET_MAP_KIND (alloc_node, k);
   13016            0 :               OMP_CLAUSE_DECL (alloc_node) = unshare_expr (last_token->expr);
   13017            0 :               OMP_CLAUSE_SIZE (alloc_node)
   13018            0 :                 = TYPE_SIZE_UNIT (TREE_TYPE (OMP_CLAUSE_DECL (alloc_node)));
   13019              :             }
   13020              : 
   13021            8 :           if (scp)
   13022            0 :             omp_siblist_insert_node_after (alloc_node, scp);
   13023              :           else
   13024              :             {
   13025            8 :               tree *new_end = omp_siblist_insert_node_after (alloc_node, sc);
   13026            8 :               if (sc == *added_tail)
   13027            8 :                 *added_tail = new_end;
   13028              :             }
   13029              : 
   13030            8 :           return NULL;
   13031              :         }
   13032              : 
   13033         1595 :       if (has_descriptor)
   13034              :         {
   13035          538 :           tree desc = OMP_CLAUSE_CHAIN (*grp_start_p);
   13036          538 :           if (code == OMP_TARGET_EXIT_DATA
   13037          538 :               || code == OACC_EXIT_DATA)
   13038          105 :             OMP_CLAUSE_SET_MAP_KIND (desc, GOMP_MAP_RELEASE);
   13039         1076 :           omp_siblist_move_node_after (desc,
   13040          538 :                                        &OMP_CLAUSE_CHAIN (*grp_start_p),
   13041              :                                        scp ? scp : sc);
   13042              :         }
   13043         1057 :       else if (attach_detach)
   13044              :         {
   13045          325 :           tree cl = NULL_TREE, extra_node;
   13046          325 :           tree alloc_node = build_omp_struct_comp_nodes (code, *grp_start_p,
   13047              :                                                          grp_end, &extra_node);
   13048          325 :           tree *tail_chain = NULL;
   13049              : 
   13050          325 :           if (*fragile_p
   13051          325 :               || (openmp
   13052              :                   && !target
   13053              :                   && attach_detach
   13054           62 :                   && TREE_CODE (TREE_TYPE (ocd)) == POINTER_TYPE
   13055           23 :                   && !OMP_CLAUSE_ATTACHMENT_MAPPING_ERASED (grp_end)))
   13056              :             {
   13057            6 :               if (!lang_GNU_Fortran ())
   13058            6 :                 OMP_CLAUSE_SIZE (alloc_node) = size_zero_node;
   13059            6 :               OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (alloc_node) = 1;
   13060              :             }
   13061              : 
   13062              :           /* Here, we have:
   13063              : 
   13064              :              grp_end : the last (or only) node in this group.
   13065              :              grp_start_p : pointer to the first node in a pointer mapping group
   13066              :                            up to and including GRP_END.
   13067              :              sc : pointer to the chain for the end of the struct component
   13068              :                   list.
   13069              :              scp : pointer to the chain for the sorted position at which we
   13070              :                    should insert in the middle of the struct component list
   13071              :                    (else NULL to insert at end).
   13072              :              alloc_node : the "alloc" node for the structure (pointer-type)
   13073              :                           component. We insert at SCP (if present), else SC
   13074              :                           (the end of the struct component list).
   13075              :              extra_node : a newly-synthesized node for an additional indirect
   13076              :                           pointer mapping or a Fortran pointer set, if needed.
   13077              :              cl : first node to prepend before grp_start_p.
   13078              :              tail_chain : pointer to chain of last prepended node.
   13079              : 
   13080              :              The general idea is we move the nodes for this struct mapping
   13081              :              together: the alloc node goes into the sorted list directly after
   13082              :              the struct mapping, and any extra nodes (together with the nodes
   13083              :              mapping arrays pointed to by struct components) get moved after
   13084              :              that list.  When SCP is NULL, we insert the nodes at SC, i.e. at
   13085              :              the end of the struct component mapping list.  It's important that
   13086              :              the alloc_node comes first in that case because it's part of the
   13087              :              sorted component mapping list (but subsequent nodes are not!).  */
   13088              : 
   13089          325 :           if (scp)
   13090          254 :             omp_siblist_insert_node_after (alloc_node, scp);
   13091              : 
   13092              :           /* Make [cl,tail_chain] a list of the alloc node (if we haven't
   13093              :              already inserted it) and the extra_node (if it is present).  The
   13094              :              list can be empty if we added alloc_node above and there is no
   13095              :              extra node.  */
   13096          254 :           if (scp && extra_node)
   13097              :             {
   13098            0 :               cl = extra_node;
   13099            0 :               tail_chain = &OMP_CLAUSE_CHAIN (extra_node);
   13100              :             }
   13101          325 :           else if (extra_node)
   13102              :             {
   13103            0 :               OMP_CLAUSE_CHAIN (alloc_node) = extra_node;
   13104            0 :               cl = alloc_node;
   13105            0 :               tail_chain = &OMP_CLAUSE_CHAIN (extra_node);
   13106              :             }
   13107          325 :           else if (!scp)
   13108              :             {
   13109           71 :               cl = alloc_node;
   13110           71 :               tail_chain = &OMP_CLAUSE_CHAIN (alloc_node);
   13111              :             }
   13112              : 
   13113           71 :           continue_at
   13114           71 :             = cl ? omp_siblist_move_concat_nodes_after (cl, tail_chain,
   13115              :                                                         grp_start_p, grp_end,
   13116              :                                                         sc)
   13117          254 :                  : omp_siblist_move_nodes_after (grp_start_p, grp_end, sc);
   13118              :         }
   13119          732 :       else if (*sc != grp_end)
   13120              :         {
   13121          692 :           gcc_assert (*grp_start_p == grp_end);
   13122              : 
   13123              :           /* We are moving the current node back to a previous struct node:
   13124              :              the node that used to point to the current node will now point to
   13125              :              the next node.  */
   13126          692 :           continue_at = grp_start_p;
   13127              :           /* In the non-pointer case, the mapping clause itself is moved into
   13128              :              the correct position in the struct component list, which in this
   13129              :              case is just SC.  */
   13130          692 :           omp_siblist_move_node_after (*grp_start_p, grp_start_p, sc);
   13131              :         }
   13132              :     }
   13133              :   return continue_at;
   13134              : }
   13135              : 
   13136              : /* Scan through GROUPS, and create sorted structure sibling lists without
   13137              :    gimplifying.  */
   13138              : 
   13139              : static bool
   13140        18102 : omp_build_struct_sibling_lists (enum tree_code code,
   13141              :                                 enum omp_region_type region_type,
   13142              :                                 vec<omp_mapping_group> *groups,
   13143              :                                 hash_map<tree_operand_hash_no_se,
   13144              :                                          omp_mapping_group *> **grpmap,
   13145              :                                 tree *list_p)
   13146              : {
   13147        18102 :   using namespace omp_addr_tokenizer;
   13148        18102 :   unsigned i;
   13149        18102 :   omp_mapping_group *grp;
   13150        18102 :   hash_map<tree_operand_hash, tree> *struct_map_to_clause = NULL;
   13151        18102 :   bool success = true;
   13152        18102 :   tree *new_next = NULL;
   13153        36204 :   tree *tail = &OMP_CLAUSE_CHAIN ((*groups)[groups->length () - 1].grp_end);
   13154        18102 :   tree added_nodes = NULL_TREE;
   13155        18102 :   tree *added_tail = &added_nodes;
   13156        18102 :   auto_vec<omp_mapping_group> pre_hwm_groups;
   13157              : 
   13158        67637 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   13159              :     {
   13160        31433 :       tree c = grp->grp_end;
   13161        31433 :       tree decl = OMP_CLAUSE_DECL (c);
   13162        31433 :       tree grp_end = grp->grp_end;
   13163        31433 :       auto_vec<omp_addr_token *> addr_tokens;
   13164        31433 :       tree sentinel = OMP_CLAUSE_CHAIN (grp_end);
   13165              : 
   13166        31433 :       if (new_next && !grp->reprocess_struct)
   13167          622 :         grp->grp_start = new_next;
   13168              : 
   13169        31433 :       new_next = NULL;
   13170              : 
   13171        31433 :       tree *grp_start_p = grp->grp_start;
   13172              : 
   13173        31433 :       if (DECL_P (decl))
   13174        21271 :         continue;
   13175              : 
   13176              :       /* Skip groups we marked for deletion in
   13177              :          {omp,oacc}_resolve_clause_dependencies.  */
   13178        10162 :       if (grp->deleted)
   13179          462 :         continue;
   13180              : 
   13181         9700 :       if (OMP_CLAUSE_CHAIN (*grp_start_p)
   13182         9700 :           && OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end)
   13183              :         {
   13184              :           /* Don't process an array descriptor that isn't inside a derived type
   13185              :              as a struct (the GOMP_MAP_POINTER following will have the form
   13186              :              "var.data", but such mappings are handled specially).  */
   13187         6126 :           tree grpmid = OMP_CLAUSE_CHAIN (*grp_start_p);
   13188         6126 :           if (omp_map_clause_descriptor_p (grpmid)
   13189        10277 :               && DECL_P (OMP_CLAUSE_DECL (grpmid)))
   13190         2807 :             continue;
   13191              :         }
   13192              : 
   13193         7937 :       tree expr = decl;
   13194              : 
   13195         7937 :       while (TREE_CODE (expr) == ARRAY_REF)
   13196         1044 :         expr = TREE_OPERAND (expr, 0);
   13197              : 
   13198         6893 :       if (!omp_parse_expr (addr_tokens, expr))
   13199            0 :         continue;
   13200              : 
   13201         6893 :       omp_addr_token *last_token
   13202         6893 :         = omp_first_chained_access_token (addr_tokens);
   13203              : 
   13204              :       /* A mapping of a reference to a pointer member that doesn't specify an
   13205              :          array section, etc., like this:
   13206              :            *mystruct.ref_to_ptr
   13207              :          should not be processed by the struct sibling-list handling code --
   13208              :          it just transfers the referenced pointer.
   13209              : 
   13210              :          In contrast, the quite similar-looking construct:
   13211              :            *mystruct.ptr
   13212              :          which is equivalent to e.g.
   13213              :            mystruct.ptr[0]
   13214              :          *does* trigger sibling-list processing.
   13215              : 
   13216              :          An exception for the former case is for "fragile" groups where the
   13217              :          reference itself is not handled otherwise; this is subject to special
   13218              :          handling in omp_accumulate_sibling_list also.  */
   13219              : 
   13220         6893 :       if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
   13221         3402 :           && last_token->type == ACCESS_METHOD
   13222         3402 :           && last_token->u.access_kind == ACCESS_REF
   13223         7175 :           && !grp->fragile)
   13224          217 :         continue;
   13225              : 
   13226         6676 :       tree d = decl;
   13227         6676 :       if (TREE_CODE (d) == ARRAY_REF)
   13228              :         {
   13229         2036 :           while (TREE_CODE (d) == ARRAY_REF)
   13230         1029 :             d = TREE_OPERAND (d, 0);
   13231         1007 :           if (TREE_CODE (d) == COMPONENT_REF
   13232         1007 :               && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
   13233              :             decl = d;
   13234              :         }
   13235         6676 :       if (d == decl
   13236         5982 :           && INDIRECT_REF_P (decl)
   13237          738 :           && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
   13238          105 :           && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
   13239              :               == REFERENCE_TYPE)
   13240         6773 :           && (OMP_CLAUSE_MAP_KIND (c)
   13241              :               != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
   13242           97 :         decl = TREE_OPERAND (decl, 0);
   13243              : 
   13244         6676 :       STRIP_NOPS (decl);
   13245              : 
   13246         6676 :       if (TREE_CODE (decl) != COMPONENT_REF)
   13247         1368 :         continue;
   13248              : 
   13249              :       /* If we're mapping the whole struct in another node, skip adding this
   13250              :          node to a sibling list.  */
   13251         5308 :       omp_mapping_group *wholestruct;
   13252         5308 :       if (omp_mapped_by_containing_struct (*grpmap, OMP_CLAUSE_DECL (c),
   13253              :                                            &wholestruct))
   13254              :         {
   13255          178 :           if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   13256          161 :             OMP_CLAUSE_MAP_SIZE_NEEDS_ADJUSTMENT (c) = 0;
   13257          178 :           continue;
   13258              :         }
   13259              : 
   13260         5130 :       if (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_TO_PSET
   13261         5130 :           && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
   13262         5025 :           && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
   13263              :           && code != OACC_UPDATE
   13264        10088 :           && code != OMP_TARGET_UPDATE)
   13265              :         {
   13266         4767 :           if (error_operand_p (decl))
   13267              :             {
   13268            0 :               success = false;
   13269            0 :               goto error_out;
   13270              :             }
   13271              : 
   13272         4767 :           tree stype = TREE_TYPE (decl);
   13273         4767 :           if (TREE_CODE (stype) == REFERENCE_TYPE)
   13274          768 :             stype = TREE_TYPE (stype);
   13275         4767 :           if (TYPE_SIZE_UNIT (stype) == NULL
   13276         4767 :               || TREE_CODE (TYPE_SIZE_UNIT (stype)) != INTEGER_CST)
   13277              :             {
   13278            0 :               error_at (OMP_CLAUSE_LOCATION (c),
   13279              :                         "mapping field %qE of variable length "
   13280            0 :                         "structure", OMP_CLAUSE_DECL (c));
   13281            0 :               success = false;
   13282            0 :               goto error_out;
   13283              :             }
   13284              : 
   13285         4767 :           tree *inner = NULL;
   13286         4767 :           bool fragile_p = grp->fragile;
   13287              : 
   13288         4767 :           new_next
   13289         4767 :             = omp_accumulate_sibling_list (region_type, code,
   13290              :                                            struct_map_to_clause, *grpmap,
   13291              :                                            grp_start_p, grp_end, addr_tokens,
   13292              :                                            &inner, &fragile_p,
   13293              :                                            grp->reprocess_struct, &added_tail);
   13294              : 
   13295         4767 :           if (inner)
   13296              :             {
   13297          318 :               omp_mapping_group newgrp;
   13298          318 :               newgrp.grp_start = inner;
   13299          318 :               if (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (*inner))
   13300              :                   == GOMP_MAP_ATTACH_DETACH)
   13301          286 :                 newgrp.grp_end = OMP_CLAUSE_CHAIN (*inner);
   13302              :               else
   13303              :                 newgrp.grp_end = *inner;
   13304          318 :               newgrp.mark = UNVISITED;
   13305          318 :               newgrp.sibling = NULL;
   13306          318 :               newgrp.deleted = false;
   13307          318 :               newgrp.reprocess_struct = true;
   13308          318 :               newgrp.fragile = fragile_p;
   13309          318 :               newgrp.next = NULL;
   13310          318 :               groups->safe_push (newgrp);
   13311              : 
   13312              :               /* !!! Growing GROUPS might invalidate the pointers in the group
   13313              :                  map.  Rebuild it here.  This is a bit inefficient, but
   13314              :                  shouldn't happen very often.  */
   13315          636 :               delete (*grpmap);
   13316          318 :               *grpmap
   13317          318 :                 = omp_reindex_mapping_groups (list_p, groups, &pre_hwm_groups,
   13318              :                                               sentinel);
   13319              :             }
   13320              :         }
   13321        31433 :     }
   13322              : 
   13323              :   /* Delete groups marked for deletion above.  At this point the order of the
   13324              :      groups may no longer correspond to the order of the underlying list,
   13325              :      which complicates this a little.  First clear out OMP_CLAUSE_DECL for
   13326              :      deleted nodes...  */
   13327              : 
   13328        49535 :   FOR_EACH_VEC_ELT (*groups, i, grp)
   13329        31433 :     if (grp->deleted)
   13330          462 :       for (tree d = *grp->grp_start;
   13331          924 :            d != OMP_CLAUSE_CHAIN (grp->grp_end);
   13332          462 :            d = OMP_CLAUSE_CHAIN (d))
   13333          462 :         OMP_CLAUSE_DECL (d) = NULL_TREE;
   13334              : 
   13335              :   /* ...then sweep through the list removing the now-empty nodes.  */
   13336              : 
   13337              :   tail = list_p;
   13338        96393 :   while (*tail)
   13339              :     {
   13340        78291 :       if (OMP_CLAUSE_CODE (*tail) == OMP_CLAUSE_MAP
   13341        78291 :           && OMP_CLAUSE_DECL (*tail) == NULL_TREE)
   13342          462 :         *tail = OMP_CLAUSE_CHAIN (*tail);
   13343              :       else
   13344        77829 :         tail = &OMP_CLAUSE_CHAIN (*tail);
   13345              :     }
   13346              : 
   13347              :   /* Tack on the struct nodes added during nested struct reprocessing.  */
   13348        18102 :   if (added_nodes)
   13349              :     {
   13350          192 :       *tail = added_nodes;
   13351          192 :       tail = added_tail;
   13352              :     }
   13353              : 
   13354              :   /* Find each attach node whose bias needs to be adjusted and move it to the
   13355              :      group containing its pointee, right after the struct node, so that it can
   13356              :      be picked up by the adjustment code further down in this function.  */
   13357        18102 :   bool attach_bias_needs_adjustment;
   13358        18102 :   attach_bias_needs_adjustment = false;
   13359        67637 :   FOR_EACH_VEC_ELT_REVERSE (*groups, i, grp)
   13360              :     {
   13361        31433 :       tree c = *grp->grp_start;
   13362        30494 :       if (c != NULL && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   13363        30479 :           && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
   13364        27406 :               || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT_UNORD)
   13365         3353 :           && OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (c)) == GOMP_MAP_TO_PSET
   13366          560 :           && OMP_CLAUSE_MAP_KIND (grp->grp_end) == GOMP_MAP_ATTACH_DETACH
   13367        31993 :           && OMP_CLAUSE_MAP_SIZE_NEEDS_ADJUSTMENT (grp->grp_end))
   13368              :         {
   13369           90 :           OMP_CLAUSE_MAP_SIZE_NEEDS_ADJUSTMENT (grp->grp_end) = 0;
   13370           90 :           attach_bias_needs_adjustment = true;
   13371           90 :           tree *cp;
   13372           90 :           for (cp = &OMP_CLAUSE_CHAIN (c); cp != NULL;
   13373          206 :                cp = &OMP_CLAUSE_CHAIN (*cp))
   13374          296 :             if (*cp == grp->grp_end)
   13375              :               {
   13376              :                 c = *cp;
   13377              :                 break;
   13378              :               }
   13379              : 
   13380           90 :           tree base = OMP_CLAUSE_DECL (c);
   13381           90 :           gcc_assert (TREE_CODE (base) == NOP_EXPR);
   13382           90 :           base = build_fold_indirect_ref (base);
   13383           90 :           tree *struct_node = struct_map_to_clause->get (base);
   13384           90 :           omp_siblist_move_node_after (c, cp, &OMP_CLAUSE_CHAIN (*struct_node));
   13385              :         }
   13386              :     }
   13387              : 
   13388              :   /* Now we have finished building the struct sibling lists, reprocess
   13389              :      newly-added "attach" nodes: we need the address of the first
   13390              :      mapped element of each struct sibling list for the bias of the attach
   13391              :      operation -- not necessarily the base address of the whole struct.  */
   13392        18102 :   if (struct_map_to_clause)
   13393         3060 :     for (hash_map<tree_operand_hash, tree>::iterator iter
   13394         2497 :            = struct_map_to_clause->begin ();
   13395         8054 :          iter != struct_map_to_clause->end ();
   13396         3060 :          ++iter)
   13397              :       {
   13398         3060 :         tree struct_node = (*iter).second;
   13399         3060 :         gcc_assert (OMP_CLAUSE_CODE (struct_node) == OMP_CLAUSE_MAP);
   13400         3060 :         tree attach = OMP_CLAUSE_CHAIN (struct_node);
   13401              : 
   13402         3060 :         if (OMP_CLAUSE_CODE (attach) != OMP_CLAUSE_MAP
   13403         3060 :             || OMP_CLAUSE_MAP_KIND (attach) != GOMP_MAP_ATTACH_DETACH)
   13404         2548 :           continue;
   13405              : 
   13406          512 :         OMP_CLAUSE_SET_MAP_KIND (attach, GOMP_MAP_ATTACH);
   13407              : 
   13408              :         /* Sanity check: the standalone attach node will not work if we have
   13409              :            an "enter data" operation (because for those, variables need to be
   13410              :            mapped separately and attach nodes must be grouped together with the
   13411              :            base they attach to).  We should only have created the
   13412              :            ATTACH_DETACH node either after GOMP_MAP_STRUCT for a target region
   13413              :            or for an intermediate descriptor that needs adjustment -- so this
   13414              :            should never be true.  */
   13415          512 :         gcc_assert ((region_type & ORT_TARGET) != 0
   13416              :                     || attach_bias_needs_adjustment);
   13417              : 
   13418              :         /* This is the first sorted node in the struct sibling list.  Use it
   13419              :            to recalculate the correct bias to use.
   13420              :            (&first_node - attach_decl).
   13421              :            For GOMP_MAP_STRUCT_UNORD, we need e.g. the
   13422              :            min(min(min(first,second),third),fourth) element, because the
   13423              :            elements aren't in any particular order.  */
   13424          512 :         tree lowest_addr;
   13425          512 :         if (OMP_CLAUSE_MAP_KIND (struct_node) == GOMP_MAP_STRUCT_UNORD)
   13426              :           {
   13427           94 :             tree first_node = OMP_CLAUSE_CHAIN (attach);
   13428           94 :             unsigned HOST_WIDE_INT num_mappings
   13429           94 :               = tree_to_uhwi (OMP_CLAUSE_SIZE (struct_node));
   13430           94 :             lowest_addr = OMP_CLAUSE_DECL (first_node);
   13431           94 :             lowest_addr = build_fold_addr_expr (lowest_addr);
   13432           94 :             lowest_addr = fold_convert (pointer_sized_int_node, lowest_addr);
   13433           94 :             tree next_node = OMP_CLAUSE_CHAIN (first_node);
   13434          185 :             while (num_mappings > 1)
   13435              :               {
   13436           91 :                 tree tmp = OMP_CLAUSE_DECL (next_node);
   13437           91 :                 tmp = build_fold_addr_expr (tmp);
   13438           91 :                 tmp = fold_convert (pointer_sized_int_node, tmp);
   13439           91 :                 lowest_addr = fold_build2 (MIN_EXPR, pointer_sized_int_node,
   13440              :                                            lowest_addr, tmp);
   13441           91 :                 next_node = OMP_CLAUSE_CHAIN (next_node);
   13442           91 :                 num_mappings--;
   13443              :               }
   13444           94 :             lowest_addr = fold_convert (ptrdiff_type_node, lowest_addr);
   13445              :           }
   13446              :         else
   13447              :           {
   13448          418 :             tree first_node = OMP_CLAUSE_DECL (OMP_CLAUSE_CHAIN (attach));
   13449          418 :             first_node = build_fold_addr_expr (first_node);
   13450          418 :             lowest_addr = fold_convert (ptrdiff_type_node, first_node);
   13451              :           }
   13452          512 :         tree attach_decl = OMP_CLAUSE_DECL (attach);
   13453          512 :         attach_decl = fold_convert (ptrdiff_type_node, attach_decl);
   13454          512 :         OMP_CLAUSE_SIZE (attach)
   13455          512 :           = fold_build2 (MINUS_EXPR, ptrdiff_type_node, lowest_addr,
   13456              :                          attach_decl);
   13457              : 
   13458              :         /* Remove GOMP_MAP_ATTACH node from after struct node.  */
   13459          512 :         OMP_CLAUSE_CHAIN (struct_node) = OMP_CLAUSE_CHAIN (attach);
   13460              :         /* ...and re-insert it at the end of our clause list.  */
   13461          512 :         *tail = attach;
   13462          512 :         OMP_CLAUSE_CHAIN (attach) = NULL_TREE;
   13463          512 :         tail = &OMP_CLAUSE_CHAIN (attach);
   13464              :       }
   13465              : 
   13466        15605 : error_out:
   13467        18102 :   if (struct_map_to_clause)
   13468         2497 :     delete struct_map_to_clause;
   13469              : 
   13470        18102 :   return success;
   13471        18102 : }
   13472              : 
   13473              : struct instantiate_mapper_info
   13474              : {
   13475              :   tree *mapper_clauses_p;
   13476              :   struct gimplify_omp_ctx *omp_ctx;
   13477              :   gimple_seq *pre_p;
   13478              : };
   13479              : 
   13480              : /* Helper function for omp_instantiate_mapper.  */
   13481              : 
   13482              : static tree
   13483         1592 : remap_mapper_decl_1 (tree *tp, int *walk_subtrees, void *data)
   13484              : {
   13485         1592 :   copy_body_data *id = (copy_body_data *) data;
   13486              : 
   13487         1592 :   if (DECL_P (*tp))
   13488              :     {
   13489          724 :       tree replacement = remap_decl (*tp, id);
   13490          724 :       if (*tp != replacement)
   13491              :         {
   13492          369 :           *tp = unshare_expr (replacement);
   13493          369 :           *walk_subtrees = 0;
   13494              :         }
   13495              :     }
   13496              : 
   13497         1592 :   return NULL_TREE;
   13498              : }
   13499              : 
   13500              : /* A copy_decl implementation (for use with tree-inline.cc functions) that
   13501              :    only transform decls or SSA names that are part of a map we already
   13502              :    prepared.  */
   13503              : 
   13504              : static tree
   13505          126 : omp_mapper_copy_decl (tree var, copy_body_data *cb)
   13506              : {
   13507          126 :   tree *repl = cb->decl_map->get (var);
   13508              : 
   13509          126 :   if (repl)
   13510            0 :     return *repl;
   13511              : 
   13512          126 :   return var;
   13513              : }
   13514              : 
   13515              : static tree *
   13516           90 : omp_instantiate_mapper (gimple_seq *pre_p,
   13517              :                         hash_map<omp_name_type<tree>, tree> *implicit_mappers,
   13518              :                         tree mapperfn, tree expr, enum gomp_map_kind outer_kind,
   13519              :                         tree *mapper_clauses_p)
   13520              : {
   13521           90 :   tree mapper_name = NULL_TREE;
   13522           90 :   tree mapper = lang_hooks.decls.omp_extract_mapper_directive (mapperfn);
   13523           90 :   gcc_assert (TREE_CODE (mapper) == OMP_DECLARE_MAPPER);
   13524              : 
   13525           90 :   tree clause = OMP_DECLARE_MAPPER_CLAUSES (mapper);
   13526           90 :   tree dummy_var = OMP_DECLARE_MAPPER_DECL (mapper);
   13527              : 
   13528              :   /* The "extraction map" is used to map the mapper variable in the "declare
   13529              :      mapper" directive, and also any temporary variables that have been created
   13530              :      as part of expanding the mapper function's body (which are expanded as a
   13531              :      "bind" expression in the pre_p sequence).  */
   13532           90 :   hash_map<tree, tree> extraction_map;
   13533              : 
   13534           90 :   extraction_map.put (dummy_var, expr);
   13535           90 :   extraction_map.put (expr, expr);
   13536              : 
   13537              :   /* This copy_body_data is only used to remap the decls in the
   13538              :      OMP_DECLARE_MAPPER tree node expansion itself.  All relevant decls should
   13539              :      already be in the current function.  */
   13540           90 :   copy_body_data id;
   13541           90 :   memset (&id, 0, sizeof (id));
   13542           90 :   id.src_fn = current_function_decl;
   13543           90 :   id.dst_fn = current_function_decl;
   13544           90 :   id.src_cfun = cfun;
   13545           90 :   id.decl_map = &extraction_map;
   13546           90 :   id.copy_decl = omp_mapper_copy_decl;
   13547           90 :   id.transform_call_graph_edges = CB_CGE_DUPLICATE; // ???
   13548           90 :   id.transform_new_cfg = true; // ???
   13549              : 
   13550          282 :   for (; clause; clause = OMP_CLAUSE_CHAIN (clause))
   13551              :     {
   13552          192 :       enum gomp_map_kind map_kind = OMP_CLAUSE_MAP_KIND (clause);
   13553          192 :       tree *nested_mapper_p = NULL;
   13554              : 
   13555          192 :       if (map_kind == GOMP_MAP_PUSH_MAPPER_NAME)
   13556              :         {
   13557            0 :           mapper_name = OMP_CLAUSE_DECL (clause);
   13558           25 :           continue;
   13559              :         }
   13560          192 :       else if (map_kind == GOMP_MAP_POP_MAPPER_NAME)
   13561              :         {
   13562            0 :           mapper_name = NULL_TREE;
   13563            0 :           continue;
   13564              :         }
   13565              : 
   13566          192 :       if (OMP_CLAUSE_HAS_ITERATORS (clause))
   13567              :         {
   13568            2 :           sorry_at (OMP_CLAUSE_LOCATION (clause),
   13569              :                     "user-defined mapper that uses a %<map%> clause "
   13570              :                     "with %<iterator%>");
   13571            2 :           continue;
   13572              :         }
   13573              : 
   13574          190 :       tree decl = OMP_CLAUSE_DECL (clause);
   13575          190 :       tree unshared, type;
   13576          190 :       bool nonunit_array_with_mapper = false;
   13577              : 
   13578          190 :       if (TREE_CODE (decl) == OMP_ARRAY_SECTION)
   13579              :         {
   13580           62 :           location_t loc = OMP_CLAUSE_LOCATION (clause);
   13581           62 :           tree tmp = lang_hooks.decls.omp_map_array_section (loc, decl);
   13582           62 :           if (tmp == decl)
   13583              :             {
   13584           48 :               unshared = unshare_expr (clause);
   13585           48 :               nonunit_array_with_mapper = true;
   13586           48 :               type = TREE_TYPE (TREE_TYPE (decl));
   13587              :             }
   13588              :           else
   13589              :             {
   13590           14 :               unshared = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
   13591           14 :                                            OMP_CLAUSE_CODE (clause));
   13592           14 :               OMP_CLAUSE_DECL (unshared) = tmp;
   13593           14 :               OMP_CLAUSE_SIZE (unshared)
   13594           28 :                 = DECL_P (tmp) ? DECL_SIZE_UNIT (tmp)
   13595           14 :                                : TYPE_SIZE_UNIT (TREE_TYPE (tmp));
   13596           14 :               type = TREE_TYPE (tmp);
   13597              :             }
   13598              :         }
   13599              :       else
   13600              :         {
   13601          128 :           unshared = unshare_expr (clause);
   13602          128 :           type = TREE_TYPE (decl);
   13603              :         }
   13604              : 
   13605          190 :       walk_tree (&unshared, remap_mapper_decl_1, &id, NULL);
   13606              : 
   13607          190 :       if (OMP_CLAUSE_MAP_KIND (unshared) == GOMP_MAP_UNSET)
   13608           28 :         OMP_CLAUSE_SET_MAP_KIND (unshared, outer_kind);
   13609              : 
   13610          190 :       decl = OMP_CLAUSE_DECL (unshared);
   13611          190 :       type = TYPE_MAIN_VARIANT (type);
   13612              : 
   13613          190 :       nested_mapper_p = implicit_mappers->get ({ mapper_name, type });
   13614              : 
   13615          190 :       if (nested_mapper_p && *nested_mapper_p != mapperfn)
   13616              :         {
   13617           23 :           if (nonunit_array_with_mapper)
   13618              :             {
   13619            8 :               sorry ("user-defined mapper with non-unit length array section");
   13620            8 :               continue;
   13621              :             }
   13622              : 
   13623           15 :           if (map_kind == GOMP_MAP_UNSET)
   13624            0 :             map_kind = outer_kind;
   13625              : 
   13626           15 :           mapper_clauses_p
   13627           15 :             = omp_instantiate_mapper (pre_p, implicit_mappers,
   13628              :                                       *nested_mapper_p, decl, map_kind,
   13629              :                                       mapper_clauses_p);
   13630           15 :           continue;
   13631              :         }
   13632              : 
   13633          167 :       *mapper_clauses_p = unshared;
   13634          167 :       mapper_clauses_p = &OMP_CLAUSE_CHAIN (unshared);
   13635              :     }
   13636              : 
   13637           90 :   return mapper_clauses_p;
   13638           90 : }
   13639              : 
   13640              : static int
   13641       138694 : omp_instantiate_implicit_mappers (splay_tree_node n, void *data)
   13642              : {
   13643       138694 :   tree decl = (tree) n->key;
   13644       138694 :   instantiate_mapper_info *im_info = (instantiate_mapper_info *) data;
   13645       138694 :   gimplify_omp_ctx *ctx = im_info->omp_ctx;
   13646       138694 :   tree *mapper_p = NULL;
   13647       138694 :   tree type = TREE_TYPE (decl);
   13648       138694 :   bool ref_p = false;
   13649       138694 :   unsigned flags = n->value;
   13650              : 
   13651       138694 :   if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
   13652              :     return 0;
   13653        23771 :   if ((flags & GOVD_SEEN) == 0)
   13654              :     return 0;
   13655              :   /* If we already have clauses pertaining to a struct variable, then we don't
   13656              :      want to implicitly invoke a user-defined mapper.  */
   13657        20237 :   if ((flags & GOVD_EXPLICIT) != 0 && AGGREGATE_TYPE_P (TREE_TYPE (decl)))
   13658              :     return 0;
   13659              : 
   13660        20237 :   if (TREE_CODE (type) == REFERENCE_TYPE)
   13661              :     {
   13662          905 :       ref_p = true;
   13663          905 :       type = TREE_TYPE (type);
   13664              :     }
   13665              : 
   13666        20237 :   type = TYPE_MAIN_VARIANT (type);
   13667              : 
   13668        20237 :   if (DECL_P (decl) && type && AGGREGATE_TYPE_P (type))
   13669              :     {
   13670         5319 :       gcc_assert (ctx);
   13671         5319 :       mapper_p = ctx->implicit_mappers->get ({ NULL_TREE, type });
   13672              :     }
   13673              : 
   13674         5319 :   if (mapper_p)
   13675              :     {
   13676              :       /* If we have a reference, map the pointed-to object rather than the
   13677              :          reference itself.  */
   13678           75 :       if (ref_p)
   13679            2 :         decl = build_fold_indirect_ref (decl);
   13680              : 
   13681           75 :       im_info->mapper_clauses_p
   13682           75 :         = omp_instantiate_mapper (im_info->pre_p, ctx->implicit_mappers,
   13683              :                                   *mapper_p, decl, GOMP_MAP_TOFROM,
   13684              :                                   im_info->mapper_clauses_p);
   13685              :       /* Make sure we don't map the same variable implicitly in
   13686              :          gimplify_adjust_omp_clauses_1 also.  */
   13687           75 :       n->value |= GOVD_EXPLICIT;
   13688              :     }
   13689              : 
   13690              :   return 0;
   13691              : }
   13692              : 
   13693              : /* Scan the OMP clauses in *LIST_P, installing mappings into a new
   13694              :    and previous omp contexts.  */
   13695              : 
   13696              : static void
   13697       131616 : gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
   13698              :                            enum omp_region_type region_type,
   13699              :                            enum tree_code code,
   13700              :                            gimple_seq *loops_seq_p = NULL)
   13701              : {
   13702       131616 :   using namespace omp_addr_tokenizer;
   13703       131616 :   struct gimplify_omp_ctx *ctx, *outer_ctx;
   13704       131616 :   tree c;
   13705       131616 :   tree *orig_list_p = list_p;
   13706       131616 :   int handled_depend_iterators = -1;
   13707       131616 :   int nowait = -1;
   13708              : 
   13709       131616 :   ctx = new_omp_context (region_type);
   13710       131616 :   ctx->code = code;
   13711       131616 :   outer_ctx = ctx->outer_context;
   13712       131616 :   if (code == OMP_TARGET)
   13713              :     {
   13714        13567 :       if (!lang_GNU_Fortran ())
   13715        11189 :         ctx->defaultmap[GDMK_POINTER] = GOVD_MAP | GOVD_MAP_0LEN_ARRAY;
   13716        13567 :       ctx->defaultmap[GDMK_SCALAR] = GOVD_FIRSTPRIVATE;
   13717        27134 :       ctx->defaultmap[GDMK_SCALAR_TARGET] = (lang_GNU_Fortran ()
   13718        13567 :                                              ? GOVD_MAP : GOVD_FIRSTPRIVATE);
   13719              :     }
   13720       131616 :   if (!lang_GNU_Fortran ())
   13721       100235 :     switch (code)
   13722              :       {
   13723        18692 :       case OMP_TARGET:
   13724        18692 :       case OMP_TARGET_DATA:
   13725        18692 :       case OMP_TARGET_ENTER_DATA:
   13726        18692 :       case OMP_TARGET_EXIT_DATA:
   13727        18692 :       case OACC_DECLARE:
   13728        18692 :       case OACC_HOST_DATA:
   13729        18692 :       case OACC_PARALLEL:
   13730        18692 :       case OACC_KERNELS:
   13731        18692 :         ctx->target_firstprivatize_array_bases = true;
   13732              :       default:
   13733              :         break;
   13734              :       }
   13735              : 
   13736       131616 :   vec<omp_mapping_group> *groups = NULL;
   13737       131616 :   hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap = NULL;
   13738       131616 :   unsigned grpnum = 0;
   13739       131616 :   tree *grp_start_p = NULL, grp_end = NULL_TREE;
   13740              : 
   13741       131616 :   if (code == OMP_TARGET
   13742       131616 :       || code == OMP_TARGET_DATA
   13743       131616 :       || code == OMP_TARGET_ENTER_DATA
   13744              :       || code == OMP_TARGET_EXIT_DATA
   13745              :       || code == OACC_DATA
   13746              :       || code == OACC_KERNELS
   13747              :       || code == OACC_PARALLEL
   13748              :       || code == OACC_SERIAL
   13749              :       || code == OACC_ENTER_DATA
   13750              :       || code == OACC_EXIT_DATA
   13751              :       || code == OACC_UPDATE
   13752              :       || code == OACC_DECLARE)
   13753              :     {
   13754        34001 :       if (!(region_type & ORT_ACC))
   13755        17489 :         *list_p = omp_remove_duplicate_maps (*list_p, false);
   13756        34001 :       groups = omp_gather_mapping_groups (list_p);
   13757              : 
   13758        34001 :       if (groups)
   13759        18303 :         grpmap = omp_index_mapping_groups (groups);
   13760              :     }
   13761              : 
   13762       338183 :   while ((c = *list_p) != NULL)
   13763              :     {
   13764       206567 :       bool remove = false;
   13765       206567 :       bool notice_outer = true;
   13766       206567 :       bool map_descriptor;
   13767       206567 :       const char *check_non_private = NULL;
   13768       206567 :       unsigned int flags;
   13769       206567 :       tree decl;
   13770       206567 :       auto_vec<omp_addr_token *, 10> addr_tokens;
   13771       206567 :       tree op = NULL_TREE;
   13772       206567 :       location_t loc = OMP_CLAUSE_LOCATION (c);
   13773              : 
   13774       244157 :       if (grp_end && c == OMP_CLAUSE_CHAIN (grp_end))
   13775              :         {
   13776              :           grp_start_p = NULL;
   13777              :           grp_end = NULL_TREE;
   13778              :         }
   13779              : 
   13780       206567 :       if (code == OMP_TARGET
   13781              :           || code == OMP_TARGET_DATA
   13782              :           || code == OMP_TARGET_ENTER_DATA
   13783       173648 :           || code == OMP_TARGET_EXIT_DATA)
   13784              :         /* Do some target-specific type checks for map operands.  */
   13785        35352 :         switch (OMP_CLAUSE_CODE (c))
   13786              :           {
   13787        25831 :           case OMP_CLAUSE_MAP:
   13788        25831 :             op = OMP_CLAUSE_OPERAND (c, 0);
   13789        25831 :             verify_type_context (loc, TCTX_OMP_MAP, TREE_TYPE (op));
   13790        25831 :             break;
   13791          186 :           case OMP_CLAUSE_PRIVATE:
   13792          186 :             op = OMP_CLAUSE_OPERAND (c, 0);
   13793          186 :             verify_type_context (loc, TCTX_OMP_PRIVATE, TREE_TYPE (op));
   13794          186 :             break;
   13795         1376 :           case OMP_CLAUSE_FIRSTPRIVATE:
   13796         1376 :             op = OMP_CLAUSE_OPERAND (c, 0);
   13797         1376 :             verify_type_context (loc, TCTX_OMP_FIRSTPRIVATE, TREE_TYPE (op));
   13798         1376 :             break;
   13799         2923 :           case OMP_CLAUSE_IS_DEVICE_PTR:
   13800         2923 :           case OMP_CLAUSE_USE_DEVICE_ADDR:
   13801         2923 :           case OMP_CLAUSE_USE_DEVICE_PTR:
   13802         2923 :           case OMP_CLAUSE_HAS_DEVICE_ADDR:
   13803         2923 :             op = OMP_CLAUSE_OPERAND (c, 0);
   13804         2923 :             verify_type_context (loc, TCTX_OMP_DEVICE_ADDR, TREE_TYPE (op));
   13805         2923 :             break;
   13806              :           default:
   13807              :             break;
   13808              :           }
   13809              : 
   13810       206567 :       switch (OMP_CLAUSE_CODE (c))
   13811              :         {
   13812        12255 :         case OMP_CLAUSE_PRIVATE:
   13813        12255 :           flags = GOVD_PRIVATE | GOVD_EXPLICIT;
   13814        12255 :           if (lang_hooks.decls.omp_private_outer_ref (OMP_CLAUSE_DECL (c)))
   13815              :             {
   13816          167 :               flags |= GOVD_PRIVATE_OUTER_REF;
   13817          167 :               OMP_CLAUSE_PRIVATE_OUTER_REF (c) = 1;
   13818              :             }
   13819              :           else
   13820              :             notice_outer = false;
   13821        12255 :           goto do_add;
   13822         5536 :         case OMP_CLAUSE_SHARED:
   13823         5536 :           flags = GOVD_SHARED | GOVD_EXPLICIT;
   13824         5536 :           goto do_add;
   13825         8059 :         case OMP_CLAUSE_FIRSTPRIVATE:
   13826         8059 :           flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
   13827         8059 :           check_non_private = "firstprivate";
   13828         8059 :           if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
   13829              :             {
   13830          380 :               gcc_assert (code == OMP_TARGET);
   13831              :               flags |= GOVD_FIRSTPRIVATE_IMPLICIT;
   13832              :             }
   13833         8059 :           goto do_add;
   13834         7338 :         case OMP_CLAUSE_LASTPRIVATE:
   13835         7338 :           if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   13836          496 :             switch (code)
   13837              :               {
   13838           25 :               case OMP_DISTRIBUTE:
   13839           25 :                 error_at (OMP_CLAUSE_LOCATION (c),
   13840              :                           "conditional %<lastprivate%> clause on "
   13841              :                           "%qs construct", "distribute");
   13842           25 :                 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
   13843           25 :                 break;
   13844           13 :               case OMP_TASKLOOP:
   13845           13 :                 error_at (OMP_CLAUSE_LOCATION (c),
   13846              :                           "conditional %<lastprivate%> clause on "
   13847              :                           "%qs construct", "taskloop");
   13848           13 :                 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
   13849           13 :                 break;
   13850              :               default:
   13851              :                 break;
   13852              :               }
   13853         7338 :           flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
   13854         7338 :           if (code != OMP_LOOP)
   13855         6987 :             check_non_private = "lastprivate";
   13856         7338 :           decl = OMP_CLAUSE_DECL (c);
   13857         7338 :           if (error_operand_p (decl))
   13858            0 :             goto do_add;
   13859         7338 :           if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
   13860         7338 :               && !lang_hooks.decls.omp_scalar_p (decl, true))
   13861              :             {
   13862            5 :               error_at (OMP_CLAUSE_LOCATION (c),
   13863              :                         "non-scalar variable %qD in conditional "
   13864              :                         "%<lastprivate%> clause", decl);
   13865            5 :               OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
   13866              :             }
   13867         7338 :           if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   13868          453 :             flags |= GOVD_LASTPRIVATE_CONDITIONAL;
   13869         7338 :           omp_lastprivate_for_combined_outer_constructs (outer_ctx, decl,
   13870              :                                                          false);
   13871         7338 :           goto do_add;
   13872        15384 :         case OMP_CLAUSE_REDUCTION:
   13873        15384 :           if (OMP_CLAUSE_REDUCTION_TASK (c))
   13874              :             {
   13875          603 :               if (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
   13876              :                 {
   13877          416 :                   if (nowait == -1)
   13878          301 :                     nowait = omp_find_clause (*list_p,
   13879          301 :                                               OMP_CLAUSE_NOWAIT) != NULL_TREE;
   13880          416 :                   if (nowait
   13881           15 :                       && (outer_ctx == NULL
   13882            0 :                           || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
   13883              :                     {
   13884           15 :                       error_at (OMP_CLAUSE_LOCATION (c),
   13885              :                                 "%<task%> reduction modifier on a construct "
   13886              :                                 "with a %<nowait%> clause");
   13887           15 :                       OMP_CLAUSE_REDUCTION_TASK (c) = 0;
   13888              :                     }
   13889              :                 }
   13890          187 :               else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
   13891              :                 {
   13892           40 :                   error_at (OMP_CLAUSE_LOCATION (c),
   13893              :                             "invalid %<task%> reduction modifier on construct "
   13894              :                             "other than %<parallel%>, %qs, %<sections%> or "
   13895           20 :                             "%<scope%>", lang_GNU_Fortran () ? "do" : "for");
   13896           20 :                   OMP_CLAUSE_REDUCTION_TASK (c) = 0;
   13897              :                 }
   13898              :             }
   13899        15384 :           if (OMP_CLAUSE_REDUCTION_INSCAN (c))
   13900          851 :             switch (code)
   13901              :               {
   13902            4 :               case OMP_SECTIONS:
   13903            4 :                 error_at (OMP_CLAUSE_LOCATION (c),
   13904              :                           "%<inscan%> %<reduction%> clause on "
   13905              :                           "%qs construct", "sections");
   13906            4 :                 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   13907            4 :                 break;
   13908            4 :               case OMP_PARALLEL:
   13909            4 :                 error_at (OMP_CLAUSE_LOCATION (c),
   13910              :                           "%<inscan%> %<reduction%> clause on "
   13911              :                           "%qs construct", "parallel");
   13912            4 :                 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   13913            4 :                 break;
   13914            4 :               case OMP_TEAMS:
   13915            4 :                 error_at (OMP_CLAUSE_LOCATION (c),
   13916              :                           "%<inscan%> %<reduction%> clause on "
   13917              :                           "%qs construct", "teams");
   13918            4 :                 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   13919            4 :                 break;
   13920            4 :               case OMP_TASKLOOP:
   13921            4 :                 error_at (OMP_CLAUSE_LOCATION (c),
   13922              :                           "%<inscan%> %<reduction%> clause on "
   13923              :                           "%qs construct", "taskloop");
   13924            4 :                 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   13925            4 :                 break;
   13926            4 :               case OMP_SCOPE:
   13927            4 :                 error_at (OMP_CLAUSE_LOCATION (c),
   13928              :                           "%<inscan%> %<reduction%> clause on "
   13929              :                           "%qs construct", "scope");
   13930            4 :                 OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
   13931            4 :                 break;
   13932              :               default:
   13933              :                 break;
   13934              :               }
   13935              :           /* FALLTHRU */
   13936        17988 :         case OMP_CLAUSE_IN_REDUCTION:
   13937        17988 :         case OMP_CLAUSE_TASK_REDUCTION:
   13938        17988 :           flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
   13939              :           /* OpenACC permits reductions on private variables.  */
   13940        17988 :           if (!(region_type & ORT_ACC)
   13941              :               /* taskgroup is actually not a worksharing region.  */
   13942        12469 :               && code != OMP_TASKGROUP)
   13943        11939 :             check_non_private = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
   13944        17988 :           decl = OMP_CLAUSE_DECL (c);
   13945        17988 :           if (TREE_CODE (decl) == MEM_REF)
   13946              :             {
   13947         2614 :               tree type = TREE_TYPE (decl);
   13948         2614 :               bool saved_into_ssa = gimplify_ctxp->into_ssa;
   13949         2614 :               gimplify_ctxp->into_ssa = false;
   13950         2614 :               if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
   13951              :                                  NULL, is_gimple_val, fb_rvalue, false)
   13952              :                   == GS_ERROR)
   13953              :                 {
   13954            0 :                   gimplify_ctxp->into_ssa = saved_into_ssa;
   13955            0 :                   remove = true;
   13956            0 :                   break;
   13957              :                 }
   13958         2614 :               gimplify_ctxp->into_ssa = saved_into_ssa;
   13959         2614 :               tree v = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
   13960         2614 :               if (DECL_P (v))
   13961              :                 {
   13962          571 :                   omp_firstprivatize_variable (ctx, v);
   13963          571 :                   omp_notice_variable (ctx, v, true);
   13964              :                 }
   13965         2614 :               decl = TREE_OPERAND (decl, 0);
   13966         2614 :               if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
   13967              :                 {
   13968          477 :                   gimplify_ctxp->into_ssa = false;
   13969          477 :                   if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
   13970              :                                      NULL, is_gimple_val, fb_rvalue, false)
   13971              :                       == GS_ERROR)
   13972              :                     {
   13973            0 :                       gimplify_ctxp->into_ssa = saved_into_ssa;
   13974            0 :                       remove = true;
   13975            0 :                       break;
   13976              :                     }
   13977          477 :                   gimplify_ctxp->into_ssa = saved_into_ssa;
   13978          477 :                   v = TREE_OPERAND (decl, 1);
   13979          477 :                   if (DECL_P (v))
   13980              :                     {
   13981          477 :                       omp_firstprivatize_variable (ctx, v);
   13982          477 :                       omp_notice_variable (ctx, v, true);
   13983              :                     }
   13984          477 :                   decl = TREE_OPERAND (decl, 0);
   13985              :                 }
   13986         2614 :               if (TREE_CODE (decl) == ADDR_EXPR
   13987         1220 :                   || TREE_CODE (decl) == INDIRECT_REF)
   13988         1510 :                 decl = TREE_OPERAND (decl, 0);
   13989              :             }
   13990        17988 :           goto do_add_decl;
   13991         2688 :         case OMP_CLAUSE_LINEAR:
   13992         2688 :           if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
   13993              :                              is_gimple_val, fb_rvalue) == GS_ERROR)
   13994              :             {
   13995              :               remove = true;
   13996              :               break;
   13997              :             }
   13998              :           else
   13999              :             {
   14000         2688 :               if (code == OMP_SIMD
   14001         2688 :                   && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
   14002              :                 {
   14003         1154 :                   struct gimplify_omp_ctx *octx = outer_ctx;
   14004         1154 :                   if (octx
   14005          741 :                       && octx->region_type == ORT_WORKSHARE
   14006          500 :                       && octx->combined_loop
   14007          500 :                       && !octx->distribute)
   14008              :                     {
   14009          492 :                       if (octx->outer_context
   14010          430 :                           && (octx->outer_context->region_type
   14011              :                               == ORT_COMBINED_PARALLEL))
   14012          393 :                         octx = octx->outer_context->outer_context;
   14013              :                       else
   14014              :                         octx = octx->outer_context;
   14015              :                     }
   14016          905 :                   if (octx
   14017          316 :                       && octx->region_type == ORT_WORKSHARE
   14018           16 :                       && octx->combined_loop
   14019           16 :                       && octx->distribute)
   14020              :                     {
   14021           16 :                       error_at (OMP_CLAUSE_LOCATION (c),
   14022              :                                 "%<linear%> clause for variable other than "
   14023              :                                 "loop iterator specified on construct "
   14024              :                                 "combined with %<distribute%>");
   14025           16 :                       remove = true;
   14026           16 :                       break;
   14027              :                     }
   14028              :                 }
   14029              :               /* For combined #pragma omp parallel for simd, need to put
   14030              :                  lastprivate and perhaps firstprivate too on the
   14031              :                  parallel.  Similarly for #pragma omp for simd.  */
   14032              :               struct gimplify_omp_ctx *octx = outer_ctx;
   14033              :               bool taskloop_seen = false;
   14034              :               decl = NULL_TREE;
   14035         3469 :               do
   14036              :                 {
   14037         3469 :                   if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
   14038         3469 :                       && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   14039              :                     break;
   14040         3409 :                   decl = OMP_CLAUSE_DECL (c);
   14041         3409 :                   if (error_operand_p (decl))
   14042              :                     {
   14043              :                       decl = NULL_TREE;
   14044              :                       break;
   14045              :                     }
   14046         3409 :                   flags = GOVD_SEEN;
   14047         3409 :                   if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
   14048         1672 :                     flags |= GOVD_FIRSTPRIVATE;
   14049         3409 :                   if (!OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   14050         3409 :                     flags |= GOVD_LASTPRIVATE;
   14051         3409 :                   if (octx
   14052         2519 :                       && octx->region_type == ORT_WORKSHARE
   14053         1220 :                       && octx->combined_loop)
   14054              :                     {
   14055         1214 :                       if (octx->outer_context
   14056         1042 :                           && (octx->outer_context->region_type
   14057              :                               == ORT_COMBINED_PARALLEL))
   14058              :                         octx = octx->outer_context;
   14059          480 :                       else if (omp_check_private (octx, decl, false))
   14060              :                         break;
   14061              :                     }
   14062              :                   else if (octx
   14063         1305 :                            && (octx->region_type & ORT_TASK) != 0
   14064          307 :                            && octx->combined_loop)
   14065              :                     taskloop_seen = true;
   14066              :                   else if (octx
   14067         1002 :                            && octx->region_type == ORT_COMBINED_PARALLEL
   14068          301 :                            && ((ctx->region_type == ORT_WORKSHARE
   14069          201 :                                 && octx == outer_ctx)
   14070          100 :                                || taskloop_seen))
   14071              :                     flags = GOVD_SEEN | GOVD_SHARED;
   14072              :                   else if (octx
   14073          701 :                            && ((octx->region_type & ORT_COMBINED_TEAMS)
   14074              :                                == ORT_COMBINED_TEAMS))
   14075              :                     flags = GOVD_SEEN | GOVD_SHARED;
   14076          544 :                   else if (octx
   14077          544 :                            && octx->region_type == ORT_COMBINED_TARGET)
   14078              :                     {
   14079          197 :                       if (flags & GOVD_LASTPRIVATE)
   14080          197 :                         flags = GOVD_SEEN | GOVD_MAP;
   14081              :                     }
   14082              :                   else
   14083              :                     break;
   14084         2080 :                   splay_tree_node on
   14085         2080 :                     = splay_tree_lookup (octx->variables,
   14086              :                                          (splay_tree_key) decl);
   14087         2080 :                   if (on && (on->value & GOVD_DATA_SHARE_CLASS) != 0)
   14088              :                     {
   14089              :                       octx = NULL;
   14090              :                       break;
   14091              :                     }
   14092         2076 :                   omp_add_variable (octx, decl, flags);
   14093         2076 :                   if (octx->outer_context == NULL)
   14094              :                     break;
   14095              :                   octx = octx->outer_context;
   14096              :                 }
   14097              :               while (1);
   14098         2672 :               if (octx
   14099         2672 :                   && decl
   14100         2672 :                   && (!OMP_CLAUSE_LINEAR_NO_COPYIN (c)
   14101          735 :                       || !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
   14102         1718 :                 omp_notice_variable (octx, decl, true);
   14103              :             }
   14104         2672 :           flags = GOVD_LINEAR | GOVD_EXPLICIT;
   14105         2672 :           if (OMP_CLAUSE_LINEAR_NO_COPYIN (c)
   14106         2672 :               && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   14107              :             {
   14108              :               notice_outer = false;
   14109              :               flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
   14110              :             }
   14111         2672 :           goto do_add;
   14112              : 
   14113        51416 :         case OMP_CLAUSE_MAP:
   14114        51416 :           if (!grp_start_p)
   14115              :             {
   14116        31210 :               grp_start_p = list_p;
   14117        31210 :               grp_end = (*groups)[grpnum].grp_end;
   14118        31210 :               grpnum++;
   14119              :             }
   14120        51416 :           decl = OMP_CLAUSE_DECL (c);
   14121              : 
   14122        51416 :           if (error_operand_p (decl))
   14123              :             {
   14124              :               remove = true;
   14125              :               break;
   14126              :             }
   14127              : 
   14128        51416 :           if (!omp_parse_expr (addr_tokens, decl))
   14129              :             {
   14130              :               remove = true;
   14131              :               break;
   14132              :             }
   14133              : 
   14134        51416 :           if (remove)
   14135              :             break;
   14136        51416 :           if (DECL_P (decl) && outer_ctx && (region_type & ORT_ACC))
   14137              :             {
   14138              :               struct gimplify_omp_ctx *octx;
   14139         1167 :               for (octx = outer_ctx; octx; octx = octx->outer_context)
   14140              :                 {
   14141         1167 :                   if (octx->region_type != ORT_ACC_HOST_DATA)
   14142              :                     break;
   14143           12 :                   splay_tree_node n2
   14144           12 :                     = splay_tree_lookup (octx->variables,
   14145              :                                          (splay_tree_key) decl);
   14146           12 :                   if (n2)
   14147            4 :                     error_at (OMP_CLAUSE_LOCATION (c), "variable %qE "
   14148              :                               "declared in enclosing %<host_data%> region",
   14149            4 :                               DECL_NAME (decl));
   14150              :                 }
   14151              :             }
   14152              : 
   14153        51416 :           map_descriptor = false;
   14154              : 
   14155              :           /* This condition checks if we're mapping an array descriptor that
   14156              :              isn't inside a derived type -- these have special handling, and
   14157              :              are not handled as structs in omp_build_struct_sibling_lists.
   14158              :              See that function for further details.  */
   14159        51416 :           if (*grp_start_p != grp_end
   14160        34234 :               && OMP_CLAUSE_CHAIN (*grp_start_p)
   14161        85650 :               && OMP_CLAUSE_CHAIN (*grp_start_p) != grp_end)
   14162              :             {
   14163        17096 :               tree grp_mid = OMP_CLAUSE_CHAIN (*grp_start_p);
   14164        17096 :               if (omp_map_clause_descriptor_p (grp_mid)
   14165        32365 :                   && DECL_P (OMP_CLAUSE_DECL (grp_mid)))
   14166              :                 map_descriptor = true;
   14167              :             }
   14168        34320 :           else if (OMP_CLAUSE_CODE (grp_end) == OMP_CLAUSE_MAP
   14169        34320 :                    && (OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_RELEASE
   14170        33576 :                        || OMP_CLAUSE_MAP_KIND (grp_end) == GOMP_MAP_DELETE)
   14171        35242 :                    && OMP_CLAUSE_RELEASE_DESCRIPTOR (grp_end))
   14172              :             map_descriptor = true;
   14173              : 
   14174              :           /* Adding the decl for a struct access: we haven't created
   14175              :              GOMP_MAP_STRUCT nodes yet, so this statement needs to predict
   14176              :              whether they will be created in gimplify_adjust_omp_clauses.
   14177              :              NOTE: Technically we should probably look through DECL_VALUE_EXPR
   14178              :              here because something that looks like a DECL_P may actually be a
   14179              :              struct access, e.g. variables in a lambda closure
   14180              :              (__closure->__foo) or class members (this->foo). Currently in both
   14181              :              those cases we map the whole of the containing object (directly in
   14182              :              the C++ FE) though, so struct nodes are not created.  */
   14183        51416 :           if (c == grp_end
   14184        31210 :               && addr_tokens[0]->type == STRUCTURE_BASE
   14185         8403 :               && addr_tokens[0]->u.structure_base_kind == BASE_DECL
   14186        59819 :               && !map_descriptor)
   14187              :             {
   14188         5599 :               gcc_assert (addr_tokens[1]->type == ACCESS_METHOD);
   14189              :               /* If we got to this struct via a chain of pointers, maybe we
   14190              :                  want to map it implicitly instead.  */
   14191         5599 :               if (omp_access_chain_p (addr_tokens, 1))
   14192              :                 break;
   14193         5438 :               omp_mapping_group *wholestruct;
   14194         5438 :               if (!(region_type & ORT_ACC)
   14195         9601 :                   && omp_mapped_by_containing_struct (grpmap,
   14196         4163 :                                                       OMP_CLAUSE_DECL (c),
   14197              :                                                       &wholestruct))
   14198              :                 break;
   14199         5201 :               decl = addr_tokens[1]->expr;
   14200         5201 :               if (splay_tree_lookup (ctx->variables, (splay_tree_key) decl))
   14201              :                 break;
   14202              :               /* Standalone attach or detach clauses for a struct element
   14203              :                  should not inhibit implicit mapping of the whole struct.  */
   14204         2987 :               if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   14205         2987 :                   || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
   14206              :                 break;
   14207         2837 :               flags = GOVD_MAP | GOVD_EXPLICIT;
   14208              : 
   14209         2837 :               gcc_assert (addr_tokens[1]->u.access_kind != ACCESS_DIRECT
   14210              :                           || TREE_ADDRESSABLE (decl));
   14211         2837 :               goto do_add_decl;
   14212              :             }
   14213              : 
   14214        45817 :           if (!DECL_P (decl))
   14215              :             {
   14216        21135 :               tree d = decl, *pd;
   14217        21135 :               if (TREE_CODE (d) == ARRAY_REF)
   14218              :                 {
   14219         5128 :                   while (TREE_CODE (d) == ARRAY_REF)
   14220         2621 :                     d = TREE_OPERAND (d, 0);
   14221         2507 :                   if (TREE_CODE (d) == COMPONENT_REF
   14222         2507 :                       && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
   14223              :                     decl = d;
   14224              :                 }
   14225        21135 :               pd = &OMP_CLAUSE_DECL (c);
   14226        21135 :               if (d == decl
   14227        18674 :                   && TREE_CODE (decl) == INDIRECT_REF
   14228        13946 :                   && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
   14229         1070 :                   && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
   14230              :                       == REFERENCE_TYPE)
   14231        21786 :                   && (OMP_CLAUSE_MAP_KIND (c)
   14232              :                       != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
   14233              :                 {
   14234          647 :                   pd = &TREE_OPERAND (decl, 0);
   14235          647 :                   decl = TREE_OPERAND (decl, 0);
   14236              :                 }
   14237              : 
   14238        21135 :               if (addr_tokens[0]->type == STRUCTURE_BASE
   14239        11440 :                   && addr_tokens[0]->u.structure_base_kind == BASE_DECL
   14240        11439 :                   && addr_tokens[1]->type == ACCESS_METHOD
   14241        11439 :                   && (addr_tokens[1]->u.access_kind == ACCESS_POINTER
   14242        10941 :                       || (addr_tokens[1]->u.access_kind
   14243              :                           == ACCESS_POINTER_OFFSET))
   14244        21715 :                   && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)))
   14245              :                 {
   14246            0 :                   tree base = addr_tokens[1]->expr;
   14247            0 :                   splay_tree_node n
   14248            0 :                     = splay_tree_lookup (ctx->variables,
   14249              :                                          (splay_tree_key) base);
   14250            0 :                   n->value |= GOVD_SEEN;
   14251              :                 }
   14252              : 
   14253        21135 :               if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
   14254              :                 {
   14255              :                   /* Don't gimplify *pd fully at this point, as the base
   14256              :                      will need to be adjusted during omp lowering.  */
   14257           88 :                   auto_vec<tree, 10> expr_stack;
   14258           88 :                   tree *p = pd;
   14259           88 :                   while (handled_component_p (*p)
   14260              :                          || TREE_CODE (*p) == INDIRECT_REF
   14261              :                          || TREE_CODE (*p) == ADDR_EXPR
   14262              :                          || TREE_CODE (*p) == MEM_REF
   14263          224 :                          || TREE_CODE (*p) == NON_LVALUE_EXPR)
   14264              :                     {
   14265          136 :                       expr_stack.safe_push (*p);
   14266          136 :                       p = &TREE_OPERAND (*p, 0);
   14267              :                     }
   14268          312 :                   for (int i = expr_stack.length () - 1; i >= 0; i--)
   14269              :                     {
   14270          136 :                       tree t = expr_stack[i];
   14271          136 :                       if (TREE_CODE (t) == ARRAY_REF
   14272          136 :                           || TREE_CODE (t) == ARRAY_RANGE_REF)
   14273              :                         {
   14274           56 :                           if (TREE_OPERAND (t, 2) == NULL_TREE)
   14275              :                             {
   14276           56 :                               tree low = unshare_expr (array_ref_low_bound (t));
   14277           56 :                               if (!is_gimple_min_invariant (low))
   14278              :                                 {
   14279            0 :                                   TREE_OPERAND (t, 2) = low;
   14280            0 :                                   if (gimplify_expr (&TREE_OPERAND (t, 2),
   14281              :                                                      pre_p, NULL,
   14282              :                                                      is_gimple_reg,
   14283              :                                                      fb_rvalue) == GS_ERROR)
   14284           56 :                                     remove = true;
   14285              :                                 }
   14286              :                             }
   14287            0 :                           else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
   14288              :                                                   NULL, is_gimple_reg,
   14289              :                                                   fb_rvalue) == GS_ERROR)
   14290           56 :                             remove = true;
   14291           56 :                           if (TREE_OPERAND (t, 3) == NULL_TREE)
   14292              :                             {
   14293           56 :                               tree elmt_size = array_ref_element_size (t);
   14294           56 :                               if (!is_gimple_min_invariant (elmt_size))
   14295              :                                 {
   14296            0 :                                   elmt_size = unshare_expr (elmt_size);
   14297            0 :                                   tree elmt_type
   14298            0 :                                     = TREE_TYPE (TREE_TYPE (TREE_OPERAND (t,
   14299              :                                                                           0)));
   14300            0 :                                   tree factor
   14301            0 :                                     = size_int (TYPE_ALIGN_UNIT (elmt_type));
   14302            0 :                                   elmt_size
   14303            0 :                                     = size_binop (EXACT_DIV_EXPR, elmt_size,
   14304              :                                                   factor);
   14305            0 :                                   TREE_OPERAND (t, 3) = elmt_size;
   14306            0 :                                   if (gimplify_expr (&TREE_OPERAND (t, 3),
   14307              :                                                      pre_p, NULL,
   14308              :                                                      is_gimple_reg,
   14309              :                                                      fb_rvalue) == GS_ERROR)
   14310            0 :                                     remove = true;
   14311              :                                 }
   14312              :                             }
   14313            0 :                           else if (gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
   14314              :                                                   NULL, is_gimple_reg,
   14315              :                                                   fb_rvalue) == GS_ERROR)
   14316            0 :                             remove = true;
   14317              :                         }
   14318           80 :                       else if (TREE_CODE (t) == COMPONENT_REF)
   14319              :                         {
   14320            0 :                           if (TREE_OPERAND (t, 2) == NULL_TREE)
   14321              :                             {
   14322            0 :                               tree offset = component_ref_field_offset (t);
   14323            0 :                               if (!is_gimple_min_invariant (offset))
   14324              :                                 {
   14325            0 :                                   offset = unshare_expr (offset);
   14326            0 :                                   tree field = TREE_OPERAND (t, 1);
   14327            0 :                                   tree factor
   14328            0 :                                     = size_int (DECL_OFFSET_ALIGN (field)
   14329              :                                                 / BITS_PER_UNIT);
   14330            0 :                                   offset = size_binop (EXACT_DIV_EXPR, offset,
   14331              :                                                        factor);
   14332            0 :                                   TREE_OPERAND (t, 2) = offset;
   14333            0 :                                   if (gimplify_expr (&TREE_OPERAND (t, 2),
   14334              :                                                      pre_p, NULL,
   14335              :                                                      is_gimple_reg,
   14336              :                                                      fb_rvalue) == GS_ERROR)
   14337            0 :                                     remove = true;
   14338              :                                 }
   14339              :                             }
   14340            0 :                           else if (gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
   14341              :                                                   NULL, is_gimple_reg,
   14342              :                                                   fb_rvalue) == GS_ERROR)
   14343            0 :                             remove = true;
   14344              :                         }
   14345              :                     }
   14346          224 :                   for (; expr_stack.length () > 0; )
   14347              :                     {
   14348          136 :                       tree t = expr_stack.pop ();
   14349              : 
   14350          136 :                       if (TREE_CODE (t) == ARRAY_REF
   14351          136 :                           || TREE_CODE (t) == ARRAY_RANGE_REF)
   14352              :                         {
   14353           56 :                           if (!is_gimple_min_invariant (TREE_OPERAND (t, 1))
   14354           56 :                               && gimplify_expr (&TREE_OPERAND (t, 1), pre_p,
   14355              :                                                 NULL, is_gimple_val,
   14356              :                                                 fb_rvalue) == GS_ERROR)
   14357              :                             remove = true;
   14358              :                         }
   14359              :                     }
   14360           88 :                 }
   14361              :               break;
   14362              :             }
   14363              : 
   14364        24682 :           if ((code == OMP_TARGET
   14365              :                || code == OMP_TARGET_DATA
   14366              :                || code == OMP_TARGET_ENTER_DATA
   14367        14229 :                || code == OMP_TARGET_EXIT_DATA)
   14368        25324 :               && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   14369              :             {
   14370              :               /* If we have attach/detach but the decl we have is a pointer to
   14371              :                  pointer, we're probably mapping the "base level" array
   14372              :                  implicitly.  Make sure we don't add the decl as if we mapped
   14373              :                  it explicitly.  That is,
   14374              : 
   14375              :                    int **arr;
   14376              :                    [...]
   14377              :                    #pragma omp target map(arr[a][b:c])
   14378              : 
   14379              :                  should *not* map "arr" explicitly.  That way we get a
   14380              :                  zero-length "alloc" mapping for it, and assuming it's been
   14381              :                  mapped by some previous directive, etc., things work as they
   14382              :                  should.  */
   14383              : 
   14384          217 :               tree basetype = TREE_TYPE (addr_tokens[0]->expr);
   14385              : 
   14386          217 :               if (TREE_CODE (basetype) == REFERENCE_TYPE)
   14387           34 :                 basetype = TREE_TYPE (basetype);
   14388              : 
   14389          217 :               if (code == OMP_TARGET
   14390           54 :                   && addr_tokens[0]->type == ARRAY_BASE
   14391           54 :                   && addr_tokens[0]->u.structure_base_kind == BASE_DECL
   14392           54 :                   && TREE_CODE (basetype) == POINTER_TYPE
   14393          271 :                   && TREE_CODE (TREE_TYPE (basetype)) == POINTER_TYPE)
   14394              :                 break;
   14395              :             }
   14396              : 
   14397        24660 :           flags = GOVD_MAP | GOVD_EXPLICIT;
   14398        24660 :           if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TO
   14399        24523 :               || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_TOFROM
   14400        24015 :               || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_PRESENT_TO
   14401        48645 :               || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_PRESENT_TOFROM)
   14402              :             flags |= GOVD_MAP_ALWAYS_TO;
   14403              : 
   14404        24660 :           goto do_add;
   14405              : 
   14406          510 :         case OMP_CLAUSE_AFFINITY:
   14407          510 :           gimplify_omp_affinity (list_p, pre_p);
   14408          510 :           remove = true;
   14409          510 :           break;
   14410            8 :         case OMP_CLAUSE_DOACROSS:
   14411            8 :           if (OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
   14412              :             {
   14413            4 :               tree deps = OMP_CLAUSE_DECL (c);
   14414            8 :               while (deps && TREE_CODE (deps) == TREE_LIST)
   14415              :                 {
   14416            4 :                   if (TREE_CODE (TREE_PURPOSE (deps)) == TRUNC_DIV_EXPR
   14417            4 :                       && DECL_P (TREE_OPERAND (TREE_PURPOSE (deps), 1)))
   14418            0 :                     gimplify_expr (&TREE_OPERAND (TREE_PURPOSE (deps), 1),
   14419              :                                    pre_p, NULL, is_gimple_val, fb_rvalue);
   14420            4 :                   deps = TREE_CHAIN (deps);
   14421              :                 }
   14422              :             }
   14423              :           else
   14424            4 :             gcc_assert (OMP_CLAUSE_DOACROSS_KIND (c)
   14425              :                         == OMP_CLAUSE_DOACROSS_SOURCE);
   14426              :           break;
   14427         2207 :         case OMP_CLAUSE_DEPEND:
   14428         2207 :           if (handled_depend_iterators == -1)
   14429         1905 :             handled_depend_iterators = gimplify_omp_depend (list_p, pre_p);
   14430         2207 :           if (handled_depend_iterators)
   14431              :             {
   14432          348 :               if (handled_depend_iterators == 2)
   14433            0 :                 remove = true;
   14434              :               break;
   14435              :             }
   14436         1859 :           if (TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPOUND_EXPR)
   14437              :             {
   14438            0 :               gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (c), 0), pre_p,
   14439              :                              NULL, is_gimple_val, fb_rvalue);
   14440            0 :               OMP_CLAUSE_DECL (c) = TREE_OPERAND (OMP_CLAUSE_DECL (c), 1);
   14441              :             }
   14442         1859 :           if (error_operand_p (OMP_CLAUSE_DECL (c)))
   14443              :             {
   14444              :               remove = true;
   14445              :               break;
   14446              :             }
   14447         1859 :           if (OMP_CLAUSE_DECL (c) != null_pointer_node)
   14448              :             {
   14449         1828 :               OMP_CLAUSE_DECL (c) = build_fold_addr_expr (OMP_CLAUSE_DECL (c));
   14450         1828 :               if (gimplify_expr (&OMP_CLAUSE_DECL (c), pre_p, NULL,
   14451              :                                  is_gimple_val, fb_rvalue) == GS_ERROR)
   14452              :                 {
   14453              :                   remove = true;
   14454              :                   break;
   14455              :                 }
   14456              :             }
   14457         1859 :           if (code == OMP_TASK)
   14458         1401 :             ctx->has_depend = true;
   14459              :           break;
   14460              : 
   14461         8383 :         case OMP_CLAUSE_TO:
   14462         8383 :         case OMP_CLAUSE_FROM:
   14463         8383 :         case OMP_CLAUSE__CACHE_:
   14464         8383 :           decl = OMP_CLAUSE_DECL (c);
   14465         8383 :           if (error_operand_p (decl))
   14466              :             {
   14467              :               remove = true;
   14468              :               break;
   14469              :             }
   14470         8383 :           if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
   14471         7682 :             OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
   14472          800 :                                   : TYPE_SIZE_UNIT (TREE_TYPE (decl));
   14473         8383 :           gimple_seq *seq_p;
   14474         8383 :           seq_p = enter_omp_iterator_loop_context (c, loops_seq_p, pre_p);
   14475         8383 :           if (gimplify_expr (&OMP_CLAUSE_SIZE (c), seq_p, NULL,
   14476              :                              is_gimple_val, fb_rvalue) == GS_ERROR)
   14477              :             {
   14478            0 :               remove = true;
   14479            0 :               exit_omp_iterator_loop_context (c);
   14480            0 :               break;
   14481              :             }
   14482         8383 :           if (!DECL_P (decl))
   14483              :             {
   14484         2180 :               if (gimplify_expr (&OMP_CLAUSE_DECL (c), seq_p, NULL,
   14485              :                                  is_gimple_lvalue, fb_lvalue) == GS_ERROR)
   14486            0 :                 remove = true;
   14487         2180 :               exit_omp_iterator_loop_context (c);
   14488         2180 :               break;
   14489              :             }
   14490         6203 :           exit_omp_iterator_loop_context (c);
   14491         6203 :           goto do_notice;
   14492              : 
   14493          135 :         case OMP_CLAUSE__MAPPER_BINDING_:
   14494          135 :           {
   14495          135 :             tree name = OMP_CLAUSE__MAPPER_BINDING__ID (c);
   14496          135 :             tree var = OMP_CLAUSE__MAPPER_BINDING__DECL (c);
   14497          135 :             tree type = TYPE_MAIN_VARIANT (TREE_TYPE (var));
   14498          135 :             tree fndecl = OMP_CLAUSE__MAPPER_BINDING__MAPPER (c);
   14499          135 :             ctx->implicit_mappers->put ({ name, type }, fndecl);
   14500          135 :             remove = true;
   14501          135 :             break;
   14502              :           }
   14503              : 
   14504         2118 :         case OMP_CLAUSE_USE_DEVICE_PTR:
   14505         2118 :         case OMP_CLAUSE_USE_DEVICE_ADDR:
   14506         2118 :           flags = GOVD_EXPLICIT;
   14507         2118 :           goto do_add;
   14508              : 
   14509          558 :         case OMP_CLAUSE_HAS_DEVICE_ADDR:
   14510          558 :           decl = OMP_CLAUSE_DECL (c);
   14511          558 :           while (TREE_CODE (decl) == INDIRECT_REF
   14512          607 :                  || TREE_CODE (decl) == ARRAY_REF)
   14513           49 :             decl = TREE_OPERAND (decl, 0);
   14514          558 :           flags = GOVD_EXPLICIT;
   14515          558 :           goto do_add_decl;
   14516              : 
   14517          500 :         case OMP_CLAUSE_IS_DEVICE_PTR:
   14518          500 :           flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
   14519          500 :           goto do_add;
   14520              : 
   14521        63328 :         do_add:
   14522        63328 :           decl = OMP_CLAUSE_DECL (c);
   14523        84711 :         do_add_decl:
   14524        84711 :           if (error_operand_p (decl))
   14525              :             {
   14526              :               remove = true;
   14527              :               break;
   14528              :             }
   14529        84703 :           if (DECL_NAME (decl) == NULL_TREE && (flags & GOVD_SHARED) == 0)
   14530              :             {
   14531         1755 :               tree t = omp_member_access_dummy_var (decl);
   14532         1755 :               if (t)
   14533              :                 {
   14534          668 :                   tree v = DECL_VALUE_EXPR (decl);
   14535          668 :                   DECL_NAME (decl) = DECL_NAME (TREE_OPERAND (v, 1));
   14536          668 :                   if (outer_ctx)
   14537          140 :                     omp_notice_variable (outer_ctx, t, true);
   14538              :                 }
   14539              :             }
   14540        84703 :           if (code == OACC_DATA
   14541         2402 :               && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   14542        87105 :               && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
   14543          307 :             flags |= GOVD_MAP_0LEN_ARRAY;
   14544        84703 :           omp_add_variable (ctx, decl, flags);
   14545        84703 :           if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   14546        69319 :                || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
   14547        67245 :                || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
   14548        87307 :               && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
   14549              :             {
   14550         2106 :               struct gimplify_omp_ctx *pctx
   14551         2166 :                 = code == OMP_TARGET ? outer_ctx : ctx;
   14552         2166 :               if (pctx)
   14553         2136 :                 omp_add_variable (pctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
   14554              :                                   GOVD_LOCAL | GOVD_SEEN);
   14555         2136 :               if (pctx
   14556         2136 :                   && OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
   14557          632 :                   && walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
   14558              :                                 find_decl_expr,
   14559              :                                 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
   14560              :                                 NULL) == NULL_TREE)
   14561          208 :                 omp_add_variable (pctx,
   14562          208 :                                   OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
   14563              :                                   GOVD_LOCAL | GOVD_SEEN);
   14564         2166 :               gimplify_omp_ctxp = pctx;
   14565         2166 :               push_gimplify_context ();
   14566              : 
   14567         2166 :               OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
   14568         2166 :               OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
   14569              : 
   14570         2166 :               gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
   14571         2166 :                                 &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
   14572         2166 :               pop_gimplify_context
   14573         2166 :                 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
   14574         2166 :               push_gimplify_context ();
   14575         4332 :               gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
   14576         2166 :                                 &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
   14577         2166 :               pop_gimplify_context
   14578         2166 :                 (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
   14579         2166 :               OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
   14580         2166 :               OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
   14581              : 
   14582         2166 :               gimplify_omp_ctxp = outer_ctx;
   14583              :             }
   14584        82537 :           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   14585        82537 :                    && OMP_CLAUSE_LASTPRIVATE_STMT (c))
   14586              :             {
   14587          303 :               gimplify_omp_ctxp = ctx;
   14588          303 :               push_gimplify_context ();
   14589          303 :               if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
   14590              :                 {
   14591          303 :                   tree bind = build3 (BIND_EXPR, void_type_node, NULL,
   14592              :                                       NULL, NULL);
   14593          303 :                   TREE_SIDE_EFFECTS (bind) = 1;
   14594          303 :                   BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
   14595          303 :                   OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
   14596              :                 }
   14597          606 :               gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
   14598          303 :                                 &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
   14599          303 :               pop_gimplify_context
   14600          303 :                 (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
   14601          303 :               OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
   14602              : 
   14603          303 :               gimplify_omp_ctxp = outer_ctx;
   14604              :             }
   14605        82234 :           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   14606        82234 :                    && OMP_CLAUSE_LINEAR_STMT (c))
   14607              :             {
   14608           60 :               gimplify_omp_ctxp = ctx;
   14609           60 :               push_gimplify_context ();
   14610           60 :               if (TREE_CODE (OMP_CLAUSE_LINEAR_STMT (c)) != BIND_EXPR)
   14611              :                 {
   14612           60 :                   tree bind = build3 (BIND_EXPR, void_type_node, NULL,
   14613              :                                       NULL, NULL);
   14614           60 :                   TREE_SIDE_EFFECTS (bind) = 1;
   14615           60 :                   BIND_EXPR_BODY (bind) = OMP_CLAUSE_LINEAR_STMT (c);
   14616           60 :                   OMP_CLAUSE_LINEAR_STMT (c) = bind;
   14617              :                 }
   14618          120 :               gimplify_and_add (OMP_CLAUSE_LINEAR_STMT (c),
   14619           60 :                                 &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
   14620           60 :               pop_gimplify_context
   14621           60 :                 (gimple_seq_first_stmt (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c)));
   14622           60 :               OMP_CLAUSE_LINEAR_STMT (c) = NULL_TREE;
   14623              : 
   14624           60 :               gimplify_omp_ctxp = outer_ctx;
   14625              :             }
   14626        84703 :           if (notice_outer)
   14627        72555 :             goto do_notice;
   14628              :           break;
   14629              : 
   14630          910 :         case OMP_CLAUSE_COPYIN:
   14631          910 :         case OMP_CLAUSE_COPYPRIVATE:
   14632          910 :           decl = OMP_CLAUSE_DECL (c);
   14633          910 :           if (error_operand_p (decl))
   14634              :             {
   14635              :               remove = true;
   14636              :               break;
   14637              :             }
   14638          910 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE
   14639              :               && !remove
   14640          910 :               && !omp_check_private (ctx, decl, true))
   14641              :             {
   14642           35 :               remove = true;
   14643           35 :               if (is_global_var (decl))
   14644              :                 {
   14645           30 :                   if (DECL_THREAD_LOCAL_P (decl))
   14646              :                     remove = false;
   14647           10 :                   else if (DECL_HAS_VALUE_EXPR_P (decl))
   14648              :                     {
   14649            2 :                       tree value = get_base_address (DECL_VALUE_EXPR (decl));
   14650              : 
   14651            2 :                       if (value
   14652            2 :                           && DECL_P (value)
   14653            4 :                           && DECL_THREAD_LOCAL_P (value))
   14654              :                         remove = false;
   14655              :                     }
   14656              :                 }
   14657              :               if (remove)
   14658           13 :                 error_at (OMP_CLAUSE_LOCATION (c),
   14659              :                           "copyprivate variable %qE is not threadprivate"
   14660           13 :                           " or private in outer context", DECL_NAME (decl));
   14661              :             }
   14662        79668 :         do_notice:
   14663        79668 :           if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   14664        64284 :                || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
   14665        56225 :                || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
   14666        30781 :               && outer_ctx
   14667        17632 :               && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
   14668        16293 :                    || (region_type == ORT_WORKSHARE
   14669         3909 :                        && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   14670         1111 :                        && (OMP_CLAUSE_REDUCTION_INSCAN (c)
   14671          928 :                            || code == OMP_LOOP)))
   14672        81621 :               && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
   14673          857 :                   || (code == OMP_LOOP
   14674          138 :                       && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   14675          138 :                       && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
   14676              :                           == ORT_COMBINED_TEAMS))))
   14677              :             {
   14678         1217 :               splay_tree_node on
   14679         1217 :                 = splay_tree_lookup (outer_ctx->variables,
   14680              :                                      (splay_tree_key)decl);
   14681         1217 :               if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
   14682              :                 {
   14683          899 :                   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   14684          713 :                       && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
   14685         1011 :                       && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
   14686           56 :                           || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
   14687            0 :                               && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
   14688              :                                   == POINTER_TYPE))))
   14689           56 :                     omp_firstprivatize_variable (outer_ctx, decl);
   14690              :                   else
   14691              :                     {
   14692          843 :                       omp_add_variable (outer_ctx, decl,
   14693              :                                         GOVD_SEEN | GOVD_SHARED);
   14694          843 :                       if (outer_ctx->outer_context)
   14695          235 :                         omp_notice_variable (outer_ctx->outer_context, decl,
   14696              :                                              true);
   14697              :                     }
   14698              :                 }
   14699              :             }
   14700        79060 :           if (outer_ctx)
   14701        29677 :             omp_notice_variable (outer_ctx, decl, true);
   14702        79668 :           if (check_non_private
   14703        26985 :               && (region_type == ORT_WORKSHARE || code == OMP_SCOPE)
   14704         4804 :               && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
   14705         1689 :                   || decl == OMP_CLAUSE_DECL (c)
   14706          224 :                   || (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
   14707          224 :                       && (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
   14708              :                           == ADDR_EXPR
   14709          103 :                           || (TREE_CODE (TREE_OPERAND (OMP_CLAUSE_DECL (c), 0))
   14710              :                               == POINTER_PLUS_EXPR
   14711           22 :                               && (TREE_CODE (TREE_OPERAND (TREE_OPERAND
   14712              :                                                 (OMP_CLAUSE_DECL (c), 0), 0))
   14713              :                                   == ADDR_EXPR)))))
   14714        84384 :               && omp_check_private (ctx, decl, false))
   14715              :             {
   14716           58 :               error ("%s variable %qE is private in outer context",
   14717           29 :                      check_non_private, DECL_NAME (decl));
   14718           29 :               remove = true;
   14719              :             }
   14720              :           break;
   14721              : 
   14722          190 :         case OMP_CLAUSE_DETACH:
   14723          190 :           flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
   14724          190 :           goto do_add;
   14725              : 
   14726         4114 :         case OMP_CLAUSE_IF:
   14727         4114 :           if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
   14728         4114 :               && OMP_CLAUSE_IF_MODIFIER (c) != code)
   14729              :             {
   14730              :               const char *p[2];
   14731          168 :               for (int i = 0; i < 2; i++)
   14732          112 :                 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
   14733              :                   {
   14734            8 :                   case VOID_CST: p[i] = "cancel"; break;
   14735           24 :                   case OMP_PARALLEL: p[i] = "parallel"; break;
   14736            4 :                   case OMP_SIMD: p[i] = "simd"; break;
   14737           12 :                   case OMP_TASK: p[i] = "task"; break;
   14738           12 :                   case OMP_TASKLOOP: p[i] = "taskloop"; break;
   14739            8 :                   case OMP_TARGET_DATA: p[i] = "target data"; break;
   14740           12 :                   case OMP_TARGET: p[i] = "target"; break;
   14741           12 :                   case OMP_TARGET_UPDATE: p[i] = "target update"; break;
   14742            8 :                   case OMP_TARGET_ENTER_DATA:
   14743            8 :                     p[i] = "target enter data"; break;
   14744           12 :                   case OMP_TARGET_EXIT_DATA: p[i] = "target exit data"; break;
   14745            0 :                   default: gcc_unreachable ();
   14746              :                   }
   14747           56 :               error_at (OMP_CLAUSE_LOCATION (c),
   14748              :                         "expected %qs %<if%> clause modifier rather than %qs",
   14749              :                         p[0], p[1]);
   14750           56 :               remove = true;
   14751              :             }
   14752              :           /* Fall through.  */
   14753              : 
   14754         4824 :         case OMP_CLAUSE_SELF:
   14755         4824 :         case OMP_CLAUSE_FINAL:
   14756         4824 :           OMP_CLAUSE_OPERAND (c, 0)
   14757         9648 :             = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
   14758              :           /* Fall through.  */
   14759              : 
   14760         5753 :         case OMP_CLAUSE_NUM_TEAMS:
   14761         5753 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
   14762          929 :               && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
   14763         5977 :               && !is_gimple_min_invariant (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
   14764              :             {
   14765          194 :               if (error_operand_p (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)))
   14766              :                 {
   14767              :                   remove = true;
   14768              :                   break;
   14769              :                 }
   14770          194 :               OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
   14771          388 :                 = get_initialized_tmp_var (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c),
   14772              :                                            pre_p, NULL, true);
   14773              :             }
   14774              :           /* Fall through.  */
   14775              : 
   14776        21960 :         case OMP_CLAUSE_SCHEDULE:
   14777        21960 :         case OMP_CLAUSE_NUM_THREADS:
   14778        21960 :         case OMP_CLAUSE_THREAD_LIMIT:
   14779        21960 :         case OMP_CLAUSE_DIST_SCHEDULE:
   14780        21960 :         case OMP_CLAUSE_DEVICE:
   14781        21960 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE
   14782        21960 :               && OMP_CLAUSE_DEVICE_ANCESTOR (c))
   14783              :             {
   14784          125 :               if (code != OMP_TARGET)
   14785              :                 {
   14786           20 :                   error_at (OMP_CLAUSE_LOCATION (c),
   14787              :                             "%<device%> clause with %<ancestor%> is only "
   14788              :                             "allowed on %<target%> construct");
   14789           20 :                   remove = true;
   14790           20 :                   break;
   14791              :                 }
   14792              : 
   14793          105 :               tree clauses = *orig_list_p;
   14794          330 :               for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
   14795          236 :                 if (OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEVICE
   14796              :                     && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_FIRSTPRIVATE
   14797              :                     && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_PRIVATE
   14798              :                     && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_DEFAULTMAP
   14799              :                     && OMP_CLAUSE_CODE (clauses) != OMP_CLAUSE_MAP
   14800              :                    )
   14801              :                   {
   14802           11 :                     error_at (OMP_CLAUSE_LOCATION (c),
   14803              :                               "with %<ancestor%>, only the %<device%>, "
   14804              :                               "%<firstprivate%>, %<private%>, %<defaultmap%>, "
   14805              :                               "and %<map%> clauses may appear on the "
   14806              :                               "construct");
   14807           11 :                     remove = true;
   14808           11 :                     break;
   14809              :                   }
   14810              :             }
   14811        21835 :           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE
   14812        21835 :                    && code == OMP_DISPATCH)
   14813              :             {
   14814          272 :               bool saved_into_ssa = gimplify_ctxp->into_ssa;
   14815          272 :               gimplify_ctxp->into_ssa = false;
   14816          272 :               if (gimplify_expr (&OMP_CLAUSE_DEVICE_ID (c), pre_p, NULL,
   14817              :                                  is_gimple_val, fb_rvalue)
   14818              :                   == GS_ERROR)
   14819              :                 remove = true;
   14820          272 :               else if (DECL_P (OMP_CLAUSE_DEVICE_ID (c)))
   14821           55 :                 omp_add_variable (ctx, OMP_CLAUSE_DEVICE_ID (c),
   14822              :                                   GOVD_SHARED | GOVD_SEEN);
   14823          272 :               gimplify_ctxp->into_ssa = saved_into_ssa;
   14824          272 :               break;
   14825              :             }
   14826              :           /* Fall through.  */
   14827              : 
   14828        31414 :         case OMP_CLAUSE_PRIORITY:
   14829        31414 :         case OMP_CLAUSE_GRAINSIZE:
   14830        31414 :         case OMP_CLAUSE_NUM_TASKS:
   14831        31414 :         case OMP_CLAUSE_FILTER:
   14832        31414 :         case OMP_CLAUSE_HINT:
   14833        31414 :         case OMP_CLAUSE_ASYNC:
   14834        31414 :         case OMP_CLAUSE_WAIT:
   14835        31414 :         case OMP_CLAUSE_NUM_GANGS:
   14836        31414 :         case OMP_CLAUSE_NUM_WORKERS:
   14837        31414 :         case OMP_CLAUSE_VECTOR_LENGTH:
   14838        31414 :         case OMP_CLAUSE_WORKER:
   14839        31414 :         case OMP_CLAUSE_VECTOR:
   14840        31414 :           if (OMP_CLAUSE_OPERAND (c, 0)
   14841        31414 :               && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) == TREE_LIST)
   14842              :             {
   14843         2604 :               for (tree t = OMP_CLAUSE_OPERAND (c, 0); t; t = TREE_CHAIN (t))
   14844         1346 :                 if (!is_gimple_min_invariant (TREE_VALUE (t)))
   14845              :                   {
   14846          280 :                     if (error_operand_p (TREE_VALUE (t)))
   14847              :                       {
   14848              :                         remove = true;
   14849              :                         break;
   14850              :                       }
   14851          560 :                     TREE_VALUE (t)
   14852          280 :                       = get_initialized_tmp_var (TREE_VALUE (t), pre_p,
   14853              :                                                  NULL, true);
   14854              :                   }
   14855              :             }
   14856        30156 :           else if (OMP_CLAUSE_OPERAND (c, 0)
   14857        30156 :                    && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0)))
   14858              :             {
   14859         7503 :               if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0)))
   14860              :                 {
   14861              :                   remove = true;
   14862              :                   break;
   14863              :                 }
   14864              :               /* All these clauses care about value, not a particular decl,
   14865              :                  so try to force it into a SSA_NAME or fresh temporary.  */
   14866         7496 :               OMP_CLAUSE_OPERAND (c, 0)
   14867        14992 :                 = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0),
   14868              :                                            pre_p, NULL, true);
   14869              :             }
   14870              :           break;
   14871              : 
   14872         2332 :         case OMP_CLAUSE_GANG:
   14873         2332 :           if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
   14874              :                              is_gimple_val, fb_rvalue) == GS_ERROR)
   14875            0 :             remove = true;
   14876         2332 :           if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 1), pre_p, NULL,
   14877              :                              is_gimple_val, fb_rvalue) == GS_ERROR)
   14878            0 :             remove = true;
   14879              :           break;
   14880              : 
   14881        13147 :         case OMP_CLAUSE_NOWAIT:
   14882        13147 :           nowait = 1;
   14883        13147 :           break;
   14884              : 
   14885          116 :         case OMP_CLAUSE_USES_ALLOCATORS:
   14886          116 :           if (TREE_CODE (OMP_CLAUSE_USES_ALLOCATORS_ALLOCATOR (c))
   14887              :               != INTEGER_CST)
   14888              :             {
   14889          112 :               decl = OMP_CLAUSE_USES_ALLOCATORS_ALLOCATOR (c);
   14890          112 :               omp_add_variable (ctx, decl,
   14891              :                                 GOVD_SEEN | GOVD_USES_ALLOCATORS_ALLOCATOR);
   14892              :             }
   14893              :           else
   14894              :             remove = true;
   14895              :           break;
   14896              : 
   14897              :         case OMP_CLAUSE_ORDERED:
   14898              :         case OMP_CLAUSE_UNTIED:
   14899              :         case OMP_CLAUSE_COLLAPSE:
   14900              :         case OMP_CLAUSE_TILE:
   14901              :         case OMP_CLAUSE_AUTO:
   14902              :         case OMP_CLAUSE_SEQ:
   14903              :         case OMP_CLAUSE_INDEPENDENT:
   14904              :         case OMP_CLAUSE_MERGEABLE:
   14905              :         case OMP_CLAUSE_MESSAGE:
   14906              :         case OMP_CLAUSE_PROC_BIND:
   14907              :         case OMP_CLAUSE_SAFELEN:
   14908              :         case OMP_CLAUSE_NOGROUP:
   14909              :         case OMP_CLAUSE_THREADS:
   14910              :         case OMP_CLAUSE_SIMD:
   14911              :         case OMP_CLAUSE_BIND:
   14912              :         case OMP_CLAUSE_IF_PRESENT:
   14913              :         case OMP_CLAUSE_FINALIZE:
   14914              :         case OMP_CLAUSE_INTEROP:
   14915              :         case OMP_CLAUSE_INIT:
   14916              :         case OMP_CLAUSE_USE:
   14917              :         case OMP_CLAUSE_DESTROY:
   14918              :         case OMP_CLAUSE_DEVICE_TYPE:
   14919              :           break;
   14920              : 
   14921          672 :         case OMP_CLAUSE_SIMDLEN:
   14922          672 :           if (OMP_CLAUSE_SIMDLEN_TYPE (c))
   14923              :             {
   14924           30 :               remove = true;
   14925           30 :               sorry_at (OMP_CLAUSE_LOCATION (c),
   14926              :                         "%<simdlen%> clause with %<scaled%> modifier");
   14927              :             }
   14928              :           break;
   14929              : 
   14930           56 :         case OMP_CLAUSE_DYN_GROUPPRIVATE:
   14931           56 :           remove = true;
   14932           56 :           sorry_at (OMP_CLAUSE_LOCATION (c),"%<dyn_groupprivate%> clause");
   14933           56 :           break;
   14934              : 
   14935         3976 :         case OMP_CLAUSE_ORDER:
   14936         3976 :           ctx->order_concurrent = true;
   14937         3976 :           break;
   14938              : 
   14939         1017 :         case OMP_CLAUSE_DEFAULTMAP:
   14940         1017 :           enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
   14941         1017 :           switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
   14942              :             {
   14943              :             case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
   14944              :             case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL:
   14945              :               gdmkmin = GDMK_SCALAR;
   14946              :               gdmkmax = GDMK_POINTER;
   14947              :               break;
   14948              :             case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
   14949              :               gdmkmin = GDMK_SCALAR;
   14950              :               gdmkmax = GDMK_SCALAR_TARGET;
   14951              :               break;
   14952              :             case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
   14953              :               gdmkmin = gdmkmax = GDMK_AGGREGATE;
   14954              :               break;
   14955              :             case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
   14956              :               gdmkmin = gdmkmax = GDMK_ALLOCATABLE;
   14957              :               break;
   14958              :             case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
   14959              :               gdmkmin = gdmkmax = GDMK_POINTER;
   14960              :               break;
   14961            0 :             default:
   14962            0 :               gcc_unreachable ();
   14963              :             }
   14964         4513 :           for (int gdmk = gdmkmin; gdmk <= gdmkmax; gdmk++)
   14965         3496 :             switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (c))
   14966              :               {
   14967           91 :               case OMP_CLAUSE_DEFAULTMAP_ALLOC:
   14968           91 :                 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_ALLOC_ONLY;
   14969           91 :                 break;
   14970           96 :               case OMP_CLAUSE_DEFAULTMAP_TO:
   14971           96 :                 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_TO_ONLY;
   14972           96 :                 break;
   14973           28 :               case OMP_CLAUSE_DEFAULTMAP_FROM:
   14974           28 :                 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FROM_ONLY;
   14975           28 :                 break;
   14976          671 :               case OMP_CLAUSE_DEFAULTMAP_TOFROM:
   14977          671 :                 ctx->defaultmap[gdmk] = GOVD_MAP;
   14978          671 :                 break;
   14979          380 :               case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
   14980          380 :                 ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
   14981          380 :                 break;
   14982         2129 :               case OMP_CLAUSE_DEFAULTMAP_NONE:
   14983         2129 :                 ctx->defaultmap[gdmk] = 0;
   14984         2129 :                 break;
   14985           45 :               case OMP_CLAUSE_DEFAULTMAP_PRESENT:
   14986           45 :                 ctx->defaultmap[gdmk] = GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
   14987           45 :                 break;
   14988           56 :               case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
   14989           56 :                 switch (gdmk)
   14990              :                   {
   14991           11 :                   case GDMK_SCALAR:
   14992           11 :                     ctx->defaultmap[gdmk] = GOVD_FIRSTPRIVATE;
   14993           11 :                     break;
   14994           11 :                   case GDMK_SCALAR_TARGET:
   14995           11 :                     ctx->defaultmap[gdmk] = (lang_GNU_Fortran ()
   14996           11 :                                              ? GOVD_MAP : GOVD_FIRSTPRIVATE);
   14997           11 :                     break;
   14998           14 :                   case GDMK_AGGREGATE:
   14999           14 :                   case GDMK_ALLOCATABLE:
   15000           14 :                     ctx->defaultmap[gdmk] = GOVD_MAP;
   15001           14 :                     break;
   15002           20 :                   case GDMK_POINTER:
   15003           20 :                     ctx->defaultmap[gdmk] = GOVD_MAP;
   15004           20 :                     if (!lang_GNU_Fortran ())
   15005           12 :                       ctx->defaultmap[gdmk] |= GOVD_MAP_0LEN_ARRAY;
   15006              :                     break;
   15007              :                   default:
   15008              :                     gcc_unreachable ();
   15009              :                   }
   15010              :                 break;
   15011            0 :               default:
   15012            0 :                 gcc_unreachable ();
   15013              :               }
   15014              :           break;
   15015              : 
   15016          824 :         case OMP_CLAUSE_ALIGNED:
   15017          824 :           decl = OMP_CLAUSE_DECL (c);
   15018          824 :           if (error_operand_p (decl))
   15019              :             {
   15020              :               remove = true;
   15021              :               break;
   15022              :             }
   15023          824 :           if (gimplify_expr (&OMP_CLAUSE_ALIGNED_ALIGNMENT (c), pre_p, NULL,
   15024              :                              is_gimple_val, fb_rvalue) == GS_ERROR)
   15025              :             {
   15026              :               remove = true;
   15027              :               break;
   15028              :             }
   15029          824 :           if (!is_global_var (decl)
   15030          824 :               && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
   15031          592 :             omp_add_variable (ctx, decl, GOVD_ALIGNED);
   15032              :           break;
   15033              : 
   15034          489 :         case OMP_CLAUSE_NONTEMPORAL:
   15035          489 :           decl = OMP_CLAUSE_DECL (c);
   15036          489 :           if (error_operand_p (decl))
   15037              :             {
   15038              :               remove = true;
   15039              :               break;
   15040              :             }
   15041          489 :           omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
   15042          489 :           break;
   15043              : 
   15044         3691 :         case OMP_CLAUSE_ALLOCATE:
   15045         3691 :           decl = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
   15046         3691 :           if (decl
   15047         1722 :               && TREE_CODE (decl) == INTEGER_CST
   15048         3720 :               && wi::eq_p (wi::to_widest (decl), GOMP_OMP_PREDEF_ALLOC_THREAD)
   15049         3720 :               && (code == OMP_TARGET || code == OMP_TASK || code == OMP_TASKLOOP))
   15050           35 :             warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
   15051              :                         "allocator with access trait set to %<thread%> "
   15052              :                         "results in undefined behavior for %qs directive",
   15053              :                         code == OMP_TARGET ? "target"
   15054              :                                            : (code == OMP_TASK
   15055           15 :                                               ? "task" : "taskloop"));
   15056         3691 :           decl = OMP_CLAUSE_DECL (c);
   15057         3691 :           if (error_operand_p (decl))
   15058              :             {
   15059              :               remove = true;
   15060              :               break;
   15061              :             }
   15062         3691 :           if ((omp_requires_mask & OMP_REQUIRES_DYNAMIC_ALLOCATORS) == 0
   15063         3679 :               && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
   15064         5413 :               && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST)
   15065              :             {
   15066          521 :               tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
   15067          521 :               tree clauses = NULL_TREE;
   15068              : 
   15069              :               /* Get clause list of the nearest enclosing target construct.  */
   15070          521 :               if (ctx->code == OMP_TARGET)
   15071           14 :                 clauses = *orig_list_p;
   15072              :               else
   15073              :                 {
   15074          507 :                   struct gimplify_omp_ctx *tctx = ctx->outer_context;
   15075          826 :                   while (tctx && tctx->code != OMP_TARGET)
   15076          319 :                     tctx = tctx->outer_context;
   15077          507 :                   if (tctx)
   15078           18 :                     clauses = tctx->clauses;
   15079              :                 }
   15080              : 
   15081           32 :               if (clauses)
   15082              :                 {
   15083           30 :                   tree uc;
   15084           30 :                   if (TREE_CODE (allocator) == MEM_REF
   15085           30 :                       || TREE_CODE (allocator) == INDIRECT_REF)
   15086            0 :                     allocator = TREE_OPERAND (allocator, 0);
   15087          132 :                   for (uc = clauses; uc; uc = OMP_CLAUSE_CHAIN (uc))
   15088          123 :                     if (OMP_CLAUSE_CODE (uc) == OMP_CLAUSE_USES_ALLOCATORS)
   15089              :                       {
   15090           29 :                         tree uc_allocator
   15091           29 :                           = OMP_CLAUSE_USES_ALLOCATORS_ALLOCATOR (uc);
   15092           29 :                         if (operand_equal_p (allocator, uc_allocator))
   15093              :                           break;
   15094              :                       }
   15095           30 :                   if (uc == NULL_TREE)
   15096              :                     {
   15097            9 :                       error_at (OMP_CLAUSE_LOCATION (c), "allocator %qE "
   15098              :                                 "requires %<uses_allocators(%E)%> clause in "
   15099              :                                 "target region", allocator, allocator);
   15100            9 :                       remove = true;
   15101            9 :                       break;
   15102              :                     }
   15103              :                 }
   15104              :             }
   15105         3682 :           if (gimplify_expr (&OMP_CLAUSE_ALLOCATE_ALLOCATOR (c), pre_p, NULL,
   15106              :                              is_gimple_val, fb_rvalue) == GS_ERROR)
   15107              :             {
   15108              :               remove = true;
   15109              :               break;
   15110              :             }
   15111         3682 :           else if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) == NULL_TREE
   15112         3682 :                    || (TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c))
   15113              :                        == INTEGER_CST))
   15114              :             ;
   15115          512 :           else if (code == OMP_TASKLOOP
   15116          512 :                    || !DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
   15117           66 :             OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
   15118          132 :               = get_initialized_tmp_var (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
   15119              :                                          pre_p, NULL, false);
   15120              :           break;
   15121              : 
   15122         4365 :         case OMP_CLAUSE_DEFAULT:
   15123         4365 :           ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
   15124         4365 :           break;
   15125              : 
   15126          652 :         case OMP_CLAUSE_INCLUSIVE:
   15127          652 :         case OMP_CLAUSE_EXCLUSIVE:
   15128          652 :           decl = OMP_CLAUSE_DECL (c);
   15129          652 :           {
   15130          652 :             splay_tree_node n = splay_tree_lookup (outer_ctx->variables,
   15131              :                                                    (splay_tree_key) decl);
   15132          652 :             if (n == NULL || (n->value & GOVD_REDUCTION) == 0)
   15133              :               {
   15134            5 :                 error_at (OMP_CLAUSE_LOCATION (c),
   15135              :                           "%qD specified in %qs clause but not in %<inscan%> "
   15136              :                           "%<reduction%> clause on the containing construct",
   15137            5 :                           decl, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
   15138            5 :                 remove = true;
   15139              :               }
   15140              :             else
   15141              :               {
   15142          647 :                 n->value |= GOVD_REDUCTION_INSCAN;
   15143          647 :                 if (outer_ctx->region_type == ORT_SIMD
   15144          528 :                     && outer_ctx->outer_context
   15145          115 :                     && outer_ctx->outer_context->region_type == ORT_WORKSHARE)
   15146              :                   {
   15147          115 :                     n = splay_tree_lookup (outer_ctx->outer_context->variables,
   15148              :                                            (splay_tree_key) decl);
   15149          115 :                     if (n && (n->value & GOVD_REDUCTION) != 0)
   15150          115 :                       n->value |= GOVD_REDUCTION_INSCAN;
   15151              :                   }
   15152              :               }
   15153              :           }
   15154              :           break;
   15155              : 
   15156          103 :         case OMP_CLAUSE_NOVARIANTS:
   15157          103 :           OMP_CLAUSE_NOVARIANTS_EXPR (c)
   15158          103 :             = gimple_boolify (OMP_CLAUSE_NOVARIANTS_EXPR (c));
   15159          103 :           break;
   15160          115 :         case OMP_CLAUSE_NOCONTEXT:
   15161          115 :           OMP_CLAUSE_NOCONTEXT_EXPR (c)
   15162          115 :             = gimple_boolify (OMP_CLAUSE_NOCONTEXT_EXPR (c));
   15163          115 :           break;
   15164            0 :         case OMP_CLAUSE_NOHOST:
   15165            0 :         default:
   15166            0 :           gcc_unreachable ();
   15167              :         }
   15168              : 
   15169       206567 :       if (code == OACC_DATA
   15170         5123 :           && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
   15171       211378 :           && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   15172         4504 :               || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   15173              :         remove = true;
   15174       206260 :       if (remove)
   15175         1216 :         *list_p = OMP_CLAUSE_CHAIN (c);
   15176              :       else
   15177       205351 :         list_p = &OMP_CLAUSE_CHAIN (c);
   15178       206567 :     }
   15179              : 
   15180       131616 :   if (groups)
   15181              :     {
   15182        36606 :       delete grpmap;
   15183        18303 :       delete groups;
   15184              :     }
   15185              : 
   15186       131616 :   ctx->clauses = *orig_list_p;
   15187       131616 :   gimplify_omp_ctxp = ctx;
   15188       131616 : }
   15189              : 
   15190              : /* Return true if DECL is a candidate for shared to firstprivate
   15191              :    optimization.  We only consider non-addressable scalars, not
   15192              :    too big, and not references.  */
   15193              : 
   15194              : static bool
   15195       406187 : omp_shared_to_firstprivate_optimizable_decl_p (tree decl)
   15196              : {
   15197       406187 :   if (TREE_ADDRESSABLE (decl))
   15198              :     return false;
   15199       357011 :   tree type = TREE_TYPE (decl);
   15200       357011 :   if (!is_gimple_reg_type (type)
   15201       332192 :       || TREE_CODE (type) == REFERENCE_TYPE
   15202       684894 :       || TREE_ADDRESSABLE (type))
   15203              :     return false;
   15204              :   /* Don't optimize too large decls, as each thread/task will have
   15205              :      its own.  */
   15206       327883 :   HOST_WIDE_INT len = int_size_in_bytes (type);
   15207       327883 :   if (len == -1 || len > 4 * POINTER_SIZE / BITS_PER_UNIT)
   15208              :     return false;
   15209       327866 :   if (omp_privatize_by_reference (decl))
   15210         1324 :     return false;
   15211              :   return true;
   15212              : }
   15213              : 
   15214              : /* Helper function of omp_find_stores_op and gimplify_adjust_omp_clauses*.
   15215              :    For omp_shared_to_firstprivate_optimizable_decl_p decl mark it as
   15216              :    GOVD_WRITTEN in outer contexts.  */
   15217              : 
   15218              : static void
   15219       304938 : omp_mark_stores (struct gimplify_omp_ctx *ctx, tree decl)
   15220              : {
   15221       467274 :   for (; ctx; ctx = ctx->outer_context)
   15222              :     {
   15223       450178 :       splay_tree_node n = splay_tree_lookup (ctx->variables,
   15224              :                                              (splay_tree_key) decl);
   15225       450178 :       if (n == NULL)
   15226       158755 :         continue;
   15227       291423 :       else if (n->value & GOVD_SHARED)
   15228              :         {
   15229         9171 :           n->value |= GOVD_WRITTEN;
   15230         9171 :           return;
   15231              :         }
   15232       282252 :       else if (n->value & GOVD_DATA_SHARE_CLASS)
   15233              :         return;
   15234              :     }
   15235              : }
   15236              : 
   15237              : /* Helper callback for walk_gimple_seq to discover possible stores
   15238              :    to omp_shared_to_firstprivate_optimizable_decl_p decls and set
   15239              :    GOVD_WRITTEN if they are GOVD_SHARED in some outer context
   15240              :    for those.  */
   15241              : 
   15242              : static tree
   15243      1131017 : omp_find_stores_op (tree *tp, int *walk_subtrees, void *data)
   15244              : {
   15245      1131017 :   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
   15246              : 
   15247      1131017 :   *walk_subtrees = 0;
   15248      1131017 :   if (!wi->is_lhs)
   15249              :     return NULL_TREE;
   15250              : 
   15251       322767 :   tree op = *tp;
   15252       401707 :   do
   15253              :     {
   15254       401707 :       if (handled_component_p (op))
   15255        78940 :         op = TREE_OPERAND (op, 0);
   15256       322767 :       else if ((TREE_CODE (op) == MEM_REF || TREE_CODE (op) == TARGET_MEM_REF)
   15257       322767 :                && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR)
   15258            0 :         op = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
   15259              :       else
   15260              :         break;
   15261              :     }
   15262              :   while (1);
   15263       322767 :   if (!DECL_P (op) || !omp_shared_to_firstprivate_optimizable_decl_p (op))
   15264              :     return NULL_TREE;
   15265              : 
   15266       264488 :   omp_mark_stores (gimplify_omp_ctxp, op);
   15267       264488 :   return NULL_TREE;
   15268              : }
   15269              : 
   15270              : /* Helper callback for walk_gimple_seq to discover possible stores
   15271              :    to omp_shared_to_firstprivate_optimizable_decl_p decls and set
   15272              :    GOVD_WRITTEN if they are GOVD_SHARED in some outer context
   15273              :    for those.  */
   15274              : 
   15275              : static tree
   15276       629103 : omp_find_stores_stmt (gimple_stmt_iterator *gsi_p,
   15277              :                       bool *handled_ops_p,
   15278              :                       struct walk_stmt_info *wi)
   15279              : {
   15280       629103 :   gimple *stmt = gsi_stmt (*gsi_p);
   15281       629103 :   switch (gimple_code (stmt))
   15282              :     {
   15283              :     /* Don't recurse on OpenMP constructs for which
   15284              :        gimplify_adjust_omp_clauses already handled the bodies,
   15285              :        except handle gimple_omp_for_pre_body.  */
   15286        26823 :     case GIMPLE_OMP_FOR:
   15287        26823 :       *handled_ops_p = true;
   15288        26823 :       if (gimple_omp_for_pre_body (stmt))
   15289         1782 :         walk_gimple_seq (gimple_omp_for_pre_body (stmt),
   15290              :                          omp_find_stores_stmt, omp_find_stores_op, wi);
   15291              :       break;
   15292         8630 :     case GIMPLE_OMP_PARALLEL:
   15293         8630 :     case GIMPLE_OMP_TASK:
   15294         8630 :     case GIMPLE_OMP_SECTIONS:
   15295         8630 :     case GIMPLE_OMP_SINGLE:
   15296         8630 :     case GIMPLE_OMP_SCOPE:
   15297         8630 :     case GIMPLE_OMP_TARGET:
   15298         8630 :     case GIMPLE_OMP_TEAMS:
   15299         8630 :     case GIMPLE_OMP_CRITICAL:
   15300         8630 :       *handled_ops_p = true;
   15301         8630 :       break;
   15302              :     default:
   15303              :       break;
   15304              :     }
   15305       629103 :   return NULL_TREE;
   15306              : }
   15307              : 
   15308              : struct gimplify_adjust_omp_clauses_data
   15309              : {
   15310              :   tree *list_p;
   15311              :   gimple_seq *pre_p;
   15312              : };
   15313              : 
   15314              : /* For all variables that were not actually used within the context,
   15315              :    remove PRIVATE, SHARED, and FIRSTPRIVATE clauses.  */
   15316              : 
   15317              : static int
   15318       678852 : gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
   15319              : {
   15320       678852 :   tree *list_p = ((struct gimplify_adjust_omp_clauses_data *) data)->list_p;
   15321       678852 :   gimple_seq *pre_p
   15322              :     = ((struct gimplify_adjust_omp_clauses_data *) data)->pre_p;
   15323       678852 :   tree decl = (tree) n->key;
   15324       678852 :   unsigned flags = n->value;
   15325       678852 :   enum omp_clause_code code;
   15326       678852 :   tree clause;
   15327       678852 :   bool private_debug;
   15328              : 
   15329       678852 :   if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
   15330       132957 :       && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
   15331              :     flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
   15332       678727 :   if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
   15333              :     return 0;
   15334       179161 :   if ((flags & GOVD_SEEN) == 0)
   15335              :     return 0;
   15336       158060 :   if (flags & GOVD_DEBUG_PRIVATE)
   15337              :     {
   15338          260 :       gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_SHARED);
   15339              :       private_debug = true;
   15340              :     }
   15341       157800 :   else if (flags & GOVD_MAP)
   15342              :     private_debug = false;
   15343              :   else
   15344       139599 :     private_debug
   15345       139599 :       = lang_hooks.decls.omp_private_debug_clause (decl,
   15346       139599 :                                                    !!(flags & GOVD_SHARED));
   15347       139599 :   if (private_debug)
   15348              :     code = OMP_CLAUSE_PRIVATE;
   15349       157678 :   else if (flags & GOVD_MAP)
   15350              :     {
   15351        18201 :       code = OMP_CLAUSE_MAP;
   15352        18201 :       if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0
   15353        18201 :           && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
   15354              :         {
   15355            2 :           error ("%<_Atomic%> %qD in implicit %<map%> clause", decl);
   15356            2 :           return 0;
   15357              :         }
   15358        18199 :       if (VAR_P (decl)
   15359        16257 :           && DECL_IN_CONSTANT_POOL (decl)
   15360        18200 :           && !lookup_attribute ("omp declare target",
   15361            1 :                                 DECL_ATTRIBUTES (decl)))
   15362              :         {
   15363            1 :           tree id = get_identifier ("omp declare target");
   15364            1 :           DECL_ATTRIBUTES (decl)
   15365            1 :             = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
   15366            1 :           varpool_node *node = varpool_node::get (decl);
   15367            1 :           if (node)
   15368              :             {
   15369            1 :               node->offloadable = 1;
   15370            1 :               if (ENABLE_OFFLOADING)
   15371              :                 g->have_offload = true;
   15372              :             }
   15373              :         }
   15374              :     }
   15375       139477 :   else if (flags & GOVD_SHARED)
   15376              :     {
   15377        49193 :       if (is_global_var (decl))
   15378              :         {
   15379        16144 :           struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
   15380        25331 :           while (ctx != NULL)
   15381              :             {
   15382        17604 :               splay_tree_node on
   15383        17604 :                 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   15384        17604 :               if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
   15385              :                                       | GOVD_PRIVATE | GOVD_REDUCTION
   15386              :                                       | GOVD_LINEAR | GOVD_MAP)) != 0)
   15387              :                 break;
   15388         9187 :               ctx = ctx->outer_context;
   15389              :             }
   15390        16144 :           if (ctx == NULL)
   15391              :             return 0;
   15392              :         }
   15393        41466 :       code = OMP_CLAUSE_SHARED;
   15394              :       /* Don't optimize shared into firstprivate for read-only vars
   15395              :          on tasks with depend clause, we shouldn't try to copy them
   15396              :          until the dependencies are satisfied.  */
   15397        41466 :       if (gimplify_omp_ctxp->has_depend)
   15398          350 :         flags |= GOVD_WRITTEN;
   15399              :     }
   15400        90284 :   else if (flags & GOVD_PRIVATE)
   15401              :     code = OMP_CLAUSE_PRIVATE;
   15402        31650 :   else if (flags & GOVD_FIRSTPRIVATE)
   15403              :     {
   15404        22132 :       code = OMP_CLAUSE_FIRSTPRIVATE;
   15405        22132 :       if ((gimplify_omp_ctxp->region_type & ORT_TARGET)
   15406        14037 :           && (gimplify_omp_ctxp->region_type & ORT_ACC) == 0
   15407        32488 :           && TYPE_ATOMIC (strip_array_types (TREE_TYPE (decl))))
   15408              :         {
   15409            1 :           error ("%<_Atomic%> %qD in implicit %<firstprivate%> clause on "
   15410              :                  "%<target%> construct", decl);
   15411            1 :           return 0;
   15412              :         }
   15413              :     }
   15414         9518 :   else if (flags & GOVD_LASTPRIVATE)
   15415              :     code = OMP_CLAUSE_LASTPRIVATE;
   15416          353 :   else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
   15417              :     return 0;
   15418          230 :   else if (flags & GOVD_CONDTEMP)
   15419              :     {
   15420          118 :       code = OMP_CLAUSE__CONDTEMP_;
   15421          118 :       gimple_add_tmp_var (decl);
   15422              :     }
   15423          112 :   else if (flags & GOVD_USES_ALLOCATORS_ALLOCATOR)
   15424              :     return 0;
   15425              :   else
   15426            0 :     gcc_unreachable ();
   15427              : 
   15428       140930 :   if (((flags & GOVD_LASTPRIVATE)
   15429       140240 :        || (code == OMP_CLAUSE_SHARED && (flags & GOVD_WRITTEN)))
   15430       156197 :       && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   15431        15253 :     omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
   15432              : 
   15433       150095 :   tree chain = *list_p;
   15434       150095 :   clause = build_omp_clause (input_location, code);
   15435       150095 :   OMP_CLAUSE_DECL (clause) = decl;
   15436       150095 :   OMP_CLAUSE_CHAIN (clause) = chain;
   15437       150095 :   if (private_debug)
   15438          382 :     OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
   15439       149713 :   else if (code == OMP_CLAUSE_PRIVATE && (flags & GOVD_PRIVATE_OUTER_REF))
   15440            6 :     OMP_CLAUSE_PRIVATE_OUTER_REF (clause) = 1;
   15441       149707 :   else if (code == OMP_CLAUSE_SHARED
   15442        41466 :            && (flags & GOVD_WRITTEN) == 0
   15443       185071 :            && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   15444        21078 :     OMP_CLAUSE_SHARED_READONLY (clause) = 1;
   15445       128629 :   else if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_EXPLICIT) == 0)
   15446        22131 :     OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (clause) = 1;
   15447       106498 :   else if (code == OMP_CLAUSE_MAP && (flags & GOVD_MAP_0LEN_ARRAY) != 0)
   15448              :     {
   15449          630 :       tree nc = build_omp_clause (input_location, OMP_CLAUSE_MAP);
   15450          630 :       OMP_CLAUSE_DECL (nc) = decl;
   15451          630 :       if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
   15452          630 :           && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == POINTER_TYPE)
   15453           15 :         OMP_CLAUSE_DECL (clause)
   15454           30 :           = build_fold_indirect_ref_loc (input_location, decl);
   15455          630 :       OMP_CLAUSE_DECL (clause)
   15456          630 :         = build2 (MEM_REF, char_type_node, OMP_CLAUSE_DECL (clause),
   15457              :                   build_int_cst (build_pointer_type (char_type_node), 0));
   15458          630 :       OMP_CLAUSE_SIZE (clause) = size_zero_node;
   15459          630 :       OMP_CLAUSE_SIZE (nc) = size_zero_node;
   15460          630 :       OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_ALLOC);
   15461          630 :       OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (clause) = 1;
   15462          630 :       tree dtype = TREE_TYPE (decl);
   15463          630 :       if (TREE_CODE (dtype) == REFERENCE_TYPE)
   15464           15 :         dtype = TREE_TYPE (dtype);
   15465              :       /* FIRSTPRIVATE_POINTER doesn't work well if we have a
   15466              :          multiply-indirected pointer.  If we have a reference to a pointer to
   15467              :          a pointer, it's possible that this should really be
   15468              :          GOMP_MAP_FIRSTPRIVATE_REFERENCE -- but that also doesn't work at the
   15469              :          moment, so stick with this.  (See PR113279 and testcases
   15470              :          baseptrs-{4,6}.C:ref2ptrptr_offset_decl_member_slice).  */
   15471          630 :       if (TREE_CODE (dtype) == POINTER_TYPE
   15472          630 :           && TREE_CODE (TREE_TYPE (dtype)) == POINTER_TYPE)
   15473           19 :         OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
   15474              :       else
   15475          611 :         OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
   15476          630 :       OMP_CLAUSE_CHAIN (nc) = chain;
   15477          630 :       OMP_CLAUSE_CHAIN (clause) = nc;
   15478          630 :       struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   15479          630 :       gimplify_omp_ctxp = ctx->outer_context;
   15480          630 :       gimplify_expr (&TREE_OPERAND (OMP_CLAUSE_DECL (clause), 0),
   15481              :                      pre_p, NULL, is_gimple_val, fb_rvalue);
   15482          630 :       gimplify_omp_ctxp = ctx;
   15483          630 :     }
   15484        17569 :   else if (code == OMP_CLAUSE_MAP)
   15485              :     {
   15486        17569 :       int kind;
   15487              :       /* Not all combinations of these GOVD_MAP flags are actually valid.  */
   15488        17569 :       switch (flags & (GOVD_MAP_TO_ONLY
   15489              :                        | GOVD_MAP_FORCE
   15490              :                        | GOVD_MAP_FORCE_PRESENT
   15491              :                        | GOVD_MAP_ALLOC_ONLY
   15492              :                        | GOVD_MAP_FROM_ONLY))
   15493              :         {
   15494              :         case 0:
   15495              :           kind = GOMP_MAP_TOFROM;
   15496              :           break;
   15497         1042 :         case GOVD_MAP_FORCE:
   15498         1042 :           kind = GOMP_MAP_TOFROM | GOMP_MAP_FLAG_FORCE;
   15499         1042 :           break;
   15500         1015 :         case GOVD_MAP_TO_ONLY:
   15501         1015 :           kind = GOMP_MAP_TO;
   15502         1015 :           break;
   15503           16 :         case GOVD_MAP_FROM_ONLY:
   15504           16 :           kind = GOMP_MAP_FROM;
   15505           16 :           break;
   15506           37 :         case GOVD_MAP_ALLOC_ONLY:
   15507           37 :           kind = GOMP_MAP_ALLOC;
   15508           37 :           break;
   15509            3 :         case GOVD_MAP_TO_ONLY | GOVD_MAP_FORCE:
   15510            3 :           kind = GOMP_MAP_TO | GOMP_MAP_FLAG_FORCE;
   15511            3 :           break;
   15512              :         case GOVD_MAP_FORCE_PRESENT:
   15513          326 :           kind = GOMP_MAP_FORCE_PRESENT;
   15514              :           break;
   15515              :         case GOVD_MAP_FORCE_PRESENT | GOVD_MAP_ALLOC_ONLY:
   15516          326 :           kind = GOMP_MAP_FORCE_PRESENT;
   15517              :           break;
   15518            0 :         default:
   15519            0 :           gcc_unreachable ();
   15520              :         }
   15521        17569 :       OMP_CLAUSE_SET_MAP_KIND (clause, kind);
   15522              :       /* Setting of the implicit flag for the runtime is currently disabled for
   15523              :          OpenACC.  */
   15524        17569 :       if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
   15525        10035 :         OMP_CLAUSE_MAP_RUNTIME_IMPLICIT_P (clause) = 1;
   15526        17569 :       if (DECL_SIZE (decl)
   15527        17569 :           && !poly_int_tree_p (DECL_SIZE (decl)))
   15528              :         {
   15529          535 :           tree decl2 = DECL_VALUE_EXPR (decl);
   15530          535 :           gcc_assert (INDIRECT_REF_P (decl2));
   15531          535 :           decl2 = TREE_OPERAND (decl2, 0);
   15532          535 :           gcc_assert (DECL_P (decl2));
   15533          535 :           tree mem = build_simple_mem_ref (decl2);
   15534          535 :           OMP_CLAUSE_DECL (clause) = mem;
   15535          535 :           OMP_CLAUSE_SIZE (clause) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
   15536          535 :           if (gimplify_omp_ctxp->outer_context)
   15537              :             {
   15538          446 :               struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp->outer_context;
   15539          446 :               omp_notice_variable (ctx, decl2, true);
   15540          446 :               omp_notice_variable (ctx, OMP_CLAUSE_SIZE (clause), true);
   15541              :             }
   15542          535 :           tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
   15543              :                                       OMP_CLAUSE_MAP);
   15544          535 :           OMP_CLAUSE_DECL (nc) = decl;
   15545          535 :           OMP_CLAUSE_SIZE (nc) = size_zero_node;
   15546          535 :           if (gimplify_omp_ctxp->target_firstprivatize_array_bases)
   15547          535 :             OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_POINTER);
   15548              :           else
   15549            0 :             OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
   15550          535 :           OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
   15551          535 :           OMP_CLAUSE_CHAIN (clause) = nc;
   15552              :         }
   15553        17034 :       else if (gimplify_omp_ctxp->target_firstprivatize_array_bases
   15554        17034 :                && omp_privatize_by_reference (decl))
   15555              :         {
   15556           28 :           OMP_CLAUSE_DECL (clause) = build_simple_mem_ref (decl);
   15557           28 :           OMP_CLAUSE_SIZE (clause)
   15558           28 :             = unshare_expr (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))));
   15559           28 :           struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   15560           28 :           gimplify_omp_ctxp = ctx->outer_context;
   15561           28 :           gimplify_expr (&OMP_CLAUSE_SIZE (clause),
   15562              :                          pre_p, NULL, is_gimple_val, fb_rvalue);
   15563           28 :           gimplify_omp_ctxp = ctx;
   15564           28 :           tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (clause),
   15565              :                                       OMP_CLAUSE_MAP);
   15566           28 :           OMP_CLAUSE_DECL (nc) = decl;
   15567           28 :           OMP_CLAUSE_SIZE (nc) = size_zero_node;
   15568           28 :           OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_FIRSTPRIVATE_REFERENCE);
   15569           28 :           OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (clause);
   15570           28 :           OMP_CLAUSE_CHAIN (clause) = nc;
   15571              :         }
   15572              :       else
   15573        17006 :         OMP_CLAUSE_SIZE (clause) = DECL_SIZE_UNIT (decl);
   15574              :     }
   15575       150095 :   if (code == OMP_CLAUSE_FIRSTPRIVATE && (flags & GOVD_LASTPRIVATE) != 0)
   15576              :     {
   15577          690 :       tree nc = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE);
   15578          690 :       OMP_CLAUSE_DECL (nc) = decl;
   15579          690 :       OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (nc) = 1;
   15580          690 :       OMP_CLAUSE_CHAIN (nc) = chain;
   15581          690 :       OMP_CLAUSE_CHAIN (clause) = nc;
   15582          690 :       struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   15583          690 :       gimplify_omp_ctxp = ctx->outer_context;
   15584          690 :       lang_hooks.decls.omp_finish_clause (nc, pre_p,
   15585          690 :                                           (ctx->region_type & ORT_ACC) != 0);
   15586          690 :       gimplify_omp_ctxp = ctx;
   15587              :     }
   15588       150095 :   *list_p = clause;
   15589       150095 :   struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   15590       150095 :   gimplify_omp_ctxp = ctx->outer_context;
   15591              :   /* Don't call omp_finish_clause on implicitly added OMP_CLAUSE_PRIVATE
   15592              :      in simd.  Those are only added for the local vars inside of simd body
   15593              :      and they don't need to be e.g. default constructible.  */
   15594       150095 :   if (code != OMP_CLAUSE_PRIVATE || ctx->region_type != ORT_SIMD)
   15595       142045 :     lang_hooks.decls.omp_finish_clause (clause, pre_p,
   15596       142045 :                                         (ctx->region_type & ORT_ACC) != 0);
   15597       150095 :   if (gimplify_omp_ctxp)
   15598       184427 :     for (; clause != chain; clause = OMP_CLAUSE_CHAIN (clause))
   15599        93626 :       if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
   15600        93626 :           && DECL_P (OMP_CLAUSE_SIZE (clause)))
   15601         1241 :         omp_notice_variable (gimplify_omp_ctxp, OMP_CLAUSE_SIZE (clause),
   15602              :                              true);
   15603       150095 :   gimplify_omp_ctxp = ctx;
   15604       150095 :   return 0;
   15605              : }
   15606              : 
   15607              : static void
   15608       130152 : gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
   15609              :                              enum tree_code code,
   15610              :                              gimple_seq *loops_seq_p = NULL)
   15611              : {
   15612       130152 :   struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   15613       130152 :   tree *orig_list_p = list_p;
   15614       130152 :   tree c, decl;
   15615       130152 :   bool has_inscan_reductions = false;
   15616              : 
   15617       130152 :   if (body)
   15618              :     {
   15619              :       struct gimplify_omp_ctx *octx;
   15620       226288 :       for (octx = ctx; octx; octx = octx->outer_context)
   15621       174750 :         if ((octx->region_type & (ORT_PARALLEL | ORT_TASK | ORT_TEAMS)) != 0)
   15622              :           break;
   15623       112412 :       if (octx)
   15624              :         {
   15625        60874 :           struct walk_stmt_info wi;
   15626        60874 :           memset (&wi, 0, sizeof (wi));
   15627        60874 :           walk_gimple_seq (body, omp_find_stores_stmt,
   15628              :                            omp_find_stores_op, &wi);
   15629              :         }
   15630              :     }
   15631              : 
   15632       130152 :   if (ctx->add_safelen1)
   15633              :     {
   15634              :       /* If there are VLAs in the body of simd loop, prevent
   15635              :          vectorization.  */
   15636            2 :       gcc_assert (ctx->region_type == ORT_SIMD);
   15637            2 :       c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
   15638            2 :       OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
   15639            2 :       OMP_CLAUSE_CHAIN (c) = *list_p;
   15640            2 :       *list_p = c;
   15641            2 :       list_p = &OMP_CLAUSE_CHAIN (c);
   15642              :     }
   15643              : 
   15644       130152 :   if (ctx->region_type == ORT_WORKSHARE
   15645        39991 :       && ctx->outer_context
   15646        28044 :       && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
   15647              :     {
   15648        25038 :       for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
   15649        12641 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   15650        12641 :             && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   15651              :           {
   15652          125 :             decl = OMP_CLAUSE_DECL (c);
   15653          125 :             splay_tree_node n
   15654          125 :               = splay_tree_lookup (ctx->outer_context->variables,
   15655              :                                    (splay_tree_key) decl);
   15656          125 :             gcc_checking_assert (!splay_tree_lookup (ctx->variables,
   15657              :                                                      (splay_tree_key) decl));
   15658          125 :             omp_add_variable (ctx, decl, n->value);
   15659          125 :             tree c2 = copy_node (c);
   15660          125 :             OMP_CLAUSE_CHAIN (c2) = *list_p;
   15661          125 :             *list_p = c2;
   15662          125 :             if ((n->value & GOVD_FIRSTPRIVATE) == 0)
   15663          103 :               continue;
   15664           22 :             c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   15665              :                                    OMP_CLAUSE_FIRSTPRIVATE);
   15666           22 :             OMP_CLAUSE_DECL (c2) = decl;
   15667           22 :             OMP_CLAUSE_CHAIN (c2) = *list_p;
   15668           22 :             *list_p = c2;
   15669              :           }
   15670              :     }
   15671              : 
   15672       130152 :   if (code == OMP_TARGET
   15673       130152 :       || code == OMP_TARGET_DATA
   15674       130152 :       || code == OMP_TARGET_ENTER_DATA
   15675       113708 :       || code == OMP_TARGET_EXIT_DATA)
   15676              :     {
   15677        17235 :       tree mapper_clauses = NULL_TREE;
   15678        17235 :       instantiate_mapper_info im_info;
   15679              : 
   15680        17235 :       im_info.mapper_clauses_p = &mapper_clauses;
   15681        17235 :       im_info.omp_ctx = ctx;
   15682        17235 :       im_info.pre_p = pre_p;
   15683              : 
   15684        17235 :       splay_tree_foreach (ctx->variables,
   15685              :                           omp_instantiate_implicit_mappers,
   15686              :                           (void *) &im_info);
   15687              : 
   15688        17235 :       if (mapper_clauses)
   15689              :         {
   15690           53 :           mapper_clauses
   15691           53 :             = lang_hooks.decls.omp_finish_mapper_clauses (mapper_clauses);
   15692              : 
   15693              :           /* Stick the implicitly-expanded mapper clauses at the end of the
   15694              :              clause list.  */
   15695           53 :           tree *tail = list_p;
   15696          163 :           while (*tail)
   15697          110 :             tail = &OMP_CLAUSE_CHAIN (*tail);
   15698           53 :           *tail = mapper_clauses;
   15699              :         }
   15700              : 
   15701        17235 :       vec<omp_mapping_group> *groups;
   15702        17235 :       groups = omp_gather_mapping_groups (list_p);
   15703        17235 :       hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap = NULL;
   15704              : 
   15705        17235 :       if (groups)
   15706              :         {
   15707         8640 :           grpmap = omp_index_mapping_groups (groups);
   15708              : 
   15709         8640 :           omp_resolve_clause_dependencies (code, groups, grpmap);
   15710         8640 :           omp_build_struct_sibling_lists (code, ctx->region_type, groups,
   15711              :                                           &grpmap, list_p);
   15712              : 
   15713         8640 :           omp_mapping_group *outlist = NULL;
   15714              : 
   15715        17280 :           delete grpmap;
   15716         8640 :           delete groups;
   15717              : 
   15718              :           /* Rebuild now we have struct sibling lists.  */
   15719         8640 :           groups = omp_gather_mapping_groups (list_p);
   15720         8640 :           grpmap = omp_index_mapping_groups (groups);
   15721              : 
   15722         8640 :           bool enter_exit = (code == OMP_TARGET_ENTER_DATA
   15723         8640 :                              || code == OMP_TARGET_EXIT_DATA);
   15724              : 
   15725         8640 :           outlist = omp_tsort_mapping_groups (groups, grpmap, enter_exit);
   15726         8640 :           outlist = omp_segregate_mapping_groups (outlist);
   15727         8640 :           list_p = omp_reorder_mapping_groups (groups, outlist, list_p);
   15728              : 
   15729         8640 :           delete grpmap;
   15730         8640 :           delete groups;
   15731              :         }
   15732        17235 :     }
   15733       112917 :   else if (ctx->region_type & ORT_ACC)
   15734              :     {
   15735        29899 :       vec<omp_mapping_group> *groups;
   15736        29899 :       groups = omp_gather_mapping_groups (list_p);
   15737        29899 :       if (groups)
   15738              :         {
   15739         9462 :           hash_map<tree_operand_hash_no_se, omp_mapping_group *> *grpmap;
   15740         9462 :           grpmap = omp_index_mapping_groups (groups);
   15741              : 
   15742         9462 :           oacc_resolve_clause_dependencies (groups, grpmap);
   15743         9462 :           omp_build_struct_sibling_lists (code, ctx->region_type, groups,
   15744              :                                           &grpmap, list_p);
   15745              : 
   15746         9462 :           delete groups;
   15747        18924 :           delete grpmap;
   15748              :         }
   15749              :     }
   15750              : 
   15751       130152 :   tree attach_list = NULL_TREE;
   15752       130152 :   tree *attach_tail = &attach_list;
   15753              : 
   15754       130152 :   tree *grp_start_p = NULL, grp_end = NULL_TREE;
   15755              : 
   15756       380242 :   while ((c = *list_p) != NULL)
   15757              :     {
   15758       250090 :       splay_tree_node n;
   15759       250090 :       bool remove = false;
   15760       250090 :       bool move_attach = false;
   15761              : 
   15762       292778 :       if (grp_end && c == OMP_CLAUSE_CHAIN (grp_end))
   15763              :         grp_end = NULL_TREE;
   15764              : 
   15765       250090 :       switch (OMP_CLAUSE_CODE (c))
   15766              :         {
   15767         8075 :         case OMP_CLAUSE_FIRSTPRIVATE:
   15768         8075 :           if ((ctx->region_type & ORT_TARGET)
   15769         1982 :               && (ctx->region_type & ORT_ACC) == 0
   15770         9451 :               && TYPE_ATOMIC (strip_array_types
   15771              :                                         (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
   15772              :             {
   15773            4 :               error_at (OMP_CLAUSE_LOCATION (c),
   15774              :                         "%<_Atomic%> %qD in %<firstprivate%> clause on "
   15775            2 :                         "%<target%> construct", OMP_CLAUSE_DECL (c));
   15776            2 :               remove = true;
   15777            2 :               break;
   15778              :             }
   15779         8073 :           if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
   15780              :             {
   15781          380 :               decl = OMP_CLAUSE_DECL (c);
   15782          380 :               n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   15783          380 :               if ((n->value & GOVD_MAP) != 0)
   15784              :                 {
   15785              :                   remove = true;
   15786              :                   break;
   15787              :                 }
   15788          368 :               OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) = 0;
   15789          368 :               OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) = 0;
   15790              :             }
   15791              :           /* FALLTHRU */
   15792        36983 :         case OMP_CLAUSE_PRIVATE:
   15793        36983 :         case OMP_CLAUSE_SHARED:
   15794        36983 :         case OMP_CLAUSE_LINEAR:
   15795        36983 :           decl = OMP_CLAUSE_DECL (c);
   15796        36983 :           n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   15797        36983 :           remove = !(n->value & GOVD_SEEN);
   15798        36983 :           if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
   15799           48 :               && code == OMP_PARALLEL
   15800        37005 :               && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
   15801              :             remove = true;
   15802        36961 :           if (! remove)
   15803              :             {
   15804        32353 :               bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
   15805        32353 :               if ((n->value & GOVD_DEBUG_PRIVATE)
   15806        32353 :                   || lang_hooks.decls.omp_private_debug_clause (decl, shared))
   15807              :                 {
   15808           87 :                   gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
   15809              :                               || ((n->value & GOVD_DATA_SHARE_CLASS)
   15810              :                                   == GOVD_SHARED));
   15811           87 :                   OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
   15812           87 :                   OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
   15813              :                 }
   15814        32353 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
   15815         4159 :                   && ctx->has_depend
   15816        32911 :                   && DECL_P (decl))
   15817          558 :                 n->value |= GOVD_WRITTEN;
   15818        32353 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
   15819         4159 :                   && (n->value & GOVD_WRITTEN) == 0
   15820         3042 :                   && DECL_P (decl)
   15821        35395 :                   && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   15822          526 :                 OMP_CLAUSE_SHARED_READONLY (c) = 1;
   15823        31827 :               else if (DECL_P (decl)
   15824        31827 :                        && ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
   15825         3633 :                             && (n->value & GOVD_WRITTEN) != 0)
   15826        30710 :                            || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   15827         9116 :                                && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
   15828        38885 :                        && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   15829         5754 :                 omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
   15830              :             }
   15831              :           else
   15832         4630 :             n->value &= ~GOVD_EXPLICIT;
   15833              :           break;
   15834              : 
   15835        13010 :         case OMP_CLAUSE_LASTPRIVATE:
   15836              :           /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
   15837              :              accurately reflect the presence of a FIRSTPRIVATE clause.  */
   15838        13010 :           decl = OMP_CLAUSE_DECL (c);
   15839        13010 :           n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   15840        13010 :           OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
   15841        13010 :             = (n->value & GOVD_FIRSTPRIVATE) != 0;
   15842        13010 :           if (code == OMP_DISTRIBUTE
   15843        13010 :               && OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
   15844              :             {
   15845            4 :               remove = true;
   15846            4 :               error_at (OMP_CLAUSE_LOCATION (c),
   15847              :                         "same variable used in %<firstprivate%> and "
   15848              :                         "%<lastprivate%> clauses on %<distribute%> "
   15849              :                         "construct");
   15850              :             }
   15851        13010 :           if (!remove
   15852        13006 :               && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   15853        13006 :               && DECL_P (decl)
   15854        13006 :               && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   15855        11411 :             omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
   15856        13010 :           if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
   15857              :             remove = true;
   15858              :           break;
   15859              : 
   15860          824 :         case OMP_CLAUSE_ALIGNED:
   15861          824 :           decl = OMP_CLAUSE_DECL (c);
   15862          824 :           if (!is_global_var (decl))
   15863              :             {
   15864          738 :               n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   15865          738 :               remove = n == NULL || !(n->value & GOVD_SEEN);
   15866           88 :               if (!remove && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
   15867              :                 {
   15868           88 :                   struct gimplify_omp_ctx *octx;
   15869           88 :                   if (n != NULL
   15870           88 :                       && (n->value & (GOVD_DATA_SHARE_CLASS
   15871              :                                       & ~GOVD_FIRSTPRIVATE)))
   15872              :                     remove = true;
   15873              :                   else
   15874          100 :                     for (octx = ctx->outer_context; octx;
   15875           12 :                          octx = octx->outer_context)
   15876              :                       {
   15877           24 :                         n = splay_tree_lookup (octx->variables,
   15878              :                                                (splay_tree_key) decl);
   15879           24 :                         if (n == NULL)
   15880           12 :                           continue;
   15881           12 :                         if (n->value & GOVD_LOCAL)
   15882              :                           break;
   15883              :                         /* We have to avoid assigning a shared variable
   15884              :                            to itself when trying to add
   15885              :                            __builtin_assume_aligned.  */
   15886           12 :                         if (n->value & GOVD_SHARED)
   15887              :                           {
   15888              :                             remove = true;
   15889              :                             break;
   15890              :                           }
   15891              :                       }
   15892              :                 }
   15893              :             }
   15894           86 :           else if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
   15895              :             {
   15896           86 :               n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   15897           86 :               if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
   15898              :                 remove = true;
   15899              :             }
   15900              :           break;
   15901              : 
   15902          553 :         case OMP_CLAUSE_HAS_DEVICE_ADDR:
   15903          553 :           decl = OMP_CLAUSE_DECL (c);
   15904          553 :           while (INDIRECT_REF_P (decl)
   15905          602 :                  || TREE_CODE (decl) == ARRAY_REF)
   15906           49 :             decl = TREE_OPERAND (decl, 0);
   15907          553 :           n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   15908          553 :           remove = n == NULL || !(n->value & GOVD_SEEN);
   15909              :           break;
   15910              : 
   15911          900 :         case OMP_CLAUSE_IS_DEVICE_PTR:
   15912          900 :         case OMP_CLAUSE_NONTEMPORAL:
   15913          900 :           decl = OMP_CLAUSE_DECL (c);
   15914          900 :           n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   15915          900 :           remove = n == NULL || !(n->value & GOVD_SEEN);
   15916              :           break;
   15917              : 
   15918        56882 :         case OMP_CLAUSE_MAP:
   15919        56882 :           if (OMP_CLAUSE_MAP_GIMPLE_ONLY (c))
   15920              :             {
   15921           90 :               remove = true;
   15922           90 :               goto end_adjust_omp_map_clause;
   15923              :             }
   15924        56792 :           decl = OMP_CLAUSE_DECL (c);
   15925        56792 :           if (!grp_end)
   15926              :             {
   15927        31871 :               grp_start_p = list_p;
   15928        31871 :               grp_end = *omp_group_last (grp_start_p);
   15929              :             }
   15930        56792 :           switch (OMP_CLAUSE_MAP_KIND (c))
   15931              :             {
   15932          183 :             case GOMP_MAP_PRESENT_ALLOC:
   15933          183 :             case GOMP_MAP_PRESENT_TO:
   15934          183 :             case GOMP_MAP_PRESENT_FROM:
   15935          183 :             case GOMP_MAP_PRESENT_TOFROM:
   15936          183 :               OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_PRESENT);
   15937          183 :               break;
   15938              :             default:
   15939              :               break;
   15940              :             }
   15941        56792 :           switch (code)
   15942              :             {
   15943         4563 :             case OACC_DATA:
   15944         4563 :               if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
   15945              :                 break;
   15946              :               /* Fallthrough.  */
   15947        19317 :             case OACC_HOST_DATA:
   15948        19317 :             case OACC_ENTER_DATA:
   15949        19317 :             case OACC_EXIT_DATA:
   15950        19317 :             case OMP_TARGET_DATA:
   15951        19317 :             case OMP_TARGET_ENTER_DATA:
   15952        19317 :             case OMP_TARGET_EXIT_DATA:
   15953        19317 :               if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   15954        19317 :                   || (OMP_CLAUSE_MAP_KIND (c)
   15955              :                       == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   15956              :                 /* For target {,enter ,exit }data only the array slice is
   15957              :                    mapped, but not the pointer to it.  */
   15958              :                 remove = true;
   15959        19317 :               if (code == OMP_TARGET_EXIT_DATA
   15960        19317 :                   && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
   15961         2805 :                       || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER))
   15962              :                 remove = true;
   15963              :               break;
   15964              :             case OMP_TARGET:
   15965              :               break;
   15966              :             default:
   15967              :               break;
   15968              :             }
   15969        19315 :           if (remove)
   15970              :             break;
   15971        56457 :           if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
   15972              :             {
   15973              :               /* Sanity check: attach/detach map kinds use the size as a bias,
   15974              :                  and it's never right to use the decl size for such
   15975              :                  mappings.  */
   15976        17835 :               gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
   15977              :                           && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
   15978              :                           && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DETACH
   15979              :                           && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
   15980              :                           && (OMP_CLAUSE_MAP_KIND (c)
   15981              :                               != GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION));
   15982        21894 :               OMP_CLAUSE_SIZE (c) = DECL_P (decl) ? DECL_SIZE_UNIT (decl)
   15983         4059 :                                     : TYPE_SIZE_UNIT (TREE_TYPE (decl));
   15984              :             }
   15985        56457 :           gimplify_omp_ctxp = ctx->outer_context;
   15986        56457 :           gimple_seq *seq_p;
   15987        56457 :           seq_p = enter_omp_iterator_loop_context (c, loops_seq_p, pre_p);
   15988        56457 :           if (gimplify_expr (&OMP_CLAUSE_SIZE (c), seq_p, NULL,
   15989              :                                   is_gimple_val, fb_rvalue) == GS_ERROR)
   15990              :             {
   15991            0 :               gimplify_omp_ctxp = ctx;
   15992            0 :               remove = true;
   15993            0 :               goto end_adjust_omp_map_clause;
   15994              :             }
   15995        56457 :           else if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER
   15996        53536 :                     || (OMP_CLAUSE_MAP_KIND (c)
   15997              :                         == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
   15998        53123 :                     || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   15999        63100 :                    && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
   16000              :             {
   16001          912 :               OMP_CLAUSE_SIZE (c)
   16002          912 :                 = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), seq_p, NULL,
   16003              :                                            false);
   16004          912 :               if ((ctx->region_type & ORT_TARGET) != 0)
   16005          703 :                 omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
   16006              :                                   GOVD_FIRSTPRIVATE | GOVD_SEEN);
   16007              :             }
   16008        56457 :           gimplify_omp_ctxp = ctx;
   16009              :           /* Data clauses associated with reductions must be
   16010              :              compatible with present_or_copy.  Warn and adjust the clause
   16011              :              if that is not the case.  */
   16012        56457 :           if (ctx->region_type == ORT_ACC_PARALLEL
   16013        47478 :               || ctx->region_type == ORT_ACC_SERIAL)
   16014              :             {
   16015         9535 :               tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
   16016         9535 :               n = NULL;
   16017              : 
   16018         9535 :               if (DECL_P (t))
   16019         7770 :                 n = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
   16020              : 
   16021         7770 :               if (n && (n->value & GOVD_REDUCTION))
   16022              :                 {
   16023          809 :                   enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c);
   16024              : 
   16025          809 :                   OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
   16026          809 :                   if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM
   16027          159 :                       && kind != GOMP_MAP_FORCE_PRESENT
   16028          159 :                       && kind != GOMP_MAP_POINTER)
   16029              :                     {
   16030          120 :                       warning_at (OMP_CLAUSE_LOCATION (c), 0,
   16031              :                                   "incompatible data clause with reduction "
   16032              :                                   "on %qE; promoting to %<present_or_copy%>",
   16033          120 :                                   DECL_NAME (t));
   16034          120 :                       OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
   16035              :                     }
   16036              :                 }
   16037              :             }
   16038        56457 :           if ((OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
   16039        53671 :                || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT_UNORD)
   16040        56731 :               && (code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA))
   16041              :             {
   16042          536 :               remove = true;
   16043          536 :               goto end_adjust_omp_map_clause;
   16044              :             }
   16045              :           /* If we have a DECL_VALUE_EXPR (e.g. this is a class member and/or
   16046              :              a variable captured in a lambda closure), look through that now
   16047              :              before the DECL_P check below.  (A code other than COMPONENT_REF,
   16048              :              i.e. INDIRECT_REF, will be a VLA/variable-length array
   16049              :              section.  A global var may be a variable in a common block.  We
   16050              :              don't want to do this here for either of those.)  */
   16051        55921 :           if ((ctx->region_type & ORT_ACC) == 0
   16052        29714 :               && DECL_P (decl)
   16053        12765 :               && !is_global_var (decl)
   16054        11353 :               && DECL_HAS_VALUE_EXPR_P (decl)
   16055        56111 :               && TREE_CODE (DECL_VALUE_EXPR (decl)) == COMPONENT_REF)
   16056            0 :             decl = OMP_CLAUSE_DECL (c) = DECL_VALUE_EXPR (decl);
   16057        55921 :           if (TREE_CODE (decl) == TARGET_EXPR)
   16058              :             {
   16059            0 :               if (gimplify_expr (&OMP_CLAUSE_DECL (c), seq_p, NULL,
   16060              :                                  is_gimple_lvalue, fb_lvalue) == GS_ERROR)
   16061        26324 :                 remove = true;
   16062              :             }
   16063        55921 :           else if (!DECL_P (decl))
   16064              :             {
   16065        29597 :               if ((ctx->region_type & ORT_TARGET) != 0
   16066        29597 :                   && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER)
   16067              :                 {
   16068           24 :                   if (INDIRECT_REF_P (decl)
   16069            0 :                       && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
   16070           24 :                       && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
   16071              :                           == REFERENCE_TYPE))
   16072            0 :                     decl = TREE_OPERAND (decl, 0);
   16073           24 :                   if (TREE_CODE (decl) == COMPONENT_REF)
   16074              :                     {
   16075            0 :                       while (TREE_CODE (decl) == COMPONENT_REF)
   16076            0 :                         decl = TREE_OPERAND (decl, 0);
   16077            0 :                       if (DECL_P (decl))
   16078              :                         {
   16079            0 :                           n = splay_tree_lookup (ctx->variables,
   16080              :                                                  (splay_tree_key) decl);
   16081            0 :                           if (!(n->value & GOVD_SEEN))
   16082        29597 :                             remove = true;
   16083              :                         }
   16084              :                     }
   16085              :                 }
   16086              : 
   16087        29597 :               tree d = decl, *pd;
   16088        29597 :               if (TREE_CODE (d) == ARRAY_REF)
   16089              :                 {
   16090         5836 :                   while (TREE_CODE (d) == ARRAY_REF)
   16091         2978 :                     d = TREE_OPERAND (d, 0);
   16092         2858 :                   if (TREE_CODE (d) == COMPONENT_REF
   16093         2858 :                       && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE)
   16094              :                     decl = d;
   16095              :                 }
   16096        29597 :               pd = &OMP_CLAUSE_DECL (c);
   16097        29597 :               if (d == decl
   16098        27098 :                   && TREE_CODE (decl) == INDIRECT_REF
   16099        15462 :                   && TREE_CODE (TREE_OPERAND (decl, 0)) == COMPONENT_REF
   16100         1471 :                   && (TREE_CODE (TREE_TYPE (TREE_OPERAND (decl, 0)))
   16101              :                       == REFERENCE_TYPE)
   16102        30397 :                   && (OMP_CLAUSE_MAP_KIND (c)
   16103              :                       != GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION))
   16104              :                 {
   16105          796 :                   pd = &TREE_OPERAND (decl, 0);
   16106          796 :                   decl = TREE_OPERAND (decl, 0);
   16107              :                 }
   16108              : 
   16109        29597 :               if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   16110         3067 :                 switch (code)
   16111              :                   {
   16112          427 :                   case OACC_ENTER_DATA:
   16113          427 :                   case OACC_EXIT_DATA:
   16114          427 :                     if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
   16115              :                         == ARRAY_TYPE)
   16116              :                       remove = true;
   16117          417 :                     else if (code == OACC_ENTER_DATA)
   16118          263 :                       goto change_to_attach;
   16119              :                     /* Fallthrough.  */
   16120          605 :                   case OMP_TARGET_EXIT_DATA:
   16121          605 :                     OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DETACH);
   16122          605 :                     OMP_CLAUSE_MAP_SIZE_NEEDS_ADJUSTMENT (c) = 0;
   16123          605 :                     break;
   16124           71 :                   case OACC_UPDATE:
   16125              :                     /* An "attach/detach" operation on an update directive
   16126              :                        should behave as a GOMP_MAP_ALWAYS_POINTER.  Note that
   16127              :                        both GOMP_MAP_ATTACH_DETACH and GOMP_MAP_ALWAYS_POINTER
   16128              :                        kinds depend on the previous mapping (for non-TARGET
   16129              :                        regions).  */
   16130           71 :                     OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
   16131           71 :                     break;
   16132         2391 :                   default:
   16133         2391 :                   change_to_attach:
   16134         2391 :                     gcc_assert (!OMP_CLAUSE_MAP_SIZE_NEEDS_ADJUSTMENT (c));
   16135         2391 :                     OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ATTACH);
   16136         2391 :                     if ((ctx->region_type & ORT_TARGET) != 0)
   16137         2113 :                       move_attach = true;
   16138              :                   }
   16139        26530 :               else if ((ctx->region_type & ORT_TARGET) != 0
   16140        26530 :                        && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   16141        11816 :                            || (OMP_CLAUSE_MAP_KIND (c)
   16142              :                                == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)))
   16143              :                 move_attach = true;
   16144              : 
   16145              :               /* If we have e.g. map(struct: *var), don't gimplify the
   16146              :                  argument since omp-low.cc wants to see the decl itself.  */
   16147        29597 :               if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT)
   16148         1136 :                 goto end_adjust_omp_map_clause;
   16149              : 
   16150              :               /* We've already partly gimplified this in
   16151              :                  gimplify_scan_omp_clauses.  Don't do any more.  */
   16152        28461 :               if (code == OMP_TARGET && OMP_CLAUSE_MAP_IN_REDUCTION (c))
   16153           88 :                 goto end_adjust_omp_map_clause;
   16154              : 
   16155        28373 :               gimplify_omp_ctxp = ctx->outer_context;
   16156        28373 :               if (gimplify_expr (pd, seq_p, NULL, is_gimple_lvalue,
   16157              :                                  fb_lvalue) == GS_ERROR)
   16158            0 :                 remove = true;
   16159        28373 :               gimplify_omp_ctxp = ctx;
   16160        28373 :               goto end_adjust_omp_map_clause;
   16161              :             }
   16162              : 
   16163        26324 :          if ((code == OMP_TARGET
   16164              :               || code == OMP_TARGET_DATA
   16165              :               || code == OMP_TARGET_ENTER_DATA
   16166        14453 :               || code == OMP_TARGET_EXIT_DATA)
   16167        26956 :              && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   16168              :            {
   16169          242 :              bool firstprivatize = false;
   16170              : 
   16171          247 :              for (struct gimplify_omp_ctx *octx = ctx->outer_context; octx;
   16172            5 :                   octx = octx->outer_context)
   16173              :                {
   16174            6 :                  splay_tree_node n
   16175           12 :                    = splay_tree_lookup (octx->variables,
   16176            6 :                                         (splay_tree_key) OMP_CLAUSE_DECL (c));
   16177              :                  /* If this is contained in an outer OpenMP region as a
   16178              :                     firstprivate value, remove the attach/detach.  */
   16179            6 :                  if (n && (n->value & GOVD_FIRSTPRIVATE))
   16180              :                    {
   16181              :                      firstprivatize = true;
   16182              :                      break;
   16183              :                    }
   16184              :                }
   16185              : 
   16186          242 :              enum gomp_map_kind map_kind;
   16187          242 :              if (firstprivatize)
   16188              :                map_kind = GOMP_MAP_FIRSTPRIVATE_POINTER;
   16189          241 :              else if (code == OMP_TARGET_EXIT_DATA)
   16190              :                map_kind = GOMP_MAP_DETACH;
   16191              :              else
   16192          190 :                map_kind = GOMP_MAP_ATTACH;
   16193          242 :              OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
   16194              :            }
   16195        26082 :          else if ((ctx->region_type & ORT_ACC) != 0
   16196        26082 :                   && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)
   16197              :            {
   16198            0 :              enum gomp_map_kind map_kind = (code == OACC_EXIT_DATA
   16199            0 :                                             ? GOMP_MAP_DETACH
   16200              :                                             : GOMP_MAP_ATTACH);
   16201            0 :              OMP_CLAUSE_SET_MAP_KIND (c, map_kind);
   16202              :            }
   16203              : 
   16204        26324 :           n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   16205        26324 :           if ((ctx->region_type & ORT_TARGET) != 0
   16206        16359 :               && !(n->value & GOVD_SEEN)
   16207         1511 :               && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
   16208        27588 :               && (!is_global_var (decl)
   16209           75 :                   || !lookup_attribute ("omp declare target link",
   16210           75 :                                         DECL_ATTRIBUTES (decl))))
   16211              :             {
   16212         1252 :               remove = true;
   16213              :               /* For struct element mapping, if struct is never referenced
   16214              :                  in target block and none of the mapping has always modifier,
   16215              :                  remove all the struct element mappings, which immediately
   16216              :                  follow the GOMP_MAP_STRUCT map clause.  */
   16217         1252 :               if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT
   16218         1252 :                   || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_STRUCT_UNORD)
   16219              :                 {
   16220           30 :                   HOST_WIDE_INT cnt = tree_to_shwi (OMP_CLAUSE_SIZE (c));
   16221           80 :                   while (cnt--)
   16222           50 :                     OMP_CLAUSE_CHAIN (c)
   16223           50 :                       = OMP_CLAUSE_CHAIN (OMP_CLAUSE_CHAIN (c));
   16224              :                 }
   16225              :             }
   16226        25072 :           else if (DECL_SIZE (decl)
   16227        25048 :                    && !poly_int_tree_p (DECL_SIZE (decl))
   16228          199 :                    && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_POINTER
   16229          199 :                    && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
   16230        25123 :                    && (OMP_CLAUSE_MAP_KIND (c)
   16231              :                        != GOMP_MAP_FIRSTPRIVATE_REFERENCE))
   16232              :             {
   16233              :               /* For GOMP_MAP_FORCE_DEVICEPTR, we'll never enter here, because
   16234              :                  for these, TREE_CODE (DECL_SIZE (decl)) will always be
   16235              :                  INTEGER_CST.  */
   16236           51 :               gcc_assert (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DEVICEPTR);
   16237              : 
   16238           51 :               tree decl2 = DECL_VALUE_EXPR (decl);
   16239           51 :               gcc_assert (INDIRECT_REF_P (decl2));
   16240           51 :               decl2 = TREE_OPERAND (decl2, 0);
   16241           51 :               gcc_assert (DECL_P (decl2));
   16242           51 :               tree mem = build_simple_mem_ref (decl2);
   16243           51 :               OMP_CLAUSE_DECL (c) = mem;
   16244           51 :               OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
   16245           51 :               if (ctx->outer_context)
   16246              :                 {
   16247           15 :                   omp_notice_variable (ctx->outer_context, decl2, true);
   16248           30 :                   omp_notice_variable (ctx->outer_context,
   16249           15 :                                        OMP_CLAUSE_SIZE (c), true);
   16250              :                 }
   16251           51 :               if (((ctx->region_type & ORT_TARGET) != 0
   16252           24 :                    || !ctx->target_firstprivatize_array_bases)
   16253           34 :                   && ((n->value & GOVD_SEEN) == 0
   16254           30 :                       || (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) == 0))
   16255              :                 {
   16256           34 :                   tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   16257              :                                               OMP_CLAUSE_MAP);
   16258           34 :                   OMP_CLAUSE_DECL (nc) = decl;
   16259           34 :                   OMP_CLAUSE_SIZE (nc) = size_zero_node;
   16260           34 :                   if (ctx->target_firstprivatize_array_bases)
   16261           27 :                     OMP_CLAUSE_SET_MAP_KIND (nc,
   16262              :                                              GOMP_MAP_FIRSTPRIVATE_POINTER);
   16263              :                   else
   16264            7 :                     OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_POINTER);
   16265           34 :                   OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
   16266           34 :                   OMP_CLAUSE_CHAIN (c) = nc;
   16267           34 :                   c = nc;
   16268              :                 }
   16269              :             }
   16270              :           else
   16271              :             {
   16272        25021 :               if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
   16273            0 :                 OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
   16274        25021 :               gcc_assert ((n->value & GOVD_SEEN) == 0
   16275              :                           || ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
   16276              :                               == 0));
   16277              :             }
   16278              : 
   16279              :           /* If we have a target region, we can push all the attaches to the
   16280              :              end of the list (we may have standalone "attach" operations
   16281              :              synthesized for GOMP_MAP_STRUCT nodes that must be processed after
   16282              :              the attachment point AND the pointed-to block have been mapped).
   16283              :              If we have something else, e.g. "enter data", we need to keep
   16284              :              "attach" nodes together with the previous node they attach to so
   16285              :              that separate "exit data" operations work properly (see
   16286              :              libgomp/target.c).  */
   16287        26324 :           if ((ctx->region_type & ORT_TARGET) != 0
   16288        26324 :               && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
   16289        16243 :                   || (OMP_CLAUSE_MAP_KIND (c)
   16290              :                       == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)))
   16291              :             move_attach = true;
   16292              : 
   16293        56547 : end_adjust_omp_map_clause:
   16294        56547 :           exit_omp_iterator_loop_context (c);
   16295        56547 :           break;
   16296              : 
   16297         8383 :         case OMP_CLAUSE_TO:
   16298         8383 :         case OMP_CLAUSE_FROM:
   16299         8383 :         case OMP_CLAUSE__CACHE_:
   16300         8383 :           decl = OMP_CLAUSE_DECL (c);
   16301         8383 :           if (!DECL_P (decl))
   16302              :             break;
   16303         6203 :           if (DECL_SIZE (decl)
   16304         6203 :               && !poly_int_tree_p (DECL_SIZE (decl)))
   16305              :             {
   16306            4 :               tree decl2 = DECL_VALUE_EXPR (decl);
   16307            4 :               gcc_assert (INDIRECT_REF_P (decl2));
   16308            4 :               decl2 = TREE_OPERAND (decl2, 0);
   16309            4 :               gcc_assert (DECL_P (decl2));
   16310            4 :               tree mem = build_simple_mem_ref (decl2);
   16311            4 :               OMP_CLAUSE_DECL (c) = mem;
   16312            4 :               OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
   16313            4 :               if (ctx->outer_context)
   16314              :                 {
   16315            4 :                   omp_notice_variable (ctx->outer_context, decl2, true);
   16316            4 :                   omp_notice_variable (ctx->outer_context,
   16317            4 :                                        OMP_CLAUSE_SIZE (c), true);
   16318              :                 }
   16319              :             }
   16320         6199 :           else if (OMP_CLAUSE_SIZE (c) == NULL_TREE)
   16321            0 :             OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl);
   16322              :           break;
   16323              : 
   16324        15379 :         case OMP_CLAUSE_REDUCTION:
   16325        15379 :           if (OMP_CLAUSE_REDUCTION_INSCAN (c))
   16326              :             {
   16327          831 :               decl = OMP_CLAUSE_DECL (c);
   16328          831 :               n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   16329          831 :               if ((n->value & GOVD_REDUCTION_INSCAN) == 0)
   16330              :                 {
   16331           69 :                   remove = true;
   16332           69 :                   error_at (OMP_CLAUSE_LOCATION (c),
   16333              :                             "%qD specified in %<inscan%> %<reduction%> clause "
   16334              :                             "but not in %<scan%> directive clause", decl);
   16335           69 :                   break;
   16336              :                 }
   16337              :               has_inscan_reductions = true;
   16338              :             }
   16339              :           /* FALLTHRU */
   16340        17914 :         case OMP_CLAUSE_IN_REDUCTION:
   16341        17914 :         case OMP_CLAUSE_TASK_REDUCTION:
   16342        17914 :           decl = OMP_CLAUSE_DECL (c);
   16343              :           /* OpenACC reductions need a present_or_copy data clause.
   16344              :              Add one if necessary.  Emit error when the reduction is private.  */
   16345        17914 :           if (ctx->region_type == ORT_ACC_PARALLEL
   16346        17382 :               || ctx->region_type == ORT_ACC_SERIAL)
   16347              :             {
   16348          803 :               n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   16349          803 :               if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE))
   16350              :                 {
   16351           13 :                   remove = true;
   16352           13 :                   error_at (OMP_CLAUSE_LOCATION (c), "invalid private "
   16353           13 :                             "reduction on %qE", DECL_NAME (decl));
   16354              :                 }
   16355          790 :               else if ((n->value & GOVD_MAP) == 0)
   16356              :                 {
   16357          524 :                   tree next = OMP_CLAUSE_CHAIN (c);
   16358          524 :                   tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP);
   16359          524 :                   OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM);
   16360          524 :                   OMP_CLAUSE_DECL (nc) = decl;
   16361          524 :                   OMP_CLAUSE_CHAIN (c) = nc;
   16362          524 :                   lang_hooks.decls.omp_finish_clause (nc, pre_p,
   16363          524 :                                                       (ctx->region_type
   16364              :                                                        & ORT_ACC) != 0);
   16365          550 :                   while (1)
   16366              :                     {
   16367          537 :                       OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1;
   16368          537 :                       if (OMP_CLAUSE_CHAIN (nc) == NULL)
   16369              :                         break;
   16370           13 :                       nc = OMP_CLAUSE_CHAIN (nc);
   16371              :                     }
   16372          524 :                   OMP_CLAUSE_CHAIN (nc) = next;
   16373          524 :                   n->value |= GOVD_MAP;
   16374              :                 }
   16375              :             }
   16376        17914 :           if (DECL_P (decl)
   16377        17914 :               && omp_shared_to_firstprivate_optimizable_decl_p (decl))
   16378         8032 :             omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
   16379              :           break;
   16380              : 
   16381         3682 :         case OMP_CLAUSE_ALLOCATE:
   16382         3682 :           decl = OMP_CLAUSE_DECL (c);
   16383         3682 :           n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   16384         3682 :           if (n != NULL && !(n->value & GOVD_SEEN))
   16385              :             {
   16386         1180 :               if ((n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE | GOVD_LINEAR))
   16387              :                   != 0
   16388         1180 :                   && (n->value & (GOVD_REDUCTION | GOVD_LASTPRIVATE)) == 0)
   16389              :                 remove = true;
   16390              :             }
   16391              :           if (!remove
   16392         2502 :               && OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
   16393         1286 :               && TREE_CODE (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)) != INTEGER_CST
   16394          492 :               && ((ctx->region_type & (ORT_PARALLEL | ORT_TARGET)) != 0
   16395          347 :                   || (ctx->region_type & ORT_TASKLOOP) == ORT_TASK
   16396          287 :                   || (ctx->region_type & ORT_HOST_TEAMS) == ORT_HOST_TEAMS))
   16397              :             {
   16398          223 :               tree allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
   16399          223 :               n = splay_tree_lookup (ctx->variables, (splay_tree_key) allocator);
   16400          223 :               if (n == NULL)
   16401              :                 {
   16402           92 :                   enum omp_clause_default_kind default_kind
   16403              :                     = ctx->default_kind;
   16404           92 :                   ctx->default_kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
   16405           92 :                   omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
   16406              :                                        true);
   16407           92 :                   ctx->default_kind = default_kind;
   16408              :                 }
   16409              :               else
   16410          131 :                 omp_notice_variable (ctx, OMP_CLAUSE_ALLOCATE_ALLOCATOR (c),
   16411              :                                      true);
   16412              :             }
   16413              :           break;
   16414              : 
   16415              :         case OMP_CLAUSE_COPYIN:
   16416              :         case OMP_CLAUSE_COPYPRIVATE:
   16417              :         case OMP_CLAUSE_IF:
   16418              :         case OMP_CLAUSE_SELF:
   16419              :         case OMP_CLAUSE_NUM_THREADS:
   16420              :         case OMP_CLAUSE_NUM_TEAMS:
   16421              :         case OMP_CLAUSE_THREAD_LIMIT:
   16422              :         case OMP_CLAUSE_DIST_SCHEDULE:
   16423              :         case OMP_CLAUSE_DEVICE:
   16424              :         case OMP_CLAUSE_SCHEDULE:
   16425              :         case OMP_CLAUSE_NOWAIT:
   16426              :         case OMP_CLAUSE_ORDERED:
   16427              :         case OMP_CLAUSE_DEFAULT:
   16428              :         case OMP_CLAUSE_UNTIED:
   16429              :         case OMP_CLAUSE_COLLAPSE:
   16430              :         case OMP_CLAUSE_FINAL:
   16431              :         case OMP_CLAUSE_MERGEABLE:
   16432              :         case OMP_CLAUSE_PROC_BIND:
   16433              :         case OMP_CLAUSE_SAFELEN:
   16434              :         case OMP_CLAUSE_SIMDLEN:
   16435              :         case OMP_CLAUSE_DEPEND:
   16436              :         case OMP_CLAUSE_DOACROSS:
   16437              :         case OMP_CLAUSE_PRIORITY:
   16438              :         case OMP_CLAUSE_GRAINSIZE:
   16439              :         case OMP_CLAUSE_NUM_TASKS:
   16440              :         case OMP_CLAUSE_NOGROUP:
   16441              :         case OMP_CLAUSE_THREADS:
   16442              :         case OMP_CLAUSE_SIMD:
   16443              :         case OMP_CLAUSE_FILTER:
   16444              :         case OMP_CLAUSE_HINT:
   16445              :         case OMP_CLAUSE_DEFAULTMAP:
   16446              :         case OMP_CLAUSE_ORDER:
   16447              :         case OMP_CLAUSE_BIND:
   16448              :         case OMP_CLAUSE_DETACH:
   16449              :         case OMP_CLAUSE_USE_DEVICE_PTR:
   16450              :         case OMP_CLAUSE_USE_DEVICE_ADDR:
   16451              :         case OMP_CLAUSE_ASYNC:
   16452              :         case OMP_CLAUSE_WAIT:
   16453              :         case OMP_CLAUSE_INDEPENDENT:
   16454              :         case OMP_CLAUSE_NUM_GANGS:
   16455              :         case OMP_CLAUSE_NUM_WORKERS:
   16456              :         case OMP_CLAUSE_VECTOR_LENGTH:
   16457              :         case OMP_CLAUSE_GANG:
   16458              :         case OMP_CLAUSE_WORKER:
   16459              :         case OMP_CLAUSE_VECTOR:
   16460              :         case OMP_CLAUSE_AUTO:
   16461              :         case OMP_CLAUSE_SEQ:
   16462              :         case OMP_CLAUSE_TILE:
   16463              :         case OMP_CLAUSE_IF_PRESENT:
   16464              :         case OMP_CLAUSE_FINALIZE:
   16465              :         case OMP_CLAUSE_INCLUSIVE:
   16466              :         case OMP_CLAUSE_EXCLUSIVE:
   16467              :         case OMP_CLAUSE_USES_ALLOCATORS:
   16468              :         case OMP_CLAUSE_DEVICE_TYPE:
   16469              :         case OMP_CLAUSE_MESSAGE:
   16470              :           break;
   16471              : 
   16472            0 :         case OMP_CLAUSE_NOHOST:
   16473            0 :         default:
   16474            0 :           gcc_unreachable ();
   16475              :         }
   16476              : 
   16477       128824 :       if (remove)
   16478         9947 :         *list_p = OMP_CLAUSE_CHAIN (c);
   16479       240143 :       else if (move_attach)
   16480              :         {
   16481              :           /* Remove attach node from here, separate out into its own list.  */
   16482         2360 :           *attach_tail = c;
   16483         2360 :           *list_p = OMP_CLAUSE_CHAIN (c);
   16484         2360 :           OMP_CLAUSE_CHAIN (c) = NULL_TREE;
   16485         2360 :           attach_tail = &OMP_CLAUSE_CHAIN (c);
   16486              :         }
   16487              :       else
   16488       237783 :         list_p = &OMP_CLAUSE_CHAIN (c);
   16489              :     }
   16490              : 
   16491              :   /* Splice attach nodes at the end of the list.  */
   16492       130152 :   if (attach_list)
   16493              :     {
   16494         1127 :       *list_p = attach_list;
   16495         1127 :       list_p = attach_tail;
   16496              :     }
   16497              : 
   16498              :   /* Add in any implicit data sharing.  */
   16499       130152 :   struct gimplify_adjust_omp_clauses_data data;
   16500       130152 :   if ((gimplify_omp_ctxp->region_type & ORT_ACC) == 0)
   16501              :     {
   16502              :       /* OpenMP.  Implicit clauses are added at the start of the clause list,
   16503              :          but after any non-map clauses.  */
   16504              :       tree *implicit_add_list_p = orig_list_p;
   16505       254477 :       while (*implicit_add_list_p
   16506       254477 :              && OMP_CLAUSE_CODE (*implicit_add_list_p) != OMP_CLAUSE_MAP)
   16507       154224 :         implicit_add_list_p = &OMP_CLAUSE_CHAIN (*implicit_add_list_p);
   16508       100253 :       data.list_p = implicit_add_list_p;
   16509              :     }
   16510              :   else
   16511              :     /* OpenACC.  */
   16512        29899 :     data.list_p = list_p;
   16513       130152 :   data.pre_p = pre_p;
   16514       130152 :   splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, &data);
   16515              : 
   16516       130152 :   if (has_inscan_reductions)
   16517         2499 :     for (c = *orig_list_p; c; c = OMP_CLAUSE_CHAIN (c))
   16518         1870 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   16519         1870 :           && !OMP_CLAUSE_LINEAR_NO_COPYIN (c))
   16520              :         {
   16521            5 :           error_at (OMP_CLAUSE_LOCATION (c),
   16522              :                     "%<inscan%> %<reduction%> clause used together with "
   16523              :                     "%<linear%> clause for a variable other than loop "
   16524              :                     "iterator");
   16525            5 :           break;
   16526              :         }
   16527              : 
   16528       130152 :   gimplify_omp_ctxp = ctx->outer_context;
   16529       130152 :   delete_omp_context (ctx);
   16530       130152 : }
   16531              : 
   16532              : /* Try to evaluate a novariants clause. Return 1 if true, 0 if false or absent,
   16533              :  * -1 if run-time evaluation is needed. */
   16534              : 
   16535              : int
   16536       252021 : omp_has_novariants (void)
   16537              : {
   16538       252021 :   struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   16539       252021 :   if (ctx != NULL && ctx->code == OMP_DISPATCH && !ctx->in_call_args)
   16540              :     {
   16541         3290 :       tree c = omp_find_clause (ctx->clauses, OMP_CLAUSE_NOVARIANTS);
   16542         3290 :       if (c != NULL_TREE)
   16543              :         {
   16544          299 :           if (integer_nonzerop (OMP_CLAUSE_NOVARIANTS_EXPR (c)))
   16545              :             return 1;
   16546          171 :           else if (integer_zerop (OMP_CLAUSE_NOVARIANTS_EXPR (c)))
   16547              :             return 0;
   16548              :           else
   16549           38 :             return -1;
   16550              :         }
   16551              :       return 0;
   16552              :     }
   16553              :   return 0;
   16554              : }
   16555              : 
   16556              : /* Try to evaluate a nocontext clause. Return 1 if true, 0 if false or absent,
   16557              :  * -1 if run-time evaluation is needed. */
   16558              : 
   16559              : static int
   16560         1903 : omp_has_nocontext (void)
   16561              : {
   16562         1903 :   struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   16563         1903 :   if (ctx != NULL && ctx->code == OMP_DISPATCH)
   16564              :     {
   16565         1903 :       tree c = omp_find_clause (ctx->clauses, OMP_CLAUSE_NOCONTEXT);
   16566         1903 :       if (c != NULL_TREE)
   16567              :         {
   16568          256 :           if (integer_nonzerop (OMP_CLAUSE_NOCONTEXT_EXPR (c)))
   16569              :             return 1;
   16570           94 :           else if (integer_zerop (OMP_CLAUSE_NOCONTEXT_EXPR (c)))
   16571              :             return 0;
   16572              :           else
   16573           44 :             return -1;
   16574              :         }
   16575              :       return 0;
   16576              :     }
   16577              :   return 0;
   16578              : }
   16579              : 
   16580              : /* Collect a list of traits for enclosing constructs in the current
   16581              :    OpenMP context.  The list is in the same format as the trait selector
   16582              :    list of construct trait sets built by the front ends.
   16583              : 
   16584              :    Per the OpenMP specification, the construct trait set includes constructs
   16585              :    up to an enclosing "target" construct.  If there is no "target" construct,
   16586              :    then additional things may be added to the construct trait set (simd for
   16587              :    simd clones, additional constructs associated with "declare variant",
   16588              :    the target trait for "declare target"); those are not handled here.
   16589              :    In particular simd clones are not known during gimplification so
   16590              :    matching/scoring of context selectors that might involve them needs
   16591              :    to be deferred to the omp_device_lower pass.  */
   16592              : 
   16593              : tree
   16594         2247 : omp_get_construct_context (void)
   16595              : {
   16596         2247 :   tree result = NULL_TREE;
   16597         4246 :   for (struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp; ctx;)
   16598              :     {
   16599         2120 :       if (((ctx->region_type & (ORT_TARGET | ORT_IMPLICIT_TARGET | ORT_ACC))
   16600              :                 == ORT_TARGET)
   16601          121 :                && ctx->code == OMP_TARGET)
   16602              :         {
   16603          121 :           result = make_trait_selector (OMP_TRAIT_CONSTRUCT_TARGET,
   16604              :                                         NULL_TREE, NULL_TREE, result);
   16605              :           /* We're not interested in any outer constructs.  */
   16606          121 :           break;
   16607              :         }
   16608         1999 :       else if ((ctx->region_type & ORT_PARALLEL) && ctx->code == OMP_PARALLEL)
   16609          216 :         result = make_trait_selector (OMP_TRAIT_CONSTRUCT_PARALLEL,
   16610              :                                       NULL_TREE, NULL_TREE, result);
   16611         1783 :       else if ((ctx->region_type & ORT_TEAMS) && ctx->code == OMP_TEAMS)
   16612           75 :         result = make_trait_selector (OMP_TRAIT_CONSTRUCT_TEAMS,
   16613              :                                       NULL_TREE, NULL_TREE, result);
   16614         1708 :       else if (ctx->region_type == ORT_WORKSHARE && ctx->code == OMP_FOR)
   16615          164 :         result = make_trait_selector (OMP_TRAIT_CONSTRUCT_FOR,
   16616              :                                       NULL_TREE, NULL_TREE, result);
   16617         1544 :       else if (ctx->code == OMP_DISPATCH && omp_has_nocontext () != 1)
   16618         1279 :         result = make_trait_selector (OMP_TRAIT_CONSTRUCT_DISPATCH,
   16619              :                                       NULL_TREE, NULL_TREE, result);
   16620          265 :       else if (ctx->region_type == ORT_SIMD
   16621           58 :                && ctx->code == OMP_SIMD
   16622          323 :                && !omp_find_clause (ctx->clauses, OMP_CLAUSE_BIND))
   16623              :         {
   16624           58 :           tree props = NULL_TREE;
   16625           58 :           tree *last = &props;
   16626          120 :           for (tree c = ctx->clauses; c; c = OMP_CLAUSE_CHAIN (c))
   16627           62 :             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SIMDLEN
   16628           42 :                 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INBRANCH
   16629          104 :                 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOTINBRANCH)
   16630              :               {
   16631           20 :                 *last = unshare_expr (c);
   16632           20 :                 last = &(OMP_CLAUSE_CHAIN (c));
   16633              :               }
   16634           58 :           result = make_trait_selector (OMP_TRAIT_CONSTRUCT_SIMD,
   16635              :                                         NULL_TREE, props, result);
   16636              :         }
   16637          207 :       else if (ctx->region_type == ORT_WORKSHARE
   16638            5 :                && ctx->code == OMP_LOOP
   16639            0 :                && ctx->outer_context
   16640            0 :                && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL
   16641            0 :                && ctx->outer_context->outer_context
   16642            0 :                && ctx->outer_context->outer_context->code == OMP_LOOP
   16643            0 :                && ctx->outer_context->outer_context->distribute)
   16644         1999 :         ctx = ctx->outer_context->outer_context;
   16645         1999 :       ctx = ctx->outer_context;
   16646              :     }
   16647              : 
   16648         2247 :   return result;
   16649              : }
   16650              : 
   16651              : /* Gimplify OACC_CACHE.  */
   16652              : 
   16653              : static void
   16654          717 : gimplify_oacc_cache (tree *expr_p, gimple_seq *pre_p)
   16655              : {
   16656          717 :   tree expr = *expr_p;
   16657              : 
   16658          717 :   gimplify_scan_omp_clauses (&OACC_CACHE_CLAUSES (expr), pre_p, ORT_ACC,
   16659              :                              OACC_CACHE);
   16660          717 :   gimplify_adjust_omp_clauses (pre_p, NULL, &OACC_CACHE_CLAUSES (expr),
   16661              :                                OACC_CACHE);
   16662              : 
   16663              :   /* TODO: Do something sensible with this information.  */
   16664              : 
   16665          717 :   *expr_p = NULL_TREE;
   16666          717 : }
   16667              : 
   16668              : /* Helper function of gimplify_oacc_declare.  The helper's purpose is to,
   16669              :    if required, translate 'kind' in CLAUSE into an 'entry' kind and 'exit'
   16670              :    kind.  The entry kind will replace the one in CLAUSE, while the exit
   16671              :    kind will be used in a new omp_clause and returned to the caller.  */
   16672              : 
   16673              : static tree
   16674          190 : gimplify_oacc_declare_1 (tree clause)
   16675              : {
   16676          190 :   HOST_WIDE_INT kind, new_op;
   16677          190 :   bool ret = false;
   16678          190 :   tree c = NULL;
   16679              : 
   16680          190 :   kind = OMP_CLAUSE_MAP_KIND (clause);
   16681              : 
   16682          190 :   switch (kind)
   16683              :     {
   16684              :       case GOMP_MAP_ALLOC:
   16685              :         new_op = GOMP_MAP_RELEASE;
   16686              :         ret = true;
   16687              :         break;
   16688              : 
   16689           29 :       case GOMP_MAP_FROM:
   16690           29 :         OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_FORCE_ALLOC);
   16691           29 :         new_op = GOMP_MAP_FROM;
   16692           29 :         ret = true;
   16693           29 :         break;
   16694              : 
   16695           40 :       case GOMP_MAP_TOFROM:
   16696           40 :         OMP_CLAUSE_SET_MAP_KIND (clause, GOMP_MAP_TO);
   16697           40 :         new_op = GOMP_MAP_FROM;
   16698           40 :         ret = true;
   16699           40 :         break;
   16700              : 
   16701              :       case GOMP_MAP_DEVICE_RESIDENT:
   16702              :       case GOMP_MAP_FORCE_DEVICEPTR:
   16703              :       case GOMP_MAP_FORCE_PRESENT:
   16704              :       case GOMP_MAP_LINK:
   16705              :       case GOMP_MAP_POINTER:
   16706              :       case GOMP_MAP_TO:
   16707              :         break;
   16708              : 
   16709            0 :       default:
   16710            0 :         gcc_unreachable ();
   16711           69 :         break;
   16712              :     }
   16713              : 
   16714           69 :   if (ret)
   16715              :     {
   16716          116 :       c = build_omp_clause (OMP_CLAUSE_LOCATION (clause), OMP_CLAUSE_MAP);
   16717          116 :       OMP_CLAUSE_SET_MAP_KIND (c, new_op);
   16718          116 :       OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clause);
   16719              :     }
   16720              : 
   16721          190 :   return c;
   16722              : }
   16723              : 
   16724              : /* Gimplify OACC_DECLARE.  */
   16725              : 
   16726              : static void
   16727          254 : gimplify_oacc_declare (tree *expr_p, gimple_seq *pre_p)
   16728              : {
   16729          254 :   tree expr = *expr_p;
   16730          254 :   gomp_target *stmt;
   16731          254 :   tree clauses, t, decl;
   16732              : 
   16733          254 :   clauses = OACC_DECLARE_CLAUSES (expr);
   16734              : 
   16735          254 :   gimplify_scan_omp_clauses (&clauses, pre_p, ORT_TARGET_DATA, OACC_DECLARE);
   16736          254 :   gimplify_adjust_omp_clauses (pre_p, NULL, &clauses, OACC_DECLARE);
   16737              : 
   16738          516 :   for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
   16739              :     {
   16740          262 :       decl = OMP_CLAUSE_DECL (t);
   16741              : 
   16742          262 :       if (TREE_CODE (decl) == MEM_REF)
   16743            8 :         decl = TREE_OPERAND (decl, 0);
   16744              : 
   16745          262 :       if (VAR_P (decl) && !is_oacc_declared (decl))
   16746              :         {
   16747          262 :           tree attr = get_identifier ("oacc declare target");
   16748          262 :           DECL_ATTRIBUTES (decl) = tree_cons (attr, NULL_TREE,
   16749          262 :                                               DECL_ATTRIBUTES (decl));
   16750              :         }
   16751              : 
   16752          262 :       if (VAR_P (decl)
   16753          262 :           && !is_global_var (decl)
   16754          452 :           && DECL_CONTEXT (decl) == current_function_decl)
   16755              :         {
   16756          190 :           tree c = gimplify_oacc_declare_1 (t);
   16757          190 :           if (c)
   16758              :             {
   16759          116 :               if (oacc_declare_returns == NULL)
   16760           40 :                 oacc_declare_returns = new hash_map<tree, tree>;
   16761              : 
   16762          116 :               oacc_declare_returns->put (decl, c);
   16763              :             }
   16764              :         }
   16765              : 
   16766          262 :       if (gimplify_omp_ctxp)
   16767           72 :         omp_add_variable (gimplify_omp_ctxp, decl, GOVD_SEEN);
   16768              :     }
   16769              : 
   16770          254 :   stmt = gimple_build_omp_target (NULL, GF_OMP_TARGET_KIND_OACC_DECLARE,
   16771              :                                   clauses);
   16772              : 
   16773          254 :   gimplify_seq_add_stmt (pre_p, stmt);
   16774              : 
   16775          254 :   *expr_p = NULL_TREE;
   16776          254 : }
   16777              : 
   16778              : /* Gimplify the contents of an OMP_PARALLEL statement.  This involves
   16779              :    gimplification of the body, as well as scanning the body for used
   16780              :    variables.  We need to do this scan now, because variable-sized
   16781              :    decls will be decomposed during gimplification.  */
   16782              : 
   16783              : static void
   16784        18392 : gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
   16785              : {
   16786        18392 :   tree expr = *expr_p;
   16787        18392 :   gimple *g;
   16788        18392 :   gimple_seq body = NULL;
   16789              : 
   16790        36784 :   gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
   16791        18392 :                              OMP_PARALLEL_COMBINED (expr)
   16792              :                              ? ORT_COMBINED_PARALLEL
   16793              :                              : ORT_PARALLEL, OMP_PARALLEL);
   16794              : 
   16795        18392 :   push_gimplify_context ();
   16796              : 
   16797        18392 :   g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
   16798        18392 :   if (gimple_code (g) == GIMPLE_BIND)
   16799        18392 :     pop_gimplify_context (g);
   16800              :   else
   16801            0 :     pop_gimplify_context (NULL);
   16802              : 
   16803        18392 :   gimplify_adjust_omp_clauses (pre_p, body, &OMP_PARALLEL_CLAUSES (expr),
   16804              :                                OMP_PARALLEL);
   16805              : 
   16806        36784 :   g = gimple_build_omp_parallel (body,
   16807        18392 :                                  OMP_PARALLEL_CLAUSES (expr),
   16808              :                                  NULL_TREE, NULL_TREE);
   16809        18392 :   if (OMP_PARALLEL_COMBINED (expr))
   16810        12584 :     gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
   16811        18392 :   gimplify_seq_add_stmt (pre_p, g);
   16812        18392 :   *expr_p = NULL_TREE;
   16813        18392 : }
   16814              : 
   16815              : /* Gimplify the contents of an OMP_TASK statement.  This involves
   16816              :    gimplification of the body, as well as scanning the body for used
   16817              :    variables.  We need to do this scan now, because variable-sized
   16818              :    decls will be decomposed during gimplification.  */
   16819              : 
   16820              : static void
   16821         4111 : gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
   16822              : {
   16823         4111 :   tree expr = *expr_p;
   16824         4111 :   gimple *g;
   16825         4111 :   gimple_seq body = NULL;
   16826         4111 :   bool nowait = false;
   16827         4111 :   bool has_depend = false;
   16828              : 
   16829         4111 :   if (OMP_TASK_BODY (expr) == NULL_TREE)
   16830              :     {
   16831          242 :       for (tree c = OMP_TASK_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   16832          153 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
   16833              :           {
   16834          111 :             has_depend = true;
   16835          111 :             if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_MUTEXINOUTSET)
   16836              :               {
   16837            9 :                 error_at (OMP_CLAUSE_LOCATION (c),
   16838              :                           "%<mutexinoutset%> kind in %<depend%> clause on a "
   16839              :                           "%<taskwait%> construct");
   16840            9 :                 break;
   16841              :               }
   16842              :           }
   16843           42 :         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOWAIT)
   16844           42 :           nowait = true;
   16845           98 :       if (nowait && !has_depend)
   16846              :         {
   16847            5 :           error_at (EXPR_LOCATION (expr),
   16848              :                     "%<taskwait%> construct with %<nowait%> clause but no "
   16849              :                     "%<depend%> clauses");
   16850            5 :           *expr_p = NULL_TREE;
   16851            5 :           return;
   16852              :         }
   16853              :     }
   16854              : 
   16855        12318 :   gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
   16856         4106 :                              omp_find_clause (OMP_TASK_CLAUSES (expr),
   16857              :                                               OMP_CLAUSE_UNTIED)
   16858              :                              ? ORT_UNTIED_TASK : ORT_TASK, OMP_TASK);
   16859              : 
   16860         4106 :   if (OMP_TASK_BODY (expr))
   16861              :     {
   16862         4013 :       push_gimplify_context ();
   16863              : 
   16864         4013 :       g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
   16865         4013 :       if (gimple_code (g) == GIMPLE_BIND)
   16866         4013 :         pop_gimplify_context (g);
   16867              :       else
   16868            0 :         pop_gimplify_context (NULL);
   16869              :     }
   16870              : 
   16871         4106 :   gimplify_adjust_omp_clauses (pre_p, body, &OMP_TASK_CLAUSES (expr),
   16872              :                                OMP_TASK);
   16873              : 
   16874         8212 :   g = gimple_build_omp_task (body,
   16875         4106 :                              OMP_TASK_CLAUSES (expr),
   16876              :                              NULL_TREE, NULL_TREE,
   16877              :                              NULL_TREE, NULL_TREE, NULL_TREE);
   16878         4106 :   if (OMP_TASK_BODY (expr) == NULL_TREE)
   16879           93 :     gimple_omp_task_set_taskwait_p (g, true);
   16880         4106 :   gimplify_seq_add_stmt (pre_p, g);
   16881         4106 :   *expr_p = NULL_TREE;
   16882              : }
   16883              : 
   16884              : /* Helper function for gimplify_omp_for.  If *TP is not a gimple constant,
   16885              :    force it into a temporary initialized in PRE_P and add firstprivate clause
   16886              :    to ORIG_FOR_STMT.  */
   16887              : 
   16888              : static void
   16889         4399 : gimplify_omp_taskloop_expr (tree type, tree *tp, gimple_seq *pre_p,
   16890              :                             tree orig_for_stmt)
   16891              : {
   16892         4399 :   if (*tp == NULL || is_gimple_constant (*tp))
   16893              :     return;
   16894              : 
   16895          779 :   if (TREE_CODE (*tp) == SAVE_EXPR)
   16896          135 :     gimplify_save_expr (tp, pre_p, NULL);
   16897              :   else
   16898          644 :     *tp = get_initialized_tmp_var (*tp, pre_p, NULL, false);
   16899              :   /* Reference to pointer conversion is considered useless,
   16900              :      but is significant for firstprivate clause.  Force it
   16901              :      here.  */
   16902          779 :   if (type
   16903          687 :       && TREE_CODE (type) == POINTER_TYPE
   16904          869 :       && TREE_CODE (TREE_TYPE (*tp)) == REFERENCE_TYPE)
   16905              :     {
   16906            2 :       tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
   16907            2 :       tree m = build2 (INIT_EXPR, TREE_TYPE (v), v, *tp);
   16908            2 :       gimplify_and_add (m, pre_p);
   16909            2 :       *tp = v;
   16910              :     }
   16911              : 
   16912          779 :   tree c = build_omp_clause (input_location, OMP_CLAUSE_FIRSTPRIVATE);
   16913          779 :   OMP_CLAUSE_DECL (c) = *tp;
   16914          779 :   OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (orig_for_stmt);
   16915          779 :   OMP_FOR_CLAUSES (orig_for_stmt) = c;
   16916              : }
   16917              : 
   16918              : /* Helper function of gimplify_omp_for, find OMP_ORDERED with
   16919              :    null OMP_ORDERED_BODY inside of OMP_FOR's body.  */
   16920              : 
   16921              : static tree
   16922        16496 : find_standalone_omp_ordered (tree *tp, int *walk_subtrees, void *)
   16923              : {
   16924        16496 :   switch (TREE_CODE (*tp))
   16925              :     {
   16926          901 :     case OMP_ORDERED:
   16927          901 :       if (OMP_ORDERED_BODY (*tp) == NULL_TREE)
   16928          531 :         return *tp;
   16929              :       break;
   16930           23 :     case OMP_SIMD:
   16931           23 :     case OMP_PARALLEL:
   16932           23 :     case OMP_TARGET:
   16933           23 :       *walk_subtrees = 0;
   16934           23 :       break;
   16935              :     default:
   16936              :       break;
   16937              :     }
   16938              :   return NULL_TREE;
   16939              : }
   16940              : 
   16941              : /* Gimplify standalone loop transforming directive which has the
   16942              :    transformations applied already.  So, all that is needed is gimplify
   16943              :    the remaining loops as normal loops.  */
   16944              : 
   16945              : static enum gimplify_status
   16946         2266 : gimplify_omp_loop_xform (tree *expr_p, gimple_seq *pre_p)
   16947              : {
   16948         2266 :   tree for_stmt = *expr_p;
   16949              : 
   16950         2266 :   if (OMP_FOR_PRE_BODY (for_stmt))
   16951          759 :     gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), pre_p);
   16952              : 
   16953         2266 :   gimple_seq pre_body = NULL, post_body = NULL;
   16954         5207 :   for (int i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   16955              :     {
   16956         2941 :       if (TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i) == NULL_TREE)
   16957         1707 :         continue;
   16958         1285 :       tree iters = NULL_TREE;
   16959         1285 :       if (i == 0
   16960          828 :           && TREE_CODE (for_stmt) == OMP_UNROLL
   16961         1775 :           && !omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_PARTIAL))
   16962              :         {
   16963          313 :           if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_FULL))
   16964          270 :             iters = omp_loop_number_of_iterations (for_stmt, 0, NULL);
   16965              :           else
   16966           43 :             iters = build_int_cst (integer_type_node, 8);
   16967              :         }
   16968         1285 :       tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   16969         1285 :       gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   16970         1285 :       tree decl = TREE_OPERAND (t, 0);
   16971         1285 :       gcc_assert (DECL_P (decl));
   16972         1285 :       gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
   16973              :                   || POINTER_TYPE_P (TREE_TYPE (decl)));
   16974         1285 :       if (DECL_ARTIFICIAL (decl)
   16975          876 :           && TREE_PRIVATE (t)
   16976          867 :           && gimplify_omp_ctxp
   16977         1615 :           && gimplify_omp_ctxp->region_type != ORT_NONE)
   16978              :         {
   16979              :           struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   16980          504 :           do
   16981              :             {
   16982          504 :               splay_tree_node n
   16983          504 :                 = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
   16984          504 :               if (n != NULL)
   16985              :                 break;
   16986          346 :               else if (ctx->region_type != ORT_WORKSHARE
   16987              :                        && ctx->region_type != ORT_TASKGROUP
   16988           62 :                        && ctx->region_type != ORT_SIMD
   16989           38 :                        && ctx->region_type != ORT_ACC
   16990           38 :                        && !(ctx->region_type & ORT_TARGET_DATA))
   16991              :                 {
   16992           38 :                   omp_add_variable (ctx, decl, GOVD_PRIVATE);
   16993           38 :                   break;
   16994              :                 }
   16995          308 :               ctx = ctx->outer_context;
   16996              :             }
   16997          308 :           while (ctx);
   16998              :         }
   16999         1285 :       if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   17000              :         {
   17001           23 :           gcc_assert (seen_error ());
   17002           23 :           continue;
   17003              :         }
   17004         1262 :       gimplify_expr (&TREE_OPERAND (t, 1), pre_p, NULL, is_gimple_val,
   17005              :                      fb_rvalue);
   17006         1262 :       gimplify_and_add (t, &pre_body);
   17007         1262 :       t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
   17008         1262 :       gcc_assert (TREE_OPERAND (t, 0) == decl);
   17009         1262 :       if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   17010              :         {
   17011           28 :           gcc_assert (seen_error ());
   17012           28 :           continue;
   17013              :         }
   17014         1234 :       gimplify_expr (&TREE_OPERAND (t, 1), pre_p, NULL, is_gimple_val,
   17015              :                      fb_rvalue);
   17016         1234 :       tree l1 = create_artificial_label (UNKNOWN_LOCATION);
   17017         1234 :       tree l2 = create_artificial_label (UNKNOWN_LOCATION);
   17018         1234 :       tree l3 = create_artificial_label (UNKNOWN_LOCATION);
   17019         1234 :       gimplify_seq_add_stmt (&pre_body, gimple_build_goto (l2));
   17020         1234 :       gimplify_seq_add_stmt (&pre_body, gimple_build_label (l1));
   17021         1234 :       gimple_seq this_post_body = NULL;
   17022         1234 :       t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   17023         1234 :       if (TREE_CODE (t) == MODIFY_EXPR)
   17024              :         {
   17025          977 :           t = TREE_OPERAND (t, 1);
   17026          977 :           if (TREE_CODE (t) == PLUS_EXPR
   17027          977 :               && TREE_OPERAND (t, 1) == decl)
   17028              :             {
   17029            0 :               TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
   17030            0 :               TREE_OPERAND (t, 0) = decl;
   17031              :             }
   17032          977 :           gimplify_expr (&TREE_OPERAND (t, 1), pre_p, NULL, is_gimple_val,
   17033              :                          fb_rvalue);
   17034              :         }
   17035         1234 :       gimplify_and_add (TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i),
   17036              :                         &this_post_body);
   17037         1234 :       gimplify_seq_add_stmt (&this_post_body, gimple_build_label (l2));
   17038         1234 :       t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
   17039         1234 :       gcond *cond = NULL;
   17040         1234 :       tree d = decl;
   17041         1234 :       gimplify_expr (&d, &this_post_body, NULL, is_gimple_val, fb_rvalue);
   17042         1234 :       if (iters && tree_fits_uhwi_p (iters))
   17043              :         {
   17044          301 :           unsigned HOST_WIDE_INT niters = tree_to_uhwi (iters);
   17045          301 :           if ((unsigned HOST_WIDE_INT) (int) niters == niters
   17046          301 :               && (int) niters > 0)
   17047              :             {
   17048          301 :               t = build2 (TREE_CODE (t), boolean_type_node, d,
   17049          301 :                           TREE_OPERAND (t, 1));
   17050          301 :               t = build3 (ANNOTATE_EXPR, TREE_TYPE (t), t,
   17051              :                           build_int_cst (integer_type_node,
   17052              :                                          annot_expr_unroll_kind),
   17053          301 :                           build_int_cst (integer_type_node, niters));
   17054          301 :               gimplify_expr (&t, &this_post_body, NULL, is_gimple_val,
   17055              :                              fb_rvalue);
   17056          301 :               cond = gimple_build_cond (NE_EXPR, t, boolean_false_node,
   17057              :                                         l1, l3);
   17058              :             }
   17059              :         }
   17060          301 :       if (cond == NULL)
   17061          933 :         cond = gimple_build_cond (TREE_CODE (t), d, TREE_OPERAND (t, 1),
   17062              :                                   l1, l3);
   17063         1234 :       gimplify_seq_add_stmt (&this_post_body, cond);
   17064         1234 :       gimplify_seq_add_stmt (&this_post_body, gimple_build_label (l3));
   17065         1234 :       gimplify_seq_add_seq (&this_post_body, post_body);
   17066         1234 :       post_body = this_post_body;
   17067              :     }
   17068         2266 :   gimplify_seq_add_seq (pre_p, pre_body);
   17069         2266 :   gimplify_and_add (OMP_FOR_BODY (for_stmt), pre_p);
   17070         2266 :   gimplify_seq_add_seq (pre_p, post_body);
   17071              : 
   17072         2266 :   *expr_p = NULL_TREE;
   17073         2266 :   return GS_ALL_DONE;
   17074              : }
   17075              : 
   17076              : /* Gimplify the gross structure of an OMP_FOR statement.  */
   17077              : 
   17078              : static enum gimplify_status
   17079        58346 : gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
   17080              : {
   17081        58346 :   tree for_stmt, orig_for_stmt, inner_for_stmt = NULL_TREE, decl, var, t;
   17082        58346 :   enum gimplify_status ret = GS_ALL_DONE;
   17083        58346 :   enum gimplify_status tret;
   17084        58346 :   gomp_for *gfor;
   17085        58346 :   gimple_seq for_body, for_pre_body;
   17086        58346 :   int i;
   17087        58346 :   bitmap has_decl_expr = NULL;
   17088        58346 :   enum omp_region_type ort = ORT_WORKSHARE;
   17089        58346 :   bool openacc = TREE_CODE (*expr_p) == OACC_LOOP;
   17090              : 
   17091        58346 :   orig_for_stmt = for_stmt = *expr_p;
   17092              : 
   17093        58346 :   bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
   17094        58346 :                  != NULL_TREE);
   17095        58417 :   while (OMP_FOR_INIT (for_stmt) == NULL_TREE)
   17096              :     {
   17097        17794 :       tree *data[4] = { NULL, NULL, NULL, NULL };
   17098        17794 :       gcc_assert (TREE_CODE (for_stmt) != OACC_LOOP);
   17099        17794 :       inner_for_stmt = walk_tree (&OMP_FOR_BODY (for_stmt),
   17100              :                                   find_combined_omp_for, data, NULL);
   17101        17794 :       if (inner_for_stmt == NULL_TREE)
   17102              :         {
   17103           36 :           gcc_assert (seen_error ());
   17104           36 :           *expr_p = NULL_TREE;
   17105         3748 :           return GS_ERROR;
   17106              :         }
   17107        17758 :       gcc_assert (inner_for_stmt == *data[3]);
   17108        17758 :       omp_maybe_apply_loop_xforms (data[3],
   17109        17758 :                                    data[2]
   17110         4281 :                                    ? OMP_FOR_CLAUSES (*data[2])
   17111        13477 :                                    : TREE_CODE (for_stmt) == OMP_FOR
   17112        13477 :                                    ? OMP_FOR_CLAUSES (for_stmt)
   17113              :                                    : NULL_TREE);
   17114        17758 :       if (inner_for_stmt != *data[3])
   17115           71 :         continue;
   17116        17687 :       if (data[2] && OMP_FOR_PRE_BODY (*data[2]))
   17117              :         {
   17118            2 :           append_to_statement_list_force (OMP_FOR_PRE_BODY (*data[2]),
   17119              :                                           &OMP_FOR_PRE_BODY (for_stmt));
   17120            2 :           OMP_FOR_PRE_BODY (*data[2]) = NULL_TREE;
   17121              :         }
   17122        17687 :       if (OMP_FOR_PRE_BODY (inner_for_stmt))
   17123              :         {
   17124         7231 :           append_to_statement_list_force (OMP_FOR_PRE_BODY (inner_for_stmt),
   17125              :                                           &OMP_FOR_PRE_BODY (for_stmt));
   17126         7231 :           OMP_FOR_PRE_BODY (inner_for_stmt) = NULL_TREE;
   17127              :         }
   17128              : 
   17129        17687 :       if (data[0])
   17130              :         {
   17131              :           /* We have some statements or variable declarations in between
   17132              :              the composite construct directives.  Move them around the
   17133              :              inner_for_stmt.  */
   17134         3712 :           data[0] = expr_p;
   17135        14848 :           for (i = 0; i < 3; i++)
   17136        11136 :             if (data[i])
   17137              :               {
   17138         7034 :                 tree t = *data[i];
   17139         7034 :                 if (i < 2 && data[i + 1] == &OMP_BODY (t))
   17140         1005 :                   data[i + 1] = data[i];
   17141         7034 :                 *data[i] = OMP_BODY (t);
   17142         7034 :                 tree body = build3 (BIND_EXPR, void_type_node, NULL_TREE,
   17143              :                                     NULL_TREE, make_node (BLOCK));
   17144         7034 :                 OMP_BODY (t) = body;
   17145         7034 :                 append_to_statement_list_force (inner_for_stmt,
   17146              :                                                 &BIND_EXPR_BODY (body));
   17147         7034 :                 *data[3] = t;
   17148         7034 :                 data[3] = tsi_stmt_ptr (tsi_start (BIND_EXPR_BODY (body)));
   17149         7034 :                 gcc_assert (*data[3] == inner_for_stmt);
   17150              :               }
   17151              :           return GS_OK;
   17152              :         }
   17153              : 
   17154        36832 :       for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
   17155        22857 :         if (!loop_p
   17156        21976 :             && OMP_FOR_ORIG_DECLS (inner_for_stmt)
   17157        11134 :             && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
   17158              :                                         i)) == TREE_LIST
   17159        22925 :             && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
   17160              :                                            i)))
   17161              :           {
   17162           40 :             tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
   17163              :             /* Class iterators aren't allowed on OMP_SIMD, so the only
   17164              :                case we need to solve is distribute parallel for.  They are
   17165              :                allowed on the loop construct, but that is already handled
   17166              :                in gimplify_omp_loop.  */
   17167           40 :             gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
   17168              :                         && TREE_CODE (for_stmt) == OMP_DISTRIBUTE
   17169              :                         && data[1]);
   17170           40 :             tree orig_decl = TREE_PURPOSE (orig);
   17171           40 :             tree last = TREE_VALUE (orig);
   17172           40 :             tree *pc;
   17173           40 :             for (pc = &OMP_FOR_CLAUSES (inner_for_stmt);
   17174           74 :                  *pc; pc = &OMP_CLAUSE_CHAIN (*pc))
   17175           42 :               if ((OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE
   17176           35 :                    || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LASTPRIVATE)
   17177           43 :                   && OMP_CLAUSE_DECL (*pc) == orig_decl)
   17178              :                 break;
   17179           40 :             if (*pc == NULL_TREE)
   17180              :               {
   17181           32 :                 tree *spc;
   17182           32 :                 for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
   17183           98 :                      *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
   17184           67 :                   if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
   17185           67 :                       && OMP_CLAUSE_DECL (*spc) == orig_decl)
   17186              :                     break;
   17187           32 :                 if (*spc)
   17188              :                   {
   17189            1 :                     tree c = *spc;
   17190            1 :                     *spc = OMP_CLAUSE_CHAIN (c);
   17191            1 :                     OMP_CLAUSE_CHAIN (c) = NULL_TREE;
   17192            1 :                     *pc = c;
   17193              :                   }
   17194              :               }
   17195           40 :             if (*pc == NULL_TREE)
   17196              :               ;
   17197            9 :             else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
   17198              :               {
   17199              :                 /* private clause will appear only on inner_for_stmt.
   17200              :                    Change it into firstprivate, and add private clause
   17201              :                    on for_stmt.  */
   17202            8 :                 tree c = copy_node (*pc);
   17203            8 :                 OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
   17204            8 :                 OMP_FOR_CLAUSES (for_stmt) = c;
   17205            8 :                 OMP_CLAUSE_CODE (*pc) = OMP_CLAUSE_FIRSTPRIVATE;
   17206            8 :                 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
   17207              :               }
   17208              :             else
   17209              :               {
   17210              :                 /* lastprivate clause will appear on both inner_for_stmt
   17211              :                    and for_stmt.  Add firstprivate clause to
   17212              :                    inner_for_stmt.  */
   17213            1 :                 tree c = build_omp_clause (OMP_CLAUSE_LOCATION (*pc),
   17214              :                                            OMP_CLAUSE_FIRSTPRIVATE);
   17215            1 :                 OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (*pc);
   17216            1 :                 OMP_CLAUSE_CHAIN (c) = *pc;
   17217            1 :                 *pc = c;
   17218            1 :                 lang_hooks.decls.omp_finish_clause (*pc, pre_p, openacc);
   17219              :               }
   17220           40 :             tree c = build_omp_clause (UNKNOWN_LOCATION,
   17221              :                                        OMP_CLAUSE_FIRSTPRIVATE);
   17222           40 :             OMP_CLAUSE_DECL (c) = last;
   17223           40 :             OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
   17224           40 :             OMP_PARALLEL_CLAUSES (*data[1]) = c;
   17225           40 :             c = build_omp_clause (UNKNOWN_LOCATION,
   17226           40 :                                   *pc ? OMP_CLAUSE_SHARED
   17227              :                                       : OMP_CLAUSE_FIRSTPRIVATE);
   17228           40 :             OMP_CLAUSE_DECL (c) = orig_decl;
   17229           40 :             OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
   17230           40 :             OMP_PARALLEL_CLAUSES (*data[1]) = c;
   17231              :           }
   17232              :       /* Similarly, take care of C++ range for temporaries, those should
   17233              :          be firstprivate on OMP_PARALLEL if any.  */
   17234        13975 :       if (data[1])
   17235        17575 :         for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
   17236        11144 :           if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
   17237         5763 :               && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
   17238              :                                           i)) == TREE_LIST
   17239        11220 :               && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
   17240              :                                            i)))
   17241              :             {
   17242           49 :               tree orig
   17243           49 :                 = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
   17244           49 :               tree v = TREE_CHAIN (orig);
   17245           49 :               tree c = build_omp_clause (UNKNOWN_LOCATION,
   17246              :                                          OMP_CLAUSE_FIRSTPRIVATE);
   17247              :               /* First add firstprivate clause for the __for_end artificial
   17248              :                  decl.  */
   17249           49 :               OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 1);
   17250           49 :               if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
   17251              :                   == REFERENCE_TYPE)
   17252            0 :                 OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
   17253           49 :               OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
   17254           49 :               OMP_PARALLEL_CLAUSES (*data[1]) = c;
   17255           49 :               if (TREE_VEC_ELT (v, 0))
   17256              :                 {
   17257              :                   /* And now the same for __for_range artificial decl if it
   17258              :                      exists.  */
   17259           49 :                   c = build_omp_clause (UNKNOWN_LOCATION,
   17260              :                                         OMP_CLAUSE_FIRSTPRIVATE);
   17261           49 :                   OMP_CLAUSE_DECL (c) = TREE_VEC_ELT (v, 0);
   17262           49 :                   if (TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c)))
   17263              :                       == REFERENCE_TYPE)
   17264           49 :                     OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE (c) = 1;
   17265           49 :                   OMP_CLAUSE_CHAIN (c) = OMP_PARALLEL_CLAUSES (*data[1]);
   17266           49 :                   OMP_PARALLEL_CLAUSES (*data[1]) = c;
   17267              :                 }
   17268              :             }
   17269        13975 :       break;
   17270              :     }
   17271        54598 :   if (OMP_FOR_INIT (for_stmt) != NULL_TREE)
   17272              :     {
   17273        40623 :       omp_maybe_apply_loop_xforms (expr_p, NULL_TREE);
   17274        40623 :       if (*expr_p != for_stmt)
   17275              :         return GS_OK;
   17276              :     }
   17277              : 
   17278        53716 :   switch (TREE_CODE (for_stmt))
   17279              :     {
   17280        18288 :     case OMP_FOR:
   17281        30594 :       if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
   17282              :         {
   17283          458 :           if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   17284              :                                OMP_CLAUSE_SCHEDULE))
   17285           47 :             error_at (EXPR_LOCATION (for_stmt),
   17286              :                       "%qs clause may not appear on non-rectangular %qs",
   17287           27 :                       "schedule", lang_GNU_Fortran () ? "do" : "for");
   17288          458 :           if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED))
   17289           34 :             error_at (EXPR_LOCATION (for_stmt),
   17290              :                       "%qs clause may not appear on non-rectangular %qs",
   17291           18 :                       "ordered", lang_GNU_Fortran () ? "do" : "for");
   17292              :         }
   17293              :       break;
   17294         8287 :     case OMP_DISTRIBUTE:
   17295         9230 :       if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt)
   17296         8287 :           && omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   17297              :                               OMP_CLAUSE_DIST_SCHEDULE))
   17298           29 :         error_at (EXPR_LOCATION (for_stmt),
   17299              :                   "%qs clause may not appear on non-rectangular %qs",
   17300              :                   "dist_schedule", "distribute");
   17301              :       break;
   17302              :     case OACC_LOOP:
   17303              :       ort = ORT_ACC;
   17304              :       break;
   17305         1586 :     case OMP_TASKLOOP:
   17306         2523 :       if (OMP_FOR_NON_RECTANGULAR (inner_for_stmt ? inner_for_stmt : for_stmt))
   17307              :         {
   17308           36 :           if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   17309              :                                OMP_CLAUSE_GRAINSIZE))
   17310           11 :             error_at (EXPR_LOCATION (for_stmt),
   17311              :                       "%qs clause may not appear on non-rectangular %qs",
   17312              :                       "grainsize", "taskloop");
   17313           36 :           if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   17314              :                                OMP_CLAUSE_NUM_TASKS))
   17315            6 :             error_at (EXPR_LOCATION (for_stmt),
   17316              :                       "%qs clause may not appear on non-rectangular %qs",
   17317              :                       "num_tasks", "taskloop");
   17318              :         }
   17319         1586 :       if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
   17320              :         ort = ORT_UNTIED_TASKLOOP;
   17321              :       else
   17322              :         ort = ORT_TASKLOOP;
   17323              :       break;
   17324        10737 :     case OMP_SIMD:
   17325        10737 :       ort = ORT_SIMD;
   17326        10737 :       break;
   17327         2266 :     case OMP_TILE:
   17328         2266 :     case OMP_UNROLL:
   17329         2266 :       gcc_assert (inner_for_stmt == NULL_TREE);
   17330         2266 :       return gimplify_omp_loop_xform (expr_p, pre_p);
   17331            0 :     default:
   17332            0 :       gcc_unreachable ();
   17333              :     }
   17334              : 
   17335              :   /* Set OMP_CLAUSE_LINEAR_NO_COPYIN flag on explicit linear
   17336              :      clause for the IV.  */
   17337        10784 :   if (ort == ORT_SIMD && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
   17338              :     {
   17339         7909 :       t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0);
   17340         7909 :       gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   17341         7909 :       decl = TREE_OPERAND (t, 0);
   17342        18756 :       for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
   17343        11981 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   17344        11981 :             && OMP_CLAUSE_DECL (c) == decl)
   17345              :           {
   17346         1134 :             OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
   17347         1134 :             break;
   17348              :           }
   17349              :     }
   17350              : 
   17351        51450 :   if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
   17352        51774 :     gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
   17353         1910 :                                loop_p && TREE_CODE (for_stmt) != OMP_SIMD
   17354              :                                ? OMP_LOOP : TREE_CODE (for_stmt));
   17355              : 
   17356        51450 :   if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
   17357         8287 :     gimplify_omp_ctxp->distribute = true;
   17358              : 
   17359              :   /* Handle OMP_FOR_INIT.  */
   17360        51450 :   for_pre_body = NULL;
   17361        51450 :   if ((ort == ORT_SIMD
   17362        40713 :        || (inner_for_stmt && TREE_CODE (inner_for_stmt) == OMP_SIMD))
   17363        62205 :       && OMP_FOR_PRE_BODY (for_stmt))
   17364              :     {
   17365         6848 :       has_decl_expr = BITMAP_ALLOC (NULL);
   17366         6848 :       if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
   17367         6848 :           && VAR_P (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt))))
   17368              :         {
   17369           18 :           t = OMP_FOR_PRE_BODY (for_stmt);
   17370           18 :           bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
   17371              :         }
   17372         6830 :       else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
   17373              :         {
   17374         6828 :           tree_stmt_iterator si;
   17375        11362 :           for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
   17376         4534 :                tsi_next (&si))
   17377              :             {
   17378         4534 :               t = tsi_stmt (si);
   17379         4534 :               if (TREE_CODE (t) == DECL_EXPR
   17380         4534 :                   && VAR_P (DECL_EXPR_DECL (t)))
   17381         4461 :                 bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
   17382              :             }
   17383              :         }
   17384              :     }
   17385        51450 :   if (OMP_FOR_PRE_BODY (for_stmt))
   17386              :     {
   17387        21133 :       if (TREE_CODE (for_stmt) != OMP_TASKLOOP || gimplify_omp_ctxp)
   17388        20408 :         gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
   17389              :       else
   17390              :         {
   17391          725 :           struct gimplify_omp_ctx ctx;
   17392          725 :           memset (&ctx, 0, sizeof (ctx));
   17393          725 :           ctx.region_type = ORT_NONE;
   17394          725 :           gimplify_omp_ctxp = &ctx;
   17395          725 :           gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
   17396          725 :           gimplify_omp_ctxp = NULL;
   17397              :         }
   17398              :     }
   17399        51450 :   OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
   17400              : 
   17401        51450 :   if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
   17402        13975 :     for_stmt = inner_for_stmt;
   17403              : 
   17404              :   /* For taskloop, need to gimplify the start, end and step before the
   17405              :      taskloop, outside of the taskloop omp context.  */
   17406        51450 :   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
   17407              :     {
   17408         3458 :       for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   17409              :         {
   17410         1872 :           t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   17411         1872 :           gimple_seq *for_pre_p = (gimple_seq_empty_p (for_pre_body)
   17412         1872 :                                    ? pre_p : &for_pre_body);
   17413         1872 :               tree type = TREE_TYPE (TREE_OPERAND (t, 0));
   17414         1872 :           if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   17415              :             {
   17416           34 :               tree v = TREE_OPERAND (t, 1);
   17417           34 :               gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
   17418              :                                           for_pre_p, orig_for_stmt);
   17419           34 :               gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
   17420              :                                           for_pre_p, orig_for_stmt);
   17421              :             }
   17422              :           else
   17423         1838 :             gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
   17424              :                                         orig_for_stmt);
   17425              : 
   17426              :           /* Handle OMP_FOR_COND.  */
   17427         1872 :           t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
   17428         1872 :           if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   17429              :             {
   17430           31 :               tree v = TREE_OPERAND (t, 1);
   17431           31 :               gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 1),
   17432              :                                           for_pre_p, orig_for_stmt);
   17433           31 :               gimplify_omp_taskloop_expr (type, &TREE_VEC_ELT (v, 2),
   17434              :                                           for_pre_p, orig_for_stmt);
   17435              :             }
   17436              :           else
   17437         1841 :             gimplify_omp_taskloop_expr (type, &TREE_OPERAND (t, 1), for_pre_p,
   17438              :                                         orig_for_stmt);
   17439              : 
   17440              :           /* Handle OMP_FOR_INCR.  */
   17441         1872 :           t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   17442         1872 :           if (TREE_CODE (t) == MODIFY_EXPR)
   17443              :             {
   17444          590 :               decl = TREE_OPERAND (t, 0);
   17445          590 :               t = TREE_OPERAND (t, 1);
   17446          590 :               tree *tp = &TREE_OPERAND (t, 1);
   17447          590 :               if (TREE_CODE (t) == PLUS_EXPR && *tp == decl)
   17448           22 :                 tp = &TREE_OPERAND (t, 0);
   17449              : 
   17450          590 :               gimplify_omp_taskloop_expr (NULL_TREE, tp, for_pre_p,
   17451              :                                           orig_for_stmt);
   17452              :             }
   17453              :         }
   17454              : 
   17455         1586 :       gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (orig_for_stmt), pre_p, ort,
   17456              :                                  OMP_TASKLOOP);
   17457              :     }
   17458              : 
   17459        51450 :   if (orig_for_stmt != for_stmt)
   17460        13975 :     gimplify_omp_ctxp->combined_loop = true;
   17461              : 
   17462        51450 :   for_body = NULL;
   17463        51450 :   gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
   17464              :               == TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
   17465        51450 :   gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
   17466              :               == TREE_VEC_LENGTH (OMP_FOR_INCR (for_stmt)));
   17467              : 
   17468        51450 :   tree c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ORDERED);
   17469        51450 :   bool is_doacross = false;
   17470        51450 :   if (c && walk_tree_without_duplicates (&OMP_FOR_BODY (for_stmt),
   17471              :                                          find_standalone_omp_ordered, NULL))
   17472              :     {
   17473          531 :       OMP_CLAUSE_ORDERED_DOACROSS (c) = 1;
   17474          531 :       is_doacross = true;
   17475          531 :       int len = TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt));
   17476          531 :       gimplify_omp_ctxp->loop_iter_var.create (len * 2);
   17477         2200 :       for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
   17478         1669 :         if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
   17479              :           {
   17480           10 :             error_at (OMP_CLAUSE_LOCATION (*pc),
   17481              :                       "%<linear%> clause may not be specified together "
   17482              :                       "with %<ordered%> clause if stand-alone %<ordered%> "
   17483              :                       "construct is nested in it");
   17484           10 :             *pc = OMP_CLAUSE_CHAIN (*pc);
   17485              :           }
   17486              :         else
   17487         1659 :           pc = &OMP_CLAUSE_CHAIN (*pc);
   17488              :     }
   17489        51450 :   int collapse = 1, tile = 0;
   17490        51450 :   c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_COLLAPSE);
   17491        51450 :   if (c)
   17492        13727 :     collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c));
   17493        51450 :   c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_TILE);
   17494        51450 :   if (c)
   17495          384 :     tile = list_length (OMP_CLAUSE_TILE_LIST (c));
   17496        51450 :   c = omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_ALLOCATE);
   17497        51450 :   hash_set<tree> *allocate_uids = NULL;
   17498        51450 :   if (c)
   17499              :     {
   17500          275 :       allocate_uids = new hash_set<tree>;
   17501         1682 :       for (; c; c = OMP_CLAUSE_CHAIN (c))
   17502         1132 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE)
   17503          478 :           allocate_uids->add (OMP_CLAUSE_DECL (c));
   17504              :     }
   17505       124646 :   for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   17506              :     {
   17507        73196 :       t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   17508        73196 :       gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   17509        73196 :       decl = TREE_OPERAND (t, 0);
   17510        73196 :       gcc_assert (DECL_P (decl));
   17511        73196 :       gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
   17512              :                   || POINTER_TYPE_P (TREE_TYPE (decl)));
   17513        73196 :       if (is_doacross)
   17514              :         {
   17515         1654 :           if (TREE_CODE (for_stmt) == OMP_FOR && OMP_FOR_ORIG_DECLS (for_stmt))
   17516              :             {
   17517          960 :               tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   17518          960 :               if (TREE_CODE (orig_decl) == TREE_LIST)
   17519              :                 {
   17520           15 :                   orig_decl = TREE_PURPOSE (orig_decl);
   17521           15 :                   if (!orig_decl)
   17522            0 :                     orig_decl = decl;
   17523              :                 }
   17524          960 :               gimplify_omp_ctxp->loop_iter_var.quick_push (orig_decl);
   17525              :             }
   17526              :           else
   17527          694 :             gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
   17528         1654 :           gimplify_omp_ctxp->loop_iter_var.quick_push (decl);
   17529              :         }
   17530              : 
   17531        73196 :       if (for_stmt == orig_for_stmt)
   17532              :         {
   17533        50339 :           tree orig_decl = decl;
   17534        50339 :           if (OMP_FOR_ORIG_DECLS (for_stmt))
   17535              :             {
   17536        24054 :               tree orig_decl = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   17537        24054 :               if (TREE_CODE (orig_decl) == TREE_LIST)
   17538              :                 {
   17539              :                   orig_decl = TREE_PURPOSE (orig_decl);
   17540              :                   if (!orig_decl)
   17541              :                     orig_decl = decl;
   17542              :                 }
   17543              :             }
   17544        50339 :           if (is_global_var (orig_decl) && DECL_THREAD_LOCAL_P (orig_decl))
   17545           36 :             error_at (EXPR_LOCATION (for_stmt),
   17546              :                       "threadprivate iteration variable %qD", orig_decl);
   17547              :         }
   17548              : 
   17549              :       /* Make sure the iteration variable is private.  */
   17550        73196 :       tree c = NULL_TREE;
   17551        73196 :       tree c2 = NULL_TREE;
   17552        73196 :       if (orig_for_stmt != for_stmt)
   17553              :         {
   17554              :           /* Preserve this information until we gimplify the inner simd.  */
   17555        22857 :           if (has_decl_expr
   17556        22857 :               && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
   17557         3421 :             TREE_PRIVATE (t) = 1;
   17558              :         }
   17559        50339 :       else if (ort == ORT_SIMD)
   17560              :         {
   17561        15810 :           splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
   17562              :                                                  (splay_tree_key) decl);
   17563        15810 :           omp_is_private (gimplify_omp_ctxp, decl,
   17564        15810 :                           1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
   17565              :                                != 1));
   17566        15810 :           if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
   17567              :             {
   17568         2538 :               omp_notice_variable (gimplify_omp_ctxp, decl, true);
   17569         2538 :               if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
   17570            0 :                 for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   17571              :                                                 OMP_CLAUSE_LASTPRIVATE);
   17572            0 :                      c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
   17573              :                                                OMP_CLAUSE_LASTPRIVATE))
   17574            0 :                   if (OMP_CLAUSE_DECL (c3) == decl)
   17575              :                     {
   17576            0 :                       warning_at (OMP_CLAUSE_LOCATION (c3), OPT_Wopenmp,
   17577              :                                   "conditional %<lastprivate%> on loop "
   17578              :                                   "iterator %qD ignored", decl);
   17579            0 :                       OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
   17580            0 :                       n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
   17581              :                     }
   17582              :             }
   17583        13272 :           else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
   17584              :             {
   17585         5701 :               c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
   17586         5701 :               OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
   17587         5701 :               unsigned int flags = GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN;
   17588         5701 :               if ((has_decl_expr
   17589         1365 :                    && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
   17590         6385 :                   || TREE_PRIVATE (t))
   17591              :                 {
   17592         2345 :                   OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
   17593         2345 :                   flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
   17594              :                 }
   17595         5701 :               struct gimplify_omp_ctx *outer
   17596         5701 :                 = gimplify_omp_ctxp->outer_context;
   17597         5701 :               if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   17598              :                 {
   17599         2433 :                   if (outer->region_type == ORT_WORKSHARE
   17600         2193 :                       && outer->combined_loop)
   17601              :                     {
   17602         2142 :                       n = splay_tree_lookup (outer->variables,
   17603              :                                              (splay_tree_key)decl);
   17604         2142 :                       if (n != NULL && (n->value & GOVD_LOCAL) != 0)
   17605              :                         {
   17606            0 :                           OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
   17607            0 :                           flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
   17608              :                         }
   17609              :                       else
   17610              :                         {
   17611         2142 :                           struct gimplify_omp_ctx *octx = outer->outer_context;
   17612         2142 :                           if (octx
   17613         1714 :                               && octx->region_type == ORT_COMBINED_PARALLEL
   17614         1476 :                               && octx->outer_context
   17615         1209 :                               && (octx->outer_context->region_type
   17616              :                                   == ORT_WORKSHARE)
   17617         1079 :                               && octx->outer_context->combined_loop)
   17618              :                             {
   17619         1079 :                               octx = octx->outer_context;
   17620         1079 :                               n = splay_tree_lookup (octx->variables,
   17621              :                                                      (splay_tree_key)decl);
   17622         1079 :                               if (n != NULL && (n->value & GOVD_LOCAL) != 0)
   17623              :                                 {
   17624            0 :                                   OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
   17625            0 :                                   flags |= GOVD_LINEAR_LASTPRIVATE_NO_OUTER;
   17626              :                                 }
   17627              :                             }
   17628              :                         }
   17629              :                     }
   17630              :                 }
   17631              : 
   17632         5701 :               OMP_CLAUSE_DECL (c) = decl;
   17633         5701 :               OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
   17634         5701 :               OMP_FOR_CLAUSES (for_stmt) = c;
   17635         5701 :               omp_add_variable (gimplify_omp_ctxp, decl, flags);
   17636         5701 :               if (outer && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
   17637         2433 :                 omp_lastprivate_for_combined_outer_constructs (outer, decl,
   17638              :                                                                true);
   17639              :             }
   17640              :           else
   17641              :             {
   17642         7571 :               bool lastprivate
   17643              :                 = (!has_decl_expr
   17644         7571 :                    || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
   17645         7571 :               if (TREE_PRIVATE (t))
   17646         1787 :                 lastprivate = false;
   17647         7571 :               if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
   17648              :                 {
   17649          509 :                   tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   17650          509 :                   if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
   17651              :                     lastprivate = false;
   17652              :                 }
   17653              : 
   17654         7571 :               struct gimplify_omp_ctx *outer
   17655         7571 :                 = gimplify_omp_ctxp->outer_context;
   17656         7571 :               if (outer && lastprivate)
   17657         4887 :                 omp_lastprivate_for_combined_outer_constructs (outer, decl,
   17658              :                                                                true);
   17659              : 
   17660         9577 :               c = build_omp_clause (input_location,
   17661              :                                     lastprivate ? OMP_CLAUSE_LASTPRIVATE
   17662              :                                                 : OMP_CLAUSE_PRIVATE);
   17663         7571 :               OMP_CLAUSE_DECL (c) = decl;
   17664         7571 :               OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
   17665         7571 :               OMP_FOR_CLAUSES (for_stmt) = c;
   17666         7571 :               omp_add_variable (gimplify_omp_ctxp, decl,
   17667              :                                 (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
   17668              :                                 | GOVD_EXPLICIT | GOVD_SEEN);
   17669         7571 :               c = NULL_TREE;
   17670              :             }
   17671              :         }
   17672        34529 :       else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
   17673              :         {
   17674         8739 :           omp_notice_variable (gimplify_omp_ctxp, decl, true);
   17675         8739 :           splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
   17676              :                                                  (splay_tree_key) decl);
   17677         8739 :           if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
   17678           80 :             for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
   17679              :                                             OMP_CLAUSE_LASTPRIVATE);
   17680           80 :                  c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
   17681              :                                            OMP_CLAUSE_LASTPRIVATE))
   17682           40 :               if (OMP_CLAUSE_DECL (c3) == decl)
   17683              :                 {
   17684           40 :                   warning_at (OMP_CLAUSE_LOCATION (c3), OPT_Wopenmp,
   17685              :                               "conditional %<lastprivate%> on loop "
   17686              :                               "iterator %qD ignored", decl);
   17687           40 :                   OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
   17688           40 :                   n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
   17689              :                 }
   17690              :         }
   17691              :       else
   17692        25790 :         omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
   17693              : 
   17694              :       /* If DECL is not a gimple register, create a temporary variable to act
   17695              :          as an iteration counter.  This is valid, since DECL cannot be
   17696              :          modified in the body of the loop.  Similarly for any iteration vars
   17697              :          in simd with collapse > 1 where the iterator vars must be
   17698              :          lastprivate.  And similarly for vars mentioned in allocate clauses.  */
   17699        73196 :       if (orig_for_stmt != for_stmt)
   17700        22857 :         var = decl;
   17701        50339 :       else if (!is_gimple_reg (decl)
   17702        47072 :                || (ort == ORT_SIMD
   17703        14209 :                    && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
   17704        90341 :                || (allocate_uids && allocate_uids->contains (decl)))
   17705              :         {
   17706        10369 :           struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   17707              :           /* Make sure omp_add_variable is not called on it prematurely.
   17708              :              We call it ourselves a few lines later.  */
   17709        10369 :           gimplify_omp_ctxp = NULL;
   17710        10369 :           var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
   17711        10369 :           gimplify_omp_ctxp = ctx;
   17712        10369 :           TREE_OPERAND (t, 0) = var;
   17713              : 
   17714        10369 :           gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
   17715              : 
   17716        10369 :           if (ort == ORT_SIMD
   17717        10369 :               && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
   17718              :             {
   17719          770 :               c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
   17720          770 :               OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
   17721          770 :               OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
   17722          770 :               OMP_CLAUSE_DECL (c2) = var;
   17723          770 :               OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
   17724          770 :               OMP_FOR_CLAUSES (for_stmt) = c2;
   17725          770 :               omp_add_variable (gimplify_omp_ctxp, var,
   17726              :                                 GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
   17727          770 :               if (c == NULL_TREE)
   17728              :                 {
   17729          518 :                   c = c2;
   17730          518 :                   c2 = NULL_TREE;
   17731              :                 }
   17732              :             }
   17733              :           else
   17734         9599 :             omp_add_variable (gimplify_omp_ctxp, var,
   17735              :                               GOVD_PRIVATE | GOVD_SEEN);
   17736              :         }
   17737              :       else
   17738              :         var = decl;
   17739              : 
   17740        73196 :       gimplify_omp_ctxp->in_for_exprs = true;
   17741        73196 :       if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   17742              :         {
   17743          719 :           tree lb = TREE_OPERAND (t, 1);
   17744          719 :           tret = gimplify_expr (&TREE_VEC_ELT (lb, 1), &for_pre_body, NULL,
   17745              :                                 is_gimple_val, fb_rvalue, false);
   17746          719 :           ret = MIN (ret, tret);
   17747          719 :           tret = gimplify_expr (&TREE_VEC_ELT (lb, 2), &for_pre_body, NULL,
   17748              :                                 is_gimple_val, fb_rvalue, false);
   17749              :         }
   17750              :       else
   17751        72477 :         tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
   17752              :                               is_gimple_val, fb_rvalue, false);
   17753        73196 :       gimplify_omp_ctxp->in_for_exprs = false;
   17754        73196 :       ret = MIN (ret, tret);
   17755        73196 :       if (ret == GS_ERROR)
   17756              :         return ret;
   17757              : 
   17758              :       /* Handle OMP_FOR_COND.  */
   17759        73196 :       t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
   17760        73196 :       gcc_assert (COMPARISON_CLASS_P (t));
   17761        73196 :       gcc_assert (TREE_OPERAND (t, 0) == decl);
   17762              : 
   17763        73196 :       gimplify_omp_ctxp->in_for_exprs = true;
   17764        73196 :       if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC)
   17765              :         {
   17766          599 :           tree ub = TREE_OPERAND (t, 1);
   17767          599 :           tret = gimplify_expr (&TREE_VEC_ELT (ub, 1), &for_pre_body, NULL,
   17768              :                                 is_gimple_val, fb_rvalue, false);
   17769          599 :           ret = MIN (ret, tret);
   17770          599 :           tret = gimplify_expr (&TREE_VEC_ELT (ub, 2), &for_pre_body, NULL,
   17771              :                                 is_gimple_val, fb_rvalue, false);
   17772              :         }
   17773              :       else
   17774        72597 :         tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
   17775              :                               is_gimple_val, fb_rvalue, false);
   17776        73196 :       gimplify_omp_ctxp->in_for_exprs = false;
   17777        73196 :       ret = MIN (ret, tret);
   17778              : 
   17779              :       /* Handle OMP_FOR_INCR.  */
   17780        73196 :       t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   17781        73196 :       switch (TREE_CODE (t))
   17782              :         {
   17783        35884 :         case PREINCREMENT_EXPR:
   17784        35884 :         case POSTINCREMENT_EXPR:
   17785        35884 :           {
   17786        35884 :             tree decl = TREE_OPERAND (t, 0);
   17787              :             /* c_omp_for_incr_canonicalize_ptr() should have been
   17788              :                called to massage things appropriately.  */
   17789        35884 :             gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
   17790              : 
   17791        35884 :             if (orig_for_stmt != for_stmt)
   17792              :               break;
   17793        25461 :             t = build_int_cst (TREE_TYPE (decl), 1);
   17794        25461 :             if (c)
   17795         4534 :               OMP_CLAUSE_LINEAR_STEP (c) = t;
   17796        25461 :             t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
   17797        25461 :             t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
   17798        25461 :             TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
   17799        25461 :             break;
   17800              :           }
   17801              : 
   17802         3830 :         case PREDECREMENT_EXPR:
   17803         3830 :         case POSTDECREMENT_EXPR:
   17804              :           /* c_omp_for_incr_canonicalize_ptr() should have been
   17805              :              called to massage things appropriately.  */
   17806         3830 :           gcc_assert (!POINTER_TYPE_P (TREE_TYPE (decl)));
   17807         3830 :           if (orig_for_stmt != for_stmt)
   17808              :             break;
   17809         1992 :           t = build_int_cst (TREE_TYPE (decl), -1);
   17810         1992 :           if (c)
   17811          112 :             OMP_CLAUSE_LINEAR_STEP (c) = t;
   17812         1992 :           t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
   17813         1992 :           t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
   17814         1992 :           TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
   17815         1992 :           break;
   17816              : 
   17817        33482 :         case MODIFY_EXPR:
   17818        33482 :           gcc_assert (TREE_OPERAND (t, 0) == decl);
   17819        33482 :           TREE_OPERAND (t, 0) = var;
   17820              : 
   17821        33482 :           t = TREE_OPERAND (t, 1);
   17822        33482 :           switch (TREE_CODE (t))
   17823              :             {
   17824        26550 :             case PLUS_EXPR:
   17825        26550 :               if (TREE_OPERAND (t, 1) == decl)
   17826              :                 {
   17827          215 :                   TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
   17828          215 :                   TREE_OPERAND (t, 0) = var;
   17829          215 :                   break;
   17830              :                 }
   17831              : 
   17832              :               /* Fallthru.  */
   17833        33267 :             case MINUS_EXPR:
   17834        33267 :             case POINTER_PLUS_EXPR:
   17835        33267 :               gcc_assert (TREE_OPERAND (t, 0) == decl);
   17836        33267 :               TREE_OPERAND (t, 0) = var;
   17837        33267 :               break;
   17838            0 :             default:
   17839            0 :               gcc_unreachable ();
   17840              :             }
   17841              : 
   17842        33482 :           gimplify_omp_ctxp->in_for_exprs = true;
   17843        33482 :           tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
   17844              :                                 is_gimple_val, fb_rvalue, false);
   17845        33482 :           ret = MIN (ret, tret);
   17846        33482 :           if (c)
   17847              :             {
   17848         1573 :               tree step = TREE_OPERAND (t, 1);
   17849         1573 :               tree stept = TREE_TYPE (decl);
   17850         1573 :               if (POINTER_TYPE_P (stept))
   17851          280 :                 stept = sizetype;
   17852         1573 :               step = fold_convert (stept, step);
   17853         1573 :               if (TREE_CODE (t) == MINUS_EXPR)
   17854          295 :                 step = fold_build1 (NEGATE_EXPR, stept, step);
   17855         1573 :               OMP_CLAUSE_LINEAR_STEP (c) = step;
   17856         1573 :               if (step != TREE_OPERAND (t, 1))
   17857              :                 {
   17858          295 :                   tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
   17859              :                                         &for_pre_body, NULL,
   17860              :                                         is_gimple_val, fb_rvalue, false);
   17861          295 :                   ret = MIN (ret, tret);
   17862              :                 }
   17863              :             }
   17864        33482 :           gimplify_omp_ctxp->in_for_exprs = false;
   17865        33482 :           break;
   17866              : 
   17867            0 :         default:
   17868            0 :           gcc_unreachable ();
   17869              :         }
   17870              : 
   17871        73196 :       if (c2)
   17872              :         {
   17873          252 :           gcc_assert (c);
   17874          252 :           OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
   17875              :         }
   17876              : 
   17877        73196 :       if ((var != decl || collapse > 1 || tile) && orig_for_stmt == for_stmt)
   17878              :         {
   17879        86698 :           for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
   17880        65136 :             if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   17881        16218 :                   && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
   17882        56127 :                  || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
   17883         2159 :                      && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
   17884         1373 :                      && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
   17885        75496 :                 && OMP_CLAUSE_DECL (c) == decl)
   17886              :               {
   17887         7535 :                 if (is_doacross && (collapse == 1 || i >= collapse))
   17888              :                   t = var;
   17889              :                 else
   17890              :                   {
   17891         7462 :                     t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   17892         7462 :                     gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   17893         7462 :                     gcc_assert (TREE_OPERAND (t, 0) == var);
   17894         7462 :                     t = TREE_OPERAND (t, 1);
   17895         7462 :                     gcc_assert (TREE_CODE (t) == PLUS_EXPR
   17896              :                                 || TREE_CODE (t) == MINUS_EXPR
   17897              :                                 || TREE_CODE (t) == POINTER_PLUS_EXPR);
   17898         7462 :                     gcc_assert (TREE_OPERAND (t, 0) == var);
   17899        14822 :                     t = build2 (TREE_CODE (t), TREE_TYPE (decl),
   17900              :                                 is_doacross ? var : decl,
   17901         7462 :                                 TREE_OPERAND (t, 1));
   17902              :                   }
   17903         7535 :                 gimple_seq *seq;
   17904         7535 :                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
   17905         6939 :                   seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
   17906              :                 else
   17907          596 :                   seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
   17908         7535 :                 push_gimplify_context ();
   17909         7535 :                 gimplify_assign (decl, t, seq);
   17910         7535 :                 gimple *bind = NULL;
   17911         7535 :                 if (gimplify_ctxp->temps)
   17912              :                   {
   17913         2072 :                     bind = gimple_build_bind (NULL_TREE, *seq, NULL_TREE);
   17914         2072 :                     *seq = NULL;
   17915         2072 :                     gimplify_seq_add_stmt (seq, bind);
   17916              :                   }
   17917         7535 :                 pop_gimplify_context (bind);
   17918              :               }
   17919              :         }
   17920        73196 :       if (OMP_FOR_NON_RECTANGULAR (for_stmt) && var != decl)
   17921         2609 :         for (int j = i + 1; j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
   17922              :           {
   17923         1197 :             t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
   17924         1197 :             gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   17925         1197 :             if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
   17926         1197 :                 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
   17927          336 :               TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
   17928         1197 :             t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
   17929         1197 :             gcc_assert (COMPARISON_CLASS_P (t));
   17930         1197 :             if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
   17931         1197 :                 && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
   17932          343 :               TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
   17933              :           }
   17934              :     }
   17935              : 
   17936        51450 :   BITMAP_FREE (has_decl_expr);
   17937        51725 :   delete allocate_uids;
   17938              : 
   17939        51450 :   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
   17940        49864 :       || (loop_p && orig_for_stmt == for_stmt))
   17941              :     {
   17942         2642 :       push_gimplify_context ();
   17943         2642 :       if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
   17944              :         {
   17945         1891 :           OMP_FOR_BODY (orig_for_stmt)
   17946         1891 :             = build3 (BIND_EXPR, void_type_node, NULL,
   17947         1891 :                       OMP_FOR_BODY (orig_for_stmt), NULL);
   17948         1891 :           TREE_SIDE_EFFECTS (OMP_FOR_BODY (orig_for_stmt)) = 1;
   17949              :         }
   17950              :     }
   17951              : 
   17952        51450 :   gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
   17953              :                                          &for_body);
   17954              : 
   17955        51450 :   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
   17956        49864 :       || (loop_p && orig_for_stmt == for_stmt))
   17957              :     {
   17958         2642 :       if (gimple_code (g) == GIMPLE_BIND)
   17959         2642 :         pop_gimplify_context (g);
   17960              :       else
   17961            0 :         pop_gimplify_context (NULL);
   17962              :     }
   17963              : 
   17964        51450 :   if (orig_for_stmt != for_stmt)
   17965        36832 :     for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   17966              :       {
   17967        22857 :         t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   17968        22857 :         decl = TREE_OPERAND (t, 0);
   17969        22857 :         struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   17970        22857 :         if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
   17971          772 :           gimplify_omp_ctxp = ctx->outer_context;
   17972        22857 :         var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
   17973        22857 :         gimplify_omp_ctxp = ctx;
   17974        22857 :         omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
   17975        22857 :         TREE_OPERAND (t, 0) = var;
   17976        22857 :         t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   17977        22857 :         TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
   17978        22857 :         TREE_OPERAND (TREE_OPERAND (t, 1), 0) = var;
   17979        22857 :         if (OMP_FOR_NON_RECTANGULAR (for_stmt))
   17980          791 :           for (int j = i + 1;
   17981          791 :                j < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); j++)
   17982              :             {
   17983          377 :               t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), j);
   17984          377 :               gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   17985          377 :               if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
   17986          377 :                   && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
   17987              :                 {
   17988          133 :                   TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
   17989          133 :                   TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
   17990              :                 }
   17991          377 :               t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), j);
   17992          377 :               gcc_assert (COMPARISON_CLASS_P (t));
   17993          377 :               if (TREE_CODE (TREE_OPERAND (t, 1)) == TREE_VEC
   17994          377 :                   && TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) == decl)
   17995              :                 {
   17996           67 :                   TREE_OPERAND (t, 1) = copy_node (TREE_OPERAND (t, 1));
   17997           67 :                   TREE_VEC_ELT (TREE_OPERAND (t, 1), 0) = var;
   17998              :                 }
   17999              :           }
   18000              :       }
   18001              : 
   18002        51450 :   gimplify_adjust_omp_clauses (pre_p, for_body,
   18003              :                                &OMP_FOR_CLAUSES (orig_for_stmt),
   18004        51450 :                                TREE_CODE (orig_for_stmt));
   18005              : 
   18006        51450 :   int kind;
   18007        51450 :   switch (TREE_CODE (orig_for_stmt))
   18008              :     {
   18009              :     case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
   18010        10737 :     case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
   18011         8287 :     case OMP_DISTRIBUTE: kind = GF_OMP_FOR_KIND_DISTRIBUTE; break;
   18012         1586 :     case OMP_TASKLOOP: kind = GF_OMP_FOR_KIND_TASKLOOP; break;
   18013        12552 :     case OACC_LOOP: kind = GF_OMP_FOR_KIND_OACC_LOOP; break;
   18014            0 :     default:
   18015            0 :       gcc_unreachable ();
   18016              :     }
   18017        51450 :   if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
   18018              :     {
   18019         1056 :       gimplify_seq_add_seq (pre_p, for_pre_body);
   18020         1056 :       for_pre_body = NULL;
   18021              :     }
   18022        51450 :   gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
   18023        51450 :                                TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
   18024              :                                for_pre_body);
   18025        51450 :   if (orig_for_stmt != for_stmt)
   18026        13975 :     gimple_omp_for_set_combined_p (gfor, true);
   18027        51450 :   if (gimplify_omp_ctxp
   18028        42705 :       && (gimplify_omp_ctxp->combined_loop
   18029        35161 :           || (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
   18030        12347 :               && gimplify_omp_ctxp->outer_context
   18031         7895 :               && gimplify_omp_ctxp->outer_context->combined_loop)))
   18032              :     {
   18033        13975 :       gimple_omp_for_set_combined_into_p (gfor, true);
   18034        13975 :       if (gimplify_omp_ctxp->combined_loop)
   18035         7544 :         gcc_assert (TREE_CODE (orig_for_stmt) == OMP_SIMD);
   18036              :       else
   18037         6431 :         gcc_assert (TREE_CODE (orig_for_stmt) == OMP_FOR);
   18038              :     }
   18039              : 
   18040       124646 :   for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   18041              :     {
   18042        73196 :       t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   18043        73196 :       gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
   18044        73196 :       gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
   18045        73196 :       t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
   18046        73196 :       gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
   18047        73196 :       gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
   18048        73196 :       t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
   18049        73196 :       gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
   18050              :     }
   18051              : 
   18052              :   /* OMP_TASKLOOP is gimplified as two GIMPLE_OMP_FOR taskloop
   18053              :      constructs with GIMPLE_OMP_TASK sandwiched in between them.
   18054              :      The outer taskloop stands for computing the number of iterations,
   18055              :      counts for collapsed loops and holding taskloop specific clauses.
   18056              :      The task construct stands for the effect of data sharing on the
   18057              :      explicit task it creates and the inner taskloop stands for expansion
   18058              :      of the static loop inside of the explicit task construct.  */
   18059        51450 :   if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
   18060              :     {
   18061         1586 :       tree *gfor_clauses_ptr = gimple_omp_for_clauses_ptr (gfor);
   18062         1586 :       tree task_clauses = NULL_TREE;
   18063         1586 :       tree c = *gfor_clauses_ptr;
   18064         1586 :       tree *gtask_clauses_ptr = &task_clauses;
   18065         1586 :       tree outer_for_clauses = NULL_TREE;
   18066         1586 :       tree *gforo_clauses_ptr = &outer_for_clauses;
   18067         1586 :       bitmap lastprivate_uids = NULL;
   18068         1586 :       if (omp_find_clause (c, OMP_CLAUSE_ALLOCATE))
   18069              :         {
   18070           36 :           c = omp_find_clause (c, OMP_CLAUSE_LASTPRIVATE);
   18071           36 :           if (c)
   18072              :             {
   18073           18 :               lastprivate_uids = BITMAP_ALLOC (NULL);
   18074           54 :               for (; c; c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
   18075              :                                              OMP_CLAUSE_LASTPRIVATE))
   18076           18 :                 bitmap_set_bit (lastprivate_uids,
   18077           18 :                                 DECL_UID (OMP_CLAUSE_DECL (c)));
   18078              :             }
   18079           36 :           c = *gfor_clauses_ptr;
   18080              :         }
   18081        12254 :       for (; c; c = OMP_CLAUSE_CHAIN (c))
   18082        10668 :         switch (OMP_CLAUSE_CODE (c))
   18083              :           {
   18084              :           /* These clauses are allowed on task, move them there.  */
   18085         6230 :           case OMP_CLAUSE_SHARED:
   18086         6230 :           case OMP_CLAUSE_FIRSTPRIVATE:
   18087         6230 :           case OMP_CLAUSE_DEFAULT:
   18088         6230 :           case OMP_CLAUSE_IF:
   18089         6230 :           case OMP_CLAUSE_UNTIED:
   18090         6230 :           case OMP_CLAUSE_FINAL:
   18091         6230 :           case OMP_CLAUSE_MERGEABLE:
   18092         6230 :           case OMP_CLAUSE_PRIORITY:
   18093         6230 :           case OMP_CLAUSE_REDUCTION:
   18094         6230 :           case OMP_CLAUSE_IN_REDUCTION:
   18095         6230 :             *gtask_clauses_ptr = c;
   18096         6230 :             gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   18097         6230 :             break;
   18098         2068 :           case OMP_CLAUSE_PRIVATE:
   18099         2068 :             if (OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c))
   18100              :               {
   18101              :                 /* We want private on outer for and firstprivate
   18102              :                    on task.  */
   18103           26 :                 *gtask_clauses_ptr
   18104           26 :                   = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   18105              :                                       OMP_CLAUSE_FIRSTPRIVATE);
   18106           26 :                 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
   18107           26 :                 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
   18108              :                                                     openacc);
   18109           26 :                 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   18110           26 :                 *gforo_clauses_ptr = c;
   18111           26 :                 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   18112              :               }
   18113              :             else
   18114              :               {
   18115         2042 :                 *gtask_clauses_ptr = c;
   18116         2042 :                 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   18117              :               }
   18118              :             break;
   18119              :           /* These clauses go into outer taskloop clauses.  */
   18120          533 :           case OMP_CLAUSE_GRAINSIZE:
   18121          533 :           case OMP_CLAUSE_NUM_TASKS:
   18122          533 :           case OMP_CLAUSE_NOGROUP:
   18123          533 :             *gforo_clauses_ptr = c;
   18124          533 :             gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   18125          533 :             break;
   18126              :           /* Collapse clause we duplicate on both taskloops.  */
   18127          584 :           case OMP_CLAUSE_COLLAPSE:
   18128          584 :             *gfor_clauses_ptr = c;
   18129          584 :             gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   18130          584 :             *gforo_clauses_ptr = copy_node (c);
   18131          584 :             gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
   18132          584 :             break;
   18133              :           /* For lastprivate, keep the clause on inner taskloop, and add
   18134              :              a shared clause on task.  If the same decl is also firstprivate,
   18135              :              add also firstprivate clause on the inner taskloop.  */
   18136         1191 :           case OMP_CLAUSE_LASTPRIVATE:
   18137         1191 :             if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
   18138              :               {
   18139              :                 /* For taskloop C++ lastprivate IVs, we want:
   18140              :                    1) private on outer taskloop
   18141              :                    2) firstprivate and shared on task
   18142              :                    3) lastprivate on inner taskloop  */
   18143           38 :                 *gtask_clauses_ptr
   18144           38 :                   = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   18145              :                                       OMP_CLAUSE_FIRSTPRIVATE);
   18146           38 :                 OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
   18147           38 :                 lang_hooks.decls.omp_finish_clause (*gtask_clauses_ptr, NULL,
   18148              :                                                     openacc);
   18149           38 :                 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   18150           38 :                 OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c) = 1;
   18151           38 :                 *gforo_clauses_ptr = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   18152              :                                                        OMP_CLAUSE_PRIVATE);
   18153           38 :                 OMP_CLAUSE_DECL (*gforo_clauses_ptr) = OMP_CLAUSE_DECL (c);
   18154           38 :                 OMP_CLAUSE_PRIVATE_TASKLOOP_IV (*gforo_clauses_ptr) = 1;
   18155           38 :                 TREE_TYPE (*gforo_clauses_ptr) = TREE_TYPE (c);
   18156           38 :                 gforo_clauses_ptr = &OMP_CLAUSE_CHAIN (*gforo_clauses_ptr);
   18157              :               }
   18158         1191 :             *gfor_clauses_ptr = c;
   18159         1191 :             gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   18160         1191 :             *gtask_clauses_ptr
   18161         1191 :               = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_SHARED);
   18162         1191 :             OMP_CLAUSE_DECL (*gtask_clauses_ptr) = OMP_CLAUSE_DECL (c);
   18163         1191 :             if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
   18164          312 :               OMP_CLAUSE_SHARED_FIRSTPRIVATE (*gtask_clauses_ptr) = 1;
   18165         1191 :             gtask_clauses_ptr
   18166         1191 :               = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   18167         1191 :             break;
   18168              :           /* Allocate clause we duplicate on task and inner taskloop
   18169              :              if the decl is lastprivate, otherwise just put on task.  */
   18170           62 :           case OMP_CLAUSE_ALLOCATE:
   18171           62 :             if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)
   18172           62 :                 && DECL_P (OMP_CLAUSE_ALLOCATE_ALLOCATOR (c)))
   18173              :               {
   18174              :                 /* Additionally, put firstprivate clause on task
   18175              :                    for the allocator if it is not constant.  */
   18176           34 :                 *gtask_clauses_ptr
   18177           34 :                   = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   18178              :                                       OMP_CLAUSE_FIRSTPRIVATE);
   18179           34 :                 OMP_CLAUSE_DECL (*gtask_clauses_ptr)
   18180           34 :                   = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
   18181           34 :                 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   18182              :               }
   18183           62 :             if (lastprivate_uids
   18184           97 :                 && bitmap_bit_p (lastprivate_uids,
   18185           35 :                                  DECL_UID (OMP_CLAUSE_DECL (c))))
   18186              :               {
   18187           17 :                 *gfor_clauses_ptr = c;
   18188           17 :                 gfor_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   18189           17 :                 *gtask_clauses_ptr = copy_node (c);
   18190           17 :                 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (*gtask_clauses_ptr);
   18191              :               }
   18192              :             else
   18193              :               {
   18194           45 :                 *gtask_clauses_ptr = c;
   18195           45 :                 gtask_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   18196              :               }
   18197              :             break;
   18198            0 :           default:
   18199            0 :             gcc_unreachable ();
   18200              :           }
   18201         1586 :       *gfor_clauses_ptr = NULL_TREE;
   18202         1586 :       *gtask_clauses_ptr = NULL_TREE;
   18203         1586 :       *gforo_clauses_ptr = NULL_TREE;
   18204         1586 :       BITMAP_FREE (lastprivate_uids);
   18205         1586 :       gimple_set_location (gfor, input_location);
   18206         1586 :       g = gimple_build_bind (NULL_TREE, gfor, NULL_TREE);
   18207         1586 :       g = gimple_build_omp_task (g, task_clauses, NULL_TREE, NULL_TREE,
   18208              :                                  NULL_TREE, NULL_TREE, NULL_TREE);
   18209         1586 :       gimple_set_location (g, input_location);
   18210         1586 :       gimple_omp_task_set_taskloop_p (g, true);
   18211         1586 :       g = gimple_build_bind (NULL_TREE, g, NULL_TREE);
   18212         1586 :       gomp_for *gforo
   18213         1586 :         = gimple_build_omp_for (g, GF_OMP_FOR_KIND_TASKLOOP, outer_for_clauses,
   18214              :                                 gimple_omp_for_collapse (gfor),
   18215              :                                 gimple_omp_for_pre_body (gfor));
   18216         1586 :       gimple_omp_for_set_pre_body (gfor, NULL);
   18217         1586 :       gimple_omp_for_set_combined_p (gforo, true);
   18218         1586 :       gimple_omp_for_set_combined_into_p (gfor, true);
   18219         3458 :       for (i = 0; i < (int) gimple_omp_for_collapse (gfor); i++)
   18220              :         {
   18221         1872 :           tree type = TREE_TYPE (gimple_omp_for_index (gfor, i));
   18222         1872 :           tree v = create_tmp_var (type);
   18223         1872 :           gimple_omp_for_set_index (gforo, i, v);
   18224         1872 :           t = unshare_expr (gimple_omp_for_initial (gfor, i));
   18225         1872 :           gimple_omp_for_set_initial (gforo, i, t);
   18226         1872 :           gimple_omp_for_set_cond (gforo, i,
   18227              :                                    gimple_omp_for_cond (gfor, i));
   18228         1872 :           t = unshare_expr (gimple_omp_for_final (gfor, i));
   18229         1872 :           gimple_omp_for_set_final (gforo, i, t);
   18230         1872 :           t = unshare_expr (gimple_omp_for_incr (gfor, i));
   18231         1872 :           gcc_assert (TREE_OPERAND (t, 0) == gimple_omp_for_index (gfor, i));
   18232         1872 :           TREE_OPERAND (t, 0) = v;
   18233         1872 :           gimple_omp_for_set_incr (gforo, i, t);
   18234         1872 :           t = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
   18235         1872 :           OMP_CLAUSE_DECL (t) = v;
   18236         1872 :           OMP_CLAUSE_CHAIN (t) = gimple_omp_for_clauses (gforo);
   18237         1872 :           gimple_omp_for_set_clauses (gforo, t);
   18238         1872 :           if (OMP_FOR_NON_RECTANGULAR (for_stmt))
   18239              :             {
   18240           90 :               tree *p1 = NULL, *p2 = NULL;
   18241           90 :               t = gimple_omp_for_initial (gforo, i);
   18242           90 :               if (TREE_CODE (t) == TREE_VEC)
   18243           34 :                 p1 = &TREE_VEC_ELT (t, 0);
   18244           90 :               t = gimple_omp_for_final (gforo, i);
   18245           90 :               if (TREE_CODE (t) == TREE_VEC)
   18246              :                 {
   18247           31 :                   if (p1)
   18248           23 :                     p2 = &TREE_VEC_ELT (t, 0);
   18249              :                   else
   18250            8 :                     p1 = &TREE_VEC_ELT (t, 0);
   18251              :                 }
   18252           90 :               if (p1)
   18253              :                 {
   18254              :                   int j;
   18255           58 :                   for (j = 0; j < i; j++)
   18256           58 :                     if (*p1 == gimple_omp_for_index (gfor, j))
   18257              :                       {
   18258           42 :                         *p1 = gimple_omp_for_index (gforo, j);
   18259           42 :                         if (p2)
   18260           23 :                           *p2 = *p1;
   18261              :                         break;
   18262              :                       }
   18263           42 :                   gcc_assert (j < i);
   18264              :                 }
   18265              :             }
   18266              :         }
   18267         1586 :       gimplify_seq_add_stmt (pre_p, gforo);
   18268              :     }
   18269              :   else
   18270        49864 :     gimplify_seq_add_stmt (pre_p, gfor);
   18271              : 
   18272        51450 :   if (TREE_CODE (orig_for_stmt) == OMP_FOR)
   18273              :     {
   18274        18288 :       struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   18275        18288 :       unsigned lastprivate_conditional = 0;
   18276        18288 :       while (ctx
   18277        18324 :              && (ctx->region_type == ORT_TARGET_DATA
   18278        14238 :                  || ctx->region_type == ORT_TASKGROUP))
   18279           36 :         ctx = ctx->outer_context;
   18280        18288 :       if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
   18281        13978 :         for (tree c = gimple_omp_for_clauses (gfor);
   18282        63348 :              c; c = OMP_CLAUSE_CHAIN (c))
   18283        49370 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   18284        49370 :               && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   18285          158 :             ++lastprivate_conditional;
   18286        13978 :       if (lastprivate_conditional)
   18287              :         {
   18288          118 :           struct omp_for_data fd;
   18289          118 :           omp_extract_for_data (gfor, &fd, NULL);
   18290          118 :           tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
   18291          118 :                                               lastprivate_conditional);
   18292          118 :           tree var = create_tmp_var_raw (type);
   18293          118 :           tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
   18294          118 :           OMP_CLAUSE_DECL (c) = var;
   18295          118 :           OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
   18296          118 :           gimple_omp_for_set_clauses (gfor, c);
   18297          118 :           omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
   18298              :         }
   18299              :     }
   18300        33162 :   else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
   18301              :     {
   18302        10737 :       unsigned lastprivate_conditional = 0;
   18303        49350 :       for (tree c = gimple_omp_for_clauses (gfor); c; c = OMP_CLAUSE_CHAIN (c))
   18304        38613 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
   18305        38613 :             && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
   18306          119 :           ++lastprivate_conditional;
   18307        10737 :       if (lastprivate_conditional)
   18308              :         {
   18309           91 :           struct omp_for_data fd;
   18310           91 :           omp_extract_for_data (gfor, &fd, NULL);
   18311           91 :           tree type = unsigned_type_for (fd.iter_type);
   18312          301 :           while (lastprivate_conditional--)
   18313              :             {
   18314          119 :               tree c = build_omp_clause (UNKNOWN_LOCATION,
   18315              :                                          OMP_CLAUSE__CONDTEMP_);
   18316          119 :               OMP_CLAUSE_DECL (c) = create_tmp_var (type);
   18317          119 :               OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
   18318          119 :               gimple_omp_for_set_clauses (gfor, c);
   18319              :             }
   18320              :         }
   18321              :     }
   18322              : 
   18323        51450 :   if (ret != GS_ALL_DONE)
   18324              :     return GS_ERROR;
   18325        51450 :   *expr_p = NULL_TREE;
   18326        51450 :   return GS_ALL_DONE;
   18327              : }
   18328              : 
   18329              : /* Helper for gimplify_omp_loop, called through walk_tree.  */
   18330              : 
   18331              : static tree
   18332          294 : note_no_context_vars (tree *tp, int *, void *data)
   18333              : {
   18334          294 :   if (VAR_P (*tp)
   18335           56 :       && DECL_CONTEXT (*tp) == NULL_TREE
   18336          309 :       && !is_global_var (*tp))
   18337              :     {
   18338           15 :       vec<tree> *d = (vec<tree> *) data;
   18339           15 :       d->safe_push (*tp);
   18340           15 :       DECL_CONTEXT (*tp) = current_function_decl;
   18341              :     }
   18342          294 :   return NULL_TREE;
   18343              : }
   18344              : 
   18345              : /* Gimplify the gross structure of an OMP_LOOP statement.  */
   18346              : 
   18347              : static enum gimplify_status
   18348         1056 : gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
   18349              : {
   18350         1056 :   tree for_stmt = *expr_p;
   18351         1056 :   tree clauses = OMP_FOR_CLAUSES (for_stmt);
   18352         1056 :   struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
   18353         1056 :   enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
   18354         1056 :   int i;
   18355              : 
   18356         1056 :   omp_maybe_apply_loop_xforms (expr_p, NULL_TREE);
   18357         1056 :   if (*expr_p != for_stmt)
   18358              :     return GS_OK;
   18359              : 
   18360              :   /* If order is not present, the behavior is as if order(concurrent)
   18361              :      appeared.  */
   18362         1056 :   tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
   18363         1056 :   if (order == NULL_TREE)
   18364              :     {
   18365          799 :       order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
   18366          799 :       OMP_CLAUSE_CHAIN (order) = clauses;
   18367          799 :       OMP_FOR_CLAUSES (for_stmt) = clauses = order;
   18368              :     }
   18369              : 
   18370         1056 :   tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
   18371         1056 :   if (bind == NULL_TREE)
   18372              :     {
   18373          574 :       if (!flag_openmp) /* flag_openmp_simd */
   18374              :         ;
   18375          557 :       else if (octx && (octx->region_type & ORT_TEAMS) != 0)
   18376              :         kind = OMP_CLAUSE_BIND_TEAMS;
   18377          327 :       else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
   18378              :         kind = OMP_CLAUSE_BIND_PARALLEL;
   18379              :       else
   18380              :         {
   18381          187 :           for (; octx; octx = octx->outer_context)
   18382              :             {
   18383           79 :               if ((octx->region_type & ORT_ACC) != 0
   18384           79 :                   || octx->region_type == ORT_NONE
   18385           79 :                   || octx->region_type == ORT_IMPLICIT_TARGET)
   18386            0 :                 continue;
   18387              :               break;
   18388              :             }
   18389          187 :           if (octx == NULL && !in_omp_construct)
   18390            4 :             error_at (EXPR_LOCATION (for_stmt),
   18391              :                       "%<bind%> clause not specified on a %<loop%> "
   18392              :                       "construct not nested inside another OpenMP construct");
   18393              :         }
   18394          574 :       bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
   18395          574 :       OMP_CLAUSE_CHAIN (bind) = clauses;
   18396          574 :       OMP_CLAUSE_BIND_KIND (bind) = kind;
   18397          574 :       OMP_FOR_CLAUSES (for_stmt) = bind;
   18398              :     }
   18399              :   else
   18400          482 :     switch (OMP_CLAUSE_BIND_KIND (bind))
   18401              :       {
   18402              :       case OMP_CLAUSE_BIND_THREAD:
   18403              :         break;
   18404          166 :       case OMP_CLAUSE_BIND_PARALLEL:
   18405          166 :         if (!flag_openmp) /* flag_openmp_simd */
   18406              :           {
   18407            0 :             OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
   18408            0 :             break;
   18409              :           }
   18410          240 :         for (; octx; octx = octx->outer_context)
   18411           78 :           if (octx->region_type == ORT_SIMD
   18412           78 :               && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
   18413              :             {
   18414            4 :               error_at (EXPR_LOCATION (for_stmt),
   18415              :                         "%<bind(parallel)%> on a %<loop%> construct nested "
   18416              :                         "inside %<simd%> construct");
   18417            4 :               OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
   18418            4 :               break;
   18419              :             }
   18420              :         kind = OMP_CLAUSE_BIND_PARALLEL;
   18421              :         break;
   18422          162 :       case OMP_CLAUSE_BIND_TEAMS:
   18423          162 :         if (!flag_openmp) /* flag_openmp_simd */
   18424              :           {
   18425            0 :             OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
   18426            0 :             break;
   18427              :           }
   18428          162 :         if ((octx
   18429          128 :              && octx->region_type != ORT_IMPLICIT_TARGET
   18430          111 :              && octx->region_type != ORT_NONE
   18431          111 :              && (octx->region_type & ORT_TEAMS) == 0)
   18432          110 :             || in_omp_construct)
   18433              :           {
   18434           64 :             error_at (EXPR_LOCATION (for_stmt),
   18435              :                       "%<bind(teams)%> on a %<loop%> region not strictly "
   18436              :                       "nested inside of a %<teams%> region");
   18437           64 :             OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
   18438           64 :             break;
   18439              :           }
   18440              :         kind = OMP_CLAUSE_BIND_TEAMS;
   18441              :         break;
   18442            0 :       default:
   18443            0 :         gcc_unreachable ();
   18444              :       }
   18445              : 
   18446         4280 :   for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
   18447         3224 :     switch (OMP_CLAUSE_CODE (*pc))
   18448              :       {
   18449          343 :       case OMP_CLAUSE_REDUCTION:
   18450          343 :         if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
   18451              :           {
   18452            4 :             error_at (OMP_CLAUSE_LOCATION (*pc),
   18453              :                       "%<inscan%> %<reduction%> clause on "
   18454              :                       "%qs construct", "loop");
   18455            4 :             OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
   18456              :           }
   18457          343 :         if (OMP_CLAUSE_REDUCTION_TASK (*pc))
   18458              :           {
   18459            8 :             error_at (OMP_CLAUSE_LOCATION (*pc),
   18460              :                       "invalid %<task%> reduction modifier on construct "
   18461              :                       "other than %<parallel%>, %qs or %<sections%>",
   18462            4 :                       lang_GNU_Fortran () ? "do" : "for");
   18463            4 :             OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
   18464              :           }
   18465          343 :         pc = &OMP_CLAUSE_CHAIN (*pc);
   18466          343 :         break;
   18467              :       case OMP_CLAUSE_LASTPRIVATE:
   18468          293 :         for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   18469              :           {
   18470          289 :             tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
   18471          289 :             gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
   18472          289 :             if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
   18473              :               break;
   18474           26 :             if (OMP_FOR_ORIG_DECLS (for_stmt)
   18475           25 :                 && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
   18476              :                                             i)) == TREE_LIST
   18477           48 :                 && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
   18478              :                                                i)))
   18479              :               {
   18480           22 :                 tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   18481           22 :                 if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
   18482              :                   break;
   18483              :               }
   18484              :           }
   18485          289 :         if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
   18486              :           {
   18487            4 :             error_at (OMP_CLAUSE_LOCATION (*pc),
   18488              :                       "%<lastprivate%> clause on a %<loop%> construct refers "
   18489              :                       "to a variable %qD which is not the loop iterator",
   18490            4 :                       OMP_CLAUSE_DECL (*pc));
   18491            4 :             *pc = OMP_CLAUSE_CHAIN (*pc);
   18492            4 :             break;
   18493              :           }
   18494          285 :         pc = &OMP_CLAUSE_CHAIN (*pc);
   18495          285 :         break;
   18496         2592 :       default:
   18497         2592 :         pc = &OMP_CLAUSE_CHAIN (*pc);
   18498         2592 :         break;
   18499              :     }
   18500              : 
   18501         1056 :   TREE_SET_CODE (for_stmt, OMP_SIMD);
   18502              : 
   18503         1056 :   int last;
   18504         1056 :   switch (kind)
   18505              :     {
   18506              :     case OMP_CLAUSE_BIND_THREAD: last = 0; break;
   18507          414 :     case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
   18508          220 :     case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
   18509              :     }
   18510         1910 :   for (int pass = 1; pass <= last; pass++)
   18511              :     {
   18512          854 :       if (pass == 2)
   18513              :         {
   18514          220 :           tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
   18515              :                               make_node (BLOCK));
   18516          220 :           append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
   18517          220 :           *expr_p = make_node (OMP_PARALLEL);
   18518          220 :           TREE_TYPE (*expr_p) = void_type_node;
   18519          220 :           OMP_PARALLEL_BODY (*expr_p) = bind;
   18520          220 :           OMP_PARALLEL_COMBINED (*expr_p) = 1;
   18521          220 :           SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
   18522          220 :           tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
   18523          672 :           for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
   18524          232 :             if (OMP_FOR_ORIG_DECLS (for_stmt)
   18525          232 :                 && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
   18526              :                     == TREE_LIST))
   18527              :               {
   18528           16 :                 tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
   18529           16 :                 if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
   18530              :                   {
   18531           13 :                     *pc = build_omp_clause (UNKNOWN_LOCATION,
   18532              :                                             OMP_CLAUSE_FIRSTPRIVATE);
   18533           13 :                     OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
   18534           13 :                     pc = &OMP_CLAUSE_CHAIN (*pc);
   18535              :                   }
   18536              :               }
   18537              :         }
   18538          854 :       tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
   18539          854 :       tree *pc = &OMP_FOR_CLAUSES (t);
   18540          854 :       TREE_TYPE (t) = void_type_node;
   18541          854 :       OMP_FOR_BODY (t) = *expr_p;
   18542          854 :       SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
   18543         3968 :       for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
   18544         3114 :         switch (OMP_CLAUSE_CODE (c))
   18545              :           {
   18546         1992 :           case OMP_CLAUSE_BIND:
   18547         1992 :           case OMP_CLAUSE_ORDER:
   18548         1992 :           case OMP_CLAUSE_COLLAPSE:
   18549         1992 :             *pc = copy_node (c);
   18550         1992 :             pc = &OMP_CLAUSE_CHAIN (*pc);
   18551         1992 :             break;
   18552              :           case OMP_CLAUSE_PRIVATE:
   18553              :           case OMP_CLAUSE_FIRSTPRIVATE:
   18554              :             /* Only needed on innermost.  */
   18555              :             break;
   18556          351 :           case OMP_CLAUSE_LASTPRIVATE:
   18557          351 :             if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
   18558              :               {
   18559            7 :                 *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   18560              :                                         OMP_CLAUSE_FIRSTPRIVATE);
   18561            7 :                 OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
   18562            7 :                 lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
   18563            7 :                 pc = &OMP_CLAUSE_CHAIN (*pc);
   18564              :               }
   18565          351 :             *pc = copy_node (c);
   18566          351 :             OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
   18567          351 :             TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
   18568          351 :             if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
   18569              :               {
   18570           22 :                 if (pass != last)
   18571            7 :                   OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
   18572              :                 else
   18573           15 :                   lang_hooks.decls.omp_finish_clause (*pc, NULL, false);
   18574           22 :                 OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
   18575              :               }
   18576          351 :             pc = &OMP_CLAUSE_CHAIN (*pc);
   18577          351 :             break;
   18578          463 :           case OMP_CLAUSE_REDUCTION:
   18579          463 :             *pc = copy_node (c);
   18580          463 :             OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
   18581          463 :             TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
   18582          463 :             if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
   18583              :               {
   18584           15 :                 auto_vec<tree> no_context_vars;
   18585           15 :                 int walk_subtrees = 0;
   18586           15 :                 note_no_context_vars (&OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
   18587              :                                       &walk_subtrees, &no_context_vars);
   18588           15 :                 if (tree p = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c))
   18589            0 :                   note_no_context_vars (&p, &walk_subtrees, &no_context_vars);
   18590           15 :                 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (c),
   18591              :                                               note_no_context_vars,
   18592              :                                               &no_context_vars);
   18593           15 :                 walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (c),
   18594              :                                               note_no_context_vars,
   18595              :                                               &no_context_vars);
   18596              : 
   18597           15 :                 OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
   18598           15 :                   = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
   18599           15 :                 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
   18600            0 :                   OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
   18601            0 :                     = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
   18602              : 
   18603           15 :                 hash_map<tree, tree> decl_map;
   18604           15 :                 decl_map.put (OMP_CLAUSE_DECL (c), OMP_CLAUSE_DECL (c));
   18605           15 :                 decl_map.put (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
   18606           15 :                               OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc));
   18607           15 :                 if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
   18608            0 :                   decl_map.put (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c),
   18609            0 :                                 OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc));
   18610              : 
   18611           15 :                 copy_body_data id;
   18612           15 :                 memset (&id, 0, sizeof (id));
   18613           15 :                 id.src_fn = current_function_decl;
   18614           15 :                 id.dst_fn = current_function_decl;
   18615           15 :                 id.src_cfun = cfun;
   18616           15 :                 id.decl_map = &decl_map;
   18617           15 :                 id.copy_decl = copy_decl_no_change;
   18618           15 :                 id.transform_call_graph_edges = CB_CGE_DUPLICATE;
   18619           15 :                 id.transform_new_cfg = true;
   18620           15 :                 id.transform_return_to_modify = false;
   18621           15 :                 id.eh_lp_nr = 0;
   18622           15 :                 walk_tree (&OMP_CLAUSE_REDUCTION_INIT (*pc), copy_tree_body_r,
   18623              :                            &id, NULL);
   18624           15 :                 walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (*pc), copy_tree_body_r,
   18625              :                            &id, NULL);
   18626              : 
   18627           60 :                 for (tree d : no_context_vars)
   18628              :                   {
   18629           15 :                     DECL_CONTEXT (d) = NULL_TREE;
   18630           15 :                     DECL_CONTEXT (*decl_map.get (d)) = NULL_TREE;
   18631              :                   }
   18632           15 :               }
   18633              :             else
   18634              :               {
   18635          448 :                 OMP_CLAUSE_REDUCTION_INIT (*pc)
   18636          448 :                   = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
   18637          448 :                 OMP_CLAUSE_REDUCTION_MERGE (*pc)
   18638          896 :                   = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
   18639              :               }
   18640          463 :             pc = &OMP_CLAUSE_CHAIN (*pc);
   18641          463 :             break;
   18642            0 :           default:
   18643            0 :             gcc_unreachable ();
   18644              :           }
   18645          854 :       *pc = NULL_TREE;
   18646          854 :       *expr_p = t;
   18647              :     }
   18648         1056 :   return gimplify_expr (expr_p, pre_p, NULL, is_gimple_stmt, fb_none);
   18649              : }
   18650              : 
   18651              : 
   18652              : /* Helper function of optimize_target_teams, find OMP_TEAMS inside
   18653              :    of OMP_TARGET's body.  */
   18654              : 
   18655              : static tree
   18656        99093 : find_omp_teams (tree *tp, int *walk_subtrees, void *)
   18657              : {
   18658        99093 :   *walk_subtrees = 0;
   18659        99093 :   switch (TREE_CODE (*tp))
   18660              :     {
   18661              :     case OMP_TEAMS:
   18662              :       return *tp;
   18663        27406 :     case BIND_EXPR:
   18664        27406 :     case STATEMENT_LIST:
   18665        27406 :       *walk_subtrees = 1;
   18666        27406 :       break;
   18667              :     default:
   18668              :       break;
   18669              :     }
   18670              :   return NULL_TREE;
   18671              : }
   18672              : 
   18673              : /* Helper function of optimize_target_teams, determine if the expression
   18674              :    can be computed safely before the target construct on the host.  */
   18675              : 
   18676              : static tree
   18677         1341 : computable_teams_clause (tree *tp, int *walk_subtrees, void *)
   18678              : {
   18679         1861 :   splay_tree_node n;
   18680              : 
   18681         1861 :   if (TYPE_P (*tp))
   18682              :     {
   18683            0 :       *walk_subtrees = 0;
   18684            0 :       return NULL_TREE;
   18685              :     }
   18686         1861 :   switch (TREE_CODE (*tp))
   18687              :     {
   18688          858 :     case VAR_DECL:
   18689          858 :     case PARM_DECL:
   18690          858 :     case RESULT_DECL:
   18691          858 :       *walk_subtrees = 0;
   18692          858 :       if (error_operand_p (*tp)
   18693          858 :           || !INTEGRAL_TYPE_P (TREE_TYPE (*tp))
   18694          858 :           || DECL_HAS_VALUE_EXPR_P (*tp)
   18695          858 :           || DECL_THREAD_LOCAL_P (*tp)
   18696          858 :           || TREE_SIDE_EFFECTS (*tp)
   18697         1716 :           || TREE_THIS_VOLATILE (*tp))
   18698            0 :         return *tp;
   18699          858 :       if (is_global_var (*tp)
   18700          858 :           && (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (*tp))
   18701            0 :               || lookup_attribute ("omp declare target link",
   18702            0 :                                    DECL_ATTRIBUTES (*tp))))
   18703           16 :         return *tp;
   18704          842 :       if (VAR_P (*tp)
   18705          536 :           && !DECL_SEEN_IN_BIND_EXPR_P (*tp)
   18706            0 :           && !is_global_var (*tp)
   18707          842 :           && decl_function_context (*tp) == current_function_decl)
   18708            0 :         return *tp;
   18709         1684 :       n = splay_tree_lookup (gimplify_omp_ctxp->variables,
   18710          842 :                              (splay_tree_key) *tp);
   18711          842 :       if (n == NULL)
   18712              :         {
   18713          210 :           if (gimplify_omp_ctxp->defaultmap[GDMK_SCALAR] & GOVD_FIRSTPRIVATE)
   18714              :             return NULL_TREE;
   18715            0 :           return *tp;
   18716              :         }
   18717          632 :       else if (n->value & GOVD_LOCAL)
   18718            0 :         return *tp;
   18719          632 :       else if (n->value & GOVD_FIRSTPRIVATE)
   18720              :         return NULL_TREE;
   18721          112 :       else if ((n->value & (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
   18722              :                == (GOVD_MAP | GOVD_MAP_ALWAYS_TO))
   18723              :         return NULL_TREE;
   18724           96 :       return *tp;
   18725           76 :     case INTEGER_CST:
   18726           76 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
   18727            0 :         return *tp;
   18728              :       return NULL_TREE;
   18729          520 :     case TARGET_EXPR:
   18730          520 :       if (TARGET_EXPR_INITIAL (*tp)
   18731          520 :           || TREE_CODE (TARGET_EXPR_SLOT (*tp)) != VAR_DECL)
   18732              :         return *tp;
   18733          520 :       return computable_teams_clause (&TARGET_EXPR_SLOT (*tp),
   18734          520 :                                       walk_subtrees, NULL);
   18735              :     /* Allow some reasonable subset of integral arithmetics.  */
   18736          193 :     case PLUS_EXPR:
   18737          193 :     case MINUS_EXPR:
   18738          193 :     case MULT_EXPR:
   18739          193 :     case TRUNC_DIV_EXPR:
   18740          193 :     case CEIL_DIV_EXPR:
   18741          193 :     case FLOOR_DIV_EXPR:
   18742          193 :     case ROUND_DIV_EXPR:
   18743          193 :     case TRUNC_MOD_EXPR:
   18744          193 :     case CEIL_MOD_EXPR:
   18745          193 :     case FLOOR_MOD_EXPR:
   18746          193 :     case ROUND_MOD_EXPR:
   18747          193 :     case RDIV_EXPR:
   18748          193 :     case EXACT_DIV_EXPR:
   18749          193 :     case MIN_EXPR:
   18750          193 :     case MAX_EXPR:
   18751          193 :     case LSHIFT_EXPR:
   18752          193 :     case RSHIFT_EXPR:
   18753          193 :     case BIT_IOR_EXPR:
   18754          193 :     case BIT_XOR_EXPR:
   18755          193 :     case BIT_AND_EXPR:
   18756          193 :     case NEGATE_EXPR:
   18757          193 :     case ABS_EXPR:
   18758          193 :     case BIT_NOT_EXPR:
   18759          193 :     case NON_LVALUE_EXPR:
   18760          193 :     CASE_CONVERT:
   18761          193 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (*tp)))
   18762            0 :         return *tp;
   18763              :       return NULL_TREE;
   18764              :     /* And disallow anything else, except for comparisons.  */
   18765          214 :     default:
   18766          214 :       if (COMPARISON_CLASS_P (*tp))
   18767            0 :         return NULL_TREE;
   18768              :       return *tp;
   18769              :     }
   18770              : }
   18771              : 
   18772              : /* Try to determine if the num_teams and/or thread_limit expressions
   18773              :    can have their values determined already before entering the
   18774              :    target construct.
   18775              :    INTEGER_CSTs trivially are,
   18776              :    integral decls that are firstprivate (explicitly or implicitly)
   18777              :    or explicitly map(always, to:) or map(always, tofrom:) on the target
   18778              :    region too, and expressions involving simple arithmetics on those
   18779              :    too, function calls are not ok, dereferencing something neither etc.
   18780              :    Add NUM_TEAMS and THREAD_LIMIT clauses to the OMP_CLAUSES of
   18781              :    EXPR based on what we find:
   18782              :    0 stands for clause not specified at all, use implementation default
   18783              :    -1 stands for value that can't be determined easily before entering
   18784              :       the target construct.
   18785              :    -2 means that no explicit teams construct was specified
   18786              :    If teams construct is not present at all, use 1 for num_teams
   18787              :    and 0 for thread_limit (only one team is involved, and the thread
   18788              :    limit is implementation defined.  */
   18789              : 
   18790              : static void
   18791        13567 : optimize_target_teams (tree target, gimple_seq *pre_p)
   18792              : {
   18793        13567 :   tree body = OMP_BODY (target);
   18794        13567 :   tree teams = walk_tree (&body, find_omp_teams, NULL, NULL);
   18795        13567 :   tree num_teams_lower = NULL_TREE;
   18796        13567 :   tree num_teams_upper = integer_zero_node;
   18797        13567 :   tree thread_limit = integer_zero_node;
   18798        13567 :   location_t num_teams_loc = EXPR_LOCATION (target);
   18799        13567 :   location_t thread_limit_loc = EXPR_LOCATION (target);
   18800        13567 :   tree c, *p, expr;
   18801        13567 :   struct gimplify_omp_ctx *target_ctx = gimplify_omp_ctxp;
   18802              : 
   18803        13567 :   if (teams == NULL_TREE)
   18804         7438 :     num_teams_upper = build_int_cst (integer_type_node, -2);
   18805              :   else
   18806        10615 :     for (c = OMP_TEAMS_CLAUSES (teams); c; c = OMP_CLAUSE_CHAIN (c))
   18807              :       {
   18808         4486 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS)
   18809              :           {
   18810          625 :             p = &num_teams_upper;
   18811          625 :             num_teams_loc = OMP_CLAUSE_LOCATION (c);
   18812          625 :             if (OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c))
   18813              :               {
   18814          136 :                 expr = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
   18815          136 :                 if (TREE_CODE (expr) == INTEGER_CST)
   18816           18 :                   num_teams_lower = expr;
   18817          118 :                 else if (walk_tree (&expr, computable_teams_clause,
   18818              :                                     NULL, NULL))
   18819           12 :                   num_teams_lower = integer_minus_one_node;
   18820              :                 else
   18821              :                   {
   18822          106 :                     num_teams_lower = expr;
   18823          106 :                     gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
   18824          106 :                     if (gimplify_expr (&num_teams_lower, pre_p, NULL,
   18825              :                                        is_gimple_val, fb_rvalue, false)
   18826              :                         == GS_ERROR)
   18827              :                       {
   18828            0 :                         gimplify_omp_ctxp = target_ctx;
   18829            0 :                         num_teams_lower = integer_minus_one_node;
   18830              :                       }
   18831              :                     else
   18832              :                       {
   18833          106 :                         gimplify_omp_ctxp = target_ctx;
   18834          106 :                         if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
   18835           28 :                           OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
   18836           56 :                             = num_teams_lower;
   18837              :                       }
   18838              :                   }
   18839              :               }
   18840              :           }
   18841         3861 :         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
   18842              :           {
   18843          479 :             p = &thread_limit;
   18844          479 :             thread_limit_loc = OMP_CLAUSE_LOCATION (c);
   18845              :           }
   18846              :         else
   18847         3382 :           continue;
   18848         1104 :         expr = OMP_CLAUSE_OPERAND (c, 0);
   18849         1104 :         if (TREE_CODE (expr) == INTEGER_CST)
   18850              :           {
   18851          150 :             *p = expr;
   18852          150 :             continue;
   18853              :           }
   18854          954 :         if (walk_tree (&expr, computable_teams_clause, NULL, NULL))
   18855              :           {
   18856          314 :             *p = integer_minus_one_node;
   18857          314 :             continue;
   18858              :           }
   18859          640 :         *p = expr;
   18860          640 :         gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
   18861          640 :         if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
   18862              :             == GS_ERROR)
   18863              :           {
   18864            0 :             gimplify_omp_ctxp = target_ctx;
   18865            0 :             *p = integer_minus_one_node;
   18866            0 :             continue;
   18867              :           }
   18868          640 :         gimplify_omp_ctxp = target_ctx;
   18869          640 :         if (!DECL_P (expr) && TREE_CODE (expr) != TARGET_EXPR)
   18870           48 :           OMP_CLAUSE_OPERAND (c, 0) = *p;
   18871              :       }
   18872        13567 :   if (!omp_find_clause (OMP_TARGET_CLAUSES (target), OMP_CLAUSE_THREAD_LIMIT))
   18873              :     {
   18874        13287 :       c = build_omp_clause (thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
   18875        13287 :       OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = thread_limit;
   18876        13287 :       OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
   18877        13287 :       OMP_TARGET_CLAUSES (target) = c;
   18878              :     }
   18879        13567 :   c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
   18880        13567 :   OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = num_teams_upper;
   18881        13567 :   OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = num_teams_lower;
   18882        13567 :   OMP_CLAUSE_CHAIN (c) = OMP_TARGET_CLAUSES (target);
   18883        13567 :   OMP_TARGET_CLAUSES (target) = c;
   18884        13567 : }
   18885              : 
   18886              : /* Gimplify the gross structure of several OMP constructs.  */
   18887              : 
   18888              : static void
   18889        40049 : gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
   18890              : {
   18891        40049 :   tree expr = *expr_p;
   18892        40049 :   gimple *stmt;
   18893        40049 :   gimple_seq body = NULL;
   18894        40049 :   enum omp_region_type ort;
   18895              : 
   18896        40049 :   switch (TREE_CODE (expr))
   18897              :     {
   18898              :     case OMP_SECTIONS:
   18899              :     case OMP_SINGLE:
   18900              :       ort = ORT_WORKSHARE;
   18901              :       break;
   18902          242 :     case OMP_SCOPE:
   18903          242 :       ort = ORT_TASKGROUP;
   18904          242 :       break;
   18905        13567 :     case OMP_TARGET:
   18906        13567 :       ort = OMP_TARGET_COMBINED (expr) ? ORT_COMBINED_TARGET : ORT_TARGET;
   18907              :       break;
   18908         2543 :     case OACC_KERNELS:
   18909         2543 :       ort = ORT_ACC_KERNELS;
   18910         2543 :       break;
   18911         7901 :     case OACC_PARALLEL:
   18912         7901 :       ort = ORT_ACC_PARALLEL;
   18913         7901 :       break;
   18914         1040 :     case OACC_SERIAL:
   18915         1040 :       ort = ORT_ACC_SERIAL;
   18916         1040 :       break;
   18917         1950 :     case OACC_DATA:
   18918         1950 :       ort = ORT_ACC_DATA;
   18919         1950 :       break;
   18920         1875 :     case OMP_TARGET_DATA:
   18921         1875 :       ort = ORT_TARGET_DATA;
   18922         1875 :       break;
   18923         8892 :     case OMP_TEAMS:
   18924         8892 :       ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
   18925         8892 :       if (gimplify_omp_ctxp == NULL
   18926         6169 :           || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
   18927         2723 :         ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
   18928              :       break;
   18929          118 :     case OACC_HOST_DATA:
   18930          118 :       ort = ORT_ACC_HOST_DATA;
   18931          118 :       break;
   18932            0 :     default:
   18933            0 :       gcc_unreachable ();
   18934              :     }
   18935              : 
   18936        40049 :   gimple_seq iterator_loops_seq = NULL;
   18937        40049 :   if (TREE_CODE (expr) == OMP_TARGET || TREE_CODE (expr) == OMP_TARGET_DATA)
   18938              :     {
   18939        15442 :       remove_unused_omp_iterator_vars (&OMP_CLAUSES (expr));
   18940        15442 :       build_omp_iterators_loops (&OMP_CLAUSES (expr), &iterator_loops_seq);
   18941              :     }
   18942              : 
   18943        40049 :   bool save_in_omp_construct = in_omp_construct;
   18944        40049 :   if ((ort & ORT_ACC) == 0)
   18945        26497 :     in_omp_construct = false;
   18946        40049 :   gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
   18947        40049 :                              TREE_CODE (expr), &iterator_loops_seq);
   18948        40049 :   if (TREE_CODE (expr) == OMP_TARGET)
   18949        13567 :     optimize_target_teams (expr, pre_p);
   18950        40049 :   if ((ort & (ORT_TARGET | ORT_TARGET_DATA)) != 0
   18951        11055 :       || (ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
   18952              :     {
   18953        31717 :       push_gimplify_context ();
   18954        31717 :       gimple *g = gimplify_and_return_first (OMP_BODY (expr), &body);
   18955        31717 :       if (gimple_code (g) == GIMPLE_BIND)
   18956        31717 :         pop_gimplify_context (g);
   18957              :       else
   18958            0 :         pop_gimplify_context (NULL);
   18959        31717 :       if ((ort & ORT_TARGET_DATA) != 0)
   18960              :         {
   18961         3943 :           enum built_in_function end_ix;
   18962         3943 :           switch (TREE_CODE (expr))
   18963              :             {
   18964              :             case OACC_DATA:
   18965              :             case OACC_HOST_DATA:
   18966              :               end_ix = BUILT_IN_GOACC_DATA_END;
   18967              :               break;
   18968         1875 :             case OMP_TARGET_DATA:
   18969         1875 :               end_ix = BUILT_IN_GOMP_TARGET_END_DATA;
   18970         1875 :               break;
   18971            0 :             default:
   18972            0 :               gcc_unreachable ();
   18973              :             }
   18974         3943 :           tree fn = builtin_decl_explicit (end_ix);
   18975         3943 :           g = gimple_build_call (fn, 0);
   18976         3943 :           gimple_seq cleanup = NULL;
   18977         3943 :           gimple_seq_add_stmt (&cleanup, g);
   18978         3943 :           g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
   18979         3943 :           body = NULL;
   18980         3943 :           gimple_seq_add_stmt (&body, g);
   18981              :         }
   18982              :     }
   18983              :   else
   18984         8332 :     gimplify_and_add (OMP_BODY (expr), &body);
   18985        40049 :   gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
   18986        40049 :                                TREE_CODE (expr), &iterator_loops_seq);
   18987        40049 :   in_omp_construct = save_in_omp_construct;
   18988              : 
   18989        40049 :   switch (TREE_CODE (expr))
   18990              :     {
   18991         1950 :     case OACC_DATA:
   18992         3900 :       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_DATA,
   18993         1950 :                                       OMP_CLAUSES (expr));
   18994         1950 :       break;
   18995          118 :     case OACC_HOST_DATA:
   18996          118 :       if (omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_IF_PRESENT))
   18997              :         {
   18998          128 :           for (tree c = OMP_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   18999           95 :             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
   19000           57 :               OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (c) = 1;
   19001              :         }
   19002              : 
   19003          236 :       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_HOST_DATA,
   19004          118 :                                       OMP_CLAUSES (expr));
   19005          118 :       break;
   19006         2543 :     case OACC_KERNELS:
   19007         5086 :       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_KERNELS,
   19008         2543 :                                       OMP_CLAUSES (expr));
   19009         2543 :       break;
   19010         7901 :     case OACC_PARALLEL:
   19011        15802 :       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_PARALLEL,
   19012         7901 :                                       OMP_CLAUSES (expr));
   19013         7901 :       break;
   19014         1040 :     case OACC_SERIAL:
   19015         2080 :       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_OACC_SERIAL,
   19016         1040 :                                       OMP_CLAUSES (expr));
   19017         1040 :       break;
   19018          634 :     case OMP_SECTIONS:
   19019          634 :       stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
   19020          634 :       break;
   19021         1287 :     case OMP_SINGLE:
   19022         1287 :       stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
   19023         1287 :       break;
   19024          242 :     case OMP_SCOPE:
   19025          242 :       stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr));
   19026          242 :       break;
   19027        13567 :     case OMP_TARGET:
   19028              :       /* Handle 'device_type(nohost)'.  */
   19029        13567 :       if (tree c = omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_DEVICE_TYPE))
   19030           20 :         if (OMP_CLAUSE_DEVICE_TYPE_KIND (c) == OMP_CLAUSE_DEVICE_TYPE_NOHOST)
   19031              :           {
   19032            9 :             location_t loc = gimple_location (body);
   19033            9 :             tree fn = builtin_decl_explicit (BUILT_IN_OMP_IS_INITIAL_DEVICE);
   19034            9 :             fn = build_call_expr_loc (loc, fn, 0);
   19035            9 :             tree err = builtin_decl_explicit (BUILT_IN_GOMP_ERROR);
   19036            9 :             const char *str = "Executing device-type 'nohost' target region "
   19037              :                               "on the host";
   19038            9 :             tree msg = build_string_literal (strlen (str) + 1, str);
   19039            9 :             tree msglen = build_int_cst (size_type_node, -2);
   19040            9 :             err = build_call_expr_loc (loc, err, 2, msg, msglen);
   19041            9 :             tree l1 = create_artificial_label (UNKNOWN_LOCATION);
   19042            9 :             tree l2 = create_artificial_label (UNKNOWN_LOCATION);
   19043            9 :             tree l3 = create_artificial_label (UNKNOWN_LOCATION);
   19044              : 
   19045            9 :             gimple_seq new_body = NULL;
   19046              : 
   19047            9 :             gimplify_expr (&fn, &new_body, NULL, is_gimple_val, fb_rvalue);
   19048            9 :             gcond *cond = gimple_build_cond (NE_EXPR, fn,
   19049            9 :                                              build_int_cst (TREE_TYPE (fn), 0),
   19050              :                                              l1, l2);
   19051            9 :             gimplify_seq_add_stmt (&new_body, cond);
   19052            9 :             gimplify_seq_add_stmt (&new_body, gimple_build_label (l1));
   19053            9 :             gimplify_and_add (err, &new_body);
   19054            9 :             gimplify_seq_add_stmt (&new_body, gimple_build_goto (l3));
   19055            9 :             gimplify_seq_add_stmt (&new_body, gimple_build_label (l2));
   19056            9 :             gimple_seq_add_seq (&new_body, body);
   19057            9 :             gimplify_seq_add_stmt (&new_body, gimple_build_label (l3));
   19058            9 :             body = gimple_build_bind (NULL_TREE, new_body, make_node (BLOCK));
   19059            9 :             gimple_set_location (body, loc);
   19060              :           }
   19061        27134 :       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
   19062        13567 :                                       OMP_CLAUSES (expr), iterator_loops_seq);
   19063        13567 :       break;
   19064         1875 :     case OMP_TARGET_DATA:
   19065              :       /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
   19066              :          to be evaluated before the use_device_{ptr,addr} clauses if they
   19067              :          refer to the same variables.  */
   19068         1875 :       {
   19069         1875 :         tree use_device_clauses;
   19070         1875 :         tree *pc, *uc = &use_device_clauses;
   19071         9974 :         for (pc = &OMP_CLAUSES (expr); *pc; )
   19072         8099 :           if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
   19073         8099 :               || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
   19074              :             {
   19075         1959 :               *uc = *pc;
   19076         1959 :               *pc = OMP_CLAUSE_CHAIN (*pc);
   19077         1959 :               uc = &OMP_CLAUSE_CHAIN (*uc);
   19078              :             }
   19079              :           else
   19080         6140 :             pc = &OMP_CLAUSE_CHAIN (*pc);
   19081         1875 :         *uc = NULL_TREE;
   19082         1875 :         *pc = use_device_clauses;
   19083         1875 :         stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
   19084         1875 :                                         OMP_CLAUSES (expr), iterator_loops_seq);
   19085              :       }
   19086         1875 :       break;
   19087         8892 :     case OMP_TEAMS:
   19088         8892 :       stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
   19089         8892 :       if ((ort & ORT_HOST_TEAMS) == ORT_HOST_TEAMS)
   19090         2723 :         gimple_omp_teams_set_host (as_a <gomp_teams *> (stmt), true);
   19091              :       break;
   19092            0 :     default:
   19093            0 :       gcc_unreachable ();
   19094              :     }
   19095              : 
   19096        40049 :   gimplify_seq_add_stmt (pre_p, stmt);
   19097        40049 :   *expr_p = NULL_TREE;
   19098        40049 : }
   19099              : 
   19100              : /* Gimplify the gross structure of OpenACC enter/exit data, update, and OpenMP
   19101              :    target update constructs.  */
   19102              : 
   19103              : static void
   19104        12382 : gimplify_omp_target_update (tree *expr_p, gimple_seq *pre_p)
   19105              : {
   19106        12382 :   tree expr = *expr_p;
   19107        12382 :   int kind;
   19108        12382 :   gomp_target *stmt;
   19109        12382 :   enum omp_region_type ort = ORT_WORKSHARE;
   19110              : 
   19111        12382 :   switch (TREE_CODE (expr))
   19112              :     {
   19113              :     case OACC_ENTER_DATA:
   19114              :       kind = GF_OMP_TARGET_KIND_OACC_ENTER_DATA;
   19115              :       ort = ORT_ACC;
   19116              :       break;
   19117              :     case OACC_EXIT_DATA:
   19118              :       kind = GF_OMP_TARGET_KIND_OACC_EXIT_DATA;
   19119              :       ort = ORT_ACC;
   19120              :       break;
   19121              :     case OACC_UPDATE:
   19122              :       kind = GF_OMP_TARGET_KIND_OACC_UPDATE;
   19123              :       ort = ORT_ACC;
   19124              :       break;
   19125              :     case OMP_TARGET_UPDATE:
   19126              :       kind = GF_OMP_TARGET_KIND_UPDATE;
   19127              :       break;
   19128              :     case OMP_TARGET_ENTER_DATA:
   19129              :       kind = GF_OMP_TARGET_KIND_ENTER_DATA;
   19130              :       break;
   19131              :     case OMP_TARGET_EXIT_DATA:
   19132              :       kind = GF_OMP_TARGET_KIND_EXIT_DATA;
   19133              :       break;
   19134            0 :     default:
   19135            0 :       gcc_unreachable ();
   19136              :     }
   19137              : 
   19138        12382 :   gimple_seq iterator_loops_seq = NULL;
   19139        12382 :   remove_unused_omp_iterator_vars (&OMP_STANDALONE_CLAUSES (expr));
   19140        12382 :   build_omp_iterators_loops (&OMP_STANDALONE_CLAUSES (expr),
   19141              :                              &iterator_loops_seq);
   19142              : 
   19143        12382 :   gimplify_scan_omp_clauses (&OMP_STANDALONE_CLAUSES (expr), pre_p,
   19144        12382 :                              ort, TREE_CODE (expr), &iterator_loops_seq);
   19145        12382 :   gimplify_adjust_omp_clauses (pre_p, NULL, &OMP_STANDALONE_CLAUSES (expr),
   19146        12382 :                                TREE_CODE (expr), &iterator_loops_seq);
   19147        12382 :   if (TREE_CODE (expr) == OACC_UPDATE
   19148        12382 :       && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
   19149              :                           OMP_CLAUSE_IF_PRESENT))
   19150              :     {
   19151              :       /* The runtime uses GOMP_MAP_{TO,FROM} to denote the if_present
   19152              :          clause.  */
   19153          123 :       for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   19154           97 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
   19155           47 :           switch (OMP_CLAUSE_MAP_KIND (c))
   19156              :             {
   19157           14 :             case GOMP_MAP_FORCE_TO:
   19158           14 :               OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
   19159           14 :               break;
   19160           24 :             case GOMP_MAP_FORCE_FROM:
   19161           24 :               OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FROM);
   19162           24 :               break;
   19163              :             default:
   19164              :               break;
   19165              :             }
   19166              :     }
   19167        12356 :   else if (TREE_CODE (expr) == OACC_EXIT_DATA
   19168        12356 :            && omp_find_clause (OMP_STANDALONE_CLAUSES (expr),
   19169              :                                OMP_CLAUSE_FINALIZE))
   19170              :     {
   19171              :       /* Use GOMP_MAP_DELETE/GOMP_MAP_FORCE_FROM to denote "finalize"
   19172              :          semantics.  */
   19173           75 :       bool have_clause = false;
   19174          275 :       for (tree c = OMP_STANDALONE_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   19175          200 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
   19176          117 :           switch (OMP_CLAUSE_MAP_KIND (c))
   19177              :             {
   19178           45 :             case GOMP_MAP_FROM:
   19179           45 :               OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_FROM);
   19180           45 :               have_clause = true;
   19181           45 :               break;
   19182           47 :             case GOMP_MAP_RELEASE:
   19183           47 :               OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_DELETE);
   19184           47 :               have_clause = true;
   19185           47 :               break;
   19186              :             case GOMP_MAP_TO_PSET:
   19187              :               /* Fortran arrays with descriptors must map that descriptor when
   19188              :                  doing standalone "attach" operations (in OpenACC).  In that
   19189              :                  case GOMP_MAP_TO_PSET appears by itself with no preceding
   19190              :                  clause (see trans-openmp.cc:gfc_trans_omp_clauses).  */
   19191              :               break;
   19192            2 :             case GOMP_MAP_POINTER:
   19193              :               /* TODO PR92929: we may see these here, but they'll always follow
   19194              :                  one of the clauses above, and will be handled by libgomp as
   19195              :                  one group, so no handling required here.  */
   19196            2 :               gcc_assert (have_clause);
   19197              :               break;
   19198           22 :             case GOMP_MAP_DETACH:
   19199           22 :               OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_FORCE_DETACH);
   19200           22 :               have_clause = false;
   19201           22 :               break;
   19202              :             case GOMP_MAP_STRUCT:
   19203              :             case GOMP_MAP_STRUCT_UNORD:
   19204          200 :               have_clause = false;
   19205              :               break;
   19206            0 :             default:
   19207            0 :               gcc_unreachable ();
   19208              :             }
   19209              :     }
   19210        12382 :   stmt = gimple_build_omp_target (NULL, kind, OMP_STANDALONE_CLAUSES (expr),
   19211              :                                   iterator_loops_seq);
   19212              : 
   19213        12382 :   gimplify_seq_add_stmt (pre_p, stmt);
   19214        12382 :   *expr_p = NULL_TREE;
   19215        12382 : }
   19216              : 
   19217              : /* A subroutine of gimplify_omp_atomic.  The front end is supposed to have
   19218              :    stabilized the lhs of the atomic operation as *ADDR.  Return true if
   19219              :    EXPR is this stabilized form.  */
   19220              : 
   19221              : static bool
   19222        36846 : goa_lhs_expr_p (tree expr, tree addr)
   19223              : {
   19224              :   /* Also include casts to other type variants.  The C front end is fond
   19225              :      of adding these for e.g. volatile variables.  This is like
   19226              :      STRIP_TYPE_NOPS but includes the main variant lookup.  */
   19227        36846 :   STRIP_USELESS_TYPE_CONVERSION (expr);
   19228              : 
   19229        36846 :   if (INDIRECT_REF_P (expr))
   19230              :     {
   19231         5027 :       expr = TREE_OPERAND (expr, 0);
   19232         5027 :       while (expr != addr
   19233           92 :              && (CONVERT_EXPR_P (expr)
   19234           92 :                  || TREE_CODE (expr) == NON_LVALUE_EXPR)
   19235            0 :              && TREE_CODE (expr) == TREE_CODE (addr)
   19236         5027 :              && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr)))
   19237              :         {
   19238            0 :           expr = TREE_OPERAND (expr, 0);
   19239            0 :           addr = TREE_OPERAND (addr, 0);
   19240              :         }
   19241         5027 :       if (expr == addr)
   19242              :         return true;
   19243           92 :       return (TREE_CODE (addr) == ADDR_EXPR
   19244           62 :               && TREE_CODE (expr) == ADDR_EXPR
   19245           92 :               && TREE_OPERAND (addr, 0) == TREE_OPERAND (expr, 0));
   19246              :     }
   19247        31819 :   if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
   19248              :     return true;
   19249              :   return false;
   19250              : }
   19251              : 
   19252              : /* Walk *EXPR_P and replace appearances of *LHS_ADDR with LHS_VAR.  If an
   19253              :    expression does not involve the lhs, evaluate it into a temporary.
   19254              :    Return 1 if the lhs appeared as a subexpression, 0 if it did not,
   19255              :    or -1 if an error was encountered.  */
   19256              : 
   19257              : static int
   19258        36846 : goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
   19259              :                     tree lhs_var, tree &target_expr, bool rhs, int depth)
   19260              : {
   19261        36846 :   tree expr = *expr_p;
   19262        36846 :   int saw_lhs = 0;
   19263              : 
   19264        36846 :   if (goa_lhs_expr_p (expr, lhs_addr))
   19265              :     {
   19266         9203 :       if (pre_p)
   19267         8544 :         *expr_p = lhs_var;
   19268              :       return 1;
   19269              :     }
   19270        27643 :   if (is_gimple_val (expr))
   19271              :     return 0;
   19272              : 
   19273              :   /* Maximum depth of lhs in expression is for the
   19274              :      __builtin_clear_padding (...), __builtin_clear_padding (...),
   19275              :      __builtin_memcmp (&TARGET_EXPR <lhs, >, ...) == 0 ? ... : lhs;  */
   19276        17299 :   if (++depth > 7)
   19277           16 :     goto finish;
   19278              : 
   19279        17283 :   switch (TREE_CODE_CLASS (TREE_CODE (expr)))
   19280              :     {
   19281         9669 :     case tcc_binary:
   19282         9669 :     case tcc_comparison:
   19283         9669 :       saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
   19284              :                                      lhs_var, target_expr, true, depth);
   19285              :       /* FALLTHRU */
   19286        11712 :     case tcc_unary:
   19287        11712 :       saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
   19288              :                                      lhs_var, target_expr, true, depth);
   19289        11712 :       break;
   19290         2983 :     case tcc_expression:
   19291         2983 :       switch (TREE_CODE (expr))
   19292              :         {
   19293          836 :         case TRUTH_ANDIF_EXPR:
   19294          836 :         case TRUTH_ORIF_EXPR:
   19295          836 :         case TRUTH_AND_EXPR:
   19296          836 :         case TRUTH_OR_EXPR:
   19297          836 :         case TRUTH_XOR_EXPR:
   19298          836 :         case BIT_INSERT_EXPR:
   19299          836 :           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
   19300              :                                          lhs_addr, lhs_var, target_expr, true,
   19301              :                                          depth);
   19302              :           /* FALLTHRU */
   19303          888 :         case TRUTH_NOT_EXPR:
   19304          888 :           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   19305              :                                          lhs_addr, lhs_var, target_expr, true,
   19306              :                                          depth);
   19307          888 :           break;
   19308          550 :         case MODIFY_EXPR:
   19309          550 :           if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
   19310              :                                             target_expr, true, depth))
   19311              :             break;
   19312          544 :           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
   19313              :                                          lhs_addr, lhs_var, target_expr, true,
   19314              :                                          depth);
   19315          544 :           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   19316              :                                          lhs_addr, lhs_var, target_expr, false,
   19317              :                                          depth);
   19318          544 :           break;
   19319              :           /* FALLTHRU */
   19320          164 :         case ADDR_EXPR:
   19321          164 :           if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr, lhs_var,
   19322              :                                             target_expr, true, depth))
   19323              :             break;
   19324          138 :           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   19325              :                                          lhs_addr, lhs_var, target_expr, false,
   19326              :                                          depth);
   19327          138 :           break;
   19328              :         case COMPOUND_EXPR:
   19329              :           /* Break out any preevaluations from cp_build_modify_expr.  */
   19330           76 :           for (; TREE_CODE (expr) == COMPOUND_EXPR;
   19331           38 :                expr = TREE_OPERAND (expr, 1))
   19332              :             {
   19333              :               /* Special-case __builtin_clear_padding call before
   19334              :                  __builtin_memcmp.  */
   19335           38 :               if (TREE_CODE (TREE_OPERAND (expr, 0)) == CALL_EXPR)
   19336              :                 {
   19337            2 :                   tree fndecl = get_callee_fndecl (TREE_OPERAND (expr, 0));
   19338            2 :                   if (fndecl
   19339            2 :                       && fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING)
   19340            0 :                       && VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
   19341            2 :                       && (!pre_p
   19342            0 :                           || goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL,
   19343              :                                                  lhs_addr, lhs_var,
   19344              :                                                  target_expr, true, depth)))
   19345              :                     {
   19346            0 :                       if (pre_p)
   19347            0 :                         *expr_p = expr;
   19348            0 :                       saw_lhs = goa_stabilize_expr (&TREE_OPERAND (expr, 0),
   19349              :                                                     pre_p, lhs_addr, lhs_var,
   19350              :                                                     target_expr, true, depth);
   19351            0 :                       saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1),
   19352              :                                                      pre_p, lhs_addr, lhs_var,
   19353              :                                                      target_expr, rhs, depth);
   19354            0 :                       return saw_lhs;
   19355              :                     }
   19356              :                 }
   19357              : 
   19358           38 :               if (pre_p)
   19359           35 :                 gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
   19360              :             }
   19361           38 :           if (!pre_p)
   19362            3 :             return goa_stabilize_expr (&expr, pre_p, lhs_addr, lhs_var,
   19363            3 :                                        target_expr, rhs, depth);
   19364           35 :           *expr_p = expr;
   19365           35 :           return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var,
   19366           35 :                                      target_expr, rhs, depth);
   19367          442 :         case COND_EXPR:
   19368          442 :           if (!goa_stabilize_expr (&TREE_OPERAND (expr, 0), NULL, lhs_addr,
   19369              :                                    lhs_var, target_expr, true, depth))
   19370              :             break;
   19371          429 :           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   19372              :                                          lhs_addr, lhs_var, target_expr, true,
   19373              :                                          depth);
   19374          429 :           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
   19375              :                                          lhs_addr, lhs_var, target_expr, true,
   19376              :                                          depth);
   19377          429 :           saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 2), pre_p,
   19378              :                                          lhs_addr, lhs_var, target_expr, true,
   19379              :                                          depth);
   19380          429 :           break;
   19381          880 :         case TARGET_EXPR:
   19382          880 :           if (TARGET_EXPR_INITIAL (expr))
   19383              :             {
   19384          880 :               if (pre_p && !goa_stabilize_expr (expr_p, NULL, lhs_addr,
   19385              :                                                 lhs_var, target_expr, true,
   19386              :                                                 depth))
   19387              :                 break;
   19388          702 :               if (expr == target_expr)
   19389              :                 saw_lhs = 1;
   19390              :               else
   19391              :                 {
   19392          702 :                   saw_lhs = goa_stabilize_expr (&TARGET_EXPR_INITIAL (expr),
   19393              :                                                 pre_p, lhs_addr, lhs_var,
   19394              :                                                 target_expr, true, depth);
   19395          702 :                   if (saw_lhs && target_expr == NULL_TREE && pre_p)
   19396           26 :                     target_expr = expr;
   19397              :                 }
   19398              :             }
   19399              :           break;
   19400              :         default:
   19401              :           break;
   19402              :         }
   19403              :       break;
   19404          565 :     case tcc_reference:
   19405          565 :       if (TREE_CODE (expr) == BIT_FIELD_REF
   19406          499 :           || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
   19407          362 :         saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
   19408              :                                        lhs_addr, lhs_var, target_expr, true,
   19409              :                                        depth);
   19410              :       break;
   19411           58 :     case tcc_vl_exp:
   19412           58 :       if (TREE_CODE (expr) == CALL_EXPR)
   19413              :         {
   19414           58 :           if (tree fndecl = get_callee_fndecl (expr))
   19415           58 :             if (fndecl_built_in_p (fndecl, BUILT_IN_CLEAR_PADDING,
   19416              :                                            BUILT_IN_MEMCMP))
   19417              :               {
   19418           56 :                 int nargs = call_expr_nargs (expr);
   19419          224 :                 for (int i = 0; i < nargs; i++)
   19420          168 :                   saw_lhs |= goa_stabilize_expr (&CALL_EXPR_ARG (expr, i),
   19421              :                                                  pre_p, lhs_addr, lhs_var,
   19422              :                                                  target_expr, true, depth);
   19423              :               }
   19424              :         }
   19425              :       break;
   19426              :     default:
   19427              :       break;
   19428              :     }
   19429              : 
   19430        17261 :  finish:
   19431        17261 :   if (saw_lhs == 0 && pre_p)
   19432              :     {
   19433         3492 :       enum gimplify_status gs;
   19434         3492 :       if (TREE_CODE (expr) == CALL_EXPR && VOID_TYPE_P (TREE_TYPE (expr)))
   19435              :         {
   19436            0 :           gimplify_stmt (&expr, pre_p);
   19437            0 :           return saw_lhs;
   19438              :         }
   19439         3492 :       else if (rhs)
   19440         3314 :         gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
   19441              :       else
   19442          178 :         gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_lvalue, fb_lvalue);
   19443         3492 :       if (gs != GS_ALL_DONE)
   19444        36846 :         saw_lhs = -1;
   19445              :     }
   19446              : 
   19447              :   return saw_lhs;
   19448              : }
   19449              : 
   19450              : /* Gimplify an OMP_ATOMIC statement.  */
   19451              : 
   19452              : static enum gimplify_status
   19453        10260 : gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
   19454              : {
   19455        10260 :   tree addr = TREE_OPERAND (*expr_p, 0);
   19456        10260 :   tree rhs = TREE_CODE (*expr_p) == OMP_ATOMIC_READ
   19457        10260 :              ? NULL : TREE_OPERAND (*expr_p, 1);
   19458        10260 :   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
   19459        10260 :   tree tmp_load;
   19460        10260 :   gomp_atomic_load *loadstmt;
   19461        10260 :   gomp_atomic_store *storestmt;
   19462        10260 :   tree target_expr = NULL_TREE;
   19463              : 
   19464        10260 :   tmp_load = create_tmp_reg (type);
   19465        10260 :   if (rhs
   19466        10260 :       && goa_stabilize_expr (&rhs, pre_p, addr, tmp_load, target_expr,
   19467              :                              true, 0) < 0)
   19468              :     return GS_ERROR;
   19469              : 
   19470        10260 :   if (gimplify_expr (&addr, pre_p, NULL, is_gimple_val, fb_rvalue)
   19471              :       != GS_ALL_DONE)
   19472              :     return GS_ERROR;
   19473              : 
   19474        10260 :   loadstmt = gimple_build_omp_atomic_load (tmp_load, addr,
   19475        10260 :                                            OMP_ATOMIC_MEMORY_ORDER (*expr_p));
   19476        10260 :   gimplify_seq_add_stmt (pre_p, loadstmt);
   19477        10260 :   if (rhs)
   19478              :     {
   19479              :       /* BIT_INSERT_EXPR is not valid for non-integral bitfield
   19480              :          representatives.  Use BIT_FIELD_REF on the lhs instead.  */
   19481         9076 :       tree rhsarg = rhs;
   19482         9076 :       if (TREE_CODE (rhs) == COND_EXPR)
   19483          429 :         rhsarg = TREE_OPERAND (rhs, 1);
   19484         9076 :       if (TREE_CODE (rhsarg) == BIT_INSERT_EXPR
   19485         9076 :           && !INTEGRAL_TYPE_P (TREE_TYPE (tmp_load)))
   19486              :         {
   19487           32 :           tree bitpos = TREE_OPERAND (rhsarg, 2);
   19488           32 :           tree op1 = TREE_OPERAND (rhsarg, 1);
   19489           32 :           tree bitsize;
   19490           32 :           tree tmp_store = tmp_load;
   19491           32 :           if (TREE_CODE (*expr_p) == OMP_ATOMIC_CAPTURE_OLD)
   19492           12 :             tmp_store = get_initialized_tmp_var (tmp_load, pre_p);
   19493           32 :           if (INTEGRAL_TYPE_P (TREE_TYPE (op1)))
   19494           32 :             bitsize = bitsize_int (TYPE_PRECISION (TREE_TYPE (op1)));
   19495              :           else
   19496            0 :             bitsize = TYPE_SIZE (TREE_TYPE (op1));
   19497           32 :           gcc_assert (TREE_OPERAND (rhsarg, 0) == tmp_load);
   19498           32 :           tree t = build2_loc (EXPR_LOCATION (rhsarg),
   19499              :                                MODIFY_EXPR, void_type_node,
   19500           32 :                                build3_loc (EXPR_LOCATION (rhsarg),
   19501           32 :                                            BIT_FIELD_REF, TREE_TYPE (op1),
   19502              :                                            tmp_store, bitsize, bitpos), op1);
   19503           32 :           if (TREE_CODE (rhs) == COND_EXPR)
   19504           16 :             t = build3_loc (EXPR_LOCATION (rhs), COND_EXPR, void_type_node,
   19505           16 :                             TREE_OPERAND (rhs, 0), t, void_node);
   19506           32 :           gimplify_and_add (t, pre_p);
   19507           32 :           rhs = tmp_store;
   19508              :         }
   19509         9076 :       bool save_allow_rhs_cond_expr = gimplify_ctxp->allow_rhs_cond_expr;
   19510         9076 :       if (TREE_CODE (rhs) == COND_EXPR)
   19511          413 :         gimplify_ctxp->allow_rhs_cond_expr = true;
   19512         9076 :       enum gimplify_status gs = gimplify_expr (&rhs, pre_p, NULL,
   19513              :                                                is_gimple_val, fb_rvalue);
   19514         9076 :       gimplify_ctxp->allow_rhs_cond_expr = save_allow_rhs_cond_expr;
   19515         9076 :       if (gs != GS_ALL_DONE)
   19516              :         return GS_ERROR;
   19517              :     }
   19518              : 
   19519        10260 :   if (TREE_CODE (*expr_p) == OMP_ATOMIC_READ)
   19520         1184 :     rhs = tmp_load;
   19521        10260 :   storestmt
   19522        10260 :     = gimple_build_omp_atomic_store (rhs, OMP_ATOMIC_MEMORY_ORDER (*expr_p));
   19523        10260 :   if (TREE_CODE (*expr_p) != OMP_ATOMIC_READ && OMP_ATOMIC_WEAK (*expr_p))
   19524              :     {
   19525           38 :       gimple_omp_atomic_set_weak (loadstmt);
   19526           38 :       gimple_omp_atomic_set_weak (storestmt);
   19527              :     }
   19528        10260 :   gimplify_seq_add_stmt (pre_p, storestmt);
   19529        10260 :   switch (TREE_CODE (*expr_p))
   19530              :     {
   19531         2072 :     case OMP_ATOMIC_READ:
   19532         2072 :     case OMP_ATOMIC_CAPTURE_OLD:
   19533         2072 :       *expr_p = tmp_load;
   19534         2072 :       gimple_omp_atomic_set_need_value (loadstmt);
   19535         2072 :       break;
   19536          868 :     case OMP_ATOMIC_CAPTURE_NEW:
   19537          868 :       *expr_p = rhs;
   19538          868 :       gimple_omp_atomic_set_need_value (storestmt);
   19539          868 :       break;
   19540         7320 :     default:
   19541         7320 :       *expr_p = NULL;
   19542         7320 :       break;
   19543              :     }
   19544              : 
   19545              :   return GS_ALL_DONE;
   19546              : }
   19547              : 
   19548              : /* Gimplify a TRANSACTION_EXPR.  This involves gimplification of the
   19549              :    body, and adding some EH bits.  */
   19550              : 
   19551              : static enum gimplify_status
   19552          478 : gimplify_transaction (tree *expr_p, gimple_seq *pre_p)
   19553              : {
   19554          478 :   tree expr = *expr_p, temp, tbody = TRANSACTION_EXPR_BODY (expr);
   19555          478 :   gimple *body_stmt;
   19556          478 :   gtransaction *trans_stmt;
   19557          478 :   gimple_seq body = NULL;
   19558          478 :   int subcode = 0;
   19559              : 
   19560              :   /* Wrap the transaction body in a BIND_EXPR so we have a context
   19561              :      where to put decls for OMP.  */
   19562          478 :   if (TREE_CODE (tbody) != BIND_EXPR)
   19563              :     {
   19564          439 :       tree bind = build3 (BIND_EXPR, void_type_node, NULL, tbody, NULL);
   19565          439 :       TREE_SIDE_EFFECTS (bind) = 1;
   19566          439 :       SET_EXPR_LOCATION (bind, EXPR_LOCATION (tbody));
   19567          439 :       TRANSACTION_EXPR_BODY (expr) = bind;
   19568              :     }
   19569              : 
   19570          478 :   push_gimplify_context ();
   19571          478 :   temp = voidify_wrapper_expr (*expr_p, NULL);
   19572              : 
   19573          478 :   body_stmt = gimplify_and_return_first (TRANSACTION_EXPR_BODY (expr), &body);
   19574          478 :   pop_gimplify_context (body_stmt);
   19575              : 
   19576          478 :   trans_stmt = gimple_build_transaction (body);
   19577          478 :   if (TRANSACTION_EXPR_OUTER (expr))
   19578              :     subcode = GTMA_IS_OUTER;
   19579          447 :   else if (TRANSACTION_EXPR_RELAXED (expr))
   19580           81 :     subcode = GTMA_IS_RELAXED;
   19581          478 :   gimple_transaction_set_subcode (trans_stmt, subcode);
   19582              : 
   19583          478 :   gimplify_seq_add_stmt (pre_p, trans_stmt);
   19584              : 
   19585          478 :   if (temp)
   19586              :     {
   19587           76 :       *expr_p = temp;
   19588           76 :       return GS_OK;
   19589              :     }
   19590              : 
   19591              :   *expr_p = NULL_TREE;
   19592              :   return GS_ALL_DONE;
   19593              : }
   19594              : 
   19595              : /* Gimplify an OMP_ORDERED construct.  EXPR is the tree version.  BODY
   19596              :    is the OMP_BODY of the original EXPR (which has already been
   19597              :    gimplified so it's not present in the EXPR).
   19598              : 
   19599              :    Return the gimplified GIMPLE_OMP_ORDERED tuple.  */
   19600              : 
   19601              : static gimple *
   19602         1954 : gimplify_omp_ordered (tree expr, gimple_seq body)
   19603              : {
   19604         1954 :   tree c, decls;
   19605         1954 :   int failures = 0;
   19606         1954 :   unsigned int i;
   19607         1954 :   tree source_c = NULL_TREE;
   19608         1954 :   tree sink_c = NULL_TREE;
   19609              : 
   19610         1954 :   if (gimplify_omp_ctxp)
   19611              :     {
   19612         3291 :       for (c = OMP_ORDERED_CLAUSES (expr); c; c = OMP_CLAUSE_CHAIN (c))
   19613         1515 :         if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
   19614         1515 :             && gimplify_omp_ctxp->loop_iter_var.is_empty ())
   19615              :           {
   19616           74 :             error_at (OMP_CLAUSE_LOCATION (c),
   19617              :                       "%<ordered%> construct with %qs clause must be "
   19618              :                       "closely nested inside a loop with %<ordered%> clause",
   19619           74 :                       OMP_CLAUSE_DOACROSS_DEPEND (c) ? "depend" : "doacross");
   19620           74 :             failures++;
   19621              :           }
   19622         1441 :         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
   19623         1441 :                  && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
   19624              :           {
   19625          642 :             bool fail = false;
   19626          642 :             sink_c = c;
   19627          642 :             if (OMP_CLAUSE_DECL (c) == NULL_TREE)
   19628           72 :               continue;  /* omp_cur_iteration - 1 */
   19629          570 :             for (decls = OMP_CLAUSE_DECL (c), i = 0;
   19630         3201 :                  decls && TREE_CODE (decls) == TREE_LIST;
   19631         2631 :                  decls = TREE_CHAIN (decls), ++i)
   19632         2631 :               if (i >= gimplify_omp_ctxp->loop_iter_var.length () / 2)
   19633            4 :                 continue;
   19634         5254 :               else if (TREE_VALUE (decls)
   19635         2627 :                        != gimplify_omp_ctxp->loop_iter_var[2 * i])
   19636              :                 {
   19637            8 :                   error_at (OMP_CLAUSE_LOCATION (c),
   19638              :                             "variable %qE is not an iteration "
   19639              :                             "of outermost loop %d, expected %qE",
   19640            8 :                             TREE_VALUE (decls), i + 1,
   19641            8 :                             gimplify_omp_ctxp->loop_iter_var[2 * i]);
   19642            8 :                   fail = true;
   19643            8 :                   failures++;
   19644              :                 }
   19645              :               else
   19646         5238 :                 TREE_VALUE (decls)
   19647         2619 :                   = gimplify_omp_ctxp->loop_iter_var[2 * i + 1];
   19648         1136 :             if (!fail && i != gimplify_omp_ctxp->loop_iter_var.length () / 2)
   19649              :               {
   19650           16 :                 error_at (OMP_CLAUSE_LOCATION (c),
   19651              :                           "number of variables in %qs clause with "
   19652              :                           "%<sink%> modifier does not match number of "
   19653              :                           "iteration variables",
   19654           16 :                           OMP_CLAUSE_DOACROSS_DEPEND (c)
   19655              :                           ? "depend" : "doacross");
   19656           16 :                 failures++;
   19657              :               }
   19658              :           }
   19659          799 :         else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DOACROSS
   19660          799 :                  && OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SOURCE)
   19661              :           {
   19662          475 :             if (source_c)
   19663              :               {
   19664            4 :                 error_at (OMP_CLAUSE_LOCATION (c),
   19665              :                           "more than one %qs clause with %<source%> "
   19666              :                           "modifier on an %<ordered%> construct",
   19667            4 :                           OMP_CLAUSE_DOACROSS_DEPEND (source_c)
   19668              :                           ? "depend" : "doacross");
   19669            4 :                 failures++;
   19670              :               }
   19671              :             else
   19672              :               source_c = c;
   19673              :           }
   19674              :     }
   19675         1954 :   if (source_c && sink_c)
   19676              :     {
   19677            4 :       error_at (OMP_CLAUSE_LOCATION (source_c),
   19678              :                 "%qs clause with %<source%> modifier specified "
   19679              :                 "together with %qs clauses with %<sink%> modifier "
   19680              :                 "on the same construct",
   19681            4 :                 OMP_CLAUSE_DOACROSS_DEPEND (source_c) ? "depend" : "doacross",
   19682            4 :                 OMP_CLAUSE_DOACROSS_DEPEND (sink_c) ? "depend" : "doacross");
   19683            4 :       failures++;
   19684              :     }
   19685              : 
   19686         1954 :   if (failures)
   19687          102 :     return gimple_build_nop ();
   19688         1852 :   return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr));
   19689              : }
   19690              : 
   19691              : /* Gimplify an OMP_INTEROP statement.  */
   19692              : 
   19693              : static enum gimplify_status
   19694          612 : gimplify_omp_interop (tree *expr_p, gimple_seq *pre_p)
   19695              : {
   19696          612 :   tree expr = *expr_p;
   19697              : 
   19698          612 :   gimplify_scan_omp_clauses (&OMP_INTEROP_CLAUSES (expr), pre_p, ORT_TASK,
   19699              :                              OMP_INTEROP);
   19700          612 :   gimple *stmt = gimple_build_omp_interop (OMP_INTEROP_CLAUSES (expr));
   19701          612 :   gimplify_seq_add_stmt (pre_p, stmt);
   19702          612 :   *expr_p = NULL_TREE;
   19703          612 :   return GS_ALL_DONE;
   19704              : }
   19705              : 
   19706              : /* Callback for walk_tree to find an IFN_GOMP_DISPATCH.  */
   19707              : 
   19708              : static tree
   19709         3100 : find_ifn_gomp_dispatch (tree *tp, int *, void *modify)
   19710              : {
   19711         3100 :   tree t = *tp;
   19712              : 
   19713         3100 :   if (TREE_CODE (t) == CALL_EXPR && CALL_EXPR_IFN (t) == IFN_GOMP_DISPATCH)
   19714          852 :     return *(tree *) modify ? *(tree *) modify : *tp;
   19715              : 
   19716         2248 :   if (TREE_CODE (t) == MODIFY_EXPR)
   19717          513 :     *(tree *) modify = *tp;
   19718              : 
   19719              :   return NULL_TREE;
   19720              : }
   19721              : 
   19722              : /* Gimplify an OMP_DISPATCH construct.  */
   19723              : 
   19724              : static enum gimplify_status
   19725          852 : gimplify_omp_dispatch (tree *expr_p, gimple_seq *pre_p)
   19726              : {
   19727          852 :   tree expr = *expr_p;
   19728          852 :   gimple_seq body = NULL;
   19729              : 
   19730          852 :   gimplify_scan_omp_clauses (&OMP_DISPATCH_CLAUSES (expr), pre_p, ORT_DISPATCH,
   19731              :                              OMP_DISPATCH);
   19732          852 :   push_gimplify_context ();
   19733              : 
   19734              :   // If device clause, adjust ICV
   19735          852 :   tree device
   19736          852 :     = omp_find_clause (OMP_DISPATCH_CLAUSES (expr), OMP_CLAUSE_DEVICE);
   19737              :   // If no device clause exists but an interop clause with a single list
   19738              :   // item, use it to obtain the device number.
   19739          852 :   if (device)
   19740          272 :     device = OMP_CLAUSE_DEVICE_ID (device);
   19741              :   else
   19742              :     {
   19743          580 :       tree first_interop_obj
   19744          580 :         = omp_find_clause (OMP_DISPATCH_CLAUSES (expr), OMP_CLAUSE_INTEROP);
   19745          580 :       if (first_interop_obj)
   19746           96 :         for (tree c = TREE_CHAIN (first_interop_obj); c; c = TREE_CHAIN (c))
   19747            8 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INTEROP)
   19748              :             {
   19749              :               first_interop_obj = NULL_TREE;
   19750              :               break;
   19751              :             }
   19752           95 :       if (first_interop_obj)
   19753              :         {
   19754           88 :           device = create_tmp_var (integer_type_node);
   19755           88 :           tree c = build_omp_clause (OMP_CLAUSE_LOCATION (first_interop_obj),
   19756              :                                      OMP_CLAUSE_DEVICE);
   19757           88 :           OMP_CLAUSE_DEVICE_ID (c) = device;
   19758           88 :           TREE_CHAIN (c) = TREE_CHAIN (first_interop_obj);
   19759           88 :           TREE_CHAIN (first_interop_obj) = c;
   19760           88 :           first_interop_obj = OMP_CLAUSE_DECL (first_interop_obj);
   19761              :           /* device = omp_get_interop_int (obj, omp_ipr_device_num, NULL);  */
   19762           88 :           tree fn = builtin_decl_explicit (BUILT_IN_OMP_GET_INTEROP_INT);
   19763           88 :           fn = build_call_expr (fn, 3, first_interop_obj,
   19764              :                                 build_int_cst (integer_type_node, -5),
   19765              :                                 null_pointer_node);
   19766           88 :           gimplify_assign (device, fold_convert (integer_type_node, fn), &body);
   19767              :         }
   19768              :     }
   19769          852 :   tree saved_device_icv = NULL_TREE;
   19770          852 :   if (device
   19771          852 :       && (TREE_CODE (device) != INTEGER_CST
   19772          852 :           || !wi::eq_p (wi::to_wide (device), -1 /* omp_initial_device */)))
   19773              :     {
   19774              :       // Save current default-device-var ICV
   19775          360 :       saved_device_icv = create_tmp_var (integer_type_node);
   19776          360 :       tree fn = builtin_decl_explicit (BUILT_IN_OMP_GET_DEFAULT_DEVICE);
   19777          360 :       gcall *call = gimple_build_call (fn, 0);
   19778          360 :       gimple_call_set_lhs (call, saved_device_icv);
   19779          360 :       gimplify_seq_add_stmt (&body, call);
   19780              : 
   19781              :       // Set default device
   19782          360 :       fn = builtin_decl_explicit (BUILT_IN_OMP_SET_DEFAULT_DEVICE);
   19783          360 :       call = gimple_build_call (fn, 1, device);
   19784          360 :       gimplify_seq_add_stmt (&body, call);
   19785              :     }
   19786              : 
   19787              :   // If the novariants and nocontext clauses are not compile-time constants,
   19788              :   // we need to generate code for all possible cases:
   19789              :   //   if (novariants) // implies nocontext
   19790              :   //       base()
   19791              :   //   else if (nocontext)
   19792              :   //       variant1()
   19793              :   //   else
   19794              :   //       variant2()
   19795          852 :   tree *dispatch_body_p = &OMP_DISPATCH_BODY (expr);
   19796          852 :   if (TREE_CODE (*dispatch_body_p) == BIND_EXPR)
   19797           28 :     dispatch_body_p = &BIND_EXPR_BODY (*dispatch_body_p);
   19798          852 :   tree dispatch_body = *dispatch_body_p;
   19799              : 
   19800              :   // Look for IFN_GOMP_DISPATCH and extract the base function call
   19801          852 :   tree base_call_expr = NULL_TREE;
   19802          852 :   if (TREE_CODE (dispatch_body) == STATEMENT_LIST)
   19803          243 :     for (tree_stmt_iterator tsi = tsi_start (dispatch_body); !tsi_end_p (tsi);
   19804          187 :          tsi_next (&tsi))
   19805              :       {
   19806          243 :         tree modify = NULL_TREE;
   19807          243 :         tree stmt = tsi_stmt (tsi);
   19808          243 :         base_call_expr
   19809          243 :           = walk_tree (&stmt, find_ifn_gomp_dispatch, &modify, NULL);
   19810          243 :         if (base_call_expr != NULL_TREE)
   19811              :           break;
   19812              :       }
   19813              :   else
   19814              :     {
   19815          796 :       tree modify = NULL_TREE;
   19816          796 :       base_call_expr
   19817          796 :         = walk_tree (dispatch_body_p, find_ifn_gomp_dispatch, &modify, NULL);
   19818              :     }
   19819          852 :   gcc_assert (base_call_expr != NULL_TREE);
   19820              : 
   19821          852 :   tree dst = NULL_TREE;
   19822          852 :   if (TREE_CODE (base_call_expr) == MODIFY_EXPR)
   19823              :     {
   19824          290 :       dst = TREE_OPERAND (base_call_expr, 0);
   19825          290 :       base_call_expr = TREE_OPERAND (base_call_expr, 1);
   19826              :     }
   19827              : 
   19828          880 :   while (TREE_CODE (base_call_expr) == FLOAT_EXPR
   19829              :          || TREE_CODE (base_call_expr) == CONVERT_EXPR
   19830              :          || TREE_CODE (base_call_expr) == COMPLEX_EXPR
   19831              :          || TREE_CODE (base_call_expr) == INDIRECT_REF
   19832          880 :          || TREE_CODE (base_call_expr) == NOP_EXPR)
   19833           28 :     base_call_expr = TREE_OPERAND (base_call_expr, 0);
   19834              : 
   19835          852 :   gcc_assert (CALL_EXPR_IFN (base_call_expr) == IFN_GOMP_DISPATCH);
   19836          852 :   base_call_expr = CALL_EXPR_ARG (base_call_expr, 0);
   19837              : 
   19838          852 :   tree base_fndecl = get_callee_fndecl (base_call_expr);
   19839          852 :   if (base_fndecl != NULL_TREE)
   19840              :     {
   19841          844 :       if (DECL_VIRTUAL_P (base_fndecl))
   19842              :         {
   19843            6 :           error_at (
   19844            3 :             EXPR_LOCATION (base_call_expr),
   19845              :             "%qD is a virtual function but only a direct call is allowed "
   19846              :             "in a dispatch construct",
   19847            3 :             DECL_NAME (base_fndecl));
   19848              :         }
   19849              : 
   19850              :       /* We are not actually going to expand the variant call or use
   19851              :          the result of omp_get_dynamic candidates here; only check that
   19852              :          it does not trivially resolve to a call to the base function
   19853              :          so that we can avoid some extra work in building code that's
   19854              :          not needed in that case.  */
   19855          844 :       tree construct_context = omp_get_construct_context ();
   19856          844 :       vec<struct omp_variant> all_candidates
   19857          844 :         = omp_declare_variant_candidates (base_fndecl, construct_context);
   19858          844 :       gcc_assert (!all_candidates.is_empty ());
   19859          844 :       vec<struct omp_variant> candidates
   19860          844 :         = omp_get_dynamic_candidates (all_candidates, construct_context);
   19861          844 :       tree variant_fndecl
   19862         1676 :         = (candidates.length () == 1 ? candidates[0].alternative : NULL_TREE);
   19863              : 
   19864          844 :       if (base_fndecl != variant_fndecl
   19865          844 :           && (omp_has_novariants () == -1 || omp_has_nocontext () == -1))
   19866              :         {
   19867           22 :           tree novariants_clause = NULL_TREE, nocontext_clause = NULL_TREE,
   19868           22 :                novariants_cond = NULL_TREE, nocontext_cond = NULL_TREE;
   19869           59 :           for (tree c = OMP_DISPATCH_CLAUSES (expr); c; c = TREE_CHAIN (c))
   19870              :             {
   19871           37 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOVARIANTS
   19872           37 :                   && !integer_zerop (OMP_CLAUSE_NOVARIANTS_EXPR (c)))
   19873              :                 {
   19874           16 :                   gcc_assert (novariants_cond == NULL_TREE);
   19875           16 :                   novariants_clause = c;
   19876           16 :                   novariants_cond = OMP_CLAUSE_NOVARIANTS_EXPR (c);
   19877              :                 }
   19878           21 :               else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOCONTEXT
   19879           21 :                        && !integer_zerop (OMP_CLAUSE_NOCONTEXT_EXPR (c)))
   19880              :                 {
   19881           16 :                   gcc_assert (nocontext_cond == NULL_TREE);
   19882           16 :                   nocontext_clause = c;
   19883           16 :                   nocontext_cond = OMP_CLAUSE_NOCONTEXT_EXPR (c);
   19884              :                 }
   19885              :             }
   19886           22 :           gcc_assert (novariants_cond != NULL_TREE
   19887              :                       || nocontext_cond != NULL_TREE);
   19888              : 
   19889           22 :           enum gimplify_status ret
   19890           22 :             = gimplify_expr (&novariants_cond, &body, NULL, is_gimple_val,
   19891              :                              fb_rvalue);
   19892           22 :           if (ret == GS_ERROR || ret == GS_UNHANDLED)
   19893            0 :             return ret;
   19894           22 :           ret = gimplify_expr (&nocontext_cond, &body, NULL, is_gimple_val,
   19895              :                                fb_rvalue);
   19896           22 :           if (ret == GS_ERROR || ret == GS_UNHANDLED)
   19897              :             return ret;
   19898              : 
   19899           22 :           tree end_label = create_artificial_label (UNKNOWN_LOCATION);
   19900              : 
   19901           22 :           if (novariants_cond != NULL_TREE)
   19902              :             {
   19903           16 :               tree base_label = create_artificial_label (UNKNOWN_LOCATION);
   19904           16 :               tree cond_label = create_artificial_label (UNKNOWN_LOCATION);
   19905           16 :               gcond *novariants_cond_stmt
   19906           16 :                 = gimple_build_cond_from_tree (novariants_cond, base_label,
   19907              :                                                cond_label);
   19908           16 :               gimplify_seq_add_stmt (&body, novariants_cond_stmt);
   19909              : 
   19910           16 :               gimplify_seq_add_stmt (&body, gimple_build_label (base_label));
   19911           16 :               tree base_call_expr2 = copy_node (base_call_expr);
   19912           16 :               base_call_expr2
   19913           16 :                 = build_call_expr_internal_loc (EXPR_LOCATION (base_call_expr2),
   19914              :                                                 IFN_GOMP_DISPATCH,
   19915           16 :                                                 TREE_TYPE (base_call_expr2), 1,
   19916              :                                                 base_call_expr2);
   19917           16 :               if (TREE_CODE (dispatch_body) == MODIFY_EXPR)
   19918              :                 {
   19919           16 :                   base_call_expr2 = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst,
   19920              :                                             base_call_expr2);
   19921              :                 }
   19922           16 :               OMP_CLAUSE_NOVARIANTS_EXPR (novariants_clause)
   19923           16 :                 = boolean_true_node;
   19924           16 :               gimplify_and_add (base_call_expr2, &body);
   19925           16 :               gimplify_seq_add_stmt (&body, gimple_build_goto (end_label));
   19926              : 
   19927           16 :               OMP_CLAUSE_NOVARIANTS_EXPR (novariants_clause)
   19928           16 :                 = boolean_false_node;
   19929           16 :               gimplify_seq_add_stmt (&body, gimple_build_label (cond_label));
   19930              :             }
   19931              : 
   19932           22 :           if (nocontext_cond != NULL_TREE)
   19933              :             {
   19934           16 :               tree variant1_label = create_artificial_label (UNKNOWN_LOCATION);
   19935           16 :               tree variant2_label = create_artificial_label (UNKNOWN_LOCATION);
   19936           16 :               gcond *nocontext_cond_stmt
   19937           16 :                 = gimple_build_cond_from_tree (nocontext_cond, variant1_label,
   19938              :                                                variant2_label);
   19939           16 :               gimplify_seq_add_stmt (&body, nocontext_cond_stmt);
   19940              : 
   19941           32 :               gimplify_seq_add_stmt (&body,
   19942           16 :                                      gimple_build_label (variant1_label));
   19943           16 :               tree variant_call_expr = copy_node (base_call_expr);
   19944           32 :               variant_call_expr = build_call_expr_internal_loc (
   19945           16 :                 EXPR_LOCATION (variant_call_expr), IFN_GOMP_DISPATCH,
   19946           16 :                 TREE_TYPE (variant_call_expr), 1, variant_call_expr);
   19947           16 :               if (TREE_CODE (dispatch_body) == MODIFY_EXPR)
   19948              :                 {
   19949           16 :                   variant_call_expr = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst,
   19950              :                                               variant_call_expr);
   19951              :                 }
   19952           16 :               OMP_CLAUSE_NOCONTEXT_EXPR (nocontext_clause) = boolean_true_node;
   19953           16 :               gimplify_and_add (variant_call_expr, &body);
   19954           16 :               gimplify_seq_add_stmt (&body, gimple_build_goto (end_label));
   19955           16 :               OMP_CLAUSE_NOCONTEXT_EXPR (nocontext_clause) = boolean_false_node;
   19956           32 :               gimplify_seq_add_stmt (&body,
   19957           16 :                                      gimple_build_label (variant2_label));
   19958              :             }
   19959              : 
   19960           22 :           tree variant_call_expr = base_call_expr;
   19961           22 :           variant_call_expr
   19962           22 :             = build_call_expr_internal_loc (EXPR_LOCATION (variant_call_expr),
   19963              :                                             IFN_GOMP_DISPATCH,
   19964           22 :                                             TREE_TYPE (variant_call_expr), 1,
   19965              :                                             variant_call_expr);
   19966           22 :           if (TREE_CODE (dispatch_body) == MODIFY_EXPR)
   19967              :             {
   19968           22 :               variant_call_expr
   19969           22 :                 = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, variant_call_expr);
   19970              :             }
   19971           22 :           gimplify_and_add (variant_call_expr, &body);
   19972           22 :           gimplify_seq_add_stmt (&body, gimple_build_label (end_label));
   19973              :         }
   19974              :       else
   19975          822 :         gimplify_and_add (OMP_DISPATCH_BODY (expr), &body);
   19976              :     }
   19977              :   else
   19978            8 :     gimplify_and_add (OMP_DISPATCH_BODY (expr), &body);
   19979              : 
   19980              :   // Restore default-device-var ICV
   19981          852 :   if (saved_device_icv != NULL_TREE)
   19982              :     {
   19983          360 :       tree fn = builtin_decl_explicit (BUILT_IN_OMP_SET_DEFAULT_DEVICE);
   19984          360 :       gcall *call = gimple_build_call (fn, 1, saved_device_icv);
   19985          360 :       gimplify_seq_add_stmt (&body, call);
   19986              :     }
   19987              : 
   19988              :   // Wrap dispatch body into a bind
   19989          852 :   gimple *bind = gimple_build_bind (NULL_TREE, body, NULL_TREE);
   19990          852 :   pop_gimplify_context (bind);
   19991              : 
   19992              :   // Manually tear down context created by gimplify_scan_omp_clauses to avoid a
   19993              :   // call to gimplify_adjust_omp_clauses
   19994          852 :   gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
   19995          852 :   if (ctx != NULL)
   19996              :     {
   19997          852 :       gcc_assert (ctx->code == OMP_DISPATCH);
   19998          852 :       gimplify_omp_ctxp = ctx->outer_context;
   19999          852 :       delete_omp_context (ctx);
   20000              :     }
   20001              : 
   20002              :   // Remove nowait as it has no effect on dispatch (OpenMP 5.2), device as it
   20003              :   // has been handled above, and depend as the front end handled it by inserting
   20004              :   // taskwait.
   20005          852 :   tree *dispatch_clauses_ptr = &OMP_DISPATCH_CLAUSES (expr);
   20006         1445 :   for (tree c = *dispatch_clauses_ptr; c; c = *dispatch_clauses_ptr)
   20007              :     {
   20008          991 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NOWAIT
   20009              :           || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
   20010              :           || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE)
   20011              :         {
   20012          398 :           *dispatch_clauses_ptr = OMP_CLAUSE_CHAIN (c);
   20013          398 :           break;
   20014              :         }
   20015              :       else
   20016          593 :         dispatch_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   20017              :     }
   20018              : 
   20019          852 :   gimple *stmt = gimple_build_omp_dispatch (bind, OMP_DISPATCH_CLAUSES (expr));
   20020          852 :   gimplify_seq_add_stmt (pre_p, stmt);
   20021          852 :   *expr_p = NULL_TREE;
   20022          852 :   return GS_ALL_DONE;
   20023              : }
   20024              : 
   20025              : /* Expand a metadirective that has been resolved at gimplification time
   20026              :    into the candidate directive variants in CANDIDATES.  */
   20027              : 
   20028              : static enum gimplify_status
   20029          175 : expand_omp_metadirective (vec<struct omp_variant> &candidates,
   20030              :                           gimple_seq *pre_p)
   20031              : {
   20032          175 :   auto_vec<tree> selectors;
   20033          175 :   auto_vec<tree> directive_labels;
   20034          175 :   auto_vec<gimple_seq> directive_bodies;
   20035          175 :   tree body_label = NULL_TREE;
   20036          175 :   tree end_label = create_artificial_label (UNKNOWN_LOCATION);
   20037              : 
   20038              :   /* Construct bodies for each candidate.  */
   20039          605 :   for (unsigned i = 0; i < candidates.length(); i++)
   20040              :     {
   20041          255 :       struct omp_variant &candidate = candidates[i];
   20042          255 :       gimple_seq body = NULL;
   20043              : 
   20044          255 :       selectors.safe_push (omp_dynamic_cond (candidate.selector,
   20045              :                                              find_supercontext ()));
   20046          255 :       directive_labels.safe_push (create_artificial_label (UNKNOWN_LOCATION));
   20047              : 
   20048          255 :       gimplify_seq_add_stmt (&body,
   20049          255 :                              gimple_build_label (directive_labels.last ()));
   20050          255 :       if (candidate.alternative != NULL_TREE)
   20051          255 :         gimplify_stmt (&candidate.alternative, &body);
   20052          255 :       if (candidate.body != NULL_TREE)
   20053              :         {
   20054           36 :           if (body_label != NULL_TREE)
   20055            0 :             gimplify_seq_add_stmt (&body, gimple_build_goto (body_label));
   20056              :           else
   20057              :             {
   20058           36 :               body_label = create_artificial_label (UNKNOWN_LOCATION);
   20059           36 :               gimplify_seq_add_stmt (&body, gimple_build_label (body_label));
   20060           36 :               gimplify_stmt (&candidate.body, &body);
   20061              :             }
   20062              :         }
   20063              : 
   20064          255 :       directive_bodies.safe_push (body);
   20065              :     }
   20066              : 
   20067          175 :   auto_vec<tree> cond_labels;
   20068              : 
   20069          175 :   cond_labels.safe_push (NULL_TREE);
   20070          386 :   for (unsigned i = 1; i < candidates.length () - 1; i++)
   20071           18 :     cond_labels.safe_push (create_artificial_label (UNKNOWN_LOCATION));
   20072          175 :   if (candidates.length () > 1)
   20073           62 :     cond_labels.safe_push (directive_labels.last ());
   20074              : 
   20075              :   /* Generate conditionals to test each dynamic selector in turn, executing
   20076              :      the directive candidate if successful.  */
   20077          510 :   for (unsigned i = 0; i < candidates.length () - 1; i++)
   20078              :     {
   20079           80 :       if (i != 0)
   20080           18 :         gimplify_seq_add_stmt (pre_p, gimple_build_label (cond_labels [i]));
   20081              : 
   20082           80 :       enum gimplify_status ret = gimplify_expr (&selectors[i], pre_p, NULL,
   20083              :                                                 is_gimple_val, fb_rvalue);
   20084           80 :       if (ret == GS_ERROR || ret == GS_UNHANDLED)
   20085              :         return ret;
   20086              : 
   20087           80 :       gcond *cond_stmt
   20088           80 :         = gimple_build_cond_from_tree (selectors[i], directive_labels[i],
   20089           80 :                                        cond_labels[i + 1]);
   20090              : 
   20091           80 :       gimplify_seq_add_stmt (pre_p, cond_stmt);
   20092           80 :       gimplify_seq_add_seq (pre_p, directive_bodies[i]);
   20093           80 :       gimplify_seq_add_stmt (pre_p, gimple_build_goto (end_label));
   20094              :     }
   20095              : 
   20096          175 :   gimplify_seq_add_seq (pre_p, directive_bodies.last ());
   20097          175 :   gimplify_seq_add_stmt (pre_p, gimple_build_label (end_label));
   20098              : 
   20099          175 :   return GS_ALL_DONE;
   20100          175 : }
   20101              : 
   20102              : /* Expand a variant construct that requires late resolution in the ompdevlow
   20103              :    pass.  It's a bit easier to do this in tree form and then gimplify that,
   20104              :    than to emit gimple.  The output is going to look something like:
   20105              : 
   20106              :      switch_var = OMP_NEXT_VARIANT (0, state);
   20107              :      loop_label:
   20108              :      switch (switch_var)
   20109              :        {
   20110              :        case 1:
   20111              :          if (dynamic_selector_predicate_1)
   20112              :            {
   20113              :              alternative_1;
   20114              :              goto end_label;
   20115              :            }
   20116              :          else
   20117              :            {
   20118              :              switch_var = OMP_NEXT_VARIANT (1, state);
   20119              :              goto loop_label;
   20120              :            }
   20121              :         case 2:
   20122              :           ...
   20123              :         }
   20124              :       end_label:
   20125              : 
   20126              :   OMP_NEXT_VARIANT is a magic cookie that is replaced with the switch variable
   20127              :   index of the next variant to try, after late resolution.  */
   20128              : 
   20129              : static tree
   20130           16 : expand_late_variant_directive (vec<struct omp_variant> all_candidates,
   20131              :                                tree construct_context)
   20132              : {
   20133           16 :   tree body_label = NULL_TREE;
   20134           16 :   tree standalone_body = NULL_TREE;
   20135           16 :   tree loop_label = create_artificial_label (UNKNOWN_LOCATION);
   20136           16 :   tree end_label = create_artificial_label (UNKNOWN_LOCATION);
   20137           32 :   tree selectors = make_tree_vec (all_candidates.length ());
   20138           16 :   tree switch_body = NULL_TREE;
   20139           16 :   tree switch_var = create_tmp_var (integer_type_node, "variant");
   20140           16 :   tree state = tree_cons (NULL_TREE, construct_context, selectors);
   20141              : 
   20142          108 :   for (unsigned int i = 0; i < all_candidates.length (); i++)
   20143              :     {
   20144           76 :       tree selector = all_candidates[i].selector;
   20145           76 :       tree alternative = all_candidates[i].alternative;
   20146           76 :       tree body = all_candidates[i].body;
   20147           76 :       TREE_VEC_ELT (selectors, i) = selector;
   20148              : 
   20149              :       /* Case label.  Numbering is 1-based.  */
   20150           76 :       tree case_val = build_int_cst (integer_type_node, i + 1);
   20151           76 :       tree case_label
   20152           76 :         = build_case_label (case_val, NULL_TREE,
   20153              :                             create_artificial_label (UNKNOWN_LOCATION));
   20154           76 :       append_to_statement_list (case_label, &switch_body);
   20155              : 
   20156              :       /* The actual body of the variant.  */
   20157           76 :       tree variant_body = NULL_TREE;
   20158           76 :       append_to_statement_list (alternative, &variant_body);
   20159              : 
   20160           76 :       if (body != NULL_TREE)
   20161              :         {
   20162            0 :           if (standalone_body == NULL)
   20163              :             {
   20164            0 :               standalone_body = body;
   20165            0 :               body_label = create_artificial_label (UNKNOWN_LOCATION);
   20166              :             }
   20167            0 :           append_to_statement_list (build1 (GOTO_EXPR, void_type_node,
   20168              :                                             body_label),
   20169              :                                     &variant_body);
   20170              :         }
   20171              :       else
   20172           76 :         append_to_statement_list (build1 (GOTO_EXPR, void_type_node,
   20173              :                                           end_label),
   20174              :                                   &variant_body);
   20175              : 
   20176              :       /* If this is a dynamic selector, wrap variant_body with a conditional.
   20177              :          If the predicate doesn't match, the else clause sets switch_var and
   20178              :          jumps to loop_var to try again.  */
   20179           76 :       tree dynamic_selector = omp_dynamic_cond (selector, find_supercontext ());
   20180           76 :       if (dynamic_selector)
   20181              :         {
   20182           20 :           tree else_stmt = NULL_TREE;
   20183           20 :           tree next = build2 (OMP_NEXT_VARIANT, integer_type_node,
   20184              :                               case_val, state);
   20185           20 :           append_to_statement_list (build2 (MODIFY_EXPR, integer_type_node,
   20186              :                                             switch_var, next),
   20187              :                                     &else_stmt);
   20188           20 :           append_to_statement_list (build1 (GOTO_EXPR, void_type_node,
   20189              :                                             loop_label),
   20190              :                                     &else_stmt);
   20191           20 :           variant_body = build3 (COND_EXPR, void_type_node, dynamic_selector,
   20192              :                                  variant_body, else_stmt);
   20193              :         }
   20194           76 :       append_to_statement_list (variant_body, &switch_body);
   20195              :     }
   20196              : 
   20197              :   /* Put it all together.  */
   20198           16 :   tree result = NULL_TREE;
   20199           16 :   tree first = build2 (OMP_NEXT_VARIANT, integer_type_node, integer_zero_node,
   20200              :                        state);
   20201           16 :   append_to_statement_list (build2 (MODIFY_EXPR, integer_type_node,
   20202              :                                     switch_var, first),
   20203              :                             &result);
   20204           16 :   append_to_statement_list (build1 (LABEL_EXPR, void_type_node, loop_label),
   20205              :                             &result);
   20206           16 :   append_to_statement_list (build2 (SWITCH_EXPR, integer_type_node,
   20207              :                                     switch_var, switch_body),
   20208              :                             &result);
   20209           16 :   if (standalone_body)
   20210              :     {
   20211            0 :       append_to_statement_list (build1 (LABEL_EXPR, void_type_node,
   20212              :                                         body_label),
   20213              :                                 &result);
   20214            0 :       append_to_statement_list (standalone_body, &result);
   20215              :     }
   20216           16 :   append_to_statement_list (build1 (LABEL_EXPR, void_type_node, end_label),
   20217              :                             &result);
   20218           16 :   cgraph_node::get (cfun->decl)->has_omp_variant_constructs = 1;
   20219           16 :   return result;
   20220              : }
   20221              : 
   20222              : 
   20223              : /* Gimplify an OMP_METADIRECTIVE construct.   EXPR is the tree version.
   20224              :    The metadirective will be resolved at this point if possible, otherwise
   20225              :    a GIMPLE_OMP_VARIANT_CONSTRUCT is created.  */
   20226              : 
   20227              : static enum gimplify_status
   20228          179 : gimplify_omp_metadirective (tree *expr_p, gimple_seq *pre_p, gimple_seq *,
   20229              :                             bool (*) (tree), fallback_t)
   20230              : {
   20231              :   /* Try to resolve the metadirective.  */
   20232          179 :   tree construct_context = omp_get_construct_context ();
   20233          179 :   vec<struct omp_variant> all_candidates
   20234          179 :     = omp_metadirective_candidates (*expr_p, construct_context);
   20235          179 :   vec<struct omp_variant> candidates
   20236          179 :     = omp_get_dynamic_candidates (all_candidates, construct_context);
   20237          179 :   if (!candidates.is_empty ())
   20238          175 :     return expand_omp_metadirective (candidates, pre_p);
   20239              : 
   20240              :   /* The metadirective cannot be resolved yet.  Turn it into a loop with
   20241              :      a nested switch statement, using OMP_NEXT_VARIANT to set the control
   20242              :      variable for the switch.  */
   20243            4 :   *expr_p = expand_late_variant_directive (all_candidates, construct_context);
   20244            4 :   return GS_OK;
   20245              : }
   20246              : 
   20247              : /* Gimplify an OMP_DECLARE_MAPPER node (by just removing it).  */
   20248              : 
   20249              : static enum gimplify_status
   20250            0 : gimplify_omp_declare_mapper (tree *expr_p)
   20251              : {
   20252            0 :   *expr_p = NULL_TREE;
   20253            0 :   return GS_ALL_DONE;
   20254              : }
   20255              : 
   20256              : /* Convert the GENERIC expression tree *EXPR_P to GIMPLE.  If the
   20257              :    expression produces a value to be used as an operand inside a GIMPLE
   20258              :    statement, the value will be stored back in *EXPR_P.  This value will
   20259              :    be a tree of class tcc_declaration, tcc_constant, tcc_reference or
   20260              :    an SSA_NAME.  The corresponding sequence of GIMPLE statements is
   20261              :    emitted in PRE_P and POST_P.
   20262              : 
   20263              :    Additionally, this process may overwrite parts of the input
   20264              :    expression during gimplification.  Ideally, it should be
   20265              :    possible to do non-destructive gimplification.
   20266              : 
   20267              :    EXPR_P points to the GENERIC expression to convert to GIMPLE.  If
   20268              :       the expression needs to evaluate to a value to be used as
   20269              :       an operand in a GIMPLE statement, this value will be stored in
   20270              :       *EXPR_P on exit.  This happens when the caller specifies one
   20271              :       of fb_lvalue or fb_rvalue fallback flags.
   20272              : 
   20273              :    PRE_P will contain the sequence of GIMPLE statements corresponding
   20274              :        to the evaluation of EXPR and all the side-effects that must
   20275              :        be executed before the main expression.  On exit, the last
   20276              :        statement of PRE_P is the core statement being gimplified.  For
   20277              :        instance, when gimplifying 'if (++a)' the last statement in
   20278              :        PRE_P will be 'if (t.1)' where t.1 is the result of
   20279              :        pre-incrementing 'a'.
   20280              : 
   20281              :    POST_P will contain the sequence of GIMPLE statements corresponding
   20282              :        to the evaluation of all the side-effects that must be executed
   20283              :        after the main expression.  If this is NULL, the post
   20284              :        side-effects are stored at the end of PRE_P.
   20285              : 
   20286              :        The reason why the output is split in two is to handle post
   20287              :        side-effects explicitly.  In some cases, an expression may have
   20288              :        inner and outer post side-effects which need to be emitted in
   20289              :        an order different from the one given by the recursive
   20290              :        traversal.  For instance, for the expression (*p--)++ the post
   20291              :        side-effects of '--' must actually occur *after* the post
   20292              :        side-effects of '++'.  However, gimplification will first visit
   20293              :        the inner expression, so if a separate POST sequence was not
   20294              :        used, the resulting sequence would be:
   20295              : 
   20296              :             1   t.1 = *p
   20297              :             2   p = p - 1
   20298              :             3   t.2 = t.1 + 1
   20299              :             4   *p = t.2
   20300              : 
   20301              :        However, the post-decrement operation in line #2 must not be
   20302              :        evaluated until after the store to *p at line #4, so the
   20303              :        correct sequence should be:
   20304              : 
   20305              :             1   t.1 = *p
   20306              :             2   t.2 = t.1 + 1
   20307              :             3   *p = t.2
   20308              :             4   p = p - 1
   20309              : 
   20310              :        So, by specifying a separate post queue, it is possible
   20311              :        to emit the post side-effects in the correct order.
   20312              :        If POST_P is NULL, an internal queue will be used.  Before
   20313              :        returning to the caller, the sequence POST_P is appended to
   20314              :        the main output sequence PRE_P.
   20315              : 
   20316              :    GIMPLE_TEST_F points to a function that takes a tree T and
   20317              :        returns nonzero if T is in the GIMPLE form requested by the
   20318              :        caller.  The GIMPLE predicates are in gimple.cc.
   20319              : 
   20320              :    FALLBACK tells the function what sort of a temporary we want if
   20321              :        gimplification cannot produce an expression that complies with
   20322              :        GIMPLE_TEST_F.
   20323              : 
   20324              :        fb_none means that no temporary should be generated
   20325              :        fb_rvalue means that an rvalue is OK to generate
   20326              :        fb_lvalue means that an lvalue is OK to generate
   20327              :        fb_either means that either is OK, but an lvalue is preferable.
   20328              :        fb_mayfail means that gimplification may fail (in which case
   20329              :        GS_ERROR will be returned)
   20330              : 
   20331              :    The return value is either GS_ERROR or GS_ALL_DONE, since this
   20332              :    function iterates until EXPR is completely gimplified or an error
   20333              :    occurs.  */
   20334              : 
   20335              : enum gimplify_status
   20336    531755877 : gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   20337              :                bool (*gimple_test_f) (tree), fallback_t fallback)
   20338              : {
   20339    531755877 :   tree tmp;
   20340    531755877 :   gimple_seq internal_pre = NULL;
   20341    531755877 :   gimple_seq internal_post = NULL;
   20342    531755877 :   tree save_expr;
   20343    531755877 :   bool is_statement;
   20344    531755877 :   location_t saved_location;
   20345    531755877 :   enum gimplify_status ret;
   20346    531755877 :   gimple_stmt_iterator pre_last_gsi, post_last_gsi;
   20347    531755877 :   tree label;
   20348              : 
   20349    531755877 :   save_expr = *expr_p;
   20350    531755877 :   if (save_expr == NULL_TREE)
   20351              :     return GS_ALL_DONE;
   20352              : 
   20353              :   /* If we are gimplifying a top-level statement, PRE_P must be valid.  */
   20354    478513032 :   is_statement = gimple_test_f == is_gimple_stmt;
   20355    478513032 :   if (is_statement)
   20356    103736426 :     gcc_assert (pre_p);
   20357              : 
   20358              :   /* Consistency checks.  */
   20359    478513032 :   if (gimple_test_f == is_gimple_reg)
   20360      6497988 :     gcc_assert (fallback & (fb_rvalue | fb_lvalue));
   20361    472015044 :   else if (gimple_test_f == is_gimple_val
   20362    348108697 :            || gimple_test_f == is_gimple_call_addr
   20363    331118915 :            || gimple_test_f == is_gimple_condexpr_for_cond
   20364    325416835 :            || gimple_test_f == is_gimple_mem_rhs
   20365    325272553 :            || gimple_test_f == is_gimple_mem_rhs_or_call
   20366    313762143 :            || gimple_test_f == is_gimple_reg_rhs
   20367    313156158 :            || gimple_test_f == is_gimple_reg_rhs_or_call
   20368    239706929 :            || gimple_test_f == is_gimple_asm_val
   20369    239666974 :            || gimple_test_f == is_gimple_mem_ref_addr)
   20370    248230243 :     gcc_assert (fallback & fb_rvalue);
   20371    223784801 :   else if (gimple_test_f == is_gimple_min_lval
   20372    192820302 :            || gimple_test_f == is_gimple_lvalue)
   20373     85690810 :     gcc_assert (fallback & fb_lvalue);
   20374    138093991 :   else if (gimple_test_f == is_gimple_addressable)
   20375     34357565 :     gcc_assert (fallback & fb_either);
   20376    103736426 :   else if (gimple_test_f == is_gimple_stmt)
   20377    103736426 :     gcc_assert (fallback == fb_none);
   20378              :   else
   20379              :     {
   20380              :       /* We should have recognized the GIMPLE_TEST_F predicate to
   20381              :          know what kind of fallback to use in case a temporary is
   20382              :          needed to hold the value or address of *EXPR_P.  */
   20383            0 :       gcc_unreachable ();
   20384              :     }
   20385              : 
   20386              :   /* We used to check the predicate here and return immediately if it
   20387              :      succeeds.  This is wrong; the design is for gimplification to be
   20388              :      idempotent, and for the predicates to only test for valid forms, not
   20389              :      whether they are fully simplified.  */
   20390    478513032 :   if (pre_p == NULL)
   20391            0 :     pre_p = &internal_pre;
   20392              : 
   20393    478513032 :   if (post_p == NULL)
   20394    193035445 :     post_p = &internal_post;
   20395              : 
   20396              :   /* Remember the last statements added to PRE_P and POST_P.  Every
   20397              :      new statement added by the gimplification helpers needs to be
   20398              :      annotated with location information.  To centralize the
   20399              :      responsibility, we remember the last statement that had been
   20400              :      added to both queues before gimplifying *EXPR_P.  If
   20401              :      gimplification produces new statements in PRE_P and POST_P, those
   20402              :      statements will be annotated with the same location information
   20403              :      as *EXPR_P.  */
   20404    478513032 :   pre_last_gsi = gsi_last (*pre_p);
   20405    478513032 :   post_last_gsi = gsi_last (*post_p);
   20406              : 
   20407    478513032 :   saved_location = input_location;
   20408    478513032 :   if (save_expr != error_mark_node
   20409    478513032 :       && EXPR_HAS_LOCATION (*expr_p))
   20410    179672384 :     input_location = EXPR_LOCATION (*expr_p);
   20411              : 
   20412              :   /* Loop over the specific gimplifiers until the toplevel node
   20413              :      remains the same.  */
   20414    497550930 :   do
   20415              :     {
   20416              :       /* Strip away as many useless type conversions as possible
   20417              :          at the toplevel.  */
   20418    497550930 :       STRIP_USELESS_TYPE_CONVERSION (*expr_p);
   20419              : 
   20420              :       /* Remember the expr.  */
   20421    497550930 :       save_expr = *expr_p;
   20422              : 
   20423              :       /* Die, die, die, my darling.  */
   20424    497550930 :       if (error_operand_p (save_expr))
   20425              :         {
   20426              :           ret = GS_ERROR;
   20427              :           break;
   20428              :         }
   20429              : 
   20430              :       /* Do any language-specific gimplification.  */
   20431    497547245 :       ret = ((enum gimplify_status)
   20432    497547245 :              lang_hooks.gimplify_expr (expr_p, pre_p, post_p));
   20433    497547245 :       if (ret == GS_OK)
   20434              :         {
   20435     30220964 :           if (*expr_p == NULL_TREE)
   20436              :             break;
   20437     30220964 :           if (*expr_p != save_expr)
   20438      5049707 :             continue;
   20439              :         }
   20440    467326281 :       else if (ret != GS_UNHANDLED)
   20441              :         break;
   20442              : 
   20443              :       /* Make sure that all the cases set 'ret' appropriately.  */
   20444    491881442 :       ret = GS_UNHANDLED;
   20445    491881442 :       switch (TREE_CODE (*expr_p))
   20446              :         {
   20447              :           /* First deal with the special cases.  */
   20448              : 
   20449      1147886 :         case POSTINCREMENT_EXPR:
   20450      1147886 :         case POSTDECREMENT_EXPR:
   20451      1147886 :         case PREINCREMENT_EXPR:
   20452      1147886 :         case PREDECREMENT_EXPR:
   20453      2295772 :           ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
   20454              :                                         fallback != fb_none,
   20455      1147886 :                                         TREE_TYPE (*expr_p));
   20456      1147886 :           break;
   20457              : 
   20458       604704 :         case VIEW_CONVERT_EXPR:
   20459       604704 :           if ((fallback & fb_rvalue)
   20460       604590 :               && is_gimple_reg_type (TREE_TYPE (*expr_p))
   20461      1032234 :               && is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
   20462              :             {
   20463       415643 :               ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   20464              :                                    post_p, is_gimple_val, fb_rvalue);
   20465       415643 :               recalculate_side_effects (*expr_p);
   20466       415643 :               break;
   20467              :             }
   20468              :           /* Fallthru.  */
   20469              : 
   20470     30901455 :         case ARRAY_REF:
   20471     30901455 :         case ARRAY_RANGE_REF:
   20472     30901455 :         case REALPART_EXPR:
   20473     30901455 :         case IMAGPART_EXPR:
   20474     30901455 :         case COMPONENT_REF:
   20475     30901455 :           ret = gimplify_compound_lval (expr_p, pre_p, post_p,
   20476              :                                         fallback ? fallback : fb_rvalue);
   20477     30901455 :           break;
   20478              : 
   20479      6329445 :         case COND_EXPR:
   20480      6329445 :           ret = gimplify_cond_expr (expr_p, pre_p, fallback);
   20481              : 
   20482              :           /* C99 code may assign to an array in a structure value of a
   20483              :              conditional expression, and this has undefined behavior
   20484              :              only on execution, so create a temporary if an lvalue is
   20485              :              required.  */
   20486      6329445 :           if (fallback == fb_lvalue)
   20487              :             {
   20488            7 :               *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
   20489            7 :               mark_addressable (*expr_p);
   20490            7 :               ret = GS_OK;
   20491              :             }
   20492              :           break;
   20493              : 
   20494     17554339 :         case CALL_EXPR:
   20495     17554339 :           ret = gimplify_call_expr (expr_p, pre_p, fallback);
   20496              : 
   20497              :           /* C99 code may assign to an array in a structure returned
   20498              :              from a function, and this has undefined behavior only on
   20499              :              execution, so create a temporary if an lvalue is
   20500              :              required.  */
   20501     17554339 :           if (fallback == fb_lvalue)
   20502              :             {
   20503        17155 :               *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
   20504        17155 :               mark_addressable (*expr_p);
   20505        17155 :               ret = GS_OK;
   20506              :             }
   20507              :           break;
   20508              : 
   20509            0 :         case TREE_LIST:
   20510            0 :           gcc_unreachable ();
   20511              : 
   20512            0 :         case OMP_ARRAY_SECTION:
   20513            0 :           gcc_unreachable ();
   20514              : 
   20515       503277 :         case COMPOUND_EXPR:
   20516       503277 :           ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
   20517       503277 :           break;
   20518              : 
   20519        37242 :         case COMPOUND_LITERAL_EXPR:
   20520        37242 :           ret = gimplify_compound_literal_expr (expr_p, pre_p,
   20521              :                                                 gimple_test_f, fallback);
   20522        37242 :           break;
   20523              : 
   20524     51338796 :         case MODIFY_EXPR:
   20525     51338796 :         case INIT_EXPR:
   20526     51338796 :           ret = gimplify_modify_expr (expr_p, pre_p, post_p,
   20527              :                                       fallback != fb_none);
   20528     51338796 :           break;
   20529              : 
   20530       117034 :         case TRUTH_ANDIF_EXPR:
   20531       117034 :         case TRUTH_ORIF_EXPR:
   20532       117034 :           {
   20533              :             /* Preserve the original type of the expression and the
   20534              :                source location of the outer expression.  */
   20535       117034 :             tree org_type = TREE_TYPE (*expr_p);
   20536       117034 :             *expr_p = gimple_boolify (*expr_p);
   20537       117034 :             *expr_p = build3_loc (input_location, COND_EXPR,
   20538              :                                   org_type, *expr_p,
   20539              :                                   fold_convert_loc
   20540              :                                     (input_location,
   20541              :                                      org_type, boolean_true_node),
   20542              :                                   fold_convert_loc
   20543              :                                     (input_location,
   20544              :                                      org_type, boolean_false_node));
   20545       117034 :             ret = GS_OK;
   20546       117034 :             break;
   20547              :           }
   20548              : 
   20549       238889 :         case TRUTH_NOT_EXPR:
   20550       238889 :           {
   20551       238889 :             tree type = TREE_TYPE (*expr_p);
   20552              :             /* The parsers are careful to generate TRUTH_NOT_EXPR
   20553              :                only with operands that are always zero or one.
   20554              :                We do not fold here but handle the only interesting case
   20555              :                manually, as fold may re-introduce the TRUTH_NOT_EXPR.  */
   20556       238889 :             *expr_p = gimple_boolify (*expr_p);
   20557       238889 :             if (TYPE_PRECISION (TREE_TYPE (*expr_p)) == 1)
   20558       238889 :               *expr_p = build1_loc (input_location, BIT_NOT_EXPR,
   20559       238889 :                                     TREE_TYPE (*expr_p),
   20560       238889 :                                     TREE_OPERAND (*expr_p, 0));
   20561              :             else
   20562            0 :               *expr_p = build2_loc (input_location, BIT_XOR_EXPR,
   20563            0 :                                     TREE_TYPE (*expr_p),
   20564            0 :                                     TREE_OPERAND (*expr_p, 0),
   20565            0 :                                     build_int_cst (TREE_TYPE (*expr_p), 1));
   20566       238889 :             if (!useless_type_conversion_p (type, TREE_TYPE (*expr_p)))
   20567         6514 :               *expr_p = fold_convert_loc (input_location, type, *expr_p);
   20568              :             ret = GS_OK;
   20569              :             break;
   20570              :           }
   20571              : 
   20572     34440966 :         case ADDR_EXPR:
   20573     34440966 :           ret = gimplify_addr_expr (expr_p, pre_p, post_p);
   20574     34440966 :           break;
   20575              : 
   20576         5801 :         case ANNOTATE_EXPR:
   20577         5801 :           {
   20578         5801 :             tree cond = TREE_OPERAND (*expr_p, 0);
   20579         5801 :             tree kind = TREE_OPERAND (*expr_p, 1);
   20580         5801 :             tree data = TREE_OPERAND (*expr_p, 2);
   20581         5801 :             tree type = TREE_TYPE (cond);
   20582         5801 :             if (!INTEGRAL_TYPE_P (type))
   20583              :               {
   20584            0 :                 *expr_p = cond;
   20585            0 :                 ret = GS_OK;
   20586            0 :                 break;
   20587              :               }
   20588         5801 :             tree tmp = create_tmp_var (type);
   20589         5801 :             gimplify_arg (&cond, pre_p, EXPR_LOCATION (*expr_p));
   20590         5801 :             gcall *call
   20591         5801 :               = gimple_build_call_internal (IFN_ANNOTATE, 3, cond, kind, data);
   20592         5801 :             gimple_call_set_lhs (call, tmp);
   20593         5801 :             gimplify_seq_add_stmt (pre_p, call);
   20594         5801 :             *expr_p = tmp;
   20595         5801 :             ret = GS_ALL_DONE;
   20596         5801 :             break;
   20597              :           }
   20598              : 
   20599        51195 :         case VA_ARG_EXPR:
   20600        51195 :           ret = gimplify_va_arg_expr (expr_p, pre_p, post_p);
   20601        51195 :           break;
   20602              : 
   20603     17811072 :         CASE_CONVERT:
   20604     17811072 :           if (IS_EMPTY_STMT (*expr_p))
   20605              :             {
   20606              :               ret = GS_ALL_DONE;
   20607              :               break;
   20608              :             }
   20609              : 
   20610     16035245 :           if (VOID_TYPE_P (TREE_TYPE (*expr_p))
   20611     16035245 :               || fallback == fb_none)
   20612              :             {
   20613              :               /* Just strip a conversion to void (or in void context) and
   20614              :                  try again.  */
   20615      2766903 :               *expr_p = TREE_OPERAND (*expr_p, 0);
   20616      2766903 :               ret = GS_OK;
   20617      2766903 :               break;
   20618              :             }
   20619              : 
   20620     13268342 :           ret = gimplify_conversion (expr_p);
   20621     13268342 :           if (ret == GS_ERROR)
   20622              :             break;
   20623     13268342 :           if (*expr_p != save_expr)
   20624              :             break;
   20625              :           /* FALLTHRU */
   20626              : 
   20627     13396391 :         case FIX_TRUNC_EXPR:
   20628              :           /* unary_expr: ... | '(' cast ')' val | ...  */
   20629     13396391 :           ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   20630              :                                is_gimple_val, fb_rvalue);
   20631     13396391 :           recalculate_side_effects (*expr_p);
   20632     13396391 :           break;
   20633              : 
   20634      6428786 :         case INDIRECT_REF:
   20635      6428786 :           {
   20636      6428786 :             bool volatilep = TREE_THIS_VOLATILE (*expr_p);
   20637      6428786 :             bool notrap = TREE_THIS_NOTRAP (*expr_p);
   20638      6428786 :             tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
   20639              : 
   20640      6428786 :             *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
   20641      6428786 :             if (*expr_p != save_expr)
   20642              :               {
   20643              :                 ret = GS_OK;
   20644              :                 break;
   20645              :               }
   20646              : 
   20647      6410165 :             ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   20648              :                                  is_gimple_reg, fb_rvalue);
   20649      6410165 :             if (ret == GS_ERROR)
   20650              :               break;
   20651              : 
   20652      6410164 :             recalculate_side_effects (*expr_p);
   20653     12820328 :             *expr_p = fold_build2_loc (input_location, MEM_REF,
   20654      6410164 :                                        TREE_TYPE (*expr_p),
   20655      6410164 :                                        TREE_OPERAND (*expr_p, 0),
   20656              :                                        build_int_cst (saved_ptr_type, 0));
   20657      6410164 :             TREE_THIS_VOLATILE (*expr_p) = volatilep;
   20658      6410164 :             TREE_THIS_NOTRAP (*expr_p) = notrap;
   20659      6410164 :             ret = GS_OK;
   20660      6410164 :             break;
   20661              :           }
   20662              : 
   20663              :         /* We arrive here through the various re-gimplifcation paths.  */
   20664     16332025 :         case MEM_REF:
   20665              :           /* First try re-folding the whole thing.  */
   20666     16332025 :           tmp = fold_binary (MEM_REF, TREE_TYPE (*expr_p),
   20667              :                              TREE_OPERAND (*expr_p, 0),
   20668              :                              TREE_OPERAND (*expr_p, 1));
   20669     16332025 :           if (tmp)
   20670              :             {
   20671         6580 :               REF_REVERSE_STORAGE_ORDER (tmp)
   20672         3290 :                 = REF_REVERSE_STORAGE_ORDER (*expr_p);
   20673         3290 :               *expr_p = tmp;
   20674         3290 :               recalculate_side_effects (*expr_p);
   20675         3290 :               ret = GS_OK;
   20676         3290 :               break;
   20677              :             }
   20678              :           /* Avoid re-gimplifying the address operand if it is already
   20679              :              in suitable form.  Re-gimplifying would mark the address
   20680              :              operand addressable.  Always gimplify when not in SSA form
   20681              :              as we still may have to gimplify decls with value-exprs.  */
   20682     16328735 :           if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
   20683     17348690 :               || !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
   20684              :             {
   20685     15363965 :               ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   20686              :                                    is_gimple_mem_ref_addr, fb_rvalue);
   20687     15363965 :               if (ret == GS_ERROR)
   20688              :                 break;
   20689              :             }
   20690     16328735 :           recalculate_side_effects (*expr_p);
   20691     16328735 :           ret = GS_ALL_DONE;
   20692     16328735 :           break;
   20693              : 
   20694              :         /* Constants need not be gimplified.  */
   20695     45059321 :         case INTEGER_CST:
   20696     45059321 :         case REAL_CST:
   20697     45059321 :         case FIXED_CST:
   20698     45059321 :         case STRING_CST:
   20699     45059321 :         case COMPLEX_CST:
   20700     45059321 :         case VECTOR_CST:
   20701              :           /* Drop the overflow flag on constants, we do not want
   20702              :              that in the GIMPLE IL.  */
   20703     45059321 :           if (TREE_OVERFLOW_P (*expr_p))
   20704          887 :             *expr_p = drop_tree_overflow (*expr_p);
   20705              :           ret = GS_ALL_DONE;
   20706              :           break;
   20707              : 
   20708       118507 :         case CONST_DECL:
   20709              :           /* If we require an lvalue, such as for ADDR_EXPR, retain the
   20710              :              CONST_DECL node.  Otherwise the decl is replaceable by its
   20711              :              value.  */
   20712              :           /* ??? Should be == fb_lvalue, but ADDR_EXPR passes fb_either.  */
   20713       118507 :           if (fallback & fb_lvalue)
   20714              :             ret = GS_ALL_DONE;
   20715              :           else
   20716              :             {
   20717         3297 :               *expr_p = DECL_INITIAL (*expr_p);
   20718         3297 :               ret = GS_OK;
   20719              :             }
   20720              :           break;
   20721              : 
   20722      6639478 :         case DECL_EXPR:
   20723      6639478 :           ret = gimplify_decl_expr (expr_p, pre_p);
   20724      6639478 :           break;
   20725              : 
   20726      6092087 :         case BIND_EXPR:
   20727      6092087 :           ret = gimplify_bind_expr (expr_p, pre_p);
   20728      6092087 :           break;
   20729              : 
   20730       207479 :         case LOOP_EXPR:
   20731       207479 :           ret = gimplify_loop_expr (expr_p, pre_p);
   20732       207479 :           break;
   20733              : 
   20734        50872 :         case SWITCH_EXPR:
   20735        50872 :           ret = gimplify_switch_expr (expr_p, pre_p);
   20736        50872 :           break;
   20737              : 
   20738         3207 :         case EXIT_EXPR:
   20739         3207 :           ret = gimplify_exit_expr (expr_p);
   20740         3207 :           break;
   20741              : 
   20742      1125877 :         case GOTO_EXPR:
   20743              :           /* If the target is not LABEL, then it is a computed jump
   20744              :              and the target needs to be gimplified.  */
   20745      1125877 :           if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
   20746              :             {
   20747         1200 :               ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
   20748              :                                    NULL, is_gimple_val, fb_rvalue);
   20749         1200 :               if (ret == GS_ERROR)
   20750              :                 break;
   20751              :             }
   20752      2251752 :           gimplify_seq_add_stmt (pre_p,
   20753      1125876 :                           gimple_build_goto (GOTO_DESTINATION (*expr_p)));
   20754      1125876 :           ret = GS_ALL_DONE;
   20755      1125876 :           break;
   20756              : 
   20757       104488 :         case PREDICT_EXPR:
   20758       417952 :           gimplify_seq_add_stmt (pre_p,
   20759       104488 :                         gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
   20760       104488 :                                               PREDICT_EXPR_OUTCOME (*expr_p)));
   20761       104488 :           ret = GS_ALL_DONE;
   20762       104488 :           break;
   20763              : 
   20764      2617976 :         case LABEL_EXPR:
   20765      2617976 :           ret = gimplify_label_expr (expr_p, pre_p);
   20766      2617976 :           label = LABEL_EXPR_LABEL (*expr_p);
   20767      2617976 :           gcc_assert (decl_function_context (label) == current_function_decl);
   20768              : 
   20769              :           /* If the label is used in a goto statement, or address of the label
   20770              :              is taken, we need to unpoison all variables that were seen so far.
   20771              :              Doing so would prevent us from reporting a false positives.  */
   20772      2617976 :           if (asan_poisoned_variables
   20773         5015 :               && asan_used_labels != NULL
   20774         1325 :               && asan_used_labels->contains (label)
   20775      2618888 :               && !gimplify_omp_ctxp)
   20776          904 :             asan_poison_variables (asan_poisoned_variables, false, pre_p);
   20777              :           break;
   20778              : 
   20779      1045379 :         case CASE_LABEL_EXPR:
   20780      1045379 :           ret = gimplify_case_label_expr (expr_p, pre_p);
   20781              : 
   20782      1045379 :           if (gimplify_ctxp->live_switch_vars)
   20783      1045192 :             asan_poison_variables (gimplify_ctxp->live_switch_vars, false,
   20784              :                                    pre_p);
   20785              :           break;
   20786              : 
   20787      2320406 :         case RETURN_EXPR:
   20788      2320406 :           ret = gimplify_return_expr (*expr_p, pre_p);
   20789      2320406 :           break;
   20790              : 
   20791       983015 :         case CONSTRUCTOR:
   20792              :           /* Don't reduce this in place; let gimplify_init_constructor work its
   20793              :              magic.  Buf if we're just elaborating this for side effects, just
   20794              :              gimplify any element that has side-effects.  */
   20795       983015 :           if (fallback == fb_none)
   20796              :             {
   20797          404 :               unsigned HOST_WIDE_INT ix;
   20798          404 :               tree val;
   20799          404 :               tree temp = NULL_TREE;
   20800          421 :               FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*expr_p), ix, val)
   20801           17 :                 if (TREE_SIDE_EFFECTS (val))
   20802            4 :                   append_to_statement_list (val, &temp);
   20803              : 
   20804          404 :               *expr_p = temp;
   20805          404 :               ret = temp ? GS_OK : GS_ALL_DONE;
   20806              :             }
   20807              :           /* C99 code may assign to an array in a constructed
   20808              :              structure or union, and this has undefined behavior only
   20809              :              on execution, so create a temporary if an lvalue is
   20810              :              required.  */
   20811       982611 :           else if (fallback == fb_lvalue)
   20812              :             {
   20813            3 :               *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
   20814            3 :               mark_addressable (*expr_p);
   20815            3 :               ret = GS_OK;
   20816              :             }
   20817              :           else
   20818              :             ret = GS_ALL_DONE;
   20819              :           break;
   20820              : 
   20821              :           /* The following are special cases that are not handled by the
   20822              :              original GIMPLE grammar.  */
   20823              : 
   20824              :           /* SAVE_EXPR nodes are converted into a GIMPLE identifier and
   20825              :              eliminated.  */
   20826       444457 :         case SAVE_EXPR:
   20827       444457 :           ret = gimplify_save_expr (expr_p, pre_p, post_p);
   20828       444457 :           break;
   20829              : 
   20830       322916 :         case BIT_FIELD_REF:
   20831       322916 :           ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   20832              :                                post_p, is_gimple_lvalue, fb_either);
   20833       322916 :           recalculate_side_effects (*expr_p);
   20834       322916 :           break;
   20835              : 
   20836         1983 :         case TARGET_MEM_REF:
   20837         1983 :           {
   20838         1983 :             enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
   20839              : 
   20840         1983 :             if (TMR_BASE (*expr_p))
   20841         1983 :               r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
   20842              :                                   post_p, is_gimple_mem_ref_addr, fb_either);
   20843         1983 :             if (TMR_INDEX (*expr_p))
   20844         1161 :               r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
   20845              :                                   post_p, is_gimple_val, fb_rvalue);
   20846         1983 :             if (TMR_INDEX2 (*expr_p))
   20847           72 :               r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
   20848              :                                   post_p, is_gimple_val, fb_rvalue);
   20849              :             /* TMR_STEP and TMR_OFFSET are always integer constants.  */
   20850         1983 :             ret = MIN (r0, r1);
   20851              :           }
   20852              :           break;
   20853              : 
   20854            0 :         case NON_LVALUE_EXPR:
   20855              :           /* This should have been stripped above.  */
   20856            0 :           gcc_unreachable ();
   20857              : 
   20858        83100 :         case ASM_EXPR:
   20859        83100 :           ret = gimplify_asm_expr (expr_p, pre_p, post_p);
   20860        83100 :           break;
   20861              : 
   20862       525765 :         case TRY_FINALLY_EXPR:
   20863       525765 :         case TRY_CATCH_EXPR:
   20864       525765 :           {
   20865       525765 :             gimple_seq eval, cleanup;
   20866       525765 :             gtry *try_;
   20867              : 
   20868              :             /* Calls to destructors are generated automatically in FINALLY/CATCH
   20869              :                block. They should have location as UNKNOWN_LOCATION. However,
   20870              :                gimplify_call_expr will reset these call stmts to input_location
   20871              :                if it finds stmt's location is unknown. To prevent resetting for
   20872              :                destructors, we set the input_location to unknown.
   20873              :                Note that this only affects the destructor calls in FINALLY/CATCH
   20874              :                block, and will automatically reset to its original value by the
   20875              :                end of gimplify_expr.  */
   20876       525765 :             input_location = UNKNOWN_LOCATION;
   20877       525765 :             eval = cleanup = NULL;
   20878       525765 :             gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
   20879       525765 :             bool save_in_handler_expr = gimplify_ctxp->in_handler_expr;
   20880       525765 :             if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
   20881       525765 :                 && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
   20882              :               {
   20883          282 :                 gimple_seq n = NULL, e = NULL;
   20884          282 :                 gimplify_ctxp->in_handler_expr = true;
   20885          282 :                 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
   20886              :                                                 0), &n);
   20887          282 :                 gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
   20888              :                                                 1), &e);
   20889          282 :                 if (!gimple_seq_empty_p (n) || !gimple_seq_empty_p (e))
   20890              :                   {
   20891          276 :                     geh_else *stmt = gimple_build_eh_else (n, e);
   20892          276 :                     gimple_seq_add_stmt (&cleanup, stmt);
   20893              :                   }
   20894              :               }
   20895              :             else
   20896              :               {
   20897       525483 :                 gimplify_ctxp->in_handler_expr = true;
   20898       525483 :                 gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
   20899              :               }
   20900       525765 :             gimplify_ctxp->in_handler_expr = save_in_handler_expr;
   20901              :             /* Don't create bogus GIMPLE_TRY with empty cleanup.  */
   20902       525765 :             if (gimple_seq_empty_p (cleanup))
   20903              :               {
   20904        27714 :                 gimple_seq_add_seq (pre_p, eval);
   20905        27714 :                 ret = GS_ALL_DONE;
   20906        27714 :                 break;
   20907              :               }
   20908       498051 :             try_ = gimple_build_try (eval, cleanup,
   20909       498051 :                                      TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
   20910              :                                      ? GIMPLE_TRY_FINALLY
   20911              :                                      : GIMPLE_TRY_CATCH);
   20912       498051 :             if (EXPR_HAS_LOCATION (save_expr))
   20913       911724 :               gimple_set_location (try_, EXPR_LOCATION (save_expr));
   20914        42189 :             else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION)
   20915        31139 :               gimple_set_location (try_, saved_location);
   20916       498051 :             if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
   20917       177554 :               gimple_try_set_catch_is_cleanup (try_,
   20918       177554 :                                                TRY_CATCH_IS_CLEANUP (*expr_p));
   20919       498051 :             gimplify_seq_add_stmt (pre_p, try_);
   20920       498051 :             ret = GS_ALL_DONE;
   20921       498051 :             break;
   20922              :           }
   20923              : 
   20924      5531759 :         case CLEANUP_POINT_EXPR:
   20925      5531759 :           ret = gimplify_cleanup_point_expr (expr_p, pre_p);
   20926      5531759 :           break;
   20927              : 
   20928       882656 :         case TARGET_EXPR:
   20929       882656 :           ret = gimplify_target_expr (expr_p, pre_p, post_p);
   20930       882656 :           break;
   20931              : 
   20932        41968 :         case CATCH_EXPR:
   20933        41968 :           {
   20934        41968 :             gimple *c;
   20935        41968 :             gimple_seq handler = NULL;
   20936        41968 :             gimplify_and_add (CATCH_BODY (*expr_p), &handler);
   20937        41968 :             c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
   20938        41968 :             gimplify_seq_add_stmt (pre_p, c);
   20939        41968 :             ret = GS_ALL_DONE;
   20940        41968 :             break;
   20941              :           }
   20942              : 
   20943         5891 :         case EH_FILTER_EXPR:
   20944         5891 :           {
   20945         5891 :             gimple *ehf;
   20946         5891 :             gimple_seq failure = NULL;
   20947              : 
   20948         5891 :             gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
   20949         5891 :             ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
   20950         5891 :             copy_warning (ehf, *expr_p);
   20951         5891 :             gimplify_seq_add_stmt (pre_p, ehf);
   20952         5891 :             ret = GS_ALL_DONE;
   20953         5891 :             break;
   20954              :           }
   20955              : 
   20956        53343 :         case OBJ_TYPE_REF:
   20957        53343 :           {
   20958        53343 :             enum gimplify_status r0, r1;
   20959        53343 :             r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
   20960              :                                 post_p, is_gimple_val, fb_rvalue);
   20961        53343 :             r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
   20962              :                                 post_p, is_gimple_val, fb_rvalue);
   20963        53343 :             TREE_SIDE_EFFECTS (*expr_p) = 0;
   20964        53343 :             ret = MIN (r0, r1);
   20965              :           }
   20966              :           break;
   20967              : 
   20968        41062 :         case LABEL_DECL:
   20969              :           /* We get here when taking the address of a label.  We mark
   20970              :              the label as "forced"; meaning it can never be removed and
   20971              :              it is a potential target for any computed goto.  */
   20972        41062 :           FORCED_LABEL (*expr_p) = 1;
   20973        41062 :           ret = GS_ALL_DONE;
   20974        41062 :           break;
   20975              : 
   20976      8719235 :         case STATEMENT_LIST:
   20977      8719235 :           ret = gimplify_statement_list (expr_p, pre_p);
   20978      8719235 :           break;
   20979              : 
   20980         1739 :         case WITH_SIZE_EXPR:
   20981         1739 :           {
   20982         2021 :             gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   20983              :                            post_p == &internal_post ? NULL : post_p,
   20984              :                            gimple_test_f, fallback);
   20985         1739 :             gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
   20986              :                            is_gimple_val, fb_rvalue);
   20987         1739 :             ret = GS_ALL_DONE;
   20988              :           }
   20989         1739 :           break;
   20990              : 
   20991    111921880 :         case VAR_DECL:
   20992    111921880 :         case PARM_DECL:
   20993    111921880 :           ret = gimplify_var_or_parm_decl (expr_p);
   20994    111921880 :           break;
   20995              : 
   20996       352067 :         case RESULT_DECL:
   20997              :           /* When within an OMP context, notice uses of variables.  */
   20998       352067 :           if (gimplify_omp_ctxp)
   20999         1412 :             omp_notice_variable (gimplify_omp_ctxp, *expr_p, true);
   21000              :           /* Handlers can refer to the function result; if that has been
   21001              :              moved, we need to track it.  */
   21002       352067 :           if (gimplify_ctxp->in_handler_expr && gimplify_ctxp->return_temp)
   21003           68 :             *expr_p = gimplify_ctxp->return_temp;
   21004              :           ret = GS_ALL_DONE;
   21005              :           break;
   21006              : 
   21007            0 :         case DEBUG_EXPR_DECL:
   21008            0 :           gcc_unreachable ();
   21009              : 
   21010      2517013 :         case DEBUG_BEGIN_STMT:
   21011      5034026 :           gimplify_seq_add_stmt (pre_p,
   21012              :                                  gimple_build_debug_begin_stmt
   21013      2517013 :                                  (TREE_BLOCK (*expr_p),
   21014      2517013 :                                   EXPR_LOCATION (*expr_p)));
   21015      2517013 :           ret = GS_ALL_DONE;
   21016      2517013 :           *expr_p = NULL;
   21017      2517013 :           break;
   21018              : 
   21019              :         case SSA_NAME:
   21020              :           /* Allow callbacks into the gimplifier during optimization.  */
   21021              :           ret = GS_ALL_DONE;
   21022              :           break;
   21023              : 
   21024        18392 :         case OMP_PARALLEL:
   21025        18392 :           gimplify_omp_parallel (expr_p, pre_p);
   21026        18392 :           ret = GS_ALL_DONE;
   21027        18392 :           break;
   21028              : 
   21029         4111 :         case OMP_TASK:
   21030         4111 :           gimplify_omp_task (expr_p, pre_p);
   21031         4111 :           ret = GS_ALL_DONE;
   21032         4111 :           break;
   21033              : 
   21034        10767 :         case OMP_SIMD:
   21035        10767 :           {
   21036              :             /* Temporarily disable into_ssa, as scan_omp_simd
   21037              :                which calls copy_gimple_seq_and_replace_locals can't deal
   21038              :                with SSA_NAMEs defined outside of the body properly.  */
   21039        10767 :             bool saved_into_ssa = gimplify_ctxp->into_ssa;
   21040        10767 :             gimplify_ctxp->into_ssa = false;
   21041        10767 :             ret = gimplify_omp_for (expr_p, pre_p);
   21042        10767 :             gimplify_ctxp->into_ssa = saved_into_ssa;
   21043        10767 :             break;
   21044              :           }
   21045              : 
   21046        47579 :         case OMP_FOR:
   21047        47579 :         case OMP_DISTRIBUTE:
   21048        47579 :         case OMP_TASKLOOP:
   21049        47579 :         case OMP_TILE:
   21050        47579 :         case OMP_UNROLL:
   21051        47579 :         case OACC_LOOP:
   21052        47579 :           ret = gimplify_omp_for (expr_p, pre_p);
   21053        47579 :           break;
   21054              : 
   21055         1056 :         case OMP_LOOP:
   21056         1056 :           ret = gimplify_omp_loop (expr_p, pre_p);
   21057         1056 :           break;
   21058              : 
   21059          717 :         case OACC_CACHE:
   21060          717 :           gimplify_oacc_cache (expr_p, pre_p);
   21061          717 :           ret = GS_ALL_DONE;
   21062          717 :           break;
   21063              : 
   21064          254 :         case OACC_DECLARE:
   21065          254 :           gimplify_oacc_declare (expr_p, pre_p);
   21066          254 :           ret = GS_ALL_DONE;
   21067          254 :           break;
   21068              : 
   21069        40049 :         case OACC_HOST_DATA:
   21070        40049 :         case OACC_DATA:
   21071        40049 :         case OACC_KERNELS:
   21072        40049 :         case OACC_PARALLEL:
   21073        40049 :         case OACC_SERIAL:
   21074        40049 :         case OMP_SCOPE:
   21075        40049 :         case OMP_SECTIONS:
   21076        40049 :         case OMP_SINGLE:
   21077        40049 :         case OMP_TARGET:
   21078        40049 :         case OMP_TARGET_DATA:
   21079        40049 :         case OMP_TEAMS:
   21080        40049 :           gimplify_omp_workshare (expr_p, pre_p);
   21081        40049 :           ret = GS_ALL_DONE;
   21082        40049 :           break;
   21083              : 
   21084        12382 :         case OACC_ENTER_DATA:
   21085        12382 :         case OACC_EXIT_DATA:
   21086        12382 :         case OACC_UPDATE:
   21087        12382 :         case OMP_TARGET_UPDATE:
   21088        12382 :         case OMP_TARGET_ENTER_DATA:
   21089        12382 :         case OMP_TARGET_EXIT_DATA:
   21090        12382 :           gimplify_omp_target_update (expr_p, pre_p);
   21091        12382 :           ret = GS_ALL_DONE;
   21092        12382 :           break;
   21093              : 
   21094         7089 :         case OMP_SECTION:
   21095         7089 :         case OMP_STRUCTURED_BLOCK:
   21096         7089 :         case OMP_MASTER:
   21097         7089 :         case OMP_MASKED:
   21098         7089 :         case OMP_ORDERED:
   21099         7089 :         case OMP_CRITICAL:
   21100         7089 :         case OMP_SCAN:
   21101         7089 :           {
   21102         7089 :             gimple_seq body = NULL;
   21103         7089 :             gimple *g;
   21104         7089 :             bool saved_in_omp_construct = in_omp_construct;
   21105              : 
   21106         7089 :             in_omp_construct = true;
   21107         7089 :             gimplify_and_add (OMP_BODY (*expr_p), &body);
   21108         7089 :             in_omp_construct = saved_in_omp_construct;
   21109         7089 :             switch (TREE_CODE (*expr_p))
   21110              :               {
   21111         1279 :               case OMP_SECTION:
   21112         1279 :                 g = gimple_build_omp_section (body);
   21113         1279 :                 break;
   21114          791 :               case OMP_STRUCTURED_BLOCK:
   21115          791 :                 g = gimple_build_omp_structured_block (body);
   21116          791 :                 break;
   21117          874 :               case OMP_MASTER:
   21118          874 :                 g = gimple_build_omp_master (body);
   21119          874 :                 break;
   21120         1954 :               case OMP_ORDERED:
   21121         1954 :                 g = gimplify_omp_ordered (*expr_p, body);
   21122         1954 :                 if (OMP_BODY (*expr_p) == NULL_TREE
   21123         1954 :                     && gimple_code (g) == GIMPLE_OMP_ORDERED)
   21124         1025 :                   gimple_omp_ordered_standalone (g);
   21125              :                 break;
   21126          497 :               case OMP_MASKED:
   21127          497 :                 gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p),
   21128              :                                            pre_p, ORT_WORKSHARE, OMP_MASKED);
   21129          497 :                 gimplify_adjust_omp_clauses (pre_p, body,
   21130              :                                              &OMP_MASKED_CLAUSES (*expr_p),
   21131              :                                              OMP_MASKED);
   21132          994 :                 g = gimple_build_omp_masked (body,
   21133          497 :                                              OMP_MASKED_CLAUSES (*expr_p));
   21134          497 :                 break;
   21135          552 :               case OMP_CRITICAL:
   21136          552 :                 gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p),
   21137              :                                            pre_p, ORT_WORKSHARE, OMP_CRITICAL);
   21138          552 :                 gimplify_adjust_omp_clauses (pre_p, body,
   21139              :                                              &OMP_CRITICAL_CLAUSES (*expr_p),
   21140              :                                              OMP_CRITICAL);
   21141         1656 :                 g = gimple_build_omp_critical (body,
   21142          552 :                                                OMP_CRITICAL_NAME (*expr_p),
   21143          552 :                                                OMP_CRITICAL_CLAUSES (*expr_p));
   21144          552 :                 break;
   21145         1142 :               case OMP_SCAN:
   21146         1142 :                 gimplify_scan_omp_clauses (&OMP_SCAN_CLAUSES (*expr_p),
   21147              :                                            pre_p, ORT_WORKSHARE, OMP_SCAN);
   21148         1142 :                 gimplify_adjust_omp_clauses (pre_p, body,
   21149              :                                              &OMP_SCAN_CLAUSES (*expr_p),
   21150              :                                              OMP_SCAN);
   21151         1142 :                 g = gimple_build_omp_scan (body, OMP_SCAN_CLAUSES (*expr_p));
   21152         1142 :                 break;
   21153            0 :               default:
   21154            0 :                 gcc_unreachable ();
   21155              :               }
   21156         7089 :             gimplify_seq_add_stmt (pre_p, g);
   21157         7089 :             ret = GS_ALL_DONE;
   21158         7089 :             break;
   21159              :           }
   21160              : 
   21161          611 :         case OMP_TASKGROUP:
   21162          611 :           {
   21163          611 :             gimple_seq body = NULL;
   21164              : 
   21165          611 :             tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
   21166          611 :             bool saved_in_omp_construct = in_omp_construct;
   21167          611 :             gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
   21168              :                                        OMP_TASKGROUP);
   21169          611 :             gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
   21170              : 
   21171          611 :             in_omp_construct = true;
   21172          611 :             gimplify_and_add (OMP_BODY (*expr_p), &body);
   21173          611 :             in_omp_construct = saved_in_omp_construct;
   21174          611 :             gimple_seq cleanup = NULL;
   21175          611 :             tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
   21176          611 :             gimple *g = gimple_build_call (fn, 0);
   21177          611 :             gimple_seq_add_stmt (&cleanup, g);
   21178          611 :             g = gimple_build_try (body, cleanup, GIMPLE_TRY_FINALLY);
   21179          611 :             body = NULL;
   21180          611 :             gimple_seq_add_stmt (&body, g);
   21181          611 :             g = gimple_build_omp_taskgroup (body, *pclauses);
   21182          611 :             gimplify_seq_add_stmt (pre_p, g);
   21183          611 :             ret = GS_ALL_DONE;
   21184          611 :             break;
   21185              :           }
   21186              : 
   21187          612 :         case OMP_INTEROP:
   21188          612 :           ret = gimplify_omp_interop (expr_p, pre_p);
   21189          612 :           break;
   21190        10260 :         case OMP_ATOMIC:
   21191        10260 :         case OMP_ATOMIC_READ:
   21192        10260 :         case OMP_ATOMIC_CAPTURE_OLD:
   21193        10260 :         case OMP_ATOMIC_CAPTURE_NEW:
   21194        10260 :           ret = gimplify_omp_atomic (expr_p, pre_p);
   21195        10260 :           break;
   21196              : 
   21197          852 :         case OMP_DISPATCH:
   21198          852 :           ret = gimplify_omp_dispatch (expr_p, pre_p);
   21199          852 :           break;
   21200              : 
   21201          179 :         case OMP_METADIRECTIVE:
   21202          179 :           ret = gimplify_omp_metadirective (expr_p, pre_p, post_p,
   21203              :                                             gimple_test_f, fallback);
   21204          179 :           break;
   21205              : 
   21206           36 :         case OMP_NEXT_VARIANT:
   21207           36 :         case OMP_TARGET_DEVICE_MATCHES:
   21208              :           /* These are placeholders for constants.  There's nothing to do with
   21209              :              them here but we must mark the containing function as needing
   21210              :              to run the ompdevlow pass to resolve them.  Note that
   21211              :              OMP_TARGET_DEVICE_MATCHES, in particular, may be inserted by
   21212              :              the front ends.  */
   21213           36 :           cgraph_node::get (cfun->decl)->has_omp_variant_constructs = 1;
   21214           36 :           ret = GS_ALL_DONE;
   21215           36 :           break;
   21216              : 
   21217            0 :         case OMP_DECLARE_MAPPER:
   21218            0 :           ret = gimplify_omp_declare_mapper (expr_p);
   21219            0 :           break;
   21220              : 
   21221          478 :         case TRANSACTION_EXPR:
   21222          478 :           ret = gimplify_transaction (expr_p, pre_p);
   21223          478 :           break;
   21224              : 
   21225       294106 :         case TRUTH_AND_EXPR:
   21226       294106 :         case TRUTH_OR_EXPR:
   21227       294106 :         case TRUTH_XOR_EXPR:
   21228       294106 :           {
   21229       294106 :             tree orig_type = TREE_TYPE (*expr_p);
   21230       294106 :             tree new_type, xop0, xop1;
   21231       294106 :             *expr_p = gimple_boolify (*expr_p);
   21232       294106 :             new_type = TREE_TYPE (*expr_p);
   21233       294106 :             if (!useless_type_conversion_p (orig_type, new_type))
   21234              :               {
   21235         1166 :                 *expr_p = fold_convert_loc (input_location, orig_type, *expr_p);
   21236         1166 :                 ret = GS_OK;
   21237         1166 :                 break;
   21238              :               }
   21239              : 
   21240              :           /* Boolified binary truth expressions are semantically equivalent
   21241              :              to bitwise binary expressions.  Canonicalize them to the
   21242              :              bitwise variant.  */
   21243       292940 :             switch (TREE_CODE (*expr_p))
   21244              :               {
   21245       177141 :               case TRUTH_AND_EXPR:
   21246       177141 :                 TREE_SET_CODE (*expr_p, BIT_AND_EXPR);
   21247       177141 :                 break;
   21248       115175 :               case TRUTH_OR_EXPR:
   21249       115175 :                 TREE_SET_CODE (*expr_p, BIT_IOR_EXPR);
   21250       115175 :                 break;
   21251          624 :               case TRUTH_XOR_EXPR:
   21252          624 :                 TREE_SET_CODE (*expr_p, BIT_XOR_EXPR);
   21253          624 :                 break;
   21254              :               default:
   21255              :                 break;
   21256              :               }
   21257              :             /* Now make sure that operands have compatible type to
   21258              :                expression's new_type.  */
   21259       292940 :             xop0 = TREE_OPERAND (*expr_p, 0);
   21260       292940 :             xop1 = TREE_OPERAND (*expr_p, 1);
   21261       292940 :             if (!useless_type_conversion_p (new_type, TREE_TYPE (xop0)))
   21262          326 :               TREE_OPERAND (*expr_p, 0) = fold_convert_loc (input_location,
   21263              :                                                             new_type,
   21264              :                                                             xop0);
   21265       292940 :             if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1)))
   21266          366 :               TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location,
   21267              :                                                             new_type,
   21268              :                                                             xop1);
   21269              :             /* Continue classified as tcc_binary.  */
   21270       292940 :             goto expr_2;
   21271              :           }
   21272              : 
   21273        11381 :         case VEC_COND_EXPR:
   21274        11381 :           goto expr_3;
   21275              : 
   21276       134378 :         case VEC_PERM_EXPR:
   21277              :           /* Classified as tcc_expression.  */
   21278       134378 :           goto expr_3;
   21279              : 
   21280           48 :         case BIT_INSERT_EXPR:
   21281              :           /* Argument 3 is a constant.  */
   21282           48 :           goto expr_2;
   21283              : 
   21284      3895274 :         case POINTER_PLUS_EXPR:
   21285      3895274 :           {
   21286      3895274 :             enum gimplify_status r0, r1;
   21287      3895274 :             r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   21288              :                                 post_p, is_gimple_val, fb_rvalue);
   21289      3895274 :             r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
   21290              :                                 post_p, is_gimple_val, fb_rvalue);
   21291      3895274 :             recalculate_side_effects (*expr_p);
   21292      3895274 :             ret = MIN (r0, r1);
   21293              :             break;
   21294              :           }
   21295              : 
   21296     45485421 :         default:
   21297     45485421 :           switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
   21298              :             {
   21299      7114485 :             case tcc_comparison:
   21300              :               /* Handle comparison of objects of non scalar mode aggregates
   21301              :                  with a call to memcmp.  It would be nice to only have to do
   21302              :                  this for variable-sized objects, but then we'd have to allow
   21303              :                  the same nest of reference nodes we allow for MODIFY_EXPR and
   21304              :                  that's too complex.
   21305              : 
   21306              :                  Compare scalar mode aggregates as scalar mode values.  Using
   21307              :                  memcmp for them would be very inefficient at best, and is
   21308              :                  plain wrong if bitfields are involved.  */
   21309      7114485 :               if (error_operand_p (TREE_OPERAND (*expr_p, 1)))
   21310              :                 ret = GS_ERROR;
   21311              :               else
   21312              :                 {
   21313      7114485 :                   tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
   21314              : 
   21315              :                   /* Vector comparisons need no boolification.  */
   21316      7114485 :                   if (TREE_CODE (type) == VECTOR_TYPE)
   21317        13431 :                     goto expr_2;
   21318      7101054 :                   else if (!AGGREGATE_TYPE_P (type))
   21319              :                     {
   21320      7101038 :                       tree org_type = TREE_TYPE (*expr_p);
   21321      7101038 :                       *expr_p = gimple_boolify (*expr_p);
   21322      7101038 :                       if (!useless_type_conversion_p (org_type,
   21323      7101038 :                                                       TREE_TYPE (*expr_p)))
   21324              :                         {
   21325        58086 :                           *expr_p = fold_convert_loc (input_location,
   21326              :                                                       org_type, *expr_p);
   21327        58086 :                           ret = GS_OK;
   21328              :                         }
   21329              :                       else
   21330      7042952 :                         goto expr_2;
   21331              :                     }
   21332           16 :                   else if (SCALAR_INT_MODE_P (TYPE_MODE (type)))
   21333           16 :                     ret = gimplify_scalar_mode_aggregate_compare (expr_p);
   21334              :                   else
   21335            0 :                     ret = gimplify_variable_sized_compare (expr_p);
   21336              :                 }
   21337              :               break;
   21338              : 
   21339              :             /* If *EXPR_P does not need to be special-cased, handle it
   21340              :                according to its class.  */
   21341      1631104 :             case tcc_unary:
   21342      1631104 :               ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   21343              :                                    post_p, is_gimple_val, fb_rvalue);
   21344      1631104 :               break;
   21345              : 
   21346     26812232 :             case tcc_binary:
   21347     26812232 :             expr_2:
   21348     26812232 :               {
   21349     26812232 :                 enum gimplify_status r0, r1;
   21350              : 
   21351     26812232 :                 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   21352              :                                     post_p, is_gimple_val, fb_rvalue);
   21353     26812232 :                 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
   21354              :                                     post_p, is_gimple_val, fb_rvalue);
   21355              : 
   21356     26812232 :                 ret = MIN (r0, r1);
   21357              :                 break;
   21358              :               }
   21359              : 
   21360       145759 :             expr_3:
   21361       145759 :               {
   21362       145759 :                 enum gimplify_status r0, r1, r2;
   21363              : 
   21364       145759 :                 r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
   21365              :                                     post_p, is_gimple_val, fb_rvalue);
   21366       145759 :                 r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
   21367              :                                     post_p, is_gimple_val, fb_rvalue);
   21368       145759 :                 r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
   21369              :                                     post_p, is_gimple_val, fb_rvalue);
   21370              : 
   21371       145759 :                 ret = MIN (MIN (r0, r1), r2);
   21372              :                 break;
   21373              :               }
   21374              : 
   21375     17276971 :             case tcc_declaration:
   21376     17276971 :             case tcc_constant:
   21377     17276971 :               ret = GS_ALL_DONE;
   21378     17276971 :               goto dont_recalculate;
   21379              : 
   21380            0 :             default:
   21381            0 :               gcc_unreachable ();
   21382              :             }
   21383              : 
   21384     28647197 :           recalculate_side_effects (*expr_p);
   21385              : 
   21386    491881442 :         dont_recalculate:
   21387              :           break;
   21388              :         }
   21389              : 
   21390    491881442 :       gcc_assert (*expr_p || ret != GS_OK);
   21391              :     }
   21392    496931149 :   while (ret == GS_OK);
   21393              : 
   21394              :   /* If we encountered an error_mark somewhere nested inside, either
   21395              :      stub out the statement or propagate the error back out.  */
   21396    478513032 :   if (ret == GS_ERROR)
   21397              :     {
   21398         5322 :       if (is_statement)
   21399         4093 :         *expr_p = NULL;
   21400         5322 :       goto out;
   21401              :     }
   21402              : 
   21403              :   /* This was only valid as a return value from the langhook, which
   21404              :      we handled.  Make sure it doesn't escape from any other context.  */
   21405    478507710 :   gcc_assert (ret != GS_UNHANDLED);
   21406              : 
   21407    478507710 :   if (fallback == fb_none && *expr_p && !is_gimple_stmt (*expr_p))
   21408              :     {
   21409              :       /* We aren't looking for a value, and we don't have a valid
   21410              :          statement.  If it doesn't have side-effects, throw it away.
   21411              :          We can also get here with code such as "*&&L;", where L is
   21412              :          a LABEL_DECL that is marked as FORCED_LABEL.  */
   21413      1245868 :       if (TREE_CODE (*expr_p) == LABEL_DECL
   21414      1245868 :           || !TREE_SIDE_EFFECTS (*expr_p))
   21415      1244836 :         *expr_p = NULL;
   21416         1032 :       else if (!TREE_THIS_VOLATILE (*expr_p))
   21417              :         {
   21418              :           /* This is probably a _REF that contains something nested that
   21419              :              has side effects.  Recurse through the operands to find it.  */
   21420            0 :           enum tree_code code = TREE_CODE (*expr_p);
   21421              : 
   21422            0 :           switch (code)
   21423              :             {
   21424            0 :             case COMPONENT_REF:
   21425            0 :             case REALPART_EXPR:
   21426            0 :             case IMAGPART_EXPR:
   21427            0 :             case VIEW_CONVERT_EXPR:
   21428            0 :               gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   21429              :                              gimple_test_f, fallback);
   21430            0 :               break;
   21431              : 
   21432            0 :             case ARRAY_REF:
   21433            0 :             case ARRAY_RANGE_REF:
   21434            0 :               gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
   21435              :                              gimple_test_f, fallback);
   21436            0 :               gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
   21437              :                              gimple_test_f, fallback);
   21438            0 :               break;
   21439              : 
   21440            0 :             default:
   21441              :                /* Anything else with side-effects must be converted to
   21442              :                   a valid statement before we get here.  */
   21443            0 :               gcc_unreachable ();
   21444              :             }
   21445              : 
   21446            0 :           *expr_p = NULL;
   21447              :         }
   21448         1032 :       else if (COMPLETE_TYPE_P (TREE_TYPE (*expr_p))
   21449          982 :                && TYPE_MODE (TREE_TYPE (*expr_p)) != BLKmode
   21450         2001 :                && !is_empty_type (TREE_TYPE (*expr_p)))
   21451              :         {
   21452              :           /* Historically, the compiler has treated a bare reference
   21453              :              to a non-BLKmode volatile lvalue as forcing a load.  */
   21454          909 :           tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
   21455              : 
   21456              :           /* Normally, we do not want to create a temporary for a
   21457              :              TREE_ADDRESSABLE type because such a type should not be
   21458              :              copied by bitwise-assignment.  However, we make an
   21459              :              exception here, as all we are doing here is ensuring that
   21460              :              we read the bytes that make up the type.  We use
   21461              :              create_tmp_var_raw because create_tmp_var will abort when
   21462              :              given a TREE_ADDRESSABLE type.  */
   21463          909 :           tree tmp = create_tmp_var_raw (type, "vol");
   21464          909 :           gimple_add_tmp_var (tmp);
   21465          909 :           gimplify_assign (tmp, *expr_p, pre_p);
   21466          909 :           *expr_p = NULL;
   21467              :         }
   21468              :       else
   21469              :         /* We can't do anything useful with a volatile reference to
   21470              :            an incomplete type, so just throw it away.  Likewise for
   21471              :            a BLKmode type, since any implicit inner load should
   21472              :            already have been turned into an explicit one by the
   21473              :            gimplification process.  */
   21474          123 :         *expr_p = NULL;
   21475              :     }
   21476              : 
   21477              :   /* If we are gimplifying at the statement level, we're done.  Tack
   21478              :      everything together and return.  */
   21479    478507710 :   if (fallback == fb_none || is_statement)
   21480              :     {
   21481              :       /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
   21482              :          it out for GC to reclaim it.  */
   21483    103732333 :       *expr_p = NULL_TREE;
   21484              : 
   21485    103732333 :       if (!gimple_seq_empty_p (internal_pre)
   21486    103732333 :           || !gimple_seq_empty_p (internal_post))
   21487              :         {
   21488           19 :           gimplify_seq_add_seq (&internal_pre, internal_post);
   21489           19 :           gimplify_seq_add_seq (pre_p, internal_pre);
   21490              :         }
   21491              : 
   21492              :       /* The result of gimplifying *EXPR_P is going to be the last few
   21493              :          statements in *PRE_P and *POST_P.  Add location information
   21494              :          to all the statements that were added by the gimplification
   21495              :          helpers.  */
   21496    103732333 :       if (!gimple_seq_empty_p (*pre_p))
   21497    101197468 :         annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
   21498              : 
   21499    103732333 :       if (!gimple_seq_empty_p (*post_p))
   21500           19 :         annotate_all_with_location_after (*post_p, post_last_gsi,
   21501              :                                           input_location);
   21502              : 
   21503    103732333 :       goto out;
   21504              :     }
   21505              : 
   21506              : #ifdef ENABLE_GIMPLE_CHECKING
   21507    374775377 :   if (*expr_p)
   21508              :     {
   21509    374775377 :       enum tree_code code = TREE_CODE (*expr_p);
   21510              :       /* These expressions should already be in gimple IR form.  */
   21511    374775377 :       gcc_assert (code != MODIFY_EXPR
   21512              :                   && code != ASM_EXPR
   21513              :                   && code != BIND_EXPR
   21514              :                   && code != CATCH_EXPR
   21515              :                   && (code != COND_EXPR || gimplify_ctxp->allow_rhs_cond_expr)
   21516              :                   && code != EH_FILTER_EXPR
   21517              :                   && code != GOTO_EXPR
   21518              :                   && code != LABEL_EXPR
   21519              :                   && code != LOOP_EXPR
   21520              :                   && code != SWITCH_EXPR
   21521              :                   && code != TRY_FINALLY_EXPR
   21522              :                   && code != EH_ELSE_EXPR
   21523              :                   && code != OACC_PARALLEL
   21524              :                   && code != OACC_KERNELS
   21525              :                   && code != OACC_SERIAL
   21526              :                   && code != OACC_DATA
   21527              :                   && code != OACC_HOST_DATA
   21528              :                   && code != OACC_DECLARE
   21529              :                   && code != OACC_UPDATE
   21530              :                   && code != OACC_ENTER_DATA
   21531              :                   && code != OACC_EXIT_DATA
   21532              :                   && code != OACC_CACHE
   21533              :                   && code != OMP_CRITICAL
   21534              :                   && code != OMP_FOR
   21535              :                   && code != OACC_LOOP
   21536              :                   && code != OMP_MASTER
   21537              :                   && code != OMP_MASKED
   21538              :                   && code != OMP_TASKGROUP
   21539              :                   && code != OMP_ORDERED
   21540              :                   && code != OMP_PARALLEL
   21541              :                   && code != OMP_SCAN
   21542              :                   && code != OMP_SECTIONS
   21543              :                   && code != OMP_SECTION
   21544              :                   && code != OMP_STRUCTURED_BLOCK
   21545              :                   && code != OMP_SINGLE
   21546              :                   && code != OMP_SCOPE
   21547              :                   && code != OMP_DISPATCH);
   21548              :     }
   21549              : #endif
   21550              : 
   21551              :   /* Otherwise we're gimplifying a subexpression, so the resulting
   21552              :      value is interesting.  If it's a valid operand that matches
   21553              :      GIMPLE_TEST_F, we're done. Unless we are handling some
   21554              :      post-effects internally; if that's the case, we need to copy into
   21555              :      a temporary before adding the post-effects to POST_P.  */
   21556    374775377 :   if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
   21557    348201470 :     goto out;
   21558              : 
   21559              :   /* Otherwise, we need to create a new temporary for the gimplified
   21560              :      expression.  */
   21561              : 
   21562              :   /* We can't return an lvalue if we have an internal postqueue.  The
   21563              :      object the lvalue refers to would (probably) be modified by the
   21564              :      postqueue; we need to copy the value out first, which means an
   21565              :      rvalue.  */
   21566     26573907 :   if ((fallback & fb_lvalue)
   21567       599396 :       && gimple_seq_empty_p (internal_post)
   21568     27173303 :       && is_gimple_addressable (*expr_p))
   21569              :     {
   21570              :       /* An lvalue will do.  Take the address of the expression, store it
   21571              :          in a temporary, and replace the expression with an INDIRECT_REF of
   21572              :          that temporary.  */
   21573           15 :       tree ref_alias_type = reference_alias_ptr_type (*expr_p);
   21574           15 :       unsigned int ref_align = get_object_alignment (*expr_p);
   21575           15 :       tree ref_type = TREE_TYPE (*expr_p);
   21576           15 :       tmp = build_fold_addr_expr_loc (input_location, *expr_p);
   21577           15 :       gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
   21578           15 :       if (TYPE_ALIGN (ref_type) != ref_align)
   21579            1 :         ref_type = build_aligned_type (ref_type, ref_align);
   21580           15 :       *expr_p = build2 (MEM_REF, ref_type,
   21581              :                         tmp, build_zero_cst (ref_alias_type));
   21582              :     }
   21583     26573892 :   else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
   21584              :     {
   21585              :       /* An rvalue will do.  Assign the gimplified expression into a
   21586              :          new temporary TMP and replace the original expression with
   21587              :          TMP.  First, make sure that the expression has a type so that
   21588              :          it can be assigned into a temporary.  */
   21589     26573884 :       gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
   21590     26573884 :       *expr_p = get_formal_tmp_var (*expr_p, pre_p);
   21591              :     }
   21592              :   else
   21593              :     {
   21594              : #ifdef ENABLE_GIMPLE_CHECKING
   21595            8 :       if (!(fallback & fb_mayfail))
   21596              :         {
   21597            0 :           fprintf (stderr, "gimplification failed:\n");
   21598            0 :           print_generic_expr (stderr, *expr_p);
   21599            0 :           debug_tree (*expr_p);
   21600            0 :           internal_error ("gimplification failed");
   21601              :         }
   21602              : #endif
   21603            8 :       gcc_assert (fallback & fb_mayfail);
   21604              : 
   21605              :       /* If this is an asm statement, and the user asked for the
   21606              :          impossible, don't die.  Fail and let gimplify_asm_expr
   21607              :          issue an error.  */
   21608            8 :       ret = GS_ERROR;
   21609            8 :       goto out;
   21610              :     }
   21611              : 
   21612              :   /* Make sure the temporary matches our predicate.  */
   21613     26573899 :   gcc_assert ((*gimple_test_f) (*expr_p));
   21614              : 
   21615     26573899 :   if (!gimple_seq_empty_p (internal_post))
   21616              :     {
   21617            0 :       annotate_all_with_location (internal_post, input_location);
   21618            0 :       gimplify_seq_add_seq (pre_p, internal_post);
   21619              :     }
   21620              : 
   21621     26573899 :  out:
   21622    478513032 :   input_location = saved_location;
   21623    478513032 :   return ret;
   21624              : }
   21625              : 
   21626              : /* Like gimplify_expr but make sure the gimplified result is not itself
   21627              :    a SSA name (but a decl if it were).  Temporaries required by
   21628              :    evaluating *EXPR_P may be still SSA names.  */
   21629              : 
   21630              : static enum gimplify_status
   21631     35472211 : gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
   21632              :                bool (*gimple_test_f) (tree), fallback_t fallback,
   21633              :                bool allow_ssa)
   21634              : {
   21635     35472211 :   enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
   21636              :                                             gimple_test_f, fallback);
   21637     35472211 :   if (! allow_ssa
   21638       267011 :       && TREE_CODE (*expr_p) == SSA_NAME)
   21639        68648 :     *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
   21640     35472211 :   return ret;
   21641              : }
   21642              : 
   21643              : /* Look through TYPE for variable-sized objects and gimplify each such
   21644              :    size that we find.  Add to LIST_P any statements generated.  */
   21645              : 
   21646              : void
   21647      8505670 : gimplify_type_sizes (tree type, gimple_seq *list_p)
   21648              : {
   21649      8505670 :   if (type == NULL || type == error_mark_node)
   21650              :     return;
   21651              : 
   21652      8505424 :   const bool ignored_p
   21653      8505424 :     = TYPE_NAME (type)
   21654      4213200 :       && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
   21655     12491763 :       && DECL_IGNORED_P (TYPE_NAME (type));
   21656      8505424 :   tree t;
   21657              : 
   21658              :   /* We first do the main variant, then copy into any other variants.  */
   21659      8505424 :   type = TYPE_MAIN_VARIANT (type);
   21660              : 
   21661              :   /* Avoid infinite recursion.  */
   21662      8505424 :   if (TYPE_SIZES_GIMPLIFIED (type))
   21663              :     return;
   21664              : 
   21665      2532114 :   TYPE_SIZES_GIMPLIFIED (type) = 1;
   21666              : 
   21667      2532114 :   switch (TREE_CODE (type))
   21668              :     {
   21669       500004 :     case INTEGER_TYPE:
   21670       500004 :     case ENUMERAL_TYPE:
   21671       500004 :     case BOOLEAN_TYPE:
   21672       500004 :     case REAL_TYPE:
   21673       500004 :     case FIXED_POINT_TYPE:
   21674       500004 :       gimplify_one_sizepos (&TYPE_MIN_VALUE (type), list_p);
   21675       500004 :       gimplify_one_sizepos (&TYPE_MAX_VALUE (type), list_p);
   21676              : 
   21677     10296702 :       for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
   21678              :         {
   21679      9796698 :           TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
   21680      9796698 :           TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
   21681              :         }
   21682              :       break;
   21683              : 
   21684       183613 :     case ARRAY_TYPE:
   21685              :       /* These types may not have declarations, so handle them here.  */
   21686       183613 :       gimplify_type_sizes (TREE_TYPE (type), list_p);
   21687       183613 :       gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
   21688              :       /* Ensure VLA bounds aren't removed, for -O0 they should be variables
   21689              :          with assigned stack slots, for -O1+ -g they should be tracked
   21690              :          by VTA.  */
   21691       183613 :       if (!ignored_p
   21692       183613 :           && TYPE_DOMAIN (type)
   21693       367001 :           && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
   21694              :         {
   21695       183388 :           t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
   21696       183388 :           if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
   21697            0 :             DECL_IGNORED_P (t) = 0;
   21698       183388 :           t = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
   21699       183388 :           if (t && VAR_P (t) && DECL_ARTIFICIAL (t))
   21700        19058 :             DECL_IGNORED_P (t) = 0;
   21701              :         }
   21702              :       break;
   21703              : 
   21704       514512 :     case RECORD_TYPE:
   21705       514512 :     case UNION_TYPE:
   21706       514512 :     case QUAL_UNION_TYPE:
   21707     11474336 :       for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
   21708     10959824 :         if (TREE_CODE (field) == FIELD_DECL)
   21709              :           {
   21710      1117666 :             gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
   21711              :             /* Likewise, ensure variable offsets aren't removed.  */
   21712      1117666 :             if (!ignored_p
   21713      1117666 :                 && (t = DECL_FIELD_OFFSET (field))
   21714      1117654 :                 && VAR_P (t)
   21715      1117828 :                 && DECL_ARTIFICIAL (t))
   21716          162 :               DECL_IGNORED_P (t) = 0;
   21717      1117666 :             gimplify_one_sizepos (&DECL_SIZE (field), list_p);
   21718      1117666 :             gimplify_one_sizepos (&DECL_SIZE_UNIT (field), list_p);
   21719      1117666 :             gimplify_type_sizes (TREE_TYPE (field), list_p);
   21720              :           }
   21721              :       break;
   21722              : 
   21723              :     case POINTER_TYPE:
   21724              :     case REFERENCE_TYPE:
   21725              :         /* We used to recurse on the pointed-to type here, which turned out to
   21726              :            be incorrect because its definition might refer to variables not
   21727              :            yet initialized at this point if a forward declaration is involved.
   21728              : 
   21729              :            It was actually useful for anonymous pointed-to types to ensure
   21730              :            that the sizes evaluation dominates every possible later use of the
   21731              :            values.  Restricting to such types here would be safe since there
   21732              :            is no possible forward declaration around, but would introduce an
   21733              :            undesirable middle-end semantic to anonymity.  We then defer to
   21734              :            front-ends the responsibility of ensuring that the sizes are
   21735              :            evaluated both early and late enough, e.g. by attaching artificial
   21736              :            type declarations to the tree.  */
   21737              :       break;
   21738              : 
   21739              :     default:
   21740              :       break;
   21741              :     }
   21742              : 
   21743      2532114 :   gimplify_one_sizepos (&TYPE_SIZE (type), list_p);
   21744      2532114 :   gimplify_one_sizepos (&TYPE_SIZE_UNIT (type), list_p);
   21745              : 
   21746     17015953 :   for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
   21747              :     {
   21748     14483839 :       TYPE_SIZE (t) = TYPE_SIZE (type);
   21749     14483839 :       TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
   21750     14483839 :       TYPE_SIZES_GIMPLIFIED (t) = 1;
   21751              :     }
   21752              : }
   21753              : 
   21754              : /* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
   21755              :    a size or position, has had all of its SAVE_EXPRs evaluated.
   21756              :    We add any required statements to *STMT_P.  */
   21757              : 
   21758              : void
   21759      9435480 : gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
   21760              : {
   21761      9435480 :   tree expr = *expr_p;
   21762              : 
   21763              :   /* We don't do anything if the value isn't there, is constant, or contains
   21764              :      A PLACEHOLDER_EXPR.  We also don't want to do anything if it's already
   21765              :      a VAR_DECL.  If it's a VAR_DECL from another function, the gimplifier
   21766              :      will want to replace it with a new variable, but that will cause problems
   21767              :      if this type is from outside the function.  It's OK to have that here.  */
   21768      9435480 :   if (expr == NULL_TREE
   21769      9516752 :       || is_gimple_constant (expr)
   21770        81272 :       || VAR_P (expr)
   21771      9512703 :       || CONTAINS_PLACEHOLDER_P (expr))
   21772              :     return;
   21773              : 
   21774        77223 :   *expr_p = unshare_expr (expr);
   21775              : 
   21776              :   /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
   21777              :      if the def vanishes.  */
   21778        77223 :   gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
   21779              : 
   21780              :   /* If expr wasn't already is_gimple_sizepos or is_gimple_constant from the
   21781              :      FE, ensure that it is a VAR_DECL, otherwise we might handle some decls
   21782              :      as gimplify_vla_decl even when they would have all sizes INTEGER_CSTs.  */
   21783        77223 :   if (is_gimple_constant (*expr_p))
   21784          548 :     *expr_p = get_initialized_tmp_var (*expr_p, stmt_p, NULL, false);
   21785              : }
   21786              : 
   21787              : /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
   21788              :    containing the sequence of corresponding GIMPLE statements.  If DO_PARMS
   21789              :    is true, also gimplify the parameters.  */
   21790              : 
   21791              : gbind *
   21792      3049005 : gimplify_body (tree fndecl, bool do_parms)
   21793              : {
   21794      3049005 :   location_t saved_location = input_location;
   21795      3049005 :   gimple_seq parm_stmts, parm_cleanup = NULL, seq;
   21796      3049005 :   gimple *outer_stmt;
   21797      3049005 :   gbind *outer_bind;
   21798              : 
   21799      3049005 :   timevar_push (TV_TREE_GIMPLIFY);
   21800              : 
   21801      3049005 :   init_tree_ssa (cfun);
   21802              : 
   21803              :   /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
   21804              :      gimplification.  */
   21805      3049005 :   default_rtl_profile ();
   21806              : 
   21807      3049005 :   gcc_assert (gimplify_ctxp == NULL);
   21808      3049005 :   push_gimplify_context (true);
   21809              : 
   21810      3049005 :   if (flag_openacc || flag_openmp)
   21811              :     {
   21812        55294 :       gcc_assert (gimplify_omp_ctxp == NULL);
   21813        55294 :       if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
   21814         9753 :         gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
   21815              :     }
   21816              : 
   21817              :   /* Unshare most shared trees in the body and in that of any nested functions.
   21818              :      It would seem we don't have to do this for nested functions because
   21819              :      they are supposed to be output and then the outer function gimplified
   21820              :      first, but the g++ front end doesn't always do it that way.  */
   21821      3049005 :   unshare_body (fndecl);
   21822      3049005 :   unvisit_body (fndecl);
   21823              : 
   21824              :   /* Make sure input_location isn't set to something weird.  */
   21825      3049005 :   input_location = DECL_SOURCE_LOCATION (fndecl);
   21826              : 
   21827              :   /* Resolve callee-copies.  This has to be done before processing
   21828              :      the body so that DECL_VALUE_EXPR gets processed correctly.  */
   21829      3049005 :   parm_stmts = do_parms ? gimplify_parameters (&parm_cleanup) : NULL;
   21830              : 
   21831              :   /* Gimplify the function's body.  */
   21832      3049005 :   seq = NULL;
   21833      3049005 :   gimplify_stmt (&DECL_SAVED_TREE (fndecl), &seq);
   21834      3049005 :   outer_stmt = gimple_seq_first_nondebug_stmt (seq);
   21835      3049005 :   if (!outer_stmt)
   21836              :     {
   21837        27242 :       outer_stmt = gimple_build_nop ();
   21838        27242 :       gimplify_seq_add_stmt (&seq, outer_stmt);
   21839              :     }
   21840              : 
   21841              :   /* The body must contain exactly one statement, a GIMPLE_BIND.  If this is
   21842              :      not the case, wrap everything in a GIMPLE_BIND to make it so.  */
   21843      3049005 :   if (gimple_code (outer_stmt) == GIMPLE_BIND
   21844      3049005 :       && (gimple_seq_first_nondebug_stmt (seq)
   21845      1744785 :           == gimple_seq_last_nondebug_stmt (seq)))
   21846              :     {
   21847      1680109 :       outer_bind = as_a <gbind *> (outer_stmt);
   21848      1680109 :       if (gimple_seq_first_stmt (seq) != outer_stmt
   21849      1680109 :           || gimple_seq_last_stmt (seq) != outer_stmt)
   21850              :         {
   21851              :           /* If there are debug stmts before or after outer_stmt, move them
   21852              :              inside of outer_bind body.  */
   21853            1 :           gimple_stmt_iterator gsi = gsi_for_stmt (outer_stmt, &seq);
   21854            1 :           gimple_seq second_seq = NULL;
   21855            1 :           if (gimple_seq_first_stmt (seq) != outer_stmt
   21856            2 :               && gimple_seq_last_stmt (seq) != outer_stmt)
   21857              :             {
   21858            0 :               second_seq = gsi_split_seq_after (gsi);
   21859            0 :               gsi_remove (&gsi, false);
   21860              :             }
   21861            1 :           else if (gimple_seq_first_stmt (seq) != outer_stmt)
   21862            1 :             gsi_remove (&gsi, false);
   21863              :           else
   21864              :             {
   21865            0 :               gsi_remove (&gsi, false);
   21866            0 :               second_seq = seq;
   21867            0 :               seq = NULL;
   21868              :             }
   21869            1 :           gimple_seq_add_seq_without_update (&seq,
   21870              :                                              gimple_bind_body (outer_bind));
   21871            1 :           gimple_seq_add_seq_without_update (&seq, second_seq);
   21872            1 :           gimple_bind_set_body (outer_bind, seq);
   21873              :         }
   21874              :     }
   21875              :   else
   21876      1368896 :     outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
   21877              : 
   21878      3049005 :   DECL_SAVED_TREE (fndecl) = NULL_TREE;
   21879              : 
   21880              :   /* If we had callee-copies statements, insert them at the beginning
   21881              :      of the function and clear DECL_HAS_VALUE_EXPR_P on the parameters.  */
   21882      3049005 :   if (!gimple_seq_empty_p (parm_stmts))
   21883              :     {
   21884           41 :       tree parm;
   21885              : 
   21886           41 :       gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
   21887           41 :       if (parm_cleanup)
   21888              :         {
   21889            0 :           gtry *g = gimple_build_try (parm_stmts, parm_cleanup,
   21890              :                                       GIMPLE_TRY_FINALLY);
   21891            0 :           parm_stmts = NULL;
   21892            0 :           gimple_seq_add_stmt (&parm_stmts, g);
   21893              :         }
   21894           41 :       gimple_bind_set_body (outer_bind, parm_stmts);
   21895              : 
   21896           41 :       for (parm = DECL_ARGUMENTS (current_function_decl);
   21897          101 :            parm; parm = DECL_CHAIN (parm))
   21898           60 :         if (DECL_HAS_VALUE_EXPR_P (parm))
   21899              :           {
   21900            0 :             DECL_HAS_VALUE_EXPR_P (parm) = 0;
   21901            0 :             DECL_IGNORED_P (parm) = 0;
   21902              :           }
   21903              :     }
   21904              : 
   21905      3049005 :   if ((flag_openacc || flag_openmp || flag_openmp_simd)
   21906        57565 :       && gimplify_omp_ctxp)
   21907              :     {
   21908         9806 :       delete_omp_context (gimplify_omp_ctxp);
   21909         9806 :       gimplify_omp_ctxp = NULL;
   21910              :     }
   21911              : 
   21912      3049005 :   pop_gimplify_context (outer_bind);
   21913      3049005 :   gcc_assert (gimplify_ctxp == NULL);
   21914              : 
   21915      3049005 :   if (flag_checking && !seen_error ())
   21916      2997562 :     verify_gimple_in_seq (gimple_bind_body (outer_bind));
   21917              : 
   21918      3049005 :   timevar_pop (TV_TREE_GIMPLIFY);
   21919      3049005 :   input_location = saved_location;
   21920              : 
   21921      3049005 :   return outer_bind;
   21922              : }
   21923              : 
   21924              : typedef char *char_p; /* For DEF_VEC_P.  */
   21925              : 
   21926              : /* Return whether we should exclude FNDECL from instrumentation.  */
   21927              : 
   21928              : static bool
   21929           43 : flag_instrument_functions_exclude_p (tree fndecl)
   21930              : {
   21931           43 :   vec<char_p> *v;
   21932              : 
   21933           43 :   v = (vec<char_p> *) flag_instrument_functions_exclude_functions;
   21934           44 :   if (v && v->length () > 0)
   21935              :     {
   21936            1 :       const char *name;
   21937            1 :       int i;
   21938            1 :       char *s;
   21939              : 
   21940            1 :       name = lang_hooks.decl_printable_name (fndecl, 1);
   21941            2 :       FOR_EACH_VEC_ELT (*v, i, s)
   21942            1 :         if (strstr (name, s) != NULL)
   21943           43 :           return true;
   21944              :     }
   21945              : 
   21946           42 :   v = (vec<char_p> *) flag_instrument_functions_exclude_files;
   21947           43 :   if (v && v->length () > 0)
   21948              :     {
   21949            1 :       const char *name;
   21950            1 :       int i;
   21951            1 :       char *s;
   21952              : 
   21953            1 :       name = DECL_SOURCE_FILE (fndecl);
   21954            1 :       FOR_EACH_VEC_ELT (*v, i, s)
   21955            1 :         if (strstr (name, s) != NULL)
   21956           43 :           return true;
   21957              :     }
   21958              : 
   21959              :   return false;
   21960              : }
   21961              : 
   21962              : /* Build a call to the instrumentation function FNCODE and add it to SEQ.
   21963              :    If COND_VAR is not NULL, it is a boolean variable guarding the call to
   21964              :    the instrumentation function.  IF STMT is not NULL, it is a statement
   21965              :    to be executed just before the call to the instrumentation function.  */
   21966              : 
   21967              : static void
   21968           82 : build_instrumentation_call (gimple_seq *seq, enum built_in_function fncode,
   21969              :                             tree cond_var, gimple *stmt)
   21970              : {
   21971              :   /* The instrumentation hooks aren't going to call the instrumented
   21972              :      function and the address they receive is expected to be matchable
   21973              :      against symbol addresses.  Make sure we don't create a trampoline,
   21974              :      in case the current function is nested.  */
   21975           82 :   tree this_fn_addr = build_fold_addr_expr (current_function_decl);
   21976           82 :   TREE_NO_TRAMPOLINE (this_fn_addr) = 1;
   21977              : 
   21978           82 :   tree label_true, label_false;
   21979           82 :   if (cond_var)
   21980              :     {
   21981           20 :       label_true = create_artificial_label (UNKNOWN_LOCATION);
   21982           20 :       label_false = create_artificial_label (UNKNOWN_LOCATION);
   21983           20 :       gcond *cond = gimple_build_cond (EQ_EXPR, cond_var, boolean_false_node,
   21984              :                                       label_true, label_false);
   21985           20 :       gimplify_seq_add_stmt (seq, cond);
   21986           20 :       gimplify_seq_add_stmt (seq, gimple_build_label (label_true));
   21987           20 :       gimplify_seq_add_stmt (seq, gimple_build_predict (PRED_COLD_LABEL,
   21988              :                                                         NOT_TAKEN));
   21989              :     }
   21990              : 
   21991           82 :   if (stmt)
   21992           10 :     gimplify_seq_add_stmt (seq, stmt);
   21993              : 
   21994           82 :   tree x = builtin_decl_implicit (BUILT_IN_RETURN_ADDRESS);
   21995           82 :   gcall *call = gimple_build_call (x, 1, integer_zero_node);
   21996           82 :   tree tmp_var = create_tmp_var (ptr_type_node, "return_addr");
   21997           82 :   gimple_call_set_lhs (call, tmp_var);
   21998           82 :   gimplify_seq_add_stmt (seq, call);
   21999           82 :   x = builtin_decl_implicit (fncode);
   22000           82 :   call = gimple_build_call (x, 2, this_fn_addr, tmp_var);
   22001           82 :   gimplify_seq_add_stmt (seq, call);
   22002              : 
   22003           82 :   if (cond_var)
   22004           20 :     gimplify_seq_add_stmt (seq, gimple_build_label (label_false));
   22005           82 : }
   22006              : 
   22007              : /* Entry point to the gimplification pass.  FNDECL is the FUNCTION_DECL
   22008              :    node for the function we want to gimplify.
   22009              : 
   22010              :    Return the sequence of GIMPLE statements corresponding to the body
   22011              :    of FNDECL.  */
   22012              : 
   22013              : void
   22014      3048501 : gimplify_function_tree (tree fndecl)
   22015              : {
   22016      3048501 :   gimple_seq seq;
   22017      3048501 :   gbind *bind;
   22018              : 
   22019      3048501 :   gcc_assert (!gimple_body (fndecl));
   22020              : 
   22021      3048501 :   if (DECL_STRUCT_FUNCTION (fndecl))
   22022      3044102 :     push_cfun (DECL_STRUCT_FUNCTION (fndecl));
   22023              :   else
   22024         4399 :     push_struct_function (fndecl);
   22025              : 
   22026      3048501 :   reset_cond_uid ();
   22027      3048501 :   if (cond_uids)
   22028              :     {
   22029           68 :       delete cond_uids;
   22030           68 :       cond_uids = NULL;
   22031              :     }
   22032              : 
   22033              :   /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
   22034              :      if necessary.  */
   22035      3048501 :   cfun->curr_properties |= PROP_gimple_lva;
   22036              : 
   22037      3048501 :   if (asan_sanitize_use_after_scope ())
   22038         8600 :     asan_poisoned_variables = new hash_set<tree> ();
   22039      3048501 :   if (flag_openmp)
   22040        47561 :     omp_resolved_variant_calls = new hash_set<tree> ();
   22041              : 
   22042      3048501 :   bind = gimplify_body (fndecl, true);
   22043              : 
   22044      3048501 :   if (omp_resolved_variant_calls)
   22045              :     {
   22046        47561 :       delete omp_resolved_variant_calls;
   22047        47561 :       omp_resolved_variant_calls = NULL;
   22048              :     }
   22049      3048501 :   if (asan_poisoned_variables)
   22050              :     {
   22051         8600 :       delete asan_poisoned_variables;
   22052         8600 :       asan_poisoned_variables = NULL;
   22053              :     }
   22054              : 
   22055              :   /* The tree body of the function is no longer needed, replace it
   22056              :      with the new GIMPLE body.  */
   22057      3048501 :   seq = NULL;
   22058      3048501 :   gimple_seq_add_stmt (&seq, bind);
   22059      3048501 :   gimple_set_body (fndecl, seq);
   22060              : 
   22061              :   /* If we're instrumenting function entry/exit, then prepend the call to
   22062              :      the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
   22063              :      catch the exit hook.  */
   22064              :   /* ??? Add some way to ignore exceptions for this TFE.  */
   22065      3048501 :   if (flag_instrument_function_entry_exit
   22066           97 :       && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
   22067              :       /* Do not instrument extern inline functions.  */
   22068           44 :       && !(DECL_DECLARED_INLINE_P (fndecl)
   22069            6 :            && DECL_EXTERNAL (fndecl)
   22070            1 :            && DECL_DISREGARD_INLINE_LIMITS (fndecl))
   22071      3048544 :       && !flag_instrument_functions_exclude_p (fndecl))
   22072              :     {
   22073           41 :       gimple_seq body = NULL, cleanup = NULL;
   22074           41 :       gassign *assign;
   22075           41 :       tree cond_var;
   22076              : 
   22077              :       /* If -finstrument-functions-once is specified, generate:
   22078              : 
   22079              :            static volatile bool C.0 = false;
   22080              :            bool tmp_called;
   22081              : 
   22082              :            tmp_called = C.0;
   22083              :            if (!tmp_called)
   22084              :              {
   22085              :                C.0 = true;
   22086              :                [call profiling enter function]
   22087              :              }
   22088              : 
   22089              :          without specific protection for data races.  */
   22090           41 :       if (flag_instrument_function_entry_exit > 1)
   22091              :         {
   22092           10 :           tree first_var
   22093           10 :             = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
   22094              :                           VAR_DECL,
   22095              :                           create_tmp_var_name ("C"),
   22096              :                           boolean_type_node);
   22097           10 :           DECL_ARTIFICIAL (first_var) = 1;
   22098           10 :           DECL_IGNORED_P (first_var) = 1;
   22099           10 :           TREE_STATIC (first_var) = 1;
   22100           10 :           TREE_THIS_VOLATILE (first_var) = 1;
   22101           10 :           TREE_USED (first_var) = 1;
   22102           10 :           DECL_INITIAL (first_var) = boolean_false_node;
   22103           10 :           varpool_node::add (first_var);
   22104              : 
   22105           10 :           cond_var = create_tmp_var (boolean_type_node, "tmp_called");
   22106           10 :           assign = gimple_build_assign (cond_var, first_var);
   22107           10 :           gimplify_seq_add_stmt (&body, assign);
   22108              : 
   22109           10 :           assign = gimple_build_assign (first_var, boolean_true_node);
   22110              :         }
   22111              : 
   22112              :       else
   22113              :         {
   22114              :           cond_var = NULL_TREE;
   22115              :           assign = NULL;
   22116              :         }
   22117              : 
   22118           41 :       build_instrumentation_call (&body, BUILT_IN_PROFILE_FUNC_ENTER,
   22119              :                                   cond_var, assign);
   22120              : 
   22121              :       /* If -finstrument-functions-once is specified, generate:
   22122              : 
   22123              :            if (!tmp_called)
   22124              :              [call profiling exit function]
   22125              : 
   22126              :          without specific protection for data races.  */
   22127           41 :       build_instrumentation_call (&cleanup, BUILT_IN_PROFILE_FUNC_EXIT,
   22128              :                                   cond_var, NULL);
   22129              : 
   22130           41 :       gimple *tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
   22131           41 :       gimplify_seq_add_stmt (&body, tf);
   22132           41 :       gbind *new_bind = gimple_build_bind (NULL, body, NULL);
   22133              : 
   22134              :       /* Replace the current function body with the body
   22135              :          wrapped in the try/finally TF.  */
   22136           41 :       seq = NULL;
   22137           41 :       gimple_seq_add_stmt (&seq, new_bind);
   22138           41 :       gimple_set_body (fndecl, seq);
   22139           41 :       bind = new_bind;
   22140              :     }
   22141              : 
   22142      3048501 :   if (sanitize_flags_p (SANITIZE_THREAD)
   22143      3048501 :       && param_tsan_instrument_func_entry_exit)
   22144              :     {
   22145          967 :       gcall *call = gimple_build_call_internal (IFN_TSAN_FUNC_EXIT, 0);
   22146          967 :       gimple *tf = gimple_build_try (seq, call, GIMPLE_TRY_FINALLY);
   22147          967 :       gbind *new_bind = gimple_build_bind (NULL, tf, NULL);
   22148              :       /* Replace the current function body with the body
   22149              :          wrapped in the try/finally TF.  */
   22150          967 :       seq = NULL;
   22151          967 :       gimple_seq_add_stmt (&seq, new_bind);
   22152          967 :       gimple_set_body (fndecl, seq);
   22153              :     }
   22154              : 
   22155      3048501 :   DECL_SAVED_TREE (fndecl) = NULL_TREE;
   22156      3048501 :   cfun->curr_properties |= PROP_gimple_any;
   22157              : 
   22158      3048501 :   pop_cfun ();
   22159              : 
   22160      3048501 :   dump_function (TDI_gimple, fndecl);
   22161      3048501 : }
   22162              : 
   22163              : /* Return a dummy expression of type TYPE in order to keep going after an
   22164              :    error.  */
   22165              : 
   22166              : static tree
   22167           30 : dummy_object (tree type)
   22168              : {
   22169           30 :   tree t = build_int_cst (build_pointer_type (type), 0);
   22170           30 :   return build2 (MEM_REF, type, t, t);
   22171              : }
   22172              : 
   22173              : /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
   22174              :    builtin function, but a very special sort of operator.  */
   22175              : 
   22176              : enum gimplify_status
   22177        51195 : gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p,
   22178              :                       gimple_seq *post_p ATTRIBUTE_UNUSED)
   22179              : {
   22180        51195 :   tree promoted_type, have_va_type;
   22181        51195 :   tree valist = TREE_OPERAND (*expr_p, 0);
   22182        51195 :   tree type = TREE_TYPE (*expr_p);
   22183        51195 :   tree t, tag, aptag;
   22184        51195 :   location_t loc = EXPR_LOCATION (*expr_p);
   22185              : 
   22186              :   /* Verify that valist is of the proper type.  */
   22187        51195 :   have_va_type = TREE_TYPE (valist);
   22188        51195 :   if (have_va_type == error_mark_node)
   22189              :     return GS_ERROR;
   22190        51176 :   have_va_type = targetm.canonical_va_list_type (have_va_type);
   22191        51176 :   if (have_va_type == NULL_TREE
   22192        51176 :       && POINTER_TYPE_P (TREE_TYPE (valist)))
   22193              :     /* Handle 'Case 1: Not an array type' from c-common.cc/build_va_arg.  */
   22194          270 :     have_va_type
   22195          270 :       = targetm.canonical_va_list_type (TREE_TYPE (TREE_TYPE (valist)));
   22196        51176 :   gcc_assert (have_va_type != NULL_TREE);
   22197              : 
   22198              :   /* Generate a diagnostic for requesting data of a type that cannot
   22199              :      be passed through `...' due to type promotion at the call site.  */
   22200        51176 :   if ((promoted_type = lang_hooks.types.type_promotes_to (type))
   22201              :            != type)
   22202              :     {
   22203           30 :       static bool gave_help;
   22204           30 :       bool warned;
   22205              :       /* Use the expansion point to handle cases such as passing bool (defined
   22206              :          in a system header) through `...'.  */
   22207           30 :       location_t xloc
   22208           30 :         = expansion_point_location_if_in_system_header (loc);
   22209              : 
   22210              :       /* Unfortunately, this is merely undefined, rather than a constraint
   22211              :          violation, so we cannot make this an error.  If this call is never
   22212              :          executed, the program is still strictly conforming.  */
   22213           30 :       auto_diagnostic_group d;
   22214           30 :       warned = warning_at (xloc, 0,
   22215              :                            "%qT is promoted to %qT when passed through %<...%>",
   22216              :                            type, promoted_type);
   22217           30 :       if (!gave_help && warned)
   22218              :         {
   22219           15 :           gave_help = true;
   22220           15 :           inform (xloc, "(so you should pass %qT not %qT to %<va_arg%>)",
   22221              :                   promoted_type, type);
   22222              :         }
   22223              : 
   22224              :       /* We can, however, treat "undefined" any way we please.
   22225              :          Call abort to encourage the user to fix the program.  */
   22226           23 :       if (warned)
   22227           23 :         inform (xloc, "if this code is reached, the program will abort");
   22228              :       /* Before the abort, allow the evaluation of the va_list
   22229              :          expression to exit or longjmp.  */
   22230           30 :       gimplify_and_add (valist, pre_p);
   22231           60 :       t = build_call_expr_loc (loc,
   22232              :                                builtin_decl_implicit (BUILT_IN_TRAP), 0);
   22233           30 :       gimplify_and_add (t, pre_p);
   22234              : 
   22235              :       /* This is dead code, but go ahead and finish so that the
   22236              :          mode of the result comes out right.  */
   22237           30 :       *expr_p = dummy_object (type);
   22238           30 :       return GS_ALL_DONE;
   22239           30 :     }
   22240              : 
   22241        51146 :   tag = build_int_cst (build_pointer_type (type), 0);
   22242        51146 :   aptag = build_int_cst (TREE_TYPE (valist), 0);
   22243              : 
   22244        51146 :   *expr_p = build_call_expr_internal_loc (loc, IFN_VA_ARG, type, 3,
   22245              :                                           valist, tag, aptag);
   22246              : 
   22247              :   /* Clear the tentatively set PROP_gimple_lva, to indicate that IFN_VA_ARG
   22248              :      needs to be expanded.  */
   22249        51146 :   cfun->curr_properties &= ~PROP_gimple_lva;
   22250              : 
   22251        51146 :   return GS_OK;
   22252              : }
   22253              : 
   22254              : /* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
   22255              : 
   22256              :    DST/SRC are the destination and source respectively.  You can pass
   22257              :    ungimplified trees in DST or SRC, in which case they will be
   22258              :    converted to a gimple operand if necessary.
   22259              : 
   22260              :    This function returns the newly created GIMPLE_ASSIGN tuple.  */
   22261              : 
   22262              : gimple *
   22263       913879 : gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
   22264              : {
   22265       913879 :   tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
   22266       913879 :   gimplify_and_add (t, seq_p);
   22267       913879 :   ggc_free (t);
   22268       913879 :   return gimple_seq_last_stmt (*seq_p);
   22269              : }
   22270              : 
   22271              : inline hashval_t
   22272      1615996 : gimplify_hasher::hash (const elt_t *p)
   22273              : {
   22274      1615996 :   tree t = p->val;
   22275      1615996 :   return iterative_hash_expr (t, 0);
   22276              : }
   22277              : 
   22278              : inline bool
   22279       598535 : gimplify_hasher::equal (const elt_t *p1, const elt_t *p2)
   22280              : {
   22281       598535 :   tree t1 = p1->val;
   22282       598535 :   tree t2 = p2->val;
   22283       598535 :   enum tree_code code = TREE_CODE (t1);
   22284              : 
   22285       598535 :   if (TREE_CODE (t2) != code
   22286       598535 :       || TREE_TYPE (t1) != TREE_TYPE (t2))
   22287              :     return false;
   22288              : 
   22289       366899 :   if (!operand_equal_p (t1, t2, 0))
   22290              :     return false;
   22291              : 
   22292              :   return true;
   22293              : }
        

Generated by: LCOV version 2.5.0-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.